Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_hd.py
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
self.nodes[0].generate(101) | self.nodes[0].generate(101) | ||||
hd_add = None | hd_add = None | ||||
NUM_HD_ADDS = 10 | NUM_HD_ADDS = 10 | ||||
for i in range(NUM_HD_ADDS): | for i in range(NUM_HD_ADDS): | ||||
hd_add = self.nodes[1].getnewaddress() | hd_add = self.nodes[1].getnewaddress() | ||||
hd_info = self.nodes[1].getaddressinfo(hd_add) | hd_info = self.nodes[1].getaddressinfo(hd_add) | ||||
assert_equal(hd_info["hdkeypath"], "m/0'/0'/" + str(i) + "'") | assert_equal(hd_info["hdkeypath"], "m/0'/0'/" + str(i) + "'") | ||||
assert_equal(hd_info["hdseedid"], masterkeyid) | assert_equal(hd_info["hdseedid"], masterkeyid) | ||||
self.nodes[0].sendtoaddress(hd_add, 1) | self.nodes[0].sendtoaddress(hd_add, 1000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.nodes[0].sendtoaddress(non_hd_add, 1) | self.nodes[0].sendtoaddress(non_hd_add, 1000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
# create an internal key (again) | # create an internal key (again) | ||||
change_addr = self.nodes[1].getrawchangeaddress() | change_addr = self.nodes[1].getrawchangeaddress() | ||||
change_addrV = self.nodes[1].getaddressinfo(change_addr) | change_addrV = self.nodes[1].getaddressinfo(change_addr) | ||||
# second internal child key | # second internal child key | ||||
assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") | assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") | ||||
self.sync_all() | self.sync_all() | ||||
assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) | assert_equal( | ||||
self.nodes[1].getbalance(), | |||||
(NUM_HD_ADDS * 1000000) + 1000000) | |||||
self.log.info("Restore backup ...") | self.log.info("Restore backup ...") | ||||
self.stop_node(1) | self.stop_node(1) | ||||
# we need to delete the complete regtest directory | # we need to delete the complete regtest directory | ||||
# otherwise node1 would auto-recover all funds in flag the keypool keys | # otherwise node1 would auto-recover all funds in flag the keypool keys | ||||
# as used | # as used | ||||
shutil.rmtree( | shutil.rmtree( | ||||
os.path.join( | os.path.join( | ||||
Show All 14 Lines | def run_test(self): | ||||
assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(i) + "'") | assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(i) + "'") | ||||
assert_equal(hd_info_2["hdseedid"], masterkeyid) | assert_equal(hd_info_2["hdseedid"], masterkeyid) | ||||
assert_equal(hd_add, hd_add_2) | assert_equal(hd_add, hd_add_2) | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
self.sync_all() | self.sync_all() | ||||
# Needs rescan | # Needs rescan | ||||
self.restart_node(1, extra_args=self.extra_args[1] + ['-rescan']) | self.restart_node(1, extra_args=self.extra_args[1] + ['-rescan']) | ||||
assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) | assert_equal( | ||||
self.nodes[1].getbalance(), | |||||
(NUM_HD_ADDS * 1000000) + 1000000) | |||||
# Try a RPC based rescan | # Try a RPC based rescan | ||||
self.stop_node(1) | self.stop_node(1) | ||||
shutil.rmtree( | shutil.rmtree( | ||||
os.path.join( | os.path.join( | ||||
self.nodes[1].datadir, | self.nodes[1].datadir, | ||||
self.chain, | self.chain, | ||||
"blocks")) | "blocks")) | ||||
shutil.rmtree(os.path.join( | shutil.rmtree(os.path.join( | ||||
self.nodes[1].datadir, self.chain, "chainstate")) | self.nodes[1].datadir, self.chain, "chainstate")) | ||||
shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join( | shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join( | ||||
self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) | self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) | ||||
self.start_node(1, extra_args=self.extra_args[1]) | self.start_node(1, extra_args=self.extra_args[1]) | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
self.sync_all() | self.sync_all() | ||||
# Wallet automatically scans blocks older than key on startup | # Wallet automatically scans blocks older than key on startup | ||||
assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) | assert_equal( | ||||
self.nodes[1].getbalance(), | |||||
(NUM_HD_ADDS * 1000000) + 1000000) | |||||
out = self.nodes[1].rescanblockchain(0, 1) | out = self.nodes[1].rescanblockchain(0, 1) | ||||
assert_equal(out['start_height'], 0) | assert_equal(out['start_height'], 0) | ||||
assert_equal(out['stop_height'], 1) | assert_equal(out['stop_height'], 1) | ||||
out = self.nodes[1].rescanblockchain(2, 4) | out = self.nodes[1].rescanblockchain(2, 4) | ||||
assert_equal(out['start_height'], 2) | assert_equal(out['start_height'], 2) | ||||
assert_equal(out['stop_height'], 4) | assert_equal(out['stop_height'], 4) | ||||
out = self.nodes[1].rescanblockchain(3) | out = self.nodes[1].rescanblockchain(3) | ||||
assert_equal(out['start_height'], 3) | assert_equal(out['start_height'], 3) | ||||
assert_equal(out['stop_height'], self.nodes[1].getblockcount()) | assert_equal(out['stop_height'], self.nodes[1].getblockcount()) | ||||
out = self.nodes[1].rescanblockchain() | out = self.nodes[1].rescanblockchain() | ||||
assert_equal(out['start_height'], 0) | assert_equal(out['start_height'], 0) | ||||
assert_equal(out['stop_height'], self.nodes[1].getblockcount()) | assert_equal(out['stop_height'], self.nodes[1].getblockcount()) | ||||
assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) | assert_equal( | ||||
self.nodes[1].getbalance(), | |||||
(NUM_HD_ADDS * 1000000) + 1000000) | |||||
# send a tx and make sure its using the internal chain for the | # send a tx and make sure its using the internal chain for the | ||||
# changeoutput | # changeoutput | ||||
txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) | txid = self.nodes[1].sendtoaddress( | ||||
self.nodes[0].getnewaddress(), 1000000) | |||||
outs = self.nodes[1].decoderawtransaction( | outs = self.nodes[1].decoderawtransaction( | ||||
self.nodes[1].gettransaction(txid)['hex'])['vout'] | self.nodes[1].gettransaction(txid)['hex'])['vout'] | ||||
keypath = "" | keypath = "" | ||||
for out in outs: | for out in outs: | ||||
if out['value'] != 1: | if out['value'] != 1000000: | ||||
keypath = self.nodes[1].getaddressinfo( | keypath = self.nodes[1].getaddressinfo( | ||||
out['scriptPubKey']['addresses'][0])['hdkeypath'] | out['scriptPubKey']['addresses'][0])['hdkeypath'] | ||||
assert_equal(keypath[0:7], "m/0'/1'") | assert_equal(keypath[0:7], "m/0'/1'") | ||||
# Generate a new HD seed on node 1 and make sure it is set | # Generate a new HD seed on node 1 and make sure it is set | ||||
orig_masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] | orig_masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] | ||||
self.nodes[1].sethdseed() | self.nodes[1].sethdseed() | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert_equal(info['ismine'], False) | assert_equal(info['ismine'], False) | ||||
# Check that the origin seed has addr | # Check that the origin seed has addr | ||||
info = origin_rpc.getaddressinfo(addr) | info = origin_rpc.getaddressinfo(addr) | ||||
assert_equal(info['ismine'], True) | assert_equal(info['ismine'], True) | ||||
# Send a transaction to addr, which is out of the initial keypool. | # Send a transaction to addr, which is out of the initial keypool. | ||||
# The wallet that has set a new seed (restore_rpc) should not | # The wallet that has set a new seed (restore_rpc) should not | ||||
# detect this transaction. | # detect this transaction. | ||||
txid = self.nodes[0].sendtoaddress(addr, 1) | txid = self.nodes[0].sendtoaddress(addr, 1000000) | ||||
origin_rpc.sendrawtransaction( | origin_rpc.sendrawtransaction( | ||||
self.nodes[0].gettransaction(txid)['hex']) | self.nodes[0].gettransaction(txid)['hex']) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_blocks() | self.sync_blocks() | ||||
origin_rpc.gettransaction(txid) | origin_rpc.gettransaction(txid) | ||||
assert_raises_rpc_error(-5, | assert_raises_rpc_error(-5, | ||||
'Invalid or non-wallet transaction id', | 'Invalid or non-wallet transaction id', | ||||
restore_rpc.gettransaction, | restore_rpc.gettransaction, | ||||
txid) | txid) | ||||
out_of_kp_txid = txid | out_of_kp_txid = txid | ||||
# Send a transaction to last_addr, which is in the initial keypool. | # Send a transaction to last_addr, which is in the initial keypool. | ||||
# The wallet that has set a new seed (restore_rpc) should detect this | # The wallet that has set a new seed (restore_rpc) should detect this | ||||
# transaction and generate 3 new keys from the initial seed. | # transaction and generate 3 new keys from the initial seed. | ||||
# The previous transaction (out_of_kp_txid) should still not be | # The previous transaction (out_of_kp_txid) should still not be | ||||
# detected as a rescan is required. | # detected as a rescan is required. | ||||
txid = self.nodes[0].sendtoaddress(last_addr, 1) | txid = self.nodes[0].sendtoaddress(last_addr, 1000000) | ||||
origin_rpc.sendrawtransaction( | origin_rpc.sendrawtransaction( | ||||
self.nodes[0].gettransaction(txid)['hex']) | self.nodes[0].gettransaction(txid)['hex']) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_blocks() | self.sync_blocks() | ||||
origin_rpc.gettransaction(txid) | origin_rpc.gettransaction(txid) | ||||
restore_rpc.gettransaction(txid) | restore_rpc.gettransaction(txid) | ||||
assert_raises_rpc_error(-5, | assert_raises_rpc_error(-5, | ||||
'Invalid or non-wallet transaction id', | 'Invalid or non-wallet transaction id', | ||||
Show All 40 Lines |