github.com/theQRL/go-zond@v0.2.1/cmd/gzond/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 gzond := runGzond(t, "account", "list") 47 gzond.ExpectExit() 48 } 49 50 func TestAccountList(t *testing.T) { 51 datadir := tmpDatadirWithKeystore(t) 52 var want = ` 53 Account #0: {Z2099d76d9a34cdd2694c4dc703930a6fbbc1d402} keystore://{{.Datadir}}/keystore/UTC--2024-05-27T07-48-33.872599000Z--Z2099d76d9a34cdd2694c4dc703930a6fbbc1d402 54 Account #1: {Z205547ba6232eec096770f7161d57dea54fd13d0} keystore://{{.Datadir}}/keystore/aaa 55 Account #2: {Z206f5f53d348954856a6d2cde75ad6381945fb46} keystore://{{.Datadir}}/keystore/zzz 56 ` 57 if runtime.GOOS == "windows" { 58 want = ` 59 Account #0: {Z2099d76d9a34cdd2694c4dc703930a6fbbc1d402} keystore://{{.Datadir}}\keystore\UTC--2024-05-27T07-48-33.872599000Z--Z2099d76d9a34cdd2694c4dc703930a6fbbc1d402 60 Account #1: {Z205547ba6232eec096770f7161d57dea54fd13d0} keystore://{{.Datadir}}\keystore\aaa 61 Account #2: {Z206f5f53d348954856a6d2cde75ad6381945fb46} keystore://{{.Datadir}}\keystore\zzz 62 ` 63 } 64 { 65 gzond := runGzond(t, "account", "list", "--datadir", datadir) 66 gzond.Expect(want) 67 gzond.ExpectExit() 68 } 69 { 70 gzond := runGzond(t, "--datadir", datadir, "account", "list") 71 gzond.Expect(want) 72 gzond.ExpectExit() 73 } 74 } 75 76 func TestAccountNew(t *testing.T) { 77 gzond := runGzond(t, "account", "new", "--lightkdf") 78 defer gzond.ExpectExit() 79 gzond.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 gzond.ExpectRegexp(` 88 Public address of the key: Z[0-9a-fA-F]{40} 89 Path of the secret key file: .*UTC--.+--Z[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, seed, output string }{ 100 { 101 name: "correct account", 102 seed: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeffcad0b19bb29d4674531d6f115237e16", 103 output: "Address: {Z20b0ebf635349c8167daac7d7246b8e0d892926f}\n", 104 }, 105 { 106 name: "invalid character", 107 seed: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeffcad0b19bb29d4674531d6f115237e161", 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.seed, test.output) 116 }) 117 } 118 } 119 120 func TestAccountHelp(t *testing.T) { 121 gzond := runGzond(t, "account", "-h") 122 gzond.WaitExit() 123 if have, want := gzond.ExitStatus(), 0; have != want { 124 t.Errorf("exit error, have %d want %d", have, want) 125 } 126 127 gzond = runGzond(t, "account", "import", "-h") 128 gzond.WaitExit() 129 if have, want := gzond.ExitStatus(), 0; have != want { 130 t.Errorf("exit error, have %d want %d", have, want) 131 } 132 } 133 134 func importAccountWithExpect(t *testing.T, seed string, expected string) { 135 dir := t.TempDir() 136 seedfile := filepath.Join(dir, "seed.txt") 137 if err := os.WriteFile(seedfile, []byte(seed), 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 gzond := runGzond(t, "--lightkdf", "account", "import", "-password", passwordFile, seedfile) 145 defer gzond.ExpectExit() 146 gzond.Expect(expected) 147 } 148 149 func TestAccountNewBadRepeat(t *testing.T) { 150 gzond := runGzond(t, "account", "new", "--lightkdf") 151 defer gzond.ExpectExit() 152 gzond.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 gzond := runGzond(t, "account", "update", 164 "--datadir", datadir, "--lightkdf", 165 "Z206f5f53d348954856a6d2cde75ad6381945fb46") 166 defer gzond.ExpectExit() 167 gzond.Expect(` 168 Unlocking account Z206f5f53d348954856a6d2cde75ad6381945fb46 | Attempt 1/3 169 !! Unsupported terminal, password will be echoed. 170 Password: {{.InputLine "1234567890"}} 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 TestUnlockFlag(t *testing.T) { 178 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 179 "--unlock", "Z206f5f53d348954856a6d2cde75ad6381945fb46", "console", "--exec", "loadScript('testdata/empty.js')") 180 gzond.Expect(` 181 Unlocking account Z206f5f53d348954856a6d2cde75ad6381945fb46 | Attempt 1/3 182 !! Unsupported terminal, password will be echoed. 183 Password: {{.InputLine "1234567890"}} 184 undefined 185 `) 186 gzond.ExpectExit() 187 188 wantMessages := []string{ 189 "Unlocked account", 190 "=Z206f5f53D348954856a6D2cDe75Ad6381945fB46", 191 } 192 for _, m := range wantMessages { 193 if !strings.Contains(gzond.StderrText(), m) { 194 t.Errorf("stderr text does not contain %q", m) 195 } 196 } 197 } 198 199 func TestUnlockFlagWrongPassword(t *testing.T) { 200 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 201 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "console", "--exec", "loadScript('testdata/empty.js')") 202 203 defer gzond.ExpectExit() 204 gzond.Expect(` 205 Unlocking account Z205547ba6232eec096770f7161d57dea54fd13d0 | Attempt 1/3 206 !! Unsupported terminal, password will be echoed. 207 Password: {{.InputLine "wrong1"}} 208 Unlocking account Z205547ba6232eec096770f7161d57dea54fd13d0 | Attempt 2/3 209 Password: {{.InputLine "wrong2"}} 210 Unlocking account Z205547ba6232eec096770f7161d57dea54fd13d0 | Attempt 3/3 211 Password: {{.InputLine "wrong3"}} 212 Fatal: Failed to unlock account Z205547ba6232eec096770f7161d57dea54fd13d0 (could not decrypt key with given password) 213 `) 214 } 215 216 func TestUnlockFlagMultiIndex(t *testing.T) { 217 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 218 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") 219 220 gzond.Expect(` 221 Unlocking account 0 | Attempt 1/3 222 !! Unsupported terminal, password will be echoed. 223 Password: {{.InputLine "1234567890"}} 224 Unlocking account 2 | Attempt 1/3 225 Password: {{.InputLine "1234567890"}} 226 undefined 227 `) 228 gzond.ExpectExit() 229 230 wantMessages := []string{ 231 "Unlocked account", 232 "=Z2099d76D9a34cDd2694c4DC703930A6fBbc1d402", 233 "=Z206f5f53D348954856a6D2cDe75Ad6381945fB46", 234 } 235 for _, m := range wantMessages { 236 if !strings.Contains(gzond.StderrText(), m) { 237 t.Errorf("stderr text does not contain %q", m) 238 } 239 } 240 } 241 242 func TestUnlockFlagPasswordFile(t *testing.T) { 243 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 244 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')") 245 246 gzond.Expect(` 247 undefined 248 `) 249 gzond.ExpectExit() 250 251 wantMessages := []string{ 252 "Unlocked account", 253 "=Z2099d76D9a34cDd2694c4DC703930A6fBbc1d402", 254 "=Z206f5f53D348954856a6D2cDe75Ad6381945fB46", 255 } 256 for _, m := range wantMessages { 257 if !strings.Contains(gzond.StderrText(), m) { 258 t.Errorf("stderr text does not contain %q", m) 259 } 260 } 261 } 262 263 func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { 264 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 265 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "--password", 266 "testdata/wrong-passwords.txt", "--unlock", "0,2") 267 defer gzond.ExpectExit() 268 gzond.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 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 276 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "--keystore", 277 store, "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", 278 "console", "--exec", "loadScript('testdata/empty.js')") 279 defer gzond.ExpectExit() 280 281 // Helper for the expect template, returns absolute keystore path. 282 gzond.SetTemplateFunc("keypath", func(file string) string { 283 abs, _ := filepath.Abs(filepath.Join(store, file)) 284 return abs 285 }) 286 gzond.Expect(` 287 Unlocking account Z205547ba6232eec096770f7161d57dea54fd13d0 | Attempt 1/3 288 !! Unsupported terminal, password will be echoed. 289 Password: {{.InputLine ""}} 290 Multiple key files exist for address Z205547ba6232eec096770f7161d57dea54fd13d0: 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 undefined 298 `) 299 gzond.ExpectExit() 300 301 wantMessages := []string{ 302 "Unlocked account", 303 "=Z205547bA6232eEc096770f7161d57dEA54FD13D0", 304 } 305 for _, m := range wantMessages { 306 if !strings.Contains(gzond.StderrText(), m) { 307 t.Errorf("stderr text does not contain %q", m) 308 } 309 } 310 } 311 312 func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { 313 store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") 314 gzond := runMinimalGzond(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 315 "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0", "--keystore", 316 store, "--unlock", "Z205547ba6232eec096770f7161d57dea54fd13d0") 317 318 defer gzond.ExpectExit() 319 320 // Helper for the expect template, returns absolute keystore path. 321 gzond.SetTemplateFunc("keypath", func(file string) string { 322 abs, _ := filepath.Abs(filepath.Join(store, file)) 323 return abs 324 }) 325 gzond.Expect(` 326 Unlocking account Z205547ba6232eec096770f7161d57dea54fd13d0 | Attempt 1/3 327 !! Unsupported terminal, password will be echoed. 328 Password: {{.InputLine "wrong"}} 329 Multiple key files exist for address Z205547ba6232eec096770f7161d57dea54fd13d0: 330 keystore://{{keypath "1"}} 331 keystore://{{keypath "2"}} 332 Testing your password against all of them... 333 Fatal: None of the listed files could be unlocked. 334 `) 335 gzond.ExpectExit() 336 }