You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wallet-hd.py 3.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2016 The Bitcoin Core developers
  3. # Distributed under the MIT software license, see the accompanying
  4. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. """Test Hierarchical Deterministic wallet function."""
  6. from test_framework.test_framework import BitcoinTestFramework
  7. from test_framework.util import (
  8. start_nodes,
  9. start_node,
  10. assert_equal,
  11. connect_nodes_bi,
  12. assert_start_raises_init_error
  13. )
  14. import os
  15. import shutil
  16. class WalletHDTest(BitcoinTestFramework):
  17. def __init__(self):
  18. super().__init__()
  19. self.setup_clean_chain = True
  20. self.num_nodes = 2
  21. self.node_args = [['-usehd=0'], ['-usehd=1', '-keypool=0']]
  22. def setup_network(self):
  23. self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.node_args)
  24. self.is_network_split = False
  25. connect_nodes_bi(self.nodes, 0, 1)
  26. def run_test (self):
  27. tmpdir = self.options.tmpdir
  28. # Make sure can't switch off usehd after wallet creation
  29. self.stop_node(1)
  30. assert_start_raises_init_error(1, self.options.tmpdir, ['-usehd=0'], 'already existing HD wallet')
  31. self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1])
  32. connect_nodes_bi(self.nodes, 0, 1)
  33. # Make sure we use hd, keep masterkeyid
  34. masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid']
  35. assert_equal(len(masterkeyid), 40)
  36. # Import a non-HD private key in the HD wallet
  37. non_hd_add = self.nodes[0].getnewaddress()
  38. self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add))
  39. # This should be enough to keep the master key and the non-HD key
  40. self.nodes[1].backupwallet(tmpdir + "/hd.bak")
  41. #self.nodes[1].dumpwallet(tmpdir + "/hd.dump")
  42. # Derive some HD addresses and remember the last
  43. # Also send funds to each add
  44. self.nodes[0].generate(101)
  45. hd_add = None
  46. num_hd_adds = 300
  47. for i in range(num_hd_adds):
  48. hd_add = self.nodes[1].getnewaddress()
  49. hd_info = self.nodes[1].validateaddress(hd_add)
  50. assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i+1)+"'")
  51. assert_equal(hd_info["hdmasterkeyid"], masterkeyid)
  52. self.nodes[0].sendtoaddress(hd_add, 1)
  53. self.nodes[0].generate(1)
  54. self.nodes[0].sendtoaddress(non_hd_add, 1)
  55. self.nodes[0].generate(1)
  56. self.sync_all()
  57. assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
  58. self.log.info("Restore backup ...")
  59. self.stop_node(1)
  60. os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat")
  61. shutil.copyfile(tmpdir + "/hd.bak", tmpdir + "/node1/regtest/wallet.dat")
  62. self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1])
  63. #connect_nodes_bi(self.nodes, 0, 1)
  64. # Assert that derivation is deterministic
  65. hd_add_2 = None
  66. for _ in range(num_hd_adds):
  67. hd_add_2 = self.nodes[1].getnewaddress()
  68. hd_info_2 = self.nodes[1].validateaddress(hd_add_2)
  69. assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_+1)+"'")
  70. assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid)
  71. assert_equal(hd_add, hd_add_2)
  72. # Needs rescan
  73. self.stop_node(1)
  74. self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1] + ['-rescan'])
  75. #connect_nodes_bi(self.nodes, 0, 1)
  76. assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
  77. if __name__ == '__main__':
  78. WalletHDTest().main ()