diff --git a/test/functional/timing.json b/test/functional/timing.json index 80e27be481..50cc398c64 100644 --- a/test/functional/timing.json +++ b/test/functional/timing.json @@ -1,430 +1,430 @@ [ { "name": "abc-cmdline.py", "time": 4 }, { "name": "abc-finalize-block.py", "time": 5 }, { "name": "abc-high_priority_transaction.py", "time": 6 }, { "name": "abc-invalid-chains.py", "time": 2 }, { "name": "abc-invalid-message.py", "time": 10 }, { "name": "abc-magnetic-anomaly-mining.py", "time": 11 }, { "name": "abc-mempool-accept-txn.py", "time": 12 }, { "name": "abc-mempool-coherence-on-activations.py", "time": 2 }, { "name": "abc-p2p-compactblocks.py", "time": 365 }, { "name": "abc-p2p-fullblocktest.py", "time": 53 }, { "name": "abc-parkedchain.py", "time": 35 }, { "name": "abc-replay-protection.py", "time": 2 }, { "name": "abc-rpc.py", "time": 6 }, { "name": "abc-schnorr.py", "time": 5 }, { "name": "abc-segwit-recovery.py", "time": 2 }, { "name": "abc-sync-chain.py", "time": 5 }, { "name": "abc-transaction-ordering.py", "time": 4 }, { "name": "example_test.py", "time": 1 }, { "name": "feature_assumevalid.py", "time": 15 }, { "name": "feature_bip68_sequence.py", "time": 42 }, { "name": "feature_block.py", "time": 94 }, { "name": "feature_blocksdir.py", "time": 2 }, { "name": "feature_cltv.py", "time": 19 }, { "name": "feature_config_args.py", "time": 3 }, { "name": "feature_csv_activation.py", "time": 10 }, { "name": "feature_dbcrash.py", "time": 1400 }, { "name": "feature_dersig.py", "time": 19 }, { "name": "feature_help.py", "time": 0 }, { "name": "feature_includeconf.py", "time": 3 }, { "name": "feature_logging.py", "time": 5 }, { "name": "feature_maxuploadtarget.py", "time": 20 }, { "name": "feature_minchainwork.py", "time": 6 }, { "name": "feature_notifications.py", "time": 2 }, { "name": "feature_nulldummy.py", "time": 1 }, { "name": "feature_proxy.py", "time": 16 }, { "name": "feature_pruning.py", "time": 1573 }, { "name": "feature_reindex.py", "time": 5 }, { "name": "feature_uacomment.py", "time": 2 }, { "name": "interface_bitcoin_cli.py", "time": 16 }, { "name": "interface_http.py", "time": 2 }, { "name": "interface_rest.py", "time": 8 }, { "name": "interface_zmq.py", "time": 5 }, { "name": "mempool_accept.py", "time": 4 }, { "name": "mempool_limit.py", "time": 9 }, { "name": "mempool_packages.py", "time": 28 }, { "name": "mempool_persist.py", "time": 13 }, { "name": "mempool_reorg.py", "time": 17 }, { "name": "mempool_resurrect.py", "time": 3 }, { "name": "mempool_spend_coinbase.py", "time": 2 }, { "name": "mining_basic.py", "time": 1 }, { "name": "mining_getblocktemplate_longpoll.py", "time": 67 }, { "name": "mining_prioritisetransaction.py", "time": 19 }, { "name": "p2p_compactblocks.py", "time": 15 }, { "name": "p2p_disconnect_ban.py", "time": 15 }, { "name": "p2p_feefilter.py", "time": 57 }, { "name": "p2p_fingerprint.py", "time": 7 }, { "name": "p2p_invalid_block.py", "time": 2 }, { "name": "p2p_invalid_tx.py", "time": 1 }, { "name": "p2p_leak.py", "time": 17 }, { "name": "p2p_leak_tx.py", "time": 1 }, { "name": "p2p_mempool.py", "time": 2 }, { "name": "p2p_node_network_limited.py", "time": 14 }, { "name": "p2p_sendheaders.py", "time": 15 }, { "name": "p2p_timeouts.py", "time": 63 }, { "name": "p2p_unrequested_blocks.py", "time": 19 }, { "name": "rpc_bind.py", "time": 19 }, { "name": "rpc_blockchain.py", "time": 12 }, { "name": "rpc_decodescript.py", "time": 1 }, { "name": "rpc_deprecated.py", "time": 1 }, { "name": "rpc_estimatefee.py", "time": 1 }, { "name": "rpc_fundrawtransaction.py", "time": 44 }, { "name": "rpc_getchaintips.py", "time": 17 }, { "name": "rpc_invalidateblock.py", "time": 8 }, { "name": "rpc_listtransactions.py", "time": 14 }, { "name": "rpc_named_arguments.py", "time": 1 }, { "name": "rpc_net.py", "time": 1 }, { "name": "rpc_preciousblock.py", "time": 2 }, { "name": "rpc_rawtransaction.py", "time": 28 }, { "name": "rpc_signmessage.py", "time": 1 }, { "name": "rpc_signrawtransaction.py", "time": 1 }, { "name": "rpc_txoutproof.py", "time": 3 }, { "name": "rpc_uptime.py", "time": 0 }, { "name": "rpc_users.py", "time": 3 }, { "name": "wallet_abandonconflict.py", "time": 11 }, { "name": "wallet_backup.py", "time": 112 }, { "name": "wallet_basic.py", "time": 32 }, { "name": "wallet_disable.py", "time": 0 }, { "name": "wallet_dump.py", "time": 38 }, { "name": "wallet_encryption.py", "time": 7 }, { "name": "wallet_groups.py", "time": 12 }, { "name": "wallet_hd.py", - "time": 104 + "time": 3 }, { "name": "wallet_import_rescan.py", "time": 16 }, { "name": "wallet_importmulti.py", "time": 5 }, { "name": "wallet_importprunedfunds.py", "time": 2 }, { "name": "wallet_keypool.py", "time": 4 }, { "name": "wallet_keypool_topup.py", "time": 10 }, { "name": "wallet_labels.py", "time": 8 }, { "name": "wallet_listreceivedby.py", "time": 8 }, { "name": "wallet_listsinceblock.py", "time": 10 }, { "name": "wallet_multiwallet.py", "time": 11 }, { "name": "wallet_multiwallet.py --usecli", "time": 10 }, { "name": "wallet_resendwallettransactions.py", "time": 10 }, { "name": "wallet_txn_clone.py", "time": 9 }, { "name": "wallet_txn_clone.py --mineblock", "time": 7 }, { "name": "wallet_txn_doublespend.py", "time": 5 }, { "name": "wallet_txn_doublespend.py --mineblock", "time": 4 }, { "name": "wallet_zapwallettxes.py", "time": 4 } ] \ No newline at end of file diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index 17c234d614..f0fbb60219 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -1,136 +1,138 @@ #!/usr/bin/env python3 # Copyright (c) 2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test Hierarchical Deterministic wallet function.""" import os import shutil from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, connect_nodes_bi class WalletHDTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 self.extra_args = [[], ['-keypool=0']] def run_test(self): # Make sure can't switch off usehd after wallet creation self.stop_node(1) self.nodes[1].assert_start_raises_init_error( ['-usehd=0'], "Error: Error loading : You can't disable HD on an already existing HD wallet") self.start_node(1) connect_nodes_bi(self.nodes[0], self.nodes[1]) # Make sure we use hd, keep masterkeyid masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] assert_equal(len(masterkeyid), 40) # create an internal key change_addr = self.nodes[1].getrawchangeaddress() change_addrV = self.nodes[1].getaddressinfo(change_addr) # first internal child key assert_equal(change_addrV["hdkeypath"], "m/0'/1'/0'") # Import a non-HD private key in the HD wallet non_hd_add = self.nodes[0].getnewaddress() self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) # This should be enough to keep the master key and the non-HD key self.nodes[1].backupwallet( os.path.join(self.nodes[1].datadir, "hd.bak")) #self.nodes[1].dumpwallet(os.path.join(self.nodes[1].datadir, "hd.dump")) # Derive some HD addresses and remember the last # Also send funds to each add self.nodes[0].generate(101) hd_add = None - num_hd_adds = 300 - for i in range(num_hd_adds): + NUM_HD_ADDS = 10 + for i in range(NUM_HD_ADDS): hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].getaddressinfo(hd_add) assert_equal(hd_info["hdkeypath"], "m/0'/0'/" + str(i) + "'") assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) self.nodes[0].sendtoaddress(non_hd_add, 1) self.nodes[0].generate(1) # create an internal key (again) change_addr = self.nodes[1].getrawchangeaddress() change_addrV = self.nodes[1].getaddressinfo(change_addr) # second internal child key assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") self.sync_all() - assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) self.log.info("Restore backup ...") self.stop_node(1) # we need to delete the complete regtest directory # otherwise node1 would auto-recover all funds in flag the keypool keys as used shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks")) shutil.rmtree(os.path.join( self.nodes[1].datadir, "regtest", "chainstate")) shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join( self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")) self.start_node(1) # Assert that derivation is deterministic hd_add_2 = None - for _ in range(num_hd_adds): + for i in range(NUM_HD_ADDS): hd_add_2 = self.nodes[1].getnewaddress() hd_info_2 = self.nodes[1].getaddressinfo(hd_add_2) - assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(_) + "'") + assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(i) + "'") assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) connect_nodes_bi(self.nodes[0], self.nodes[1]) self.sync_all() # Needs rescan self.stop_node(1) self.start_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 + 1) # Try a RPC based rescan self.stop_node(1) shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks")) shutil.rmtree(os.path.join( self.nodes[1].datadir, "regtest", "chainstate")) shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join( self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")) self.start_node(1, extra_args=self.extra_args[1]) connect_nodes_bi(self.nodes[0], self.nodes[1]) self.sync_all() + # Wallet automatically scans blocks older than key on startup + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) out = self.nodes[1].rescanblockchain(0, 1) assert_equal(out['start_height'], 0) assert_equal(out['stop_height'], 1) out = self.nodes[1].rescanblockchain(2, 4) assert_equal(out['start_height'], 2) assert_equal(out['stop_height'], 4) out = self.nodes[1].rescanblockchain(3) assert_equal(out['start_height'], 3) assert_equal(out['stop_height'], self.nodes[1].getblockcount()) out = self.nodes[1].rescanblockchain() assert_equal(out['start_height'], 0) 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 + 1) # send a tx and make sure its using the internal chain for the changeoutput txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) outs = self.nodes[1].decoderawtransaction( self.nodes[1].gettransaction(txid)['hex'])['vout'] keypath = "" for out in outs: if out['value'] != 1: keypath = self.nodes[1].getaddressinfo( out['scriptPubKey']['addresses'][0])['hdkeypath'] assert_equal(keypath[0:7], "m/0'/1'") if __name__ == '__main__': WalletHDTest().main()