|
|
@@ -23,11 +23,14 @@ import (
|
|
|
"runtime"
|
|
|
"sort"
|
|
|
"strings"
|
|
|
+ "sync"
|
|
|
+ "sync/atomic"
|
|
|
"testing"
|
|
|
"time"
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
+ "github.com/ethereum/go-ethereum/crypto"
|
|
|
"github.com/ethereum/go-ethereum/event"
|
|
|
)
|
|
|
|
|
|
@@ -338,6 +341,88 @@ func TestWalletNotifications(t *testing.T) {
|
|
|
checkEvents(t, wantEvents, events)
|
|
|
}
|
|
|
|
|
|
+// TestImportExport tests the import functionality of a keystore.
|
|
|
+func TestImportECDSA(t *testing.T) {
|
|
|
+ dir, ks := tmpKeyStore(t, true)
|
|
|
+ defer os.RemoveAll(dir)
|
|
|
+ key, err := crypto.GenerateKey()
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to generate key: %v", key)
|
|
|
+ }
|
|
|
+ if _, err = ks.ImportECDSA(key, "old"); err != nil {
|
|
|
+ t.Errorf("importing failed: %v", err)
|
|
|
+ }
|
|
|
+ if _, err = ks.ImportECDSA(key, "old"); err == nil {
|
|
|
+ t.Errorf("importing same key twice succeeded")
|
|
|
+ }
|
|
|
+ if _, err = ks.ImportECDSA(key, "new"); err == nil {
|
|
|
+ t.Errorf("importing same key twice succeeded")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// TestImportECDSA tests the import and export functionality of a keystore.
|
|
|
+func TestImportExport(t *testing.T) {
|
|
|
+ dir, ks := tmpKeyStore(t, true)
|
|
|
+ defer os.RemoveAll(dir)
|
|
|
+ acc, err := ks.NewAccount("old")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create account: %v", acc)
|
|
|
+ }
|
|
|
+ json, err := ks.Export(acc, "old", "new")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to export account: %v", acc)
|
|
|
+ }
|
|
|
+ dir2, ks2 := tmpKeyStore(t, true)
|
|
|
+ defer os.RemoveAll(dir2)
|
|
|
+ if _, err = ks2.Import(json, "old", "old"); err == nil {
|
|
|
+ t.Errorf("importing with invalid password succeeded")
|
|
|
+ }
|
|
|
+ acc2, err := ks2.Import(json, "new", "new")
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("importing failed: %v", err)
|
|
|
+ }
|
|
|
+ if acc.Address != acc2.Address {
|
|
|
+ t.Error("imported account does not match exported account")
|
|
|
+ }
|
|
|
+ if _, err = ks2.Import(json, "new", "new"); err == nil {
|
|
|
+ t.Errorf("importing a key twice succeeded")
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// TestImportRace tests the keystore on races.
|
|
|
+// This test should fail under -race if importing races.
|
|
|
+func TestImportRace(t *testing.T) {
|
|
|
+ dir, ks := tmpKeyStore(t, true)
|
|
|
+ defer os.RemoveAll(dir)
|
|
|
+ acc, err := ks.NewAccount("old")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create account: %v", acc)
|
|
|
+ }
|
|
|
+ json, err := ks.Export(acc, "old", "new")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to export account: %v", acc)
|
|
|
+ }
|
|
|
+ dir2, ks2 := tmpKeyStore(t, true)
|
|
|
+ defer os.RemoveAll(dir2)
|
|
|
+ var atom uint32
|
|
|
+ var wg sync.WaitGroup
|
|
|
+ wg.Add(2)
|
|
|
+ for i := 0; i < 2; i++ {
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ if _, err := ks2.Import(json, "new", "new"); err != nil {
|
|
|
+ atomic.AddUint32(&atom, 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ }()
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+ if atom != 1 {
|
|
|
+ t.Errorf("Import is racy")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// checkAccounts checks that all known live accounts are present in the wallet list.
|
|
|
func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, wallets []accounts.Wallet) {
|
|
|
if len(live) != len(wallets) {
|