accountcmd_test.go 12 KB

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