diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -44,6 +44,13 @@ def setup_nodes(self): skip_if_no_py3_zmq() skip_if_no_bitcoind_zmq(self) + + # Import keys + self.add_nodes(self.num_nodes) + self.start_nodes() + super().import_deterministic_coinbase_privkeys() + self.stop_nodes() + import zmq # Initialize ZMQ context and socket. @@ -63,11 +70,13 @@ self.rawblock = ZMQSubscriber(socket, b"rawblock") self.rawtx = ZMQSubscriber(socket, b"rawtx") - self.extra_args = [["-zmqpub{}={}".format(sub.topic.decode(), address) for sub in [ - self.hashblock, self.hashtx, self.rawblock, self.rawtx]], []] - self.add_nodes(self.num_nodes, self.extra_args) + self.nodes[0].extra_args = ["-zmqpub{}={}".format(sub.topic.decode(), address) for sub in [ + self.hashblock, self.hashtx, self.rawblock, self.rawtx]] self.start_nodes() + def import_deterministic_coinbase_privkeys(self): + pass + def run_test(self): try: self._zmq_test() diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -43,7 +43,7 @@ return (txid, send_value) def run_test(self): - ''' Mine some blocks and have them mature. ''' + # Mine some blocks and have them mature. self.nodes[0].generate(101) utxo = self.nodes[0].listunspent(10) txid = utxo[0]['txid'] diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -49,9 +49,11 @@ def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-stopatheight=207', '-prune=1']] def run_test(self): + # Set extra args with pruning after rescan is complete + self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) + self._test_getblockchaininfo() self._test_getchaintxstats() self._test_gettxoutsetinfo() @@ -181,7 +183,7 @@ assert_equal(res['transactions'], 200) assert_equal(res['height'], 200) assert_equal(res['txouts'], 200) - assert_equal(res['bogosize'], 17000), + assert_equal(res['bogosize'], 15000), assert_equal(res['bestblock'], node.getblockhash(200)) size = res['disk_size'] assert size > 6400 @@ -283,7 +285,7 @@ assert_equal( getblockinfo['versionHex'], getblockheaderinfo['versionHex']) assert_equal(getblockinfo['version'], getblockheaderinfo['version']) - assert_equal(getblockinfo['size'], 188) + assert_equal(getblockinfo['size'], 181) assert_equal( getblockinfo['merkleroot'], getblockheaderinfo['merkleroot']) # Verify transaction data by check the hex values diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -147,6 +147,7 @@ "--usecli specified but test does not support using CLI") self.setup_chain() self.setup_network() + self.import_deterministic_coinbase_privkeys() self.run_test() success = TestStatus.PASSED except JSONRPCException: @@ -240,6 +241,19 @@ self.add_nodes(self.num_nodes, extra_args) self.start_nodes() + def import_deterministic_coinbase_privkeys(self): + if self.setup_clean_chain: + return + + for n in self.nodes: + try: + n.getwalletinfo() + except JSONRPCException as e: + assert str(e).startswith('Method not found') + continue + + n.importprivkey(n.get_deterministic_priv_key()[1]) + def run_test(self): """Tests must override this method to define test logic""" raise NotImplementedError @@ -407,6 +421,7 @@ i), p2p_port=p2p_port(i), timewait=None, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None)) self.nodes[i].clear_default_args() self.nodes[i].extend_default_args(["-datadir=" + datadir]) + self.nodes[i].extend_default_args(["-disablewallet"]) if i > 0: self.nodes[i].extend_default_args( ["-connect=127.0.0.1:" + str(p2p_port(0))]) @@ -436,7 +451,8 @@ for peer in range(4): for j in range(25): set_node_times(self.nodes, block_time) - self.nodes[peer].generate(1) + self.nodes[peer].generatetoaddress( + 1, self.nodes[peer].get_deterministic_priv_key()[0]) block_time += 10 * 60 # Must sync before next peer starts generating blocks sync_blocks(self.nodes) @@ -450,8 +466,10 @@ return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths) for i in range(MAX_NODES): + # Remove empty wallets dir + os.rmdir(cache_path(i, 'wallets')) for entry in os.listdir(cache_path(i)): - if entry not in ['wallets', 'chainstate', 'blocks']: + if entry not in ['chainstate', 'blocks']: os.remove(cache_path(i, entry)) for i in range(self.num_nodes): diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -103,6 +103,31 @@ self.cleanup_on_exit = True self.p2ps = [] + def get_deterministic_priv_key(self): + """Return a deterministic priv key in base58, that only depends on the node's index""" + PRIV_KEYS = [ + # address , privkey + ('mjTkW3DjgyZck4KbiRusZsqTgaYTxdSz6z', + 'cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW'), + ('msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg', + 'cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE'), + ('mnonCMyH9TmAsSj3M59DsbH8H63U3RKoFP', + 'cTrh7dkEAeJd6b3MRX9bZK8eRmNqVCMH3LSUkE3dSFDyzjU38QxK'), + ('mqJupas8Dt2uestQDvV2NH3RU8uZh2dqQR', + 'cVuKKa7gbehEQvVq717hYcbE9Dqmq7KEBKqWgWrYBa2CKKrhtRim'), + ('msYac7Rvd5ywm6pEmkjyxhbCDKqWsVeYws', + 'cQDCBuKcjanpXDpCqacNSjYfxeQj8G6CAtH1Dsk3cXyqLNC4RPuh'), + ('n2rnuUnwLgXqf9kk2kjvVm8R5BZK1yxQBi', + 'cQakmfPSLSqKHyMFGwAqKHgWUiofJCagVGhiB4KCainaeCSxeyYq'), + ('myzuPxRwsf3vvGzEuzPfK9Nf2RfwauwYe6', + 'cQMpDLJwA8DBe9NcQbdoSb1BhmFxVjWD5gRyrLZCtpuF9Zi3a9RK'), + ('mumwTaMtbxEPUswmLBBN3vM9oGRtGBrys8', + 'cSXmRKXVcoouhNNVpcNKFfxsTsToY5pvB9DVsFksF1ENunTzRKsy'), + ('mpV7aGShMkJCZgbW7F6iZgrvuPHjZjH9qg', + 'cSoXt6tm3pqy43UMabY6eUTmR3eSUYFtB2iNQDGgb3VUnRsQys2k'), + ] + return PRIV_KEYS[self.index] + def _node_msg(self, msg: str) -> str: """Return a modified msg that identifies this node by its index as a debugging aid.""" return "[node {}] {}".format(self.index, msg) diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -25,43 +25,47 @@ # only read non comment lines if line[0] != "#" and len(line) > 10: # split out some data - key_label, comment = line.split("#") - # key = key_label.split(" ")[0] - keytype = key_label.split(" ")[2] - if len(comment) > 1: - addr_keypath = comment.split(" addr=")[1] - addr = addr_keypath.split(" ")[0] + key_date_label, comment = line.split("#") + key_date_label = key_date_label.split(" ") + # key = key_date_label[0] + date = key_date_label[1] + keytype = key_date_label[2] + if not len(comment) or date.startswith('1970'): + continue + + addr_keypath = comment.split(" addr=")[1] + addr = addr_keypath.split(" ")[0] + keypath = None + if keytype == "inactivehdseed=1": + # ensure the old master is still available + assert hd_master_addr_old == addr + elif keytype == "hdseed=1": + # ensure we have generated a new hd master key + assert hd_master_addr_old != addr + hd_master_addr_ret = addr + elif keytype == "script=1": + # scripts don't have keypaths keypath = None - if keytype == "inactivehdseed=1": - # ensure the old master is still available - assert hd_master_addr_old == addr - elif keytype == "hdseed=1": - # ensure we have generated a new hd master key - assert hd_master_addr_old != addr - hd_master_addr_ret = addr - elif keytype == "script=1": - # scripts don't have keypaths - keypath = None - else: - keypath = addr_keypath.rstrip().split("hdkeypath=")[1] - - # count key types - for addrObj in addrs: - if addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label=": - found_addr += 1 - break - elif keytype == "change=1": - found_addr_chg += 1 - break - elif keytype == "reserve=1": - found_addr_rsv += 1 - break - - # count scripts - for script_addr in script_addrs: - if script_addr == addr.rstrip() and keytype == "script=1": - found_script_addr += 1 - break + else: + keypath = addr_keypath.rstrip().split("hdkeypath=")[1] + + # count key types + for addrObj in addrs: + if addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label=": + found_addr += 1 + break + elif keytype == "change=1": + found_addr_chg += 1 + break + elif keytype == "reserve=1": + found_addr_rsv += 1 + break + + # count scripts + for script_addr in script_addrs: + if script_addr == addr.rstrip() and keytype == "script=1": + found_script_addr += 1 + break return found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret @@ -110,8 +114,8 @@ assert_equal(found_addr, test_addr_count) # all scripts must be in the dump assert_equal(found_script_addr, 1) - # 50 blocks where mined - assert_equal(found_addr_chg, 50) + # 0 blocks where mined + assert_equal(found_addr_chg, 0) # 90 keys plus 100% internal keys assert_equal(found_addr_rsv, 90 * 2) @@ -129,7 +133,7 @@ assert_equal(found_addr, test_addr_count) assert_equal(found_script_addr, 1) # old reserve keys are marked as change now - assert_equal(found_addr_chg, 90 * 2 + 50) + assert_equal(found_addr_chg, 90 * 2) assert_equal(found_addr_rsv, 90 * 2) # Overwriting should fail diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -138,10 +138,19 @@ extra_args[i] += ["-prune=1"] self.add_nodes(self.num_nodes, extra_args=extra_args) + + # Import keys + self.start_nodes(extra_args=[[]] * self.num_nodes) + super().import_deterministic_coinbase_privkeys() + self.stop_nodes() + self.start_nodes() for i in range(1, self.num_nodes): connect_nodes(self.nodes[i], self.nodes[0]) + def import_deterministic_coinbase_privkeys(self): + pass + def run_test(self): # Create one transaction on node 0 with a unique amount and label for # each possible type of wallet import RPC. diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -20,6 +20,13 @@ self.num_nodes = 2 self.extra_args = [['-deprecatedrpc=accounts']] * 2 + def import_deterministic_coinbase_privkeys(self): + assert_equal(0, len(self.nodes[1].listreceivedbyaddress( + minconf=0, include_empty=True, include_watchonly=True))) + super().import_deterministic_coinbase_privkeys() + self.num_cb_reward_addresses = len(self.nodes[1].listreceivedbyaddress( + minconf=0, include_empty=True, include_watchonly=True)) + def run_test(self): # Generate block to get out of IBD self.nodes[0].generate(1) @@ -70,7 +77,8 @@ self.nodes[1].listreceivedbyaddress, minconf=0, include_empty=True, include_watchonly=True, address_filter="bamboozling") # Another address receive money res = self.nodes[1].listreceivedbyaddress(0, True, True) - assert_equal(len(res), 2) # Right now 2 entries + # Right now 2 entries + assert_equal(len(res), 2 + self.num_cb_reward_addresses) other_addr = self.nodes[1].getnewaddress() txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1) self.nodes[0].generate(1) @@ -89,7 +97,8 @@ assert_equal(len(res), 1) # Should be two entries though without filter res = self.nodes[1].listreceivedbyaddress(0, True, True) - assert_equal(len(res), 3) # Became 3 entries + # Became 3 entries + assert_equal(len(res), 3 + self.num_cb_reward_addresses) # Not on random addr # note on node[0]! just a random addr