github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/cmd/geth/accountcmd_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"io/ioutil"
    21  	"path/filepath"
    22  	"runtime"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/cespare/cp"
    27  )
    28  
    29  // These tests are 'smoke tests' for the account related
    30  // subcommands and flags.
    31  //
    32  // For most tests, the test files from package accounts
    33  // are copied into a temporary keystore directory.
    34  
    35  func tmpDatadirWithKeystore(t *testing.T) string {
    36  	datadir := tmpdir(t)
    37  	keystore := filepath.Join(datadir, "keystore")
    38  	source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore")
    39  	if err := cp.CopyAll(keystore, source); err != nil {
    40  		t.Fatal(err)
    41  	}
    42  	return datadir
    43  }
    44  
    45  func TestAccountListEmpty(t *testing.T) {
    46  	geth := runGeth(t, "account", "list")
    47  	geth.ExpectExit()
    48  }
    49  
    50  func TestAccountList(t *testing.T) {
    51  	datadir := tmpDatadirWithKeystore(t)
    52  	geth := runGeth(t, "account", "list", "--datadir", datadir)
    53  	defer geth.ExpectExit()
    54  	if runtime.GOOS == "windows" {
    55  		geth.Expect(`
    56  Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
    57  Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa
    58  Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz
    59  `)
    60  	} else {
    61  		geth.Expect(`
    62  Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
    63  Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
    64  Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz
    65  `)
    66  	}
    67  }
    68  
    69  func TestAccountNew(t *testing.T) {
    70  	geth := runGeth(t, "account", "new", "--lightkdf")
    71  	defer geth.ExpectExit()
    72  	geth.Expect(`
    73  Your new account is locked with a password. Please give a password. Do not forget this password.
    74  !! Unsupported terminal, password will be echoed.
    75  Password: {{.InputLine "foobar"}}
    76  Repeat password: {{.InputLine "foobar"}}
    77  
    78  Your new key was generated
    79  `)
    80  	geth.ExpectRegexp(`
    81  Public address of the key:   0x[0-9a-fA-F]{40}
    82  Path of the secret key file: .*UTC--.+--[0-9a-f]{40}
    83  
    84  - You can share your public address with anyone. Others need it to interact with you.
    85  - You must NEVER share the secret key with anyone! The key controls access to your funds!
    86  - You must BACKUP your key file! Without the key, it's impossible to access account funds!
    87  - You must REMEMBER your password! Without the password, it's impossible to decrypt the key!
    88  `)
    89  }
    90  
    91  func TestAccountImport(t *testing.T) {
    92  	tests := []struct{ name, key, output string }{
    93  		{
    94  			name:   "correct account",
    95  			key:    "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    96  			output: "Address: {fcad0b19bb29d4674531d6f115237e16afce377c}\n",
    97  		},
    98  		{
    99  			name:   "invalid character",
   100  			key:    "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef1",
   101  			output: "Fatal: Failed to load the private key: invalid character '1' at end of key file\n",
   102  		},
   103  	}
   104  	for _, test := range tests {
   105  		test := test
   106  		t.Run(test.name, func(t *testing.T) {
   107  			t.Parallel()
   108  			importAccountWithExpect(t, test.key, test.output)
   109  		})
   110  	}
   111  }
   112  
   113  func importAccountWithExpect(t *testing.T, key string, expected string) {
   114  	dir := tmpdir(t)
   115  	keyfile := filepath.Join(dir, "key.prv")
   116  	if err := ioutil.WriteFile(keyfile, []byte(key), 0600); err != nil {
   117  		t.Error(err)
   118  	}
   119  	passwordFile := filepath.Join(dir, "password.txt")
   120  	if err := ioutil.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil {
   121  		t.Error(err)
   122  	}
   123  	geth := runGeth(t, "account", "import", keyfile, "-password", passwordFile)
   124  	defer geth.ExpectExit()
   125  	geth.Expect(expected)
   126  }
   127  
   128  func TestAccountNewBadRepeat(t *testing.T) {
   129  	geth := runGeth(t, "account", "new", "--lightkdf")
   130  	defer geth.ExpectExit()
   131  	geth.Expect(`
   132  Your new account is locked with a password. Please give a password. Do not forget this password.
   133  !! Unsupported terminal, password will be echoed.
   134  Password: {{.InputLine "something"}}
   135  Repeat password: {{.InputLine "something else"}}
   136  Fatal: Passwords do not match
   137  `)
   138  }
   139  
   140  func TestAccountUpdate(t *testing.T) {
   141  	datadir := tmpDatadirWithKeystore(t)
   142  	geth := runGeth(t, "account", "update",
   143  		"--datadir", datadir, "--lightkdf",
   144  		"f466859ead1932d743d622cb74fc058882e8648a")
   145  	defer geth.ExpectExit()
   146  	geth.Expect(`
   147  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   148  !! Unsupported terminal, password will be echoed.
   149  Password: {{.InputLine "foobar"}}
   150  Please give a new password. Do not forget this password.
   151  Password: {{.InputLine "foobar2"}}
   152  Repeat password: {{.InputLine "foobar2"}}
   153  `)
   154  }
   155  
   156  func TestWalletImport(t *testing.T) {
   157  	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   158  	defer geth.ExpectExit()
   159  	geth.Expect(`
   160  !! Unsupported terminal, password will be echoed.
   161  Password: {{.InputLine "foo"}}
   162  Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
   163  `)
   164  
   165  	files, err := ioutil.ReadDir(filepath.Join(geth.Datadir, "keystore"))
   166  	if len(files) != 1 {
   167  		t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
   168  	}
   169  }
   170  
   171  func TestWalletImportBadPassword(t *testing.T) {
   172  	geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   173  	defer geth.ExpectExit()
   174  	geth.Expect(`
   175  !! Unsupported terminal, password will be echoed.
   176  Password: {{.InputLine "wrong"}}
   177  Fatal: could not decrypt key with given password
   178  `)
   179  }
   180  
   181  func TestUnlockFlag(t *testing.T) {
   182  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   183  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js")
   184  	geth.Expect(`
   185  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   186  !! Unsupported terminal, password will be echoed.
   187  Password: {{.InputLine "foobar"}}
   188  `)
   189  	geth.ExpectExit()
   190  
   191  	wantMessages := []string{
   192  		"Unlocked account",
   193  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   194  	}
   195  	for _, m := range wantMessages {
   196  		if !strings.Contains(geth.StderrText(), m) {
   197  			t.Errorf("stderr text does not contain %q", m)
   198  		}
   199  	}
   200  }
   201  
   202  func TestUnlockFlagWrongPassword(t *testing.T) {
   203  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   204  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js")
   205  
   206  	defer geth.ExpectExit()
   207  	geth.Expect(`
   208  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   209  !! Unsupported terminal, password will be echoed.
   210  Password: {{.InputLine "wrong1"}}
   211  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
   212  Password: {{.InputLine "wrong2"}}
   213  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
   214  Password: {{.InputLine "wrong3"}}
   215  Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password)
   216  `)
   217  }
   218  
   219  // https://github.com/DxChainNetwork/dxc/issues/1785
   220  func TestUnlockFlagMultiIndex(t *testing.T) {
   221  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   222  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "js", "testdata/empty.js")
   223  
   224  	geth.Expect(`
   225  Unlocking account 0 | Attempt 1/3
   226  !! Unsupported terminal, password will be echoed.
   227  Password: {{.InputLine "foobar"}}
   228  Unlocking account 2 | Attempt 1/3
   229  Password: {{.InputLine "foobar"}}
   230  `)
   231  	geth.ExpectExit()
   232  
   233  	wantMessages := []string{
   234  		"Unlocked account",
   235  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   236  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   237  	}
   238  	for _, m := range wantMessages {
   239  		if !strings.Contains(geth.StderrText(), m) {
   240  			t.Errorf("stderr text does not contain %q", m)
   241  		}
   242  	}
   243  }
   244  
   245  func TestUnlockFlagPasswordFile(t *testing.T) {
   246  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   247  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "js", "testdata/empty.js")
   248  
   249  	geth.ExpectExit()
   250  
   251  	wantMessages := []string{
   252  		"Unlocked account",
   253  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   254  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   255  	}
   256  	for _, m := range wantMessages {
   257  		if !strings.Contains(geth.StderrText(), m) {
   258  			t.Errorf("stderr text does not contain %q", m)
   259  		}
   260  	}
   261  }
   262  
   263  func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
   264  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   265  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password",
   266  		"testdata/wrong-passwords.txt", "--unlock", "0,2")
   267  	defer geth.ExpectExit()
   268  	geth.Expect(`
   269  Fatal: Failed to unlock account 0 (could not decrypt key with given password)
   270  `)
   271  }
   272  
   273  func TestUnlockFlagAmbiguous(t *testing.T) {
   274  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   275  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   276  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
   277  		store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
   278  		"js", "testdata/empty.js")
   279  	defer geth.ExpectExit()
   280  
   281  	// Helper for the expect template, returns absolute keystore path.
   282  	geth.SetTemplateFunc("keypath", func(file string) string {
   283  		abs, _ := filepath.Abs(filepath.Join(store, file))
   284  		return abs
   285  	})
   286  	geth.Expect(`
   287  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   288  !! Unsupported terminal, password will be echoed.
   289  Password: {{.InputLine "foobar"}}
   290  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   291     keystore://{{keypath "1"}}
   292     keystore://{{keypath "2"}}
   293  Testing your password against all of them...
   294  Your password unlocked keystore://{{keypath "1"}}
   295  In order to avoid this warning, you need to remove the following duplicate key files:
   296     keystore://{{keypath "2"}}
   297  `)
   298  	geth.ExpectExit()
   299  
   300  	wantMessages := []string{
   301  		"Unlocked account",
   302  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   303  	}
   304  	for _, m := range wantMessages {
   305  		if !strings.Contains(geth.StderrText(), m) {
   306  			t.Errorf("stderr text does not contain %q", m)
   307  		}
   308  	}
   309  }
   310  
   311  func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
   312  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   313  	geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
   314  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
   315  		store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   316  
   317  	defer geth.ExpectExit()
   318  
   319  	// Helper for the expect template, returns absolute keystore path.
   320  	geth.SetTemplateFunc("keypath", func(file string) string {
   321  		abs, _ := filepath.Abs(filepath.Join(store, file))
   322  		return abs
   323  	})
   324  	geth.Expect(`
   325  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   326  !! Unsupported terminal, password will be echoed.
   327  Password: {{.InputLine "wrong"}}
   328  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   329     keystore://{{keypath "1"}}
   330     keystore://{{keypath "2"}}
   331  Testing your password against all of them...
   332  Fatal: None of the listed files could be unlocked.
   333  `)
   334  	geth.ExpectExit()
   335  }