diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 709910f2e407d..bc6cd4bdcf0e3 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -168,6 +168,11 @@ def transact_and_mine(self, numblocks, mining_node): newmem.append(utx) self.memutxo = newmem + def import_deterministic_coinbase_privkeys(self): + self.start_nodes() + super().import_deterministic_coinbase_privkeys() + self.stop_nodes() + def run_test(self): self.log.info("This test is time consuming, please be patient") self.log.info("Splitting inputs so we can generate tx's") diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index 72de696259093..745cc9e4fcdd2 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -40,6 +40,13 @@ def set_test_params(self): 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. @@ -59,10 +66,12 @@ def setup_nodes(self): self.rawblock = ZMQSubscriber(socket, b"rawblock") self.rawtx = ZMQSubscriber(socket, b"rawtx") - self.extra_args = [["-zmqpub%s=%s" % (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%s=%s" % (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 index da254181fec17..e2ac76aac4f7d 100755 --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -34,7 +34,7 @@ def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs): 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/mining_getblocktemplate_longpoll.py b/test/functional/mining_getblocktemplate_longpoll.py index 1259754c5af15..20f472521a9f6 100755 --- a/test/functional/mining_getblocktemplate_longpoll.py +++ b/test/functional/mining_getblocktemplate_longpoll.py @@ -70,4 +70,3 @@ def run_test(self): if __name__ == '__main__': GetBlockTemplateLPTest().main() - diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index d681cdc8abcda..c8144bba71fe8 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -47,9 +47,10 @@ class BlockchainTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-stopatheight=207', '-prune=1']] def run_test(self): + self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) # Set extra args with pruning after rescan is complete + self._test_getblockchaininfo() self._test_getchaintxstats() self._test_gettxoutsetinfo() @@ -169,7 +170,7 @@ def _test_gettxoutsetinfo(self): 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 diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 0e76b525707c0..afb098395320f 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -158,6 +158,7 @@ def main(self): raise SkipTest("--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 as e: @@ -247,6 +248,19 @@ def setup_nodes(self): 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 @@ -415,7 +429,7 @@ def _initialize_chain(self): # Create cache directories, run bitcoinds: for i in range(MAX_NODES): datadir = initialize_datadir(self.options.cachedir, i) - args = [self.options.bitcoind, "-datadir=" + datadir] + args = [self.options.bitcoind, "-datadir=" + datadir, '-disablewallet'] if i > 0: args.append("-connect=127.0.0.1:" + str(p2p_port(0))) self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=self.rpc_timewait, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=None)) @@ -439,7 +453,7 @@ def _initialize_chain(self): 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) @@ -453,8 +467,9 @@ def cache_path(n, *paths): return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths) for i in range(MAX_NODES): + os.rmdir(cache_path(i, 'wallets')) # Remove empty wallets dir 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 index a831fdcd5d2b6..908dda94c5790 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -97,6 +97,22 @@ def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mock 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 = [ + # adress , 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 %d] %s" % (self.index, msg) diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py index 63316d964400f..bebaea79566e2 100755 --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -29,50 +29,54 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): # 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.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=": - # a labeled entry in the wallet should contain both a native address - # and the p2sh-p2wpkh address that was added at wallet setup - if len(addr.split(",")) == 2: - addr_list = addr.split(",") - # the entry should be of the first key in the wallet - assert_equal(addrs[0]['address'], addr_list[0]) - witness_addr_ret = addr_list[1] - 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.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=": + # a labeled entry in the wallet should contain both a native address + # and the p2sh-p2wpkh address that was added at wallet setup + if len(addr.split(",")) == 2: + addr_list = addr.split(",") + # the entry should be of the first key in the wallet + assert_equal(addrs[0]['address'], addr_list[0]) + witness_addr_ret = addr_list[1] + 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, witness_addr_ret @@ -116,9 +120,9 @@ def run_test(self): read_dump(wallet_unenc_dump, addrs, script_addrs, None) assert_equal(found_addr, test_addr_count) # all keys must be in the dump assert_equal(found_script_addr, 2) # all scripts must be in the dump - assert_equal(found_addr_chg, 50) # 50 blocks where mined - assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys - assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key + assert_equal(found_addr_chg, 0) # 0 blocks where mined + assert_equal(found_addr_rsv, 90 * 2) # 90 keys plus 100% internal keys + assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key #encrypt wallet, restart, unlock and dump self.nodes[0].node_encrypt_wallet('test') @@ -132,8 +136,8 @@ def run_test(self): read_dump(wallet_enc_dump, addrs, script_addrs, hd_master_addr_unenc) assert_equal(found_addr, test_addr_count) assert_equal(found_script_addr, 2) - assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now - assert_equal(found_addr_rsv, 90*2) + assert_equal(found_addr_chg, 90 * 2) # old reserve keys are marked as change now + assert_equal(found_addr_rsv, 90 * 2) assert_equal(witness_addr_ret, witness_addr) # Overwriting should fail diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py index 0c6359976a385..bb8dee0022a32 100755 --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -116,10 +116,19 @@ def setup_network(self): 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], 0) + def import_deterministic_coinbase_privkeys(self): + pass + def run_test(self): # Create one transaction on node 0 with a unique amount for # each possible type of wallet import RPC. diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py index 09a7c723471f7..554cd61daa2de 100755 --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -18,6 +18,11 @@ class ReceivedByTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 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) @@ -64,7 +69,7 @@ def run_test(self): assert_raises_rpc_error(-4, "address_filter parameter was invalid", 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 + assert_equal(len(res), 2 + self.num_cb_reward_addresses) # Right now 2 entries other_addr = self.nodes[1].getnewaddress() txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1) self.nodes[0].generate(1) @@ -81,7 +86,7 @@ def run_test(self): 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 + assert_equal(len(res), 3 + self.num_cb_reward_addresses) # Became 3 entries # Not on random addr other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr