github.com/bcskill/bcschain/v3@v3.4.9-beta2/cmd/gochain/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 := runGoChain(t, "account", "list")
    47  	geth.ExpectExit()
    48  }
    49  
    50  func TestAccountList(t *testing.T) {
    51  	datadir := tmpDatadirWithKeystore(t)
    52  	geth := runGoChain(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 := runGoChain(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  		t.Run(test.name, func(t *testing.T) {
   106  			t.Parallel()
   107  			importAccountWithExpect(t, test.key, test.output)
   108  		})
   109  	}
   110  }
   111  
   112  func importAccountWithExpect(t *testing.T, key string, expected string) {
   113  	dir := tmpdir(t)
   114  	keyfile := filepath.Join(dir, "key.prv")
   115  	if err := ioutil.WriteFile(keyfile, []byte(key), 0600); err != nil {
   116  		t.Error(err)
   117  	}
   118  	passwordFile := filepath.Join(dir, "password.txt")
   119  	if err := ioutil.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil {
   120  		t.Error(err)
   121  	}
   122  	geth := runGoChain(t, "account", "import", keyfile, "-password", passwordFile)
   123  	defer geth.ExpectExit()
   124  	geth.Expect(expected)
   125  }
   126  
   127  func TestAccountNewBadRepeat(t *testing.T) {
   128  	geth := runGoChain(t, "account", "new", "--lightkdf")
   129  	defer geth.ExpectExit()
   130  	geth.Expect(`
   131  Your new account is locked with a password. Please give a password. Do not forget this password.
   132  !! Unsupported terminal, password will be echoed.
   133  Password: {{.InputLine "something"}}
   134  Repeat password: {{.InputLine "something else"}}
   135  Fatal: Passwords do not match
   136  `)
   137  }
   138  
   139  func TestAccountUpdate(t *testing.T) {
   140  	datadir := tmpDatadirWithKeystore(t)
   141  	geth := runGoChain(t, "account", "update",
   142  		"--datadir", datadir, "--lightkdf",
   143  		"f466859ead1932d743d622cb74fc058882e8648a")
   144  	defer geth.ExpectExit()
   145  	geth.Expect(`
   146  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   147  !! Unsupported terminal, password will be echoed.
   148  Password: {{.InputLine "foobar"}}
   149  Please give a new password. Do not forget this password.
   150  Password: {{.InputLine "foobar2"}}
   151  Repeat password: {{.InputLine "foobar2"}}
   152  `)
   153  }
   154  
   155  func TestWalletImport(t *testing.T) {
   156  	geth := runGoChain(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   157  	defer geth.ExpectExit()
   158  	geth.Expect(`
   159  !! Unsupported terminal, password will be echoed.
   160  Password: {{.InputLine "foo"}}
   161  Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
   162  `)
   163  
   164  	files, err := ioutil.ReadDir(filepath.Join(geth.Datadir, "keystore"))
   165  	if len(files) != 1 {
   166  		t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
   167  	}
   168  }
   169  
   170  func TestWalletImportBadPassword(t *testing.T) {
   171  	geth := runGoChain(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
   172  	defer geth.ExpectExit()
   173  	geth.Expect(`
   174  !! Unsupported terminal, password will be echoed.
   175  Password: {{.InputLine "wrong"}}
   176  Fatal: could not decrypt key with given password
   177  `)
   178  }
   179  
   180  func TestUnlockFlag(t *testing.T) {
   181  	datadir := tmpDatadirWithKeystore(t)
   182  	geth := runGoChain(t,
   183  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   184  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
   185  		"js", "testdata/empty.js")
   186  	geth.Expect(`
   187  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   188  !! Unsupported terminal, password will be echoed.
   189  Password: {{.InputLine "foobar"}}
   190  `)
   191  	geth.ExpectExit()
   192  
   193  	wantMessages := []string{
   194  		"Unlocked account",
   195  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   196  	}
   197  	for _, m := range wantMessages {
   198  		if !strings.Contains(geth.StderrText(), m) {
   199  			t.Errorf("stderr text does not contain %q", m)
   200  		}
   201  	}
   202  }
   203  
   204  func TestUnlockFlagWrongPassword(t *testing.T) {
   205  	datadir := tmpDatadirWithKeystore(t)
   206  	geth := runGoChain(t,
   207  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   208  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   209  	defer geth.ExpectExit()
   210  	geth.Expect(`
   211  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   212  !! Unsupported terminal, password will be echoed.
   213  Password: {{.InputLine "wrong1"}}
   214  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
   215  Password: {{.InputLine "wrong2"}}
   216  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
   217  Password: {{.InputLine "wrong3"}}
   218  Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password)
   219  `)
   220  }
   221  
   222  // https://github.com/ethereum/go-ethereum/issues/1785
   223  func TestUnlockFlagMultiIndex(t *testing.T) {
   224  	datadir := tmpDatadirWithKeystore(t)
   225  	geth := runGoChain(t,
   226  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   227  		"--unlock", "0,2",
   228  		"js", "testdata/empty.js")
   229  	geth.Expect(`
   230  Unlocking account 0 | Attempt 1/3
   231  !! Unsupported terminal, password will be echoed.
   232  Password: {{.InputLine "foobar"}}
   233  Unlocking account 2 | Attempt 1/3
   234  Password: {{.InputLine "foobar"}}
   235  `)
   236  	geth.ExpectExit()
   237  
   238  	wantMessages := []string{
   239  		"Unlocked account",
   240  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   241  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   242  	}
   243  	for _, m := range wantMessages {
   244  		if !strings.Contains(geth.StderrText(), m) {
   245  			t.Errorf("stderr text does not contain %q", m)
   246  		}
   247  	}
   248  }
   249  
   250  func TestUnlockFlagPasswordFile(t *testing.T) {
   251  	datadir := tmpDatadirWithKeystore(t)
   252  	geth := runGoChain(t,
   253  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   254  		"--password", "testdata/passwords.txt", "--unlock", "0,2",
   255  		"js", "testdata/empty.js")
   256  	geth.ExpectExit()
   257  
   258  	wantMessages := []string{
   259  		"Unlocked account",
   260  		"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
   261  		"=0x289d485D9771714CCe91D3393D764E1311907ACc",
   262  	}
   263  	for _, m := range wantMessages {
   264  		if !strings.Contains(geth.StderrText(), m) {
   265  			t.Errorf("stderr text does not contain %q", m)
   266  		}
   267  	}
   268  }
   269  
   270  func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
   271  	datadir := tmpDatadirWithKeystore(t)
   272  	geth := runGoChain(t,
   273  		"--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   274  		"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
   275  	defer geth.ExpectExit()
   276  	geth.Expect(`
   277  Fatal: Failed to unlock account 0 (could not decrypt key with given password)
   278  `)
   279  }
   280  
   281  func TestUnlockFlagAmbiguous(t *testing.T) {
   282  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   283  	geth := runGoChain(t,
   284  		"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   285  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
   286  		"js", "testdata/empty.js")
   287  	defer geth.ExpectExit()
   288  
   289  	// Helper for the expect template, returns absolute keystore path.
   290  	geth.SetTemplateFunc("keypath", func(file string) string {
   291  		abs, _ := filepath.Abs(filepath.Join(store, file))
   292  		return abs
   293  	})
   294  	geth.Expect(`
   295  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   296  !! Unsupported terminal, password will be echoed.
   297  Password: {{.InputLine "foobar"}}
   298  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   299     keystore://{{keypath "1"}}
   300     keystore://{{keypath "2"}}
   301  Testing your password against all of them...
   302  Your password unlocked keystore://{{keypath "1"}}
   303  In order to avoid this warning, you need to remove the following duplicate key files:
   304     keystore://{{keypath "2"}}
   305  `)
   306  	geth.ExpectExit()
   307  
   308  	wantMessages := []string{
   309  		"Unlocked account",
   310  		"=0xf466859eAD1932D743d622CB74FC058882E8648A",
   311  	}
   312  	for _, m := range wantMessages {
   313  		if !strings.Contains(geth.StderrText(), m) {
   314  			t.Errorf("stderr text does not contain %q", m)
   315  		}
   316  	}
   317  }
   318  
   319  func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
   320  	store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
   321  	geth := runGoChain(t,
   322  		"--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
   323  		"--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
   324  	defer geth.ExpectExit()
   325  
   326  	// Helper for the expect template, returns absolute keystore path.
   327  	geth.SetTemplateFunc("keypath", func(file string) string {
   328  		abs, _ := filepath.Abs(filepath.Join(store, file))
   329  		return abs
   330  	})
   331  	geth.Expect(`
   332  Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
   333  !! Unsupported terminal, password will be echoed.
   334  Password: {{.InputLine "wrong"}}
   335  Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
   336     keystore://{{keypath "1"}}
   337     keystore://{{keypath "2"}}
   338  Testing your password against all of them...
   339  Fatal: None of the listed files could be unlocked.
   340  `)
   341  	geth.ExpectExit()
   342  }