github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/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 "os" 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 := t.TempDir() 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 var want = ` 53 Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 54 Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa 55 Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz 56 ` 57 if runtime.GOOS == "windows" { 58 want = ` 59 Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 60 Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa 61 Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz 62 ` 63 } 64 { 65 geth := runGeth(t, "account", "list", "--datadir", datadir) 66 geth.Expect(want) 67 geth.ExpectExit() 68 } 69 { 70 geth := runGeth(t, "--datadir", datadir, "account", "list") 71 geth.Expect(want) 72 geth.ExpectExit() 73 } 74 } 75 76 func TestAccountNew(t *testing.T) { 77 geth := runGeth(t, "account", "new", "--lightkdf") 78 defer geth.ExpectExit() 79 geth.Expect(` 80 Your new account is locked with a password. Please give a password. Do not forget this password. 81 !! Unsupported terminal, password will be echoed. 82 Password: {{.InputLine "foobar"}} 83 Repeat password: {{.InputLine "foobar"}} 84 85 Your new key was generated 86 `) 87 geth.ExpectRegexp(` 88 Public address of the key: 0x[0-9a-fA-F]{40} 89 Path of the secret key file: .*UTC--.+--[0-9a-f]{40} 90 91 - You can share your public address with anyone. Others need it to interact with you. 92 - You must NEVER share the secret key with anyone! The key controls access to your funds! 93 - You must BACKUP your key file! Without the key, it's impossible to access account funds! 94 - You must REMEMBER your password! Without the password, it's impossible to decrypt the key! 95 `) 96 } 97 98 func TestAccountImport(t *testing.T) { 99 tests := []struct{ name, key, output string }{ 100 { 101 name: "correct account", 102 key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 103 output: "Address: {fcad0b19bb29d4674531d6f115237e16afce377c}\n", 104 }, 105 { 106 name: "invalid character", 107 key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef1", 108 output: "Fatal: Failed to load the private key: invalid character '1' at end of key file\n", 109 }, 110 } 111 for _, test := range tests { 112 test := test 113 t.Run(test.name, func(t *testing.T) { 114 t.Parallel() 115 importAccountWithExpect(t, test.key, test.output) 116 }) 117 } 118 } 119 120 func TestAccountHelp(t *testing.T) { 121 geth := runGeth(t, "account", "-h") 122 geth.WaitExit() 123 if have, want := geth.ExitStatus(), 0; have != want { 124 t.Errorf("exit error, have %d want %d", have, want) 125 } 126 127 geth = runGeth(t, "account", "import", "-h") 128 geth.WaitExit() 129 if have, want := geth.ExitStatus(), 0; have != want { 130 t.Errorf("exit error, have %d want %d", have, want) 131 } 132 } 133 134 func importAccountWithExpect(t *testing.T, key string, expected string) { 135 dir := t.TempDir() 136 keyfile := filepath.Join(dir, "key.prv") 137 if err := os.WriteFile(keyfile, []byte(key), 0600); err != nil { 138 t.Error(err) 139 } 140 passwordFile := filepath.Join(dir, "password.txt") 141 if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil { 142 t.Error(err) 143 } 144 geth := runGeth(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile) 145 defer geth.ExpectExit() 146 geth.Expect(expected) 147 } 148 149 func TestAccountNewBadRepeat(t *testing.T) { 150 geth := runGeth(t, "account", "new", "--lightkdf") 151 defer geth.ExpectExit() 152 geth.Expect(` 153 Your new account is locked with a password. Please give a password. Do not forget this password. 154 !! Unsupported terminal, password will be echoed. 155 Password: {{.InputLine "something"}} 156 Repeat password: {{.InputLine "something else"}} 157 Fatal: Passwords do not match 158 `) 159 } 160 161 func TestAccountUpdate(t *testing.T) { 162 datadir := tmpDatadirWithKeystore(t) 163 geth := runGeth(t, "account", "update", 164 "--datadir", datadir, "--lightkdf", 165 "f466859ead1932d743d622cb74fc058882e8648a") 166 defer geth.ExpectExit() 167 geth.Expect(` 168 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 169 !! Unsupported terminal, password will be echoed. 170 Password: {{.InputLine "foobar"}} 171 Please give a new password. Do not forget this password. 172 Password: {{.InputLine "foobar2"}} 173 Repeat password: {{.InputLine "foobar2"}} 174 `) 175 } 176 177 func TestWalletImport(t *testing.T) { 178 geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") 179 defer geth.ExpectExit() 180 geth.Expect(` 181 !! Unsupported terminal, password will be echoed. 182 Password: {{.InputLine "foo"}} 183 Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} 184 `) 185 186 files, err := os.ReadDir(filepath.Join(geth.Datadir, "keystore")) 187 if len(files) != 1 { 188 t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err) 189 } 190 } 191 192 func TestWalletImportBadPassword(t *testing.T) { 193 geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json") 194 defer geth.ExpectExit() 195 geth.Expect(` 196 !! Unsupported terminal, password will be echoed. 197 Password: {{.InputLine "wrong"}} 198 Fatal: could not decrypt key with given password 199 `) 200 } 201 202 func TestUnlockFlag(t *testing.T) { 203 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 204 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')") 205 geth.Expect(` 206 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 207 !! Unsupported terminal, password will be echoed. 208 Password: {{.InputLine "foobar"}} 209 undefined 210 `) 211 geth.ExpectExit() 212 213 wantMessages := []string{ 214 "Unlocked account", 215 "=0xf466859eAD1932D743d622CB74FC058882E8648A", 216 } 217 for _, m := range wantMessages { 218 if !strings.Contains(geth.StderrText(), m) { 219 t.Errorf("stderr text does not contain %q", m) 220 } 221 } 222 } 223 224 func TestUnlockFlagWrongPassword(t *testing.T) { 225 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 226 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')") 227 228 defer geth.ExpectExit() 229 geth.Expect(` 230 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 231 !! Unsupported terminal, password will be echoed. 232 Password: {{.InputLine "wrong1"}} 233 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3 234 Password: {{.InputLine "wrong2"}} 235 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3 236 Password: {{.InputLine "wrong3"}} 237 Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password) 238 `) 239 } 240 241 // https://github.com/ethereum/go-ethereum/issues/1785 242 func TestUnlockFlagMultiIndex(t *testing.T) { 243 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 244 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") 245 246 geth.Expect(` 247 Unlocking account 0 | Attempt 1/3 248 !! Unsupported terminal, password will be echoed. 249 Password: {{.InputLine "foobar"}} 250 Unlocking account 2 | Attempt 1/3 251 Password: {{.InputLine "foobar"}} 252 undefined 253 `) 254 geth.ExpectExit() 255 256 wantMessages := []string{ 257 "Unlocked account", 258 "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", 259 "=0x289d485D9771714CCe91D3393D764E1311907ACc", 260 } 261 for _, m := range wantMessages { 262 if !strings.Contains(geth.StderrText(), m) { 263 t.Errorf("stderr text does not contain %q", m) 264 } 265 } 266 } 267 268 func TestUnlockFlagPasswordFile(t *testing.T) { 269 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 270 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") 271 272 geth.Expect(` 273 undefined 274 `) 275 geth.ExpectExit() 276 277 wantMessages := []string{ 278 "Unlocked account", 279 "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", 280 "=0x289d485D9771714CCe91D3393D764E1311907ACc", 281 } 282 for _, m := range wantMessages { 283 if !strings.Contains(geth.StderrText(), m) { 284 t.Errorf("stderr text does not contain %q", m) 285 } 286 } 287 } 288 289 func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { 290 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 291 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", 292 "testdata/wrong-passwords.txt", "--unlock", "0,2") 293 defer geth.ExpectExit() 294 geth.Expect(` 295 Fatal: Failed to unlock account 0 (could not decrypt key with given password) 296 `) 297 } 298 299 func TestUnlockFlagAmbiguous(t *testing.T) { 300 store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") 301 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 302 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore", 303 store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", 304 "console", "--exec", "loadScript('testdata/empty.js')") 305 defer geth.ExpectExit() 306 307 // Helper for the expect template, returns absolute keystore path. 308 geth.SetTemplateFunc("keypath", func(file string) string { 309 abs, _ := filepath.Abs(filepath.Join(store, file)) 310 return abs 311 }) 312 geth.Expect(` 313 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 314 !! Unsupported terminal, password will be echoed. 315 Password: {{.InputLine "foobar"}} 316 Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: 317 keystore://{{keypath "1"}} 318 keystore://{{keypath "2"}} 319 Testing your password against all of them... 320 Your password unlocked keystore://{{keypath "1"}} 321 In order to avoid this warning, you need to remove the following duplicate key files: 322 keystore://{{keypath "2"}} 323 undefined 324 `) 325 geth.ExpectExit() 326 327 wantMessages := []string{ 328 "Unlocked account", 329 "=0xf466859eAD1932D743d622CB74FC058882E8648A", 330 } 331 for _, m := range wantMessages { 332 if !strings.Contains(geth.StderrText(), m) { 333 t.Errorf("stderr text does not contain %q", m) 334 } 335 } 336 } 337 338 func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { 339 store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") 340 geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 341 "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore", 342 store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") 343 344 defer geth.ExpectExit() 345 346 // Helper for the expect template, returns absolute keystore path. 347 geth.SetTemplateFunc("keypath", func(file string) string { 348 abs, _ := filepath.Abs(filepath.Join(store, file)) 349 return abs 350 }) 351 geth.Expect(` 352 Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 353 !! Unsupported terminal, password will be echoed. 354 Password: {{.InputLine "wrong"}} 355 Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: 356 keystore://{{keypath "1"}} 357 keystore://{{keypath "2"}} 358 Testing your password against all of them... 359 Fatal: None of the listed files could be unlocked. 360 `) 361 geth.ExpectExit() 362 }