diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/functional/feature_maxtipage.py | 23 | ||||
-rwxr-xr-x | test/functional/feature_txindex_compatibility.py | 6 | ||||
-rwxr-xr-x | test/functional/interface_bitcoin_cli.py | 4 | ||||
-rwxr-xr-x | test/functional/mempool_compatibility.py | 5 | ||||
-rwxr-xr-x | test/functional/rpc_net.py | 3 | ||||
-rwxr-xr-x | test/functional/rpc_rawtransaction.py | 81 | ||||
-rwxr-xr-x | test/functional/test_framework/test_node.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/test_shell.py | 3 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 8 | ||||
-rwxr-xr-x | test/functional/wallet_backwards_compatibility.py (renamed from test/functional/feature_backwards_compatibility.py) | 5 | ||||
-rwxr-xr-x | test/functional/wallet_fundrawtransaction.py (renamed from test/functional/rpc_fundrawtransaction.py) | 0 |
11 files changed, 111 insertions, 29 deletions
diff --git a/test/functional/feature_maxtipage.py b/test/functional/feature_maxtipage.py index ddc2102542..51f37ef1e0 100755 --- a/test/functional/feature_maxtipage.py +++ b/test/functional/feature_maxtipage.py @@ -22,23 +22,24 @@ class MaxTipAgeTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 2 - def test_maxtipage(self, maxtipage, set_parameter=True): + def test_maxtipage(self, maxtipage, set_parameter=True, test_deltas=True): node_miner = self.nodes[0] node_ibd = self.nodes[1] self.restart_node(1, [f'-maxtipage={maxtipage}'] if set_parameter else None) self.connect_nodes(0, 1) - - # tips older than maximum age -> stay in IBD cur_time = int(time.time()) - node_ibd.setmocktime(cur_time) - for delta in [5, 4, 3, 2, 1]: - node_miner.setmocktime(cur_time - maxtipage - delta) - self.generate(node_miner, 1) - assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], True) + + if test_deltas: + # tips older than maximum age -> stay in IBD + node_ibd.setmocktime(cur_time) + for delta in [5, 4, 3, 2, 1]: + node_miner.setmocktime(cur_time - maxtipage - delta) + self.generate(node_miner, 1) + assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], True) # tip within maximum age -> leave IBD - node_miner.setmocktime(cur_time - maxtipage) + node_miner.setmocktime(max(cur_time - maxtipage, 0)) self.generate(node_miner, 1) assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], False) @@ -51,6 +52,10 @@ class MaxTipAgeTest(BitcoinTestFramework): self.log.info(f"Test IBD with maximum tip age of {hours} hours (-maxtipage={maxtipage}).") self.test_maxtipage(maxtipage) + max_long_val = 9223372036854775807 + self.log.info(f"Test IBD with highest allowable maximum tip age ({max_long_val}).") + self.test_maxtipage(max_long_val, test_deltas=False) + if __name__ == '__main__': MaxTipAgeTest().main() diff --git a/test/functional/feature_txindex_compatibility.py b/test/functional/feature_txindex_compatibility.py index 20b023d82c..13dbdfce71 100755 --- a/test/functional/feature_txindex_compatibility.py +++ b/test/functional/feature_txindex_compatibility.py @@ -14,7 +14,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.wallet import MiniWallet -class MempoolCompatibilityTest(BitcoinTestFramework): +class TxindexCompatibilityTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 3 self.extra_args = [ @@ -33,7 +33,7 @@ class MempoolCompatibilityTest(BitcoinTestFramework): versions=[ 160300, # Last release with legacy txindex None, # For MiniWallet, without migration code - 200100, # Any release with migration code (0.17.x - 22.x) + 220000, # Last release with migration code (0.17.x - 22.x) ], ) self.start_nodes() @@ -89,4 +89,4 @@ class MempoolCompatibilityTest(BitcoinTestFramework): if __name__ == "__main__": - MempoolCompatibilityTest().main() + TxindexCompatibilityTest().main() diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py index b1369c2615..90a543b51b 100755 --- a/test/functional/interface_bitcoin_cli.py +++ b/test/functional/interface_bitcoin_cli.py @@ -90,6 +90,10 @@ class TestBitcoinCli(BitcoinTestFramework): assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", self.nodes[0].cli.echo, 0, 1, arg1=1) assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", self.nodes[0].cli.echo, 0, None, 2, arg1=1) + self.log.info("Test that later cli named arguments values silently overwrite earlier ones") + assert_equal(self.nodes[0].cli("-named", "echo", "arg0=0", "arg1=1", "arg2=2", "arg1=3").send_cli(), ['0', '3', '2']) + assert_raises_rpc_error(-8, "Parameter args specified multiple times", self.nodes[0].cli("-named", "echo", "args=[0,1,2,3]", "4", "5", "6", ).send_cli) + user, password = get_auth_cookie(self.nodes[0].datadir, self.chain) self.log.info("Test -stdinrpcpass option") diff --git a/test/functional/mempool_compatibility.py b/test/functional/mempool_compatibility.py index f789a19ef3..c9233d6133 100755 --- a/test/functional/mempool_compatibility.py +++ b/test/functional/mempool_compatibility.py @@ -7,7 +7,7 @@ NOTE: The test is designed to prevent cases when compatibility is broken accidentally. In case we need to break mempool compatibility we can continue to use the test by just bumping the version number. -The previous release v0.19.1 is required by this test, see test/README.md. +Previous releases are required by this test, see test/README.md. """ import os @@ -29,7 +29,7 @@ class MempoolCompatibilityTest(BitcoinTestFramework): def setup_network(self): self.add_nodes(self.num_nodes, versions=[ - 190100, # oldest version with getmempoolinfo.loaded (used to avoid intermittent issues) + 200100, # Last release with previous mempool format None, ]) self.start_nodes() @@ -38,6 +38,7 @@ class MempoolCompatibilityTest(BitcoinTestFramework): self.log.info("Test that mempool.dat is compatible between versions") old_node, new_node = self.nodes + assert "unbroadcastcount" not in old_node.getmempoolinfo() new_wallet = MiniWallet(new_node, mode=MiniWalletMode.RAW_P2PK) self.generate(new_wallet, 1, sync_fun=self.no_op) self.generate(new_node, COINBASE_MATURITY, sync_fun=self.no_op) diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index 0501befe0f..06e76c4f92 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -307,6 +307,9 @@ class NetTest(BitcoinTestFramework): assert_equal(node.addpeeraddress(address="", port=8333), {"success": False}) assert_equal(node.getnodeaddresses(count=0), []) + self.log.debug("Test that non-bool tried fails") + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type bool", self.nodes[0].addpeeraddress, address="1.2.3.4", tried="True", port=1234) + self.log.debug("Test that adding an address with invalid port fails") assert_raises_rpc_error(-1, "JSON integer out of range", self.nodes[0].addpeeraddress, address="1.2.3.4", port=-1) assert_raises_rpc_error(-1, "JSON integer out of range", self.nodes[0].addpeeraddress,address="1.2.3.4", port=65536) diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 15fc947eef..b87f3ad6f3 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -14,6 +14,7 @@ Test the following RPCs: from collections import OrderedDict from decimal import Decimal +from itertools import product from test_framework.blocktools import COINBASE_MATURITY from test_framework.messages import ( @@ -81,6 +82,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.generate(self.nodes[0], COINBASE_MATURITY + 1) self.getrawtransaction_tests() + self.getrawtransaction_verbosity_tests() self.createrawtransaction_tests() self.sendrawtransaction_tests() self.sendrawtransaction_testmempoolaccept_tests() @@ -116,6 +118,7 @@ class RawTransactionsTest(BitcoinTestFramework): # 4. valid parameters - supply txid and 1 for verbose. # We only check the "hex" field of the output so we don't need to update this test every time the output format changes. assert_equal(self.nodes[n].getrawtransaction(txId, 1)["hex"], tx['hex']) + assert_equal(self.nodes[n].getrawtransaction(txId, 2)["hex"], tx['hex']) # 5. valid parameters - supply txid and True for non-verbose assert_equal(self.nodes[n].getrawtransaction(txId, True)["hex"], tx['hex']) @@ -126,13 +129,14 @@ class RawTransactionsTest(BitcoinTestFramework): # 6. invalid parameters - supply txid and invalid boolean values (strings) for verbose for value in ["True", "False"]: - assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txid=txId, verbose=value) + assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txid=txId, verbose=value) + assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txid=txId, verbosity=value) # 7. invalid parameters - supply txid and empty array - assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, []) + assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txId, []) # 8. invalid parameters - supply txid and empty dict - assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, {}) + assert_raises_rpc_error(-3, "not of expected type number", self.nodes[n].getrawtransaction, txId, {}) # Make a tx by sending, then generate 2 blocks; block1 has the tx in it tx = self.wallet.send_self_transfer(from_node=self.nodes[2])['txid'] @@ -145,9 +149,10 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(gottx['in_active_chain'], True) if n == 0: self.log.info("Test getrawtransaction with -txindex, without blockhash: 'in_active_chain' should be absent") - gottx = self.nodes[n].getrawtransaction(txid=tx, verbose=True) - assert_equal(gottx['txid'], tx) - assert 'in_active_chain' not in gottx + for v in [1,2]: + gottx = self.nodes[n].getrawtransaction(txid=tx, verbosity=v) + assert_equal(gottx['txid'], tx) + assert 'in_active_chain' not in gottx else: self.log.info("Test getrawtransaction without -txindex, without blockhash: expect the call to raise") assert_raises_rpc_error(-5, err_msg, self.nodes[n].getrawtransaction, txid=tx, verbose=True) @@ -172,6 +177,70 @@ class RawTransactionsTest(BitcoinTestFramework): block = self.nodes[0].getblock(self.nodes[0].getblockhash(0)) assert_raises_rpc_error(-5, "The genesis block coinbase is not considered an ordinary transaction", self.nodes[0].getrawtransaction, block['merkleroot']) + def getrawtransaction_verbosity_tests(self): + tx = self.wallet.send_self_transfer(from_node=self.nodes[1])['txid'] + [block1] = self.generate(self.nodes[1], 1) + fields = [ + 'blockhash', + 'blocktime', + 'confirmations', + 'hash', + 'hex', + 'in_active_chain', + 'locktime', + 'size', + 'time', + 'txid', + 'vin', + 'vout', + 'vsize', + 'weight', + ] + prevout_fields = [ + 'generated', + 'height', + 'value', + 'scriptPubKey', + ] + script_pub_key_fields = [ + 'address', + 'asm', + 'hex', + 'type', + ] + # node 0 & 2 with verbosity 1 & 2 + for n, v in product([0, 2], [1, 2]): + self.log.info(f"Test getrawtransaction_verbosity {v} {'with' if n == 0 else 'without'} -txindex, with blockhash") + gottx = self.nodes[n].getrawtransaction(txid=tx, verbosity=v, blockhash=block1) + missing_fields = set(fields).difference(gottx.keys()) + if missing_fields: + raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction") + + assert(len(gottx['vin']) > 0) + if v == 1: + assert('fee' not in gottx) + assert('prevout' not in gottx['vin'][0]) + if v == 2: + assert(isinstance(gottx['fee'], Decimal)) + assert('prevout' in gottx['vin'][0]) + prevout = gottx['vin'][0]['prevout'] + script_pub_key = prevout['scriptPubKey'] + + missing_fields = set(prevout_fields).difference(prevout.keys()) + if missing_fields: + raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction") + + missing_fields = set(script_pub_key_fields).difference(script_pub_key.keys()) + if missing_fields: + raise AssertionError(f"fields {', '.join(missing_fields)} are not in transaction") + + # check verbosity 2 without blockhash but with txindex + assert('fee' in self.nodes[0].getrawtransaction(txid=tx, verbosity=2)) + # check that coinbase has no fee or does not throw any errors for verbosity 2 + coin_base = self.nodes[1].getblock(block1)['tx'][0] + gottx = self.nodes[1].getrawtransaction(txid=coin_base, verbosity=2, blockhash=block1) + assert('fee' not in gottx) + def createrawtransaction_tests(self): self.log.info("Test createrawtransaction") # Test `createrawtransaction` required parameters diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index fc93940b63..2d3b105fa2 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -337,7 +337,7 @@ class TestNode(): return self.log.debug("Stopping node") try: - # Do not use wait argument when testing older nodes, e.g. in feature_backwards_compatibility.py + # Do not use wait argument when testing older nodes, e.g. in wallet_backwards_compatibility.py if self.version_is_at_least(180000): self.stop(wait=wait) else: diff --git a/test/functional/test_framework/test_shell.py b/test/functional/test_framework/test_shell.py index 26df128f1f..2d8935dfe6 100644 --- a/test/functional/test_framework/test_shell.py +++ b/test/functional/test_framework/test_shell.py @@ -16,6 +16,9 @@ class TestShell: start a single TestShell at a time.""" class __TestShell(BitcoinTestFramework): + def add_options(self, parser): + self.add_wallet_options(parser) + def set_test_params(self): pass diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index b9adb5dcb5..31b308546d 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -98,8 +98,8 @@ BASE_SCRIPTS = [ 'mining_getblocktemplate_longpoll.py', 'feature_maxuploadtarget.py', 'feature_block.py', - 'rpc_fundrawtransaction.py --legacy-wallet', - 'rpc_fundrawtransaction.py --descriptors', + 'wallet_fundrawtransaction.py --legacy-wallet', + 'wallet_fundrawtransaction.py --descriptors', 'p2p_compactblocks.py', 'p2p_compactblocks_blocksonly.py', 'feature_segwit.py --legacy-wallet', @@ -226,8 +226,8 @@ BASE_SCRIPTS = [ 'wallet_txn_doublespend.py --legacy-wallet', 'wallet_multisig_descriptor_psbt.py --descriptors', 'wallet_txn_doublespend.py --descriptors', - 'feature_backwards_compatibility.py --legacy-wallet', - 'feature_backwards_compatibility.py --descriptors', + 'wallet_backwards_compatibility.py --legacy-wallet', + 'wallet_backwards_compatibility.py --descriptors', 'wallet_txn_clone.py --mineblock', 'feature_notifications.py', 'rpc_getblockfilter.py', diff --git a/test/functional/feature_backwards_compatibility.py b/test/functional/wallet_backwards_compatibility.py index 5fe4a95f6f..c9cb3285fb 100755 --- a/test/functional/feature_backwards_compatibility.py +++ b/test/functional/wallet_backwards_compatibility.py @@ -7,10 +7,6 @@ Test various backwards compatibility scenarios. Requires previous releases binaries, see test/README.md. -v0.15.2 is not required by this test, but it is used in wallet_upgradewallet.py. -Due to a hardfork in regtest, it can't be used to sync nodes. - - Due to RPC changes introduced in various versions the below tests won't work for older versions without some patches or workarounds. @@ -274,6 +270,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework): assert_equal(info["desc"], descsum_create(descriptor)) # Now copy that same wallet back to 0.16 to make sure no automatic upgrade breaks it + node_master.unloadwallet("u1_v16") os.remove(os.path.join(node_v16_wallets_dir, "wallets/u1_v16")) shutil.copyfile( os.path.join(node_master_wallets_dir, "u1_v16"), diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py index bf218bfee9..bf218bfee9 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/wallet_fundrawtransaction.py |