From 7c97d6a811c420f2bb8f8d0d2bca021e157c29a2 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 29 Jan 2019 15:01:25 +0000 Subject: [PATCH] MERGE FIX: sync up bitcoin_functional --- .../functional/combine_logs.py | 25 +- .../functional/data/rpc_getblockstats.json | 270 +++++++++--------- .../functional/data/rpc_psbt.json | 8 - .../functional/example_test.py | 16 +- .../functional/feature_bip68_sequence.py | 3 + .../functional/feature_block.py | 85 +++--- .../functional/feature_blocksdir.py | 13 +- .../functional/feature_cltv.py | 42 ++- .../functional/feature_config_args.py | 7 +- .../functional/feature_csv_activation.py | 7 +- .../functional/feature_dbcrash.py | 3 + .../functional/feature_dersig.py | 40 ++- .../functional/feature_fee_estimation.py | 8 + .../functional/feature_logging.py | 5 +- .../functional/feature_maxuploadtarget.py | 3 + .../functional/feature_notifications.py | 3 + .../functional/feature_nulldummy.py | 5 +- .../functional/feature_pruning.py | 23 +- .../functional/feature_rbf.py | 33 ++- .../functional/feature_reindex.py | 3 + .../functional/feature_segwit.py | 27 +- .../functional/feature_versionbits_warning.py | 3 + .../functional/interface_bitcoin_cli.py | 5 +- .../functional/interface_rest.py | 3 + .../functional/interface_zmq.py | 25 +- .../functional/mempool_accept.py | 3 + .../functional/mempool_limit.py | 3 + .../functional/mempool_packages.py | 5 +- .../functional/mempool_persist.py | 7 +- .../functional/mempool_reorg.py | 3 + .../functional/mempool_resurrect.py | 3 + .../functional/mempool_spend_coinbase.py | 3 + .../functional/mining_basic.py | 101 ++++++- .../mining_getblocktemplate_longpoll.py | 16 +- .../mining_prioritisetransaction.py | 3 + .../functional/p2p_compactblocks.py | 3 + .../functional/p2p_feefilter.py | 3 + .../functional/p2p_fingerprint.py | 3 + .../functional/p2p_invalid_block.py | 19 +- .../functional/p2p_invalid_locator.py | 3 + .../functional/p2p_invalid_tx.py | 15 +- .../bitcoin_functional/functional/p2p_leak.py | 3 + .../functional/p2p_node_network_limited.py | 5 +- .../functional/p2p_segwit.py | 263 ++++++++--------- .../functional/p2p_sendheaders.py | 3 + .../functional/p2p_unrequested_blocks.py | 3 + .../bitcoin_functional/functional/rpc_bind.py | 2 +- .../functional/rpc_blockchain.py | 8 +- .../functional/rpc_createmultisig.py | 5 +- .../functional/rpc_deprecated.py | 88 +----- .../functional/rpc_fundrawtransaction.py | 9 +- .../functional/rpc_getchaintips.py | 17 +- .../bitcoin_functional/functional/rpc_help.py | 42 +++ .../functional/rpc_invalidateblock.py | 3 + test/bitcoin_functional/functional/rpc_net.py | 5 + .../functional/rpc_preciousblock.py | 3 + .../bitcoin_functional/functional/rpc_psbt.py | 5 +- .../functional/rpc_rawtransaction.py | 5 +- .../functional/rpc_scantxoutset.py | 6 +- .../functional/rpc_signmessage.py | 3 + .../functional/rpc_signrawtransaction.py | 15 +- .../functional/rpc_txoutproof.py | 3 + test/bitcoin_functional/functional/rpc_zmq.py | 9 +- .../functional/test_framework/blocktools.py | 2 +- .../functional/test_framework/messages.py | 21 +- .../functional/test_framework/mininode.py | 82 +++--- .../test_framework/test_framework.py | 100 +++++-- .../functional/test_framework/test_node.py | 58 ++-- .../functional/test_framework/util.py | 40 +-- .../functional/test_runner.py | 50 ++-- .../functional/wallet_abandonconflict.py | 3 + .../functional/wallet_address_types.py | 8 +- .../functional/wallet_backup.py | 31 +- .../functional/wallet_basic.py | 3 + .../functional/wallet_bumpfee.py | 15 +- .../functional/wallet_disableprivatekeys.py | 3 + .../functional/wallet_dump.py | 106 +++---- .../functional/wallet_encryption.py | 6 +- .../functional/wallet_fallbackfee.py | 3 + .../functional/wallet_groups.py | 5 +- .../functional/wallet_hd.py | 17 +- .../functional/wallet_import_rescan.py | 22 +- .../functional/wallet_importmulti.py | 42 ++- .../functional/wallet_importprunedfunds.py | 3 + .../functional/wallet_keypool.py | 7 +- .../functional/wallet_keypool_topup.py | 5 +- .../functional/wallet_labels.py | 127 ++------ .../functional/wallet_listreceivedby.py | 12 +- .../functional/wallet_listsinceblock.py | 3 + .../functional/wallet_listtransactions.py | 3 + .../functional/wallet_multiwallet.py | 7 +- .../wallet_resendwallettransactions.py | 3 + .../functional/wallet_txn_clone.py | 3 + .../functional/wallet_txn_doublespend.py | 3 + .../functional/wallet_zapwallettxes.py | 3 + 95 files changed, 1201 insertions(+), 958 deletions(-) create mode 100755 test/bitcoin_functional/functional/rpc_help.py diff --git a/test/bitcoin_functional/functional/combine_logs.py b/test/bitcoin_functional/functional/combine_logs.py index 39fcea62d2..3759913e44 100755 --- a/test/bitcoin_functional/functional/combine_logs.py +++ b/test/bitcoin_functional/functional/combine_logs.py @@ -13,7 +13,7 @@ import re import sys # Matches on the date format at the start of the log event -TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z") +TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{6})?Z") LogEvent = namedtuple('LogEvent', ['timestamp', 'source', 'event']) @@ -23,7 +23,6 @@ def main(): parser = argparse.ArgumentParser(usage='%(prog)s [options] ', description=__doc__) parser.add_argument('-c', '--color', dest='color', action='store_true', help='outputs the combined log with events colored by source (requires posix terminal colors. Use less -r for viewing)') parser.add_argument('--html', dest='html', action='store_true', help='outputs the combined log as html. Requires jinja2. pip install jinja2') - parser.add_argument('--chain', dest='chain', help='selected chain in the tests (default: regtest2)', default='regtest2') args, unknown_args = parser.parse_known_args() if args.color and os.name != 'posix': @@ -39,11 +38,11 @@ def main(): print("Unexpected arguments" + str(unknown_args)) sys.exit(1) - log_events = read_logs(unknown_args[0], args.chain) + log_events = read_logs(unknown_args[0]) print_logs(log_events, color=args.color, html=args.html) -def read_logs(tmp_dir, chain): +def read_logs(tmp_dir): """Reads log files. Delegates to generator function get_log_events() to provide individual log events @@ -51,7 +50,7 @@ def read_logs(tmp_dir, chain): files = [("test", "%s/test_framework.log" % tmp_dir)] for i in itertools.count(): - logfile = "{}/node{}/{}/debug.log".format(tmp_dir, i, chain) + logfile = "{}/node{}/regtest/debug.log".format(tmp_dir, i) if not os.path.isfile(logfile): break files.append(("node%d" % i, logfile)) @@ -76,11 +75,17 @@ def get_log_events(source, logfile): if time_match: if event: yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) - event = line timestamp = time_match.group() + if time_match.group(1) is None: + # timestamp does not have microseconds. Add zeroes. + timestamp_micro = timestamp.replace("Z", ".000000Z") + line = line.replace(timestamp, timestamp_micro) + timestamp = timestamp_micro + event = line # if it doesn't have a timestamp, it's a continuation line of the previous log. else: - event += "\n" + line + # Add the line. Prefix with space equivalent to the source + timestamp so log lines are aligned + event += " " + line # Flush the final event yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) except FileNotFoundError: @@ -99,7 +104,11 @@ def print_logs(log_events, color=False, html=False): colors["reset"] = "\033[0m" # Reset font color for event in log_events: - print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], event.source, event.event, colors["reset"])) + lines = event.event.splitlines() + print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], event.source, lines[0], colors["reset"])) + if len(lines) > 1: + for line in lines[1:]: + print("{0}{1}{2}".format(colors[event.source.rstrip()], line, colors["reset"])) else: try: diff --git a/test/bitcoin_functional/functional/data/rpc_getblockstats.json b/test/bitcoin_functional/functional/data/rpc_getblockstats.json index e89329170f..b8cabe1e5e 100644 --- a/test/bitcoin_functional/functional/data/rpc_getblockstats.json +++ b/test/bitcoin_functional/functional/data/rpc_getblockstats.json @@ -1,117 +1,117 @@ { "blocks": [ "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", - "0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f7a89f139fa6a18259cc762eb92b4c81fd039fe329f7de41b71f6f67118f89d576edb125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203777929efb067caba22b4883bc68de588aa0cc8bc53a9e40a46237b0a388001c69c4c4e426a7c8c7b1c5849ea0627054b210074c7c7801188070e2ce2457e4f16fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a4a275601657b98def1fbe297253a18c1b34d95c3625f9b25321753da790404ca1aa4c8337e583c35f40bd56a1d134b36568e8900fe6348e152d8b580b99bd6f6fdb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f20675346e2cf617779375d5c3b3b30ea2d503395c70bdeb46ad9578302a0a2e5830431da5d492c90a73fb38b237525ce6025d0e4455d9bf8753af494639745d70db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002096ed32f9574f687e8ab1f17d6eeb7b9559a5d99b17238c0a2996aa1a2af16e6e64f2b580a13fde615c08aa2331b3974085b79c1936317707d055a20d6a57a82770db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e6497983b279bce0a171467a1d6527246ef8c71d9106fd6667c96173c8f9c06d3a443d428ea7f7da67d63fc7b5e65421fc74947e6430875106d3ef1c1024430770db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020bdd3c2ca8596f6ef65e69c12c2ba8926197d3b3f84e7249075053face4baff4efd3da827167a7160575133fd0b5566700eb89a485ffeb9711d1099ffa77bfc4370db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201353dcc0075143eeb4992a45deeb05d5cc767a7e408269ea2262002c92449212d4374501a550725478a20e26f767af3dcc5f11b89dc3f03dcb2ea7e36cad025271db125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205c2376e807db4e03c8990ab97f06d890f02d764da4d10437133ad38f689069610ea002eb4462e10aea9cf8679a4ad55c6a20eb06f54089aa89167e31b854844a71db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020db668d26a7cb937f97112dc138b5db686151b986d6ecde81be6e83ea1e570d2afccf3e6731e69914f38ef4a843f3377faca4345c5c0de7b82dca25ee1fa8191871db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002098826c41b1af464b0c3a5cdc67815a863f48df0cc068f772f7eaec3ae78e934c7c274269b4dcc0b1a04343cd98d73895afe6306f46ee1617a2e93c27bb537c7971db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002006b73f24f16577acd7f7661af14c3d331308f0dc00f89d7c3a716d1674fb43216e51cb009ee7566290c33b00a2efcfc8e9098f62afa7d981dc6b5f90851316ec71db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c6738bba0b0b78b999d190dc7ba0bf0f280def582715f9f1453ab29c70e5191f2a41a3f842b3cc10f2584e772c37614edc7ac6f299aa4215bdcea2cfedecf7e471db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002030fd36cee9fdbdb3babee443393404d723c83cbc87d5911b1cc55c452fd8c82138d05b16cef49b9a7d4c2503b6eef8ec5fa454136a70ef53f99ff20fcdb4d37972db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020bb29a0839fff600f2e7369fe614588007ab6c090d7240339d759a25c5c4df81a70f60faa04217730c9201a3cfc730d6faa37d00a6d872739b7d45be84577ce6772db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204a520b4e0c95a35512120d6c1304794a52e7d39f006d66a71b8daf9bdfeb4f31662462a04097bb08e0d0193218ea3f7e76f92db1c141f967e8cd95f1e407990672db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202a8565ef2294d42a8bd49ea63fe473556be09ca9750b06fae77c997fd60b3921ad66f6ac59cbb39e3554dc283ada59c4fd0d40dc715aa0b063f132db52a63e1072db125cffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020ac9336d0b89143894a19e268ed18202fff41c8fefe4450cad1b15473e727a710048c595e60a3b0ac66f9ab6ce120da07cdd39c0984ff5892a1a3adbe9f1ceab172db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020ff55d56e6b18423dcb45a63ee2da9e81792dab47c06ec5deca2ec5f46035606b485d6db68f3fe017e912dac671df5c494e31859550278d5713e53b54bb04b8cb72db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020cf655dc853078e67f206427eed1ce0ec676b248fa851b89f5cf1d36cbf435c30281e2eeae9dda9b6a061491b73c239b1061c6b4a8b7412fc9abaee957bb5a78473db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c27c72db47bf8dd75cd3e76ad504b12aad9e601dfada8c3f99afe28f2b671a0f1dc80bb17ad2f58fea67685c273a34833fe849ad969660359804005c8f653b5c73db125cffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002097a1946e551124f298c351ed20ef2d0949a7adcd3b41852c1bafd63b74f6192589e54ebe7d7d867a972b83dae9296d4f2aa719dfdb96a6bfddd5d5f7f2783ed373db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002097124b92c7e65d71aaaf80483a96224fa7f4c35fa2bbca7f8948986ea980ca0286f0757debadb780f1a0c2805e4be49cb962f3a01f11f52b8fab6716bfbdcc2c73db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a51ad94f54f9711fe41b5df458f93fae1a0f9d5dd54bab80c950fa643a1e4e430624bd029c544c9d593857cf0b2a4b70d84e2a61df272e6ed9ae58cca7abbbef73db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020052ff9ff37428785296dcb84fc5c35bd69b0b2964ba48db8ef255d2a8711e11882d8492cec31bd4fb68c7f43bec867fa5456800f52b5c2177137cafd9478b8b673db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020fd708f97c3f49f1737db0b9fce1db44d635be396b40df6737d1d8dffa9597a646d7cf5ba44657be8c36067623881e79210522a762e716c28dd76704c3fe250fc74db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d86df645826e84501e0b4bb6103f62e090aa10d24b6f27d74c2a8823cef1c902f292a0ad85ee14c2f1308c1243e5b80b098c3c0680b9a1949841634d68f89f3674db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002033749b28c6fc27a5d3ab7a8104ff4d6404ba78e76034213ca143adb7542efe7835571a3338ccd8525a09bcf6baa98d8d0372435d3e23c51bf56a57aef869b5b174db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020458fef5b1d996dee62053947815d725af8a58edc21873b0167de59a6a059921c125bcf6d71cc4e3815052a4262943501fb16eea31da91c596023331a41b9ec6c74db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208ac6c0dbe5ebbfc494d37fe53b168c6a2ac800cf9ef3fb2e6e47ee030463224f8b956d2c11613f4e866a8ce07a6ba4440b7bf5e69276c533915720b0ca91aa9074db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020edc35e5f376ad3390e6613cb02e81c138bef0d390e8d9077af51e08a0017dd439deb7904030ed0d43186914e2877083d9f41cd2e31da67cdaec81f1f5d5ea62f74db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a663de1ad9c9efb03612e7e0c678d9be7b8b5547103a7bb4cc77d5f7faf72b4d81c9b4d8f772cbb9a71064c9bd4bec5050c2ca9879829cb25f97e3ebdced238075db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c16479a0839de43ce26eb24d9c645d227a4c0b47cae98d2d8201adbdd444e16e0371dfb645cdd5578c242ec16cd4a6c32f08378ef2ade47f52f1453294fcc43375db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000206d45cc167d7120739376b0cfc87136277e9214e39a5410df3b65522f1e807071241cb2f6fc02ddd0834db556ea6201603103215ec4863f7d0a8f3b642c375ec075db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020faa3dfade917d2dc10fcbefc64d9cbfb9c6dd75b756fb7bf39fd130b4e43e95ed66974da9770f84d702e6cb7516926dbfb959fe063ff49651f9836a599ff706f75db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f68235e6980469667502db16ae7b07669effb2009d3c56c2c5ab88d1ece8f27a9d041df5a4a1524954b583a6a84ed0d884eb8bd8a6cd288de39e291526fc626c75db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205b9585c43580d469ed30e6fd0093839beb171d9c07140c1cb6650075d250c61587eaccdfbe19085257b3720dd9fea4ef09a286187858277e7fdbd9b713b8fac475db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020809a2376c1fabe12d3f140ef6e480be2ba6f630ab2a5673acd38025f006c001c493ab77370d732cf8557c32894aca7d1e8c32679e72ccf91f5ed25f8b3212ad776db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205e23d997878ca564bece109cbb6ece3c73452b2c64b24b1a06163ff5f5e4d0352e27e9bc17045a1fe6482e806fe62b6de48be30ab1cc77fc90ec87f897a97b3c76db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a5ded1149cda67a96495e4e1a4fb42b436f8e624fc312db1af461c1f6990a20fadc61d68fbfc5d008639eb38d436e9d6e74b10b3fcd6c669b4b8b302febdf5f776db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203e452d97ffac506ab5d9b67f33c2b07a265da7693ddaf26961fc48e5e32de817380571164e2e48c7e9a5d799ba293ba295a2ef8b53dbea9a32da0360319926c076db125cffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e8214900e89b520ef79543e8ad897ed4c303f1ff7b77310757882c9bda236b3b30a0107db802dba2b95c7eda54b22698b76a7742d87cce817b4a7d3700ac87c876db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202fd95a8f04387a08843c508530fe866ec24bd95ed3517444e4993965368cd06d499920d6ce7a6ef317767069e1547176e576a0783eedec4529a43c458a44300b76db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020905091fd6b0e2fc6fa55a27fe7bf2471dec938247c9e37567812ce861123b0570d69408566432e6d649187d5c4a7ca5f87e3351c2a94d559a11f12d9e911dbe677db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000207101a14bf3754f2ff47fc0d1061a39081cd8d57a4be3221d17ef526a3730ae1ed1789da060dae0ad7fd22406f2de7de3e13f184fc78d9040c4bbc47faa4300c077db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e0ca5dd8c3c1931808451b46f3eb1539c822fd175dfd19fd18fe5e7ca8e9c03c6ed4aca3ae696966cda08c5e0cf7a6192737b07277104743fed2cc6a0e8311b477db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201df2ae8eed8e38f2110dc2ad8741ceaee6a498910b52dc7a16e751f58966722f8ed6f9652cb9e59247f19746ef553786061db8b1a6f11075164aaea43364863977db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020329be633bad578915c06c743b6df8adf485c6cdf94a2467f9dbae756ac94614f1a8f221ecb67486e52eb1d444055573d99e9dce6942148b3a36dd6ac4bdf5a8c77db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d72ec439241642e7eebe94df1dae5ab51d6e5045ebeda1d9fb9d1ccc3fde0462d0716b2bc83a609ee39d33334cae196273f53d8ded28ed166197251eefca01b377db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020dda419461029e12ef7dbf9376635d3e95f9bfe36fa1cbbc623742cf27d7adf4f6ec1c9a25205592ca521d538d1e5bb27ef282821db9bcb44fc971b16938d1e8b78db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000209025ba65fb292a38405ae41767dd1669b5ba5096622d85f214bb1ef06040603933434911c4701b5ac10fbcda8ad5f95b37e1fa1396432fb93f69688bda14787b78db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e4bd15c1a9c12557c65f72b1134c319f4cda85300ca7843115ebd5877be6f90c4e54cda1b4f23b29b3ba2664f0e0212c5e0f971b0d19599557ce87e1b77ccab078db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020573c84ccee02b896dcf995eeaad45b994728a7c0ca6d20e6bc56e648bd81e46dfdbb1a2d099b0ef3a9aec600df25409ffdb37e8d5eac956eb7d7dddcb7cb02eb78db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203097633bfe71440d3afb4f38fecb052535673ddde0722fd263c3dcf62a9293124b6e0e018708ca022c0f1d83aef35f6b94809be6043b1490c5deea7c0624afb978db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020607adcb53049a48e47bbf24ebec7040da5c3b0539f9d22fc3f6d87ca61637329c89a613c90d595f3f5e0b06fd1509cf19a2b3e0fd5940a06feb93ebf150bc5a478db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200b39cddf6273db05d28b4bfc05bcaa98799d688544956a10663e21ce14625d405b3d443e5fabd5df15cc929d6f88681b2cfb8c4bc14167d69fca81dc243d231679db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002045de23c4cf1d49d16cf72dbd92a75a2cc01b392bade635bf883e48651bdec93f3c40bcd10bf40765348a84f46a8369036d64fb84ab69fb23e012bb1c6b8bc12f79db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c237ff92864748d315dcce45ffbdfe564bbff38899791d031072087ca6ffe115960ba6980aa18ea0c9e1a9eeea0ddeb40d17cac98bafe885c48b96b018647d7579db125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205b432cbd5833fc54204548947ca4226ac79e73eb15bef026c1b3fe4560de5421e1d64b98a0f6b57b522021f1076fd654c59b585c09a25db784bf81b7536fc91d79db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020dc2c03a2f4206de9d8b8e5d821419c3adb43326253ea91b6739ef527ca40fb4136c83c5b0944229ea919350630d605d359a731f3cb4bbc257b623c551ae7e4f179db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200aa4323341cc3b056bed35fd830dba6b9ad63ec9d791fb12d87448d0dd988633a2d6b7c78e7c3f656f7b5e09662dc759444a0cc4d8bd9a7ca5ddb79cb6e1f63479db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e57fbbde40b187d102bea4c575adc770cfec75c4c49e2b24626fe3ecc86f12269d41632f28232719f50549bae516d37d1d1e6486c5c42d2806b5b2aebce96e8e7adb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b3596a2d1137d64d920f388a122f65e0b2ac21115bd8b9d4e439e0076007f958bdfffe0449081c15842206c6fcb2e269e2fcb8a170534c1d8570aae12fd994a27adb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200e3210c029528a000508b6c85ac9d79c0b5f5b85b6e385dd07fae0ff1c67b139445835bbf9205b77190b2780ed279ae47ea93f70dc45300c23f45c6ccd6575d67adb125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020068153ca95ee28829fb820aab79105d7309555d1ce049b04da3b2a37ef9b1748f79db9d3d4e8b84dcdcf26cb2a79f0350d78e4b010db73ef290de513a17a5deb7adb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020cb675aae02dd520a4ee591c344d59544ca3299182902ddc7cdf5691c1b6bd36c16dec14fc782d1ffcf73da0dd4d36db6e44392923df102600d54bce4cdb3618d7adb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002048c507454abb253879a91652b8ac5a7ed75ea61d7ede12993efe899de202e9137c74025dd31e1a67a2c0af072f2064747cbe7dd09bd3c4993b11e345a25ad3ab7adb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f4e7b8ac08807bb42045edada8bf2ac49cb45a14f5622ef69123ce68795b935c044104ed3d366318c67c03140990570fd0ddc43a59b1bd4799fe0127dd912a447bdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020379fa579480cc6acb60eb1ff0826e167b097ea258d54416ccc246ce570d4cb27ed54f21477a937118d8415f4cec278c9285a1387159a426d9fc9d76f82a05ea47bdb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f3c2a8b0b4f2d078a0264c02980c026248dcbd4bd129ec85ee1e99ce7a87a100f56fe338b484173183324703d5182caa1d7b6f46b6d7f12e7138369810b38e0a7bdb125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a322aab7f671411be497aebf0c00e47dec9dc11783beda75521fd8b2435ca446da56e43b15c2a9a353971d33abd4584a517e488ea3cc387be6ad4bad7c8ed3a87bdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020bcb756d1eb1496ffd359a1a0c6e18428da4b090994404dd506139da0e7f9e47bd0c4de211aabf2fc6164b55085f43bfe8ce63356a0bd0ed68ef1470b4ca045787bdb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020eecd05620116c3fb8b7bf8e95f61fdcbaa092aba0c856079bd65e4fdf1eaa151048bc267c799b52aaf83b2428d0788757d38281eb4de12a7d577e907e722ea677bdb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020fa05ebf001eb48f3eefc7ca7d98ce7adf2c7e8d0b2b0548c747cb9b0747b000429f736411522fc09b8437dd5e02eb658a2446311731419f658db2d7632544e6e7cdb125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203f6c2d553ff251b263b61b9d553a031dd735e31b9db52891c54b02b846132c60191a03d3ba21c204aa59f3324e245d08edecd1c2295d435acc994d9ebeebaca77cdb125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002057659dc19e6726e4d0ab2b652d8812356eaba8484be03f34cd50ff584d64eb6a38c4ac2c550f70a2aed6d7020a77fb594a0a65c7bff9f8ba41f7cfeab55384677cdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000209408a004311eb26a2ac80e349a80e0e1654362c2e121483bccefbec1edfcd80bf0b580e533eb7d317f4ca7cbe19af1f60a00a99f6b9055d6ab5087fe44d1c8d97cdb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002034df5c133af532635b61b3bcd882986f5983ce7322de29f96c28b3ee50040b063a3b39601aa8400be083341861886765b3ef8c570c2c36d915c0cb3e14ef11af7cdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208bb1e26740a0558ebbf2feda35a084dfb6ea76779ede57195093c71960902c28f68eb9502c284f08d2346600e4c09571bd0016b60e743f13d4269e18078158677cdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002047c1bd25c4bc2585dd737837d2fc596aa2ceb8782a7ed9daa787ab04b170ca17db30859822b27fbc7c49516ede9366eb7e7144c6e39d69352b08afca5e1e6c847ddb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020490f8e589f41d8ad8d62bea5632cb81a3b242798820e1402d3997d4f976bcf7673a9ce49a177282515e79699ff97ad5980de3488c9509ed19090e3a52222469c7ddb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208ef25be9a074ff3d43d9b6f6b75ee0374d8940192d8c27d5058a2555916f49730c3f972bdaec8249f7b5ac2c250ff8f2761e88b3ea6916422d695b8bd9a7ec2c7ddb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020ffa7e7b55ea2b308176e24923bda438651c1edf0aef8bd84eb36e8a4d9f546607f7df39bed4f52cba68655fea20e8d507a0da5f6b30b3adcce129db77e0da68c7ddb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020eb8b6e4bcf8c3d7bdbdd23a2cec7f50d9c10df7a8e5bcb950afb6e9875307c6aee037d266ef68b6f44e278e7af7f2399e7036a008fa52dc711b9d21d52d4043c7ddb125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208bb066c71aac93170e90e992faa2ac30e84c9e07e00dcb01819e3ba60136023f1665d6e23b42bb4f114806d18da1f6e6f5afa0afe967753957f78746b2b3e8927ddb125cffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020878c098dd62b4e47820b85675c0a05212cc392b061be96715213ade90a90f70906b34acffc2ff7546170855f93108d30c6d472626c23c151478f10a6a2d2552e7edb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c9e9f6d3018a58c0b062c34dd8731d661c7a4233d4d2afd555ece7635ab99771b4c93c90698e4fa630b2c1ed22baf346beca77a488abda890432869bbf4cb2747edb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208675c3ecbe5c80cbc261f924f7776d25ef6631837ad4634833a40d4a4a4be40e031dcb9f4da2d6c07ff4809de59d3273fe3d49c8ae16b968bc9516a0ec56cb527edb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002061f7014628613f3ceb46cee357dc9567629223edd7a94600c461ec110fb8523c80e898a4168efd1b9b962ab7b1ab5a103b9567ee52bf8d861fd4592142d282907edb125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002015c52e4a857e31230afc5e4aeab8d9a3511b1ea4950bd81c8b951c7be3fae64e1d1eced2301f1456b34dd15a94cf58c33853a6e8ba8e6699b9d50cf334fcb7307edb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f58dfe90e8e80c931b233e8deb24dece7856afe525258f635aefebe8fa097873d199da75978be95348ecaba01b3d16f44fb50aab50334fd644b157a360111f667edb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200a166a0ccf9f9bc4a9bd970157c434c9fc030b7822d9ea20baa71c89d72e831ffe1fc65d1fbf3577d33d2b777168013ab640da43858dae8dbc7de8a6d5ddf2e87fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002082eb7f23ecfd6865e6e20fb0fb5d3288c1af39cb3ccca4f9577c7cc532e4907f91f81380bcc33e9972ab94dc674592189aa42a1f6c84cd77a104c48a5a4543797fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e5953ba9dab21d158d2a36d1857ab95a3b1119d7529d03c92f3ef39e19288b6a4757ba7bff505d993a04fa536e075ae59e1ede6da99013ad896c3af440a93f037fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002035673f65d10dd505e74589b2f5f566ce890253c3c28b0a143f203448dd15f75baccf8057c924a2575b4ceba14933e7e29798db3c36e137cae7709cdc91c8b0e17fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002078d4fafef0be333a2c75cee1adf6a3057efebbf2b46b1ee94849a3b76a3b576c9b9526bc800bf916f908ee1ff47cd817aec3ea0c55e453d27f0dfb2a7aae5e8e7fdb125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002037641a7627a040bcd78f07db26b752ce8f1ee8352583a87cdd6f3593a0963223f087bc5d2e291a820c46a9829cab6c6a9b0e359e12502bd8941b5685e48939b37fdb125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000209185cf5aa8edd6db7c5cc3dbfd3c031133052238ffb655a3dd4a250b243b5d4dcb519d8cc917c10bf6673ec41cfebd90bb78a04453bcd7e6589141592829776980db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205e2b1ff80d3a006b4eca50a975fc9e2e1b1c4443fc3cd4b069fe30f94a974a1f60e4fcc01635d4a8409e0da993c85d1fc07eaac5f1131c115c80b771a6df764b80db125cffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f15673211feb7eef5c41e1d7879554cb5152b5985ee358d028adf25748312c51eb3565c0125934bbe2e60434509ed68edb67b6892cdd2cafdb6b007b2f53bcbd80db125cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200bdd672491275f9b07c0b9c7213d30d49e44dbcfb9ff83cc82a6eb5c5c8fe50b5df780599eca956f3d50fae82699219af2d85a3b7a34eb800111b15bff05ca0b80db125cffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200f2052a010000002321036f6ded90e5420a1985c8b94b49fc52b00fc62c97246049df80344a4826fb4549ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020eb11503e1c3f1adc28c3539c9e5b10002e62bb7cd443a8735186713c9e42863129ad7376b93dcd27c510a33de11495a9addacd3220d3ecca6f8baab019a10f5a80db125cffff7f200000000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff029c00062a010000002321029423a365b19b0bd9e40fb37a7e39f70ce872334ae2526c1c652794dec2347fecac0000000000000000266a24aa21a9ed66c7d30aad7e7136713ea61e09b846a2c49c7520a769fd8793fd9fabd5542896012000000000000000000000000000000000000000000000000000000000000000000000000002000000017a89f139fa6a18259cc762eb92b4c81fd039fe329f7de41b71f6f67118f89d57000000004847304402200dfcd95d0187b3cda34a87b8f1c74bc903438ec9e39d075da516dd65419db441022012c66f1cca7aa556e68682e6db96ff2780c9a5de4aab5febfbd0343d105744b701feffffff0264bb9a3b0000000017a9143653e5a4c5e09c8b1e350c94be4b0374154425618700286bee0000000017a9143e25db9394263141c06ac24491332d88383aa6dc8765000000", - "00000020721037c073ea7f880b3a99e0124f32c4020f6cad20c7ae5dc71754c594b39d137374d85d27e440dfe24bd3bb15219a374d91f56cfa4153406fbed0b9a6a2a33280db125cffff7f200100000004020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff021cd0062a01000000232103f84c00b62c7e7ba17640ed22a99e4a368fca73ee82063853cc9215e7746dc505ac0000000000000000266a24aa21a9ed9ad93006bf536a376b0ef2f2e74b33130963d887ff20a7854dee16e339b477f40120000000000000000000000000000000000000000000000000000000000000000000000000020000000001013fde0b6d48c6512afc750e2f7ef78ebaab62ed094335911dc3fc6f1919534b6d00000000171600144581d3486bf1fe4f8ee507a900e3bd6a03c3f7a4feffffff0264daa4350000000017a914416c6899a0708166e3fb85943921d3a5be87d9d887781ef5050000000017a914e7435774e899931993d11f3e05971f438015ca10870247304402207a1ce0ce88de6e45d695389a9f757625faa359aae1e3ad30225870a8aad1a4a302204dc15dc97573e5a7aa1ba82e69f2ea4e602eefd2638897194becc189778501320121021149faffcef3c4795ca9aeccb675d248a077ba2ad8ce48ec3e2ce829961331e466000000020000000169c4c4e426a7c8c7b1c5849ea0627054b210074c7c7801188070e2ce2457e4f10000000048473044022021a0101c62b6e3f84c325b3b7efabdbff6aa76e19a6233fe951b707aacbf8e0202206190588d4c7aaab2a4118f7e2fb60a3593766d49112d722b6060af3e8f6b6d7301feffffff0200ca9a3b0000000017a9149767de1f41cb6a90795255bdedf77fff0e30bf798764196bee0000000017a914ae05a4752e1249e834eb6560d47212f0330b9ebe8766000000020000000001013fde0b6d48c6512afc750e2f7ef78ebaab62ed094335911dc3fc6f1919534b6d0100000017160014eb43921b3f8a28674fa8488666e3c68ccc924977feffffff02005ed0b20000000017a9147ab1a26013f61a84ba842ee9b7368e187d545f188708bd9a3b0000000017a9142d6669bd028551e8489ca1dd7f94a233ceee9d80870247304402203ec1c57d183be2e28800b72f67aecd88b4fb0887337f567e73f9479de9dd3632022030e5f33dfa525f574018fda26d689a34ae9c943168d4f95e52695e26e27aee9c0121035dfbae9f252a020cdb2695d285c6a719de7364046c87a494c260bf578a5ae8f066000000" + "0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f1cd16b94f20a8a3dda91027c888025f2ec1a07ddcb2786bdff5916e66c00406f194ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002014341131c18d3b3aa30056a0f7a97c9ac852d3fd0ec9c76f7a25e83c01e7f821bf83574fb606f25c59200c844443201faf923ef5284fd4401f3104a323c601491a4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002078616da95299bd42cd8f813c8043816ec5741de466be3162e16bfff471808461f671e694afaf534d37df484f1990fc19a65fc26964b38141b7f8ecf61b8a50241a4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a08613f37d305835a3a1553e77a479eba0f34c06c52e429ece54f5973cd77a7086a1efcaf75f1cd5be2c9deb6a7850225757a2cfc3031a91cc1330b3af4acc891b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203b304fa1ce0505c2366982939ac148d9124c5ac747cc9aea133cea9916484966305de0e8d049f2be65c68d64d2c45746def5a9b4fcb8e298692b53b83b4690241b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fbdf49978ec4f0b23704b6772a614336872587e29c463f375836ffd775248837fed9f3fdfc33f076c6663ae78070fad7263c1e24161f3ee1a4857b8931815e2c1b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020c37548b9ca256b9ff17187d4d4309cf3143845b0a5811d3ca5427b2fddf000731a10985dfd473561c070c3527c3fe3941834cf51b3dfbacb501b44c69c9745ce1b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020383dd3766c0675440f26370ad62d687e335ea3a650dec9b02fe544107cc1823a13b98696d41562945457d655f4c6921f736068f7a72afd1ad6b335f2857d16631c4ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207476dd96d81f53e63934ce28c9e89022e0f24d040ec3c838443e925fc3a2f230a94d0cbcefb4a151191dd7664153944d9eee3b7b46d4ba997f397ed2b72c3afe1c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000209e425c73eea16cce98c0d47d6070aca29f0524eab4b97af84c386aa5322dd43055002f097e929bc6ad88ce869968e1b049aab7f6e45a5b869cf4349afd5d43e01c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202090e16a514fad40386413a100bbaa4fc14086a8d3501ac64c91fdef922e834a369e409444d0ec496eb0dd9a47f1fe81a7ab974bab28c50a912b994acf13b5f91c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020777b767e42624c52775b331f19e81ba03be2f51a0608166cd5388c1a47d5e776473570bb9bba553a7db4a9a3083533027c54af1fea3ef6ef67757ef2255d64631c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002076bb2bf3251a51ec367a42f8584043171a5d53157394cd776ebd017e2982127653d953aca3e2217f56533c043c07b9a926a30672ebce2562f1d06a6dc5044e7b1c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020e6d7f02292655b73fc1f1958b09633ba07265d71d2a2784060b354cbbf1900202e9c9b02b63170002a94a0c9d8d787e2faa4c074a1ebdeb2855555347321dd101d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d61f077b0ed326e17f0a3d5af3fa876b72b434a252c9c3248d20130ed744287fcb10da470222dd29c7a07e2da7eb25d6499ed3919676df89cc630bd1b23fbb411d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205efa9741cf51533ed6e07a97c71768372f53ca9c6df83894d64fe94c718eee23a207441e79ecdcf99ef3326385f5f675e2dea84c85ab8973219c63f92847ed5b1d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020368386b0a0f46b2a2c4648eb9cb5dd1380c4f22e437e0bd49420670993361e5b9026632c2ddbb4b31b3c3118c51e43ea4d78e05c0aca0956278ead26a263d1521d4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dd0a1594bbff6345a3e34f326e5ee605c855f5e0a5c363fc39615a8b1539b736200b51297dbee4aadf9b536cd2afe7617651e0a1d0f0610f436518a2a4dc54621d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f302a1092709dc27a32d7229d391b90824a75828692c4bb2ca8f0ca5c88b3613c2e18797ffe8b367336338f90b2cf8c3f66277eb1e1ddbe18c052977294f10691d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203dcc77aac703a8cd0e799384b74383c1d5f236426f77d516694607fc88fe85581276a20ceb98d02e6355c9dba4312e2fdc9832f4302cc307e1263f2df0aadd6a1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dfe109704a0b2801aee4232c31fb744145a7c80dd91a7727e16d4057719d5c3730f8296243521d82d96ed75c5af800a722fc9dde2e02af95c8c9822190ba07b21e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201ef9ef2699bc36fd646bb9ba8629644bc98396122f6753710caf0315d7539f751382d3d85f17eb8b42cf17e54baa327886dcf6fa63207e097df8f9b84cc5422f1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020834c91f23cd91b727be08b892f1c1a2f33c1e66d66f35607925fa1be4bca2c25b4145a73b1c71b945f5bb9ede3d8d95c9a3b12a0a81b7b14f440ec5146dd4ec71e4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205743202bf1e543a9be2a59b62be6a5a494511fab96968007b8d7199ea60a524697227ba473ceaf48d4f48ee17f8ee6cd2f1f5ddff03a641642ece240e7872f8f1e4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207469f5c1841bf57275d82db23e5a8f0e8512af1eb10119c238519cdd6cdced34fd96dc659a874b3f5d30fbe6ea421a6b9791dfce8450f8851e4b90d80f0f794e1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b6338f55fcc473b744d53d675b4a83dcd80ddec9d02ad3323cf1ff50ac0412239d986ec20885d772fdc67803273aaec43871426ac93d3815846a8cd13dea5af11f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a19d9edf2d22415cf226b4e1416c8a3097e0af222efac2bfeab15fa1f07b3f24c18580c4004de6d6244a30ce431c4be3ca44731509fc6b11710c792efed5e9191f4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000208f9f29a27424ec01ce77485617088506ca8faeef69300f0a474ad63ca5d32972d6049609fa3588d6ffab4d9d89a90636ac94c0ca1995f7768163abeb25dbf2bc1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fbd87d530a9ec3835ab579337fd16e512cec6c4779ab4d84e7256b3333dece28de1065c8c3d3d166e057139ac59af6f4f2c0d241b6269bbea6f61c5eff3dba431f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dc6ef4f436baab2d6880f242a2588313a2739ac694e30319344045ee318c9524d0ec7fbcaca30ce85392cb03b64015ece769afb50fd07db05c15ec49abf7d71c1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020386bf4cbb3708ae6345b9f2459bdd99d07422b05f9b005d2d4d1d3bf87d47359ebb22b3a15c8e94ddd8129527873b9bebfa10c54d11196961376efbcaad3c4681f4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020600e892f12ad82a23ce12684d3ffa0887eab5e3e97804fa651050b23366cc55ef2468e65c3d3cf49650657eb47d0b0b7949c71dcc0922eb824523157b7eff478204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002068e4aec52a3f4e44279e3a65cd476237bdfcc2328390bb31b8a903f89ddfa70e8d669f61b469acb31b1d4ecdc238e6616a83a30644a5d06fc2ca1aad6449d09b204ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020cf2428ae9a5014b910275807f54a8bbbeec47d462f9d284ada60329b4955ff10cf83c44ddde39a709aef54fb302c7f1cb36db8fe7c3befce20dcc3729767518c204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205801eef8cca082407ce4798648c4d3ba0fc4dd2d4459eccfe5300c7960760d16cb3dd78a2f22fb88717a175e45c53d34f970b94ef9f7cd1b6c279294d427d163204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002088320983a4bcb95b9f342994c6943c227f3102d3b16282f048ceb8e15748662a52d1207591a0a364bc9245a76e36530f147ec4d1b4e1917676b4071f542c3b19204ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020acd85b6d8087d3b6bd2a208a2e39b75da459c0e0eb14088075a23a2e043e8a4ed5a1754491f8180d293b42e6c04ec3f82e29c1f2600dc8607616f69a4a464e6e204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204873bcb379f78da4497ce1e22f6bfb63537b89c8c522257a7b7bef74e515ed1b6b235faab048fa73a76c68fdbdde6a4ee7ebe0a3b7b23df24ce75dbd2cf49c33214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a87f6d13bae8e2e07996c3316e8e0da6aec7d1aee6b80aa5883018e4d136db3e9a498ff7d322ad93863e0a5318af7e7d0ed683fd2e4ecf523f2b7369106dbe4a214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d9b0618450a51c08f43187c479e20d351f0466464409bb3071dc0af7c51d65498a198cef23dddd2c4b93d9d3288ae922584e221a9ef1ded3dba5a2ad494d9237214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020167dff31847b8dcad472bb6bb7d0af53b245f0f1d4c9f83d4ce14a0f05d42d7f0f2638ffc0e6896230f28df1865ef133dccb1f027545c6a1177dffd1fecf8a01214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000208236c04424573692504e777e179b9247e54622b118239311413812f13cefbf6e39a639143f599dc76208b2014de12a364716df2918af9186453e3676dca743d7214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fab7b55aeb59f63315dbc10784c55e55635a7600cc4f3b94a00003007e7fc90b4af016248e9908882f8a7f0bd8743c8da82da119446e8b02e4d3b8d1d938a3aa214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020794b4160d8fd4ebe7611d0fc9d3e04f3038a485669f74075aa153852ed181121c577f4c0b7151f6d78a16e3c21ab291b53ced8a5c4f05a22caf24a25ed029d56224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204a8acdb549d2ed922360ae0e81de6c913c3fd84b0de51abacbf97162a99f7c26c656b252d3259c33ffc7e5d403843accc6ace9b7e60e911e2347a6a0b0abd122224ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dee6d00c7058b3422e4273c98c16181e04ea93116496a8442de546c2ee9fd86b550013f39e004b3829dc3717b17fcfedc87de9450315fcca540963119cb264c1224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202ebca471f5fb2226a790233c3d0bc323f73d935872f3e15b66bd5fdcb822101d7b68788ed61d3fb8cb746f627e09db2fc09d8a07672747709d92ae400e053e78224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ee500470fc1c71a82f2cbb9f8d5723bcdf57b8051fc458a8dbd8d0dbf60d0e40d1a0be0e50f3312d4830e3900186e5a6760d44006c164b4f0758218ef2b2de8e224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205057e8d8a7451d79325851dc8e0f4dfdb1dfaaab637509d9e61f0e064af5ee5c185221c53c0cf43261b3c238c0e8117da5d6ac60085615f7a3d8027726cb2143224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200907f01d9c5c872296796ca77feb62eb414cc080e13a93e59e181528bc19c336eaabacb1ebcbd20b26f6bacdc712ffe17d4c8131e7f99b9cac309c0683737c04234ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000209bd6a4ec962d9e6199c0a2f39481a7ecc322fedbd2320cbe7dc984c6ab958421fe7a5c7f2513a3c3de9ddf7b211f5bfe85675b31183c4bb98ae79ab28cd055ac234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202b8a6381b7c9476fd77be379a929863db6b7edd9858d6eca0f68a430dc87cc3a9c6c8b34bfadfdacbe95cb1d4ae5ce4e4f4ccf0300171d7a91cdc97f620c7b37234ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203d3e9a0b4decf12b4402a2178b60599311c8a9c7d50ece365a61ca29530da7056754ddf7d77a11cc8ce680a74fae01d851bda024fc9c51712c55b4a190caef24234ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002067fa05082d4f7a29a3985f30798940cd854c76a2b20e9560b2047f7753193f71ac61b8df17a8a63f099c8f55869301fc2a0aa37355a4a2f89078135ee72a1362234ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020249684272865fec3ad62ecb73dfd930500e32e475306c9e5d4b6d545e3687b0a48deaeebfafa213f0a560994b3f4000d5e2b93951d7e5be40073503877292dc7234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204671db1df91098669bb03c3e8504d432da99853601366c7de7585bb8f23a6e1e2996a16c11a0f9ae87d937f566c8bbd919040528c1bf8dae4e22a8f0ac5f935a244ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203046500cabfee552ed114c505279cd75c28faa811adcb5010c53c14df5de3216d265321a4168c70fff1c85fd83bd976cc03c8c1fb6567398cc24053e343ad137244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020591533cf8dd1fa1872c7e6d62ef714b28886f38f7921ee614e13b748eaf923282a96287277f18b1113a9c3ac384fd7b43bccd0e45114908ca5396a76cbd736fd244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205286b5747d0244a55e1dce435fdbb9f300d7138fff3b16767bc09196eb00256c6795e3f372a2d5d137244a4fd72fd799e8de913f868f22269eaa628d7d2970a1244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000209649b55f6a5ff0d5db73aeb7089fcce605fb9dd23971e577b73747ffab586f4edf84581240223e2d8912a6eca049e06aa46ddbf271af08e9ac9605505311418b244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fe7ff82c11ad3a3db3dc11a03a67e0b86b727d232c80f37209b028bc2689296c0da76fb756e1c9833f38b198cfe843ab820fbc0c38e30f8f858f6ffdbd64e834244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020c02e6109b6aaf6643cac109ad5b5be7f7ec47c7993335bdceea6e0e490ae9067eb1fcee49ecc40a61477f934e3b9821f2cc7ada429fcca2cd645866742854c40254ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020956c46fce0adfc8a30d91c7b7f328f17c2a90771083884c4fdb7f24640598f6fa69c4e5971bd3b6cdc7e3ee98e03a969b28c3220fdc685cc2eb77293763ca4ba254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203eec7d0ea9c539f47e684eec9dba900e27c805b8200f237924c7df8065957726c83caf659fa341bf45f733a92cf76daf2cfb6bccbf969a2753f5f7d9cda4bd1e254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203c022b42283bf651ee4d536fe71b7e5382e9783d4a85f8bc159f00b97f16d82d312ac4f89f1b1496de576811f2ff17de44b512db0beddae59e030e2ce3eba4df254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205da9709dea4bea4f3229d0eed439a4820a0e817f9fbbcd8bb355cd8052702973403358080a2881b823a740f58b6b0c922b42189e06326478cc33390f2c704743254ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020447c49f664916cc13a839e27f7cbe0b09dea990dec71dd479b537ecfb771c7159ae6241727c2645ce00817909ba97d43447fe2e146bce55b7dccd5bcd27d2e3d254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ae3b214b1495953eea3b99af7ade4b8d22d615d598dd6c790c6576d6453ef35d37fbd3446f8431f00052f278c3e0359beba54a2f5064bc6be4990478fcf4e086264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204cc68f9f571f59145e1f7505550d56da13a797fbc7e5a178dd7f6f9241d91f007f2400f7aa1b32b30bf869e4da86f75eaf2baae182efc45c42c6245f06aba675264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002096d55714a83c3d030cc72141eac3577b8a394b8366b2c93354fcecdafeab025022f5e26de7e4eba3f8e4a09f243b55ea6f08bfd013e2051cf1d5df20dcb3331b264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202ccf49665bd46e4915dcc9221f5fc72124bb73fb11fed8869dc5862a47950c0d654693a1d86098212d68fa9a27f9df0faafea4aecebd8b203f2ab8f3f0b86196264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205d0be5aea546eab7734cbee757ea5f4983ab3a3f202323c1c88590bdbc8b561974cb0de6549bfdec92322ad53d8a4192433edab0e33a10e7561d2e27c7759f8a264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fc3d70d4f690d7d7da90b1c832a51c2a92940cdd9fccda6a909c7256ad567160550e1089b48fe75f0f1e6f712cc2a1d4aad384a4ceacf1c71576420fe8e7de46264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020995ab1f2293e3aa1e7bef418919bdce60032e89e60223b8c12b17488c50af83b3a360b4f89551aa0ced646a6210b0c3d3f7d0464faa248b9d252c89615babc9f274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020e02dd5e1201ebe7ef453e77df3021cffde1b5447b9eced017963489e005ac247e1f2b80e91180cd9744c3e126eb8a0fb34ced45587da6b0fa9fd1c6946f049bf274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002081b265800d61feb37525c58aacc7e6d32cfc6b6579784f9952dca51c3addeb37da900ae4ec1b2075056001a361c0fc8f9ac1ca018bde2a2bd8fc587424dfe18f274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207daba0dc6fccc067a19dec46770d1443fc715b50540242ff26073a6748bcd9583804c315b783d4f9aac4dc8f109fa60bcbf1c3cf98a7e1e593fcb969e88aafae274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204a35ab2d9c4656c4992d2445ee566e4f5cd0468358292c94839de2b270ba0628de9148db03da59ca2eb727a4f7a03f2b9ee1e4045f37bdaa4b75a89de56b63ee274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020215ed7b31d118a45a06407133e41f3f9d25c913ff98f3e798144f981d9145305266efc9274f7c836aa0f8b831732aec2c1d85c5bb9176af4c889a707cca380fc274ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020425321a1f12ed4613b63b3cc5b4c7674242c3de67ea86984f2d9bb2766f6220a5c460ce6840832b7ef05f206c5d255bc2d8ea83753a7f5ef5c0bf3dbcbc7c74a284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204e088cfd312091bf589f0fc24131dba20ed83f716530a7b033356e9ec803be23a73c4af5b64fc631d20aa1f646c7c61c4cc5d4be6e2fa29570030d72219726a0284ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204287a2bf40300e39b45d6667d6e17abba37d98c41efc7023fd21b643fb2f6b76d915d10e1f9e224d3bfdf5203da57173f0b8d8eedc92ed9ff23372927e86073b284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002083137929ca902f409a1f35385b4d31e0f5163d488d71b00ade724d7831986a280a187c13fe0db45aed5fa4f5089d544a617da9f4f80fe6ce1d0711b228f3a6bd284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b38c074d78cbcc8bbbf20c48e30639c2dcf444488efee59f5aa01c48322a30418009c11df7e14de6a6d0d72cc22f20ff5fdba3a7dbe409409ff92b1302340fb8284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a6865148220c7f5ac3259f57fa381676d6be5fdab56eed8e060808fcce4118492476fe6d5ecc681e7a18c20a04239143de1c2cddefbb08f15153b8e9b0c22f62284ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ae146263f4087106b8c51ffb5cdddb03a4e593ea1a22a8f6580eaa374185126db2187dbe694a1b17b7c5664115307965407274c25bf6ae02049817685f923256294ae75affff7f200600000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020718abe22705f33134812b56d04c129d453da890e27caf6e77d2bfb3f9be460083634f35fc8ea4a29b0f30d6c6b4926455a31de62d2f763bc95c8cd1a7a425599294ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002084537c50520f4e6b0173926320c3193f6b4259c9a724fe202337d3d5cf7da70b1104e1d6f25c411165a856a0bfdd5ddbe168238425c05271962aa6e5ebb676fb294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204bae65b948c9790468cfc8fbf78a81e7aec5407dbab18c18ef1ab37a13f0c257792cd1246dac5ce265a8439e539db1aebe4776535d422315bac8e57a51605aa6294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201e68985b2a15920524c3c2da77354c0ccfb202c3ab4005128eb2743aa33f0a5b0527a624a6d1f808c896d8cd1552c251a4ae5310e6c62493977b0965d17f580d294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ab1d90854505caa1ee748c1987f4cb6674844b84d17224bc3983fdd6e44a930b2edf3e5a90be7a9080ad15014ce796b38b6c19ddd3754443243fc277bcd2368a294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002062242f316efa083c17e2173d9f9831afc1465f3fe84431d8e52fec71ae358b243e29246e0db770708987f2cff380920321636926d9c66c2c808d2d5f0ed27d672a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020258c1a9b0ca17819d8d7fea5178e9c72c2e7c6769696f70098e0d5d2a9dc0e5cf039f5f686d727c6158ef5405ee8794ec2f89c641093a1dff0f5240263a441bc2a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020434ce26cddae99571a1d663419d715f88e6ff0e413c45f21c44b1991d041fd2745534db221054e2233052aaffe7d7232a91b3f0918c14eac74b2f704b37bfb8e2a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ec94475f112ea37dddd84f066e61446b431d28d2d9b6fbb336d16295e7eece52f1dc01abb3b27e71d8a25c3ed2d6fbbc5900bf954738ed63d57689ba5e68f6532a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000206188cca18a2be3b7f0b500a724f1b73312873488f04c5082abd81ca0b2250a75ec0efb2fa994ad23e1f39416e69976e66fc4ef9f101bd4f60fcee1f8c45a2b802a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202384b91bd0bfb1385ef42bda9b2fa43930aa8889214bb14f63c61a74f380dc7f9d547f2925ad39b9161fa55b9cd258463fd058234778a7c7b3061113d64179812a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204c266a3008c3bd95ae4bc8228bf878595cabf76cc2ef3fed32936777fe37833a1a13ea016868b2352a8d6d1eb35d0aee784cef06ed50655b8d84c089324351df2b4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ab2c78d1249de8482cf26bfb1616ac04f7b8404eafcae3e0654f398943fd41571b4d7549862be0b06ed1408ddc3e7c01b07af24c203a18fe9744e214b14d2d652b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002031aa0fc5e0242a9c9d91024b6b7e67544da72c4773537f881ee5caacd45a3c38c650ff5fa0ffd080b3e5f9752527b718e8c6b731467028e14b0b009d4e7406ee2b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200418c57609fc6ea3f24f569dc3afe163538a6aab940fe8c3d73c72cd781221380482c6f8ef2c19429da2f7a842bb811496aa86247c55f7ecb3337718b694d9472b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204f36abaf10d6a8b3113103f3413475db0640c89a39f02a718e8bd2190fe87f1d6ffaf2b9fdbed67ebae4b36c97f9582814c99c90d0b5123f14da4861bf3e4f742b4ae75affff7f200100000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff02b000062a01000000232102f6869601b2b9980b07fc047e309c1fc1433e08c5bf0498115c5c0e117ef59bfdac0000000000000000266a24aa21a9ed5896cd6a40cd126b09e317cbd179f39e2bcef2f9d423751d980258396416e671012000000000000000000000000000000000000000000000000000000000000000000000000002000000011cd16b94f20a8a3dda91027c888025f2ec1a07ddcb2786bdff5916e66c00406f0000000048473044022046d00465c4508cfd02fcb878b19d120e28be28e40658b1f15458828891ed1541022036aac054f36a42666dfb7b42a20506315a0b72232ce7704406e23c7a9515178701feffffff0200286bee0000000017a91481ddd4a9708ba8088cdcfeab9583ede8d83a298c8750bb9a3b0000000017a91484e16967722289584257803688aae36cd64480688765000000", + "00000020cc7c39992f2dae21e0ebd958f6ba77a6d0bcc568e044b9b61ca4d77536a4214e7b4ade79dd733ea72d97993aaac27f2263b91b1500467350ff35ea40c2850d392b4ae75affff7f200100000004020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff0230d0062a01000000232102f58ba54b2d51c4e2a6096f9d266261b45f1026a86ba88c29ed8070dfe3f5ec6bac0000000000000000266a24aa21a9edb824d92cb231c2366f0726aedf8bfc2705239a40ae6b10a106534e8b5395a09d01200000000000000000000000000000000000000000000000000000000000000000000000000200000000010196bac2a0f6212b8e5710f8c7214dd32c393d38d20b7703cf0b7b25276bb6ab8001000000171600144f8a6c8d4c6c309b1e2b725b7496859e172ea367feffffff02781ef5050000000017a9149f00bafb542049fe32d532b0ea7494ebb7ae41398750daa4350000000017a9147794e6dc43de332ca7a095e582478c331446686d8702483045022100bd85ed3954f1151c2fde32c4021a32c96d7defa4a57c14b1a056be9b361a8e49022054947bf6fdb535c46cbee62efc1262cc0389a6eaa19afbcfa98fb1fb30c3ef230121031b2371df07fb88dddf590b246dc74defc265fdbfe258e4b168250859b806f5ce660000000200000001bf83574fb606f25c59200c844443201faf923ef5284fd4401f3104a323c601490000000049483045022100d1c4b09b488f6375ee4540a531a13b5549e88e2459bd88c84867e293c54862740220222e8af70c8d8b1139c2a7b616d9132bde94244edca7eee3c7a783b12839dadc01feffffff0250196bee0000000017a91490e5e33cfedf18d5cf911d6f853770c62e1f5d028700ca9a3b0000000017a91422311ee58518edf3a2289012461dc66bc8739d2687660000000200000000010196bac2a0f6212b8e5710f8c7214dd32c393d38d20b7703cf0b7b25276bb6ab800000000017160014b81faaafa52f7723f539f8d595147b1a112b38ecfeffffff0208bd9a3b0000000017a9146b2e611708a94d9c674dd08c7c4c1fbb97bcdba987005ed0b20000000017a914933a20f07bab1d8f341f391819466a271f0cfd648702483045022100dfa8b0052c7825e6abcea05d10fc82550a8d6538681ffc8188d48ba789e4d9b40220697371cdf527a6ecd1887f87da3c87dca3419e4a1aa2683e5c4e035199084d100121021cc37c2ec090f30ea0b49508ae8a7d65d9759903932666da56671c1faa445d5d53000000" ], - "mocktime": 1544739694, + "mocktime": 1525107225, "stats": [ { "avgfee": 0, "avgfeerate": 0, "avgtxsize": 0, - "blockhash": "3186429e3c71865173a843d47cbb622e00105b9e9c53c328dc1a3f1c3e5011eb", + "blockhash": "1d7fe80f19d28b8e712af0399ac84006db753441f3033111b3a8d610afab364f", "feerate_percentiles": [ 0, 0, @@ -125,7 +125,7 @@ "maxfeerate": 0, "maxtxsize": 0, "medianfee": 0, - "mediantime": 1544739711, + "mediantime": 1525107242, "mediantxsize": 0, "minfee": 0, "minfeerate": 0, @@ -135,7 +135,7 @@ "swtotal_size": 0, "swtotal_weight": 0, "swtxs": 0, - "time": 1544739712, + "time": 1525107243, "total_out": 0, "total_size": 0, "total_weight": 0, @@ -145,10 +145,11 @@ "utxo_size_inc": 173 }, { - "avgfee": 3740, + "avgfee": 3760, "avgfeerate": 20, "avgtxsize": 187, - "blockhash": "139db394c55417c75daec720ad6c0f02c4324f12e0993a0b887fea73c0371072", + "blockhash": "4e21a43675d7a41cb6b944e068c5bcd0a677baf658d9ebe021ae2d2f99397ccc", + "height": 102, "feerate_percentiles": [ 20, 20, @@ -156,15 +157,14 @@ 20, 20 ], - "height": 102, "ins": 1, - "maxfee": 3740, + "maxfee": 3760, "maxfeerate": 20, "maxtxsize": 187, - "medianfee": 3740, - "mediantime": 1544739711, + "medianfee": 3760, + "mediantime": 1525107242, "mediantxsize": 187, - "minfee": 3740, + "minfee": 3760, "minfeerate": 20, "mintxsize": 187, "outs": 4, @@ -172,48 +172,48 @@ "swtotal_size": 0, "swtotal_weight": 0, "swtxs": 0, - "time": 1544739712, - "total_out": 4999996260, + "time": 1525107243, + "total_out": 4999996240, "total_size": 187, "total_weight": 748, - "totalfee": 3740, + "totalfee": 3760, "txs": 2, "utxo_increase": 3, "utxo_size_inc": 234 }, { - "avgfee": 18953, + "avgfee": 18960, "avgfeerate": 109, - "avgtxsize": 227, - "blockhash": "343d5e65800ab2c88ff2b3817016e0100331c71b2d4be2d207572ce810e0141f", + "avgtxsize": 228, + "blockhash": "22d9b8b9c2a37c81515f3fc84f7241f6c07dbcea85ef16b00bcc33ae400a030f", "feerate_percentiles": [ 20, 20, 20, - 301, - 301 + 300, + 300 ], "height": 103, "ins": 3, "maxfee": 49800, - "maxfeerate": 301, - "maxtxsize": 247, - "medianfee": 3740, - "mediantime": 1544739712, - "mediantxsize": 247, + "maxfeerate": 300, + "maxtxsize": 248, + "medianfee": 3760, + "mediantime": 1525107243, + "mediantxsize": 248, "minfee": 3320, "minfeerate": 20, - "mintxsize": 187, + "mintxsize": 188, "outs": 8, "subsidy": 5000000000, - "swtotal_size": 494, - "swtotal_weight": 1322, + "swtotal_size": 496, + "swtotal_weight": 1324, "swtxs": 2, - "time": 1544739712, - "total_out": 9999939400, - "total_size": 681, - "total_weight": 2070, - "totalfee": 56860, + "time": 1525107243, + "total_out": 9999939360, + "total_size": 684, + "total_weight": 2076, + "totalfee": 56880, "txs": 4, "utxo_increase": 5, "utxo_size_inc": 380 diff --git a/test/bitcoin_functional/functional/data/rpc_psbt.json b/test/bitcoin_functional/functional/data/rpc_psbt.json index 9f970b4961..dd40a096de 100644 --- a/test/bitcoin_functional/functional/data/rpc_psbt.json +++ b/test/bitcoin_functional/functional/data/rpc_psbt.json @@ -67,14 +67,6 @@ "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210cwRAIgYxqYn+c4qSrQGYYCMxLBkhT+KAKznly8GsNniAbGksMCIDnbbDh70mdxbf2z1NjaULjoXSEzJrp8faqkwM5B65IjAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgICOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" }, - { - "privkeys" : [ - "cT7J9YpCwY3AVRFSjN6ukeEeWY6mhpbJPxRaDaP5QTdygQRxP9Au", - "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" - ], - "psbt" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAQMEAQAAAAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohwEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAAQMEAQAAAAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA", - "result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210cwRAIgYxqYn+c4qSrQGYYCMxLBkhT+KAKznly8GsNniAbGksMCIDnbbDh70mdxbf2z1NjaULjoXSEzJrp8faqkwM5B65IjAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgICOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNHMEQCIGX0W6WZi1mif/4ae+0BavHx+Q1Us6qPdFCqX1aiUQO9AiB/ckcDrR7blmgLKEtW1P/LiPf7dZ6rvgiqMPKbhROD0gEBAwQBAAAAAQQiACCMI1MXN0O1ld+0oHtyuo5C43l9p06H/n2ddJfjsgKJAwEFR1IhAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcIQI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc1KuIgYCOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnMQ2QxqTwAAAIAAAACAAwAAgCIGAwidwQx6xttU+RMpr2FzM9s4jOrQwjH3IzedG5kDCwLcENkMak8AAACAAAAAgAIAAIAAIgIDqaTDf1mW06ol26xrVwrwZQOUSSlCRgs1R1Ptnuylh3EQ2QxqTwAAAIAAAACABAAAgAAiAgJ/Y5l1fS7/VaE2rQLGhLGDi2VW5fG2s0KCqUtrUAUQlhDZDGpPAAAAgAAAAIAFAACAAA==" - }, { "privkeys" : [ "cNBc3SWUip9PPm1GjRoLEJT6T41iNzCYtD7qro84FMnM5zEqeJsE" diff --git a/test/bitcoin_functional/functional/example_test.py b/test/bitcoin_functional/functional/example_test.py index 332fec9736..937a525401 100755 --- a/test/bitcoin_functional/functional/example_test.py +++ b/test/bitcoin_functional/functional/example_test.py @@ -15,9 +15,7 @@ from collections import defaultdict # Avoid wildcard * imports if possible from test_framework.blocktools import (create_block, create_coinbase) -from test_framework.messages import ( - CInv, -) +from test_framework.messages import CInv from test_framework.mininode import ( P2PInterface, mininode_lock, @@ -69,16 +67,17 @@ def custom_function(): # self.log.info("running custom_function") # Oops! Can't run self.log outside the BitcoinTestFramework pass + class ExampleTest(BitcoinTestFramework): # Each functional test is a subclass of the BitcoinTestFramework class. - # Override the set_test_params(), add_options(), setup_chain(), setup_network() + # Override the set_test_params(), skip_test_if_missing_module(), add_options(), setup_chain(), setup_network() # and setup_nodes() methods to customize the test setup as required. def set_test_params(self): """Override test parameters for your individual test. - This method must be overridden and num_nodes must be exlicitly set.""" + This method must be overridden and num_nodes must be explicitly set.""" self.setup_clean_chain = True self.num_nodes = 3 # Use self.extra_args to change command-line arguments for the nodes @@ -86,6 +85,9 @@ class ExampleTest(BitcoinTestFramework): # self.log.info("I've finished set_test_params") # Oops! Can't run self.log before run_test() + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + # Use add_options() to add specific command-line options for your test. # In practice this is not used very much, since the tests are mostly written # to be run in automated environments without command-line options. @@ -113,7 +115,7 @@ class ExampleTest(BitcoinTestFramework): # sync_all() should not include node2, since we're not expecting it to # sync. connect_nodes(self.nodes[0], 1) - self.sync_all([self.nodes[0:1]]) + self.sync_all([self.nodes[0:2]]) # Use setup_nodes() to customize the node start behaviour (for example if # you don't want to start all nodes at the start of the test). @@ -137,7 +139,7 @@ class ExampleTest(BitcoinTestFramework): # Generating a block on one of the nodes will get us out of IBD blocks = [int(self.nodes[0].generate(nblocks=1)[0], 16)] - self.sync_all([self.nodes[0:1]]) + self.sync_all([self.nodes[0:2]]) # Notice above how we called an RPC by calling a method with the same # name on the node object. Notice also how we used a keyword argument diff --git a/test/bitcoin_functional/functional/feature_bip68_sequence.py b/test/bitcoin_functional/functional/feature_bip68_sequence.py index 4a9445f503..8466f851ca 100755 --- a/test/bitcoin_functional/functional/feature_bip68_sequence.py +++ b/test/bitcoin_functional/functional/feature_bip68_sequence.py @@ -25,6 +25,9 @@ class BIP68Test(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [[], ["-acceptnonstdtxn=0"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] diff --git a/test/bitcoin_functional/functional/feature_block.py b/test/bitcoin_functional/functional/feature_block.py index 79ed902871..6e36ea5601 100755 --- a/test/bitcoin_functional/functional/feature_block.py +++ b/test/bitcoin_functional/functional/feature_block.py @@ -75,6 +75,9 @@ class FullBlockTest(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [[]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node = self.nodes[0] # convenience reference to the node @@ -169,7 +172,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block where the miner creates too much coinbase reward") self.move_tip(6) b9 = self.next_block(9, spend=out[4], additional_coinbase_value=1) - self.sync_blocks([b9], False, 16, b'bad-cb-amount', reconnect=True) + self.sync_blocks([b9], success=False, reject_reason='bad-cb-amount', reconnect=True) # Create a fork that ends in a block with too much fee (the one that causes the reorg) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -181,7 +184,7 @@ class FullBlockTest(BitcoinTestFramework): self.sync_blocks([b10], False) b11 = self.next_block(11, spend=out[4], additional_coinbase_value=1) - self.sync_blocks([b11], False, 16, b'bad-cb-amount', reconnect=True) + self.sync_blocks([b11], success=False, reject_reason='bad-cb-amount', reconnect=True) # Try again, but with a valid fork first # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -194,7 +197,7 @@ class FullBlockTest(BitcoinTestFramework): b13 = self.next_block(13, spend=out[4]) self.save_spendable_output() b14 = self.next_block(14, spend=out[5], additional_coinbase_value=1) - self.sync_blocks([b12, b13, b14], False, 16, b'bad-cb-amount', reconnect=True) + self.sync_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True) # New tip should be b13. assert_equal(node.getbestblockhash(), b13.hash) @@ -213,7 +216,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block with too many checksigs") too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS)) b16 = self.next_block(16, spend=out[6], script=too_many_checksigs) - self.sync_blocks([b16], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b16], success=False, reject_reason='bad-blk-sigops', reconnect=True) # Attempt to spend a transaction created on a different fork # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -222,7 +225,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block with a spend from a re-org'ed out tx") self.move_tip(15) b17 = self.next_block(17, spend=txout_b3) - self.sync_blocks([b17], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b17], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # Attempt to spend a transaction created on a different fork (on a fork this time) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -235,7 +238,7 @@ class FullBlockTest(BitcoinTestFramework): self.sync_blocks([b18], False) b19 = self.next_block(19, spend=out[6]) - self.sync_blocks([b19], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b19], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # Attempt to spend a coinbase at depth too low # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -244,7 +247,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block spending an immature coinbase.") self.move_tip(15) b20 = self.next_block(20, spend=out[7]) - self.sync_blocks([b20], False, 16, b'bad-txns-premature-spend-of-coinbase') + self.sync_blocks([b20], success=False, reject_reason='bad-txns-premature-spend-of-coinbase') # Attempt to spend a coinbase at depth too low (on a fork this time) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -257,7 +260,7 @@ class FullBlockTest(BitcoinTestFramework): self.sync_blocks([b21], False) b22 = self.next_block(22, spend=out[5]) - self.sync_blocks([b22], False, 16, b'bad-txns-premature-spend-of-coinbase') + self.sync_blocks([b22], success=False, reject_reason='bad-txns-premature-spend-of-coinbase') # Create a block on either side of MAX_BLOCK_BASE_SIZE and make sure its accepted/rejected # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) @@ -286,7 +289,7 @@ class FullBlockTest(BitcoinTestFramework): tx.vout = [CTxOut(0, script_output)] b24 = self.update_block(24, [tx]) assert_equal(len(b24.serialize()), MAX_BLOCK_BASE_SIZE + 1) - self.sync_blocks([b24], False, 16, b'bad-blk-length', reconnect=True) + self.sync_blocks([b24], success=False, reject_reason='bad-blk-length', reconnect=True) b25 = self.next_block(25, spend=out[7]) self.sync_blocks([b25], False) @@ -304,7 +307,7 @@ class FullBlockTest(BitcoinTestFramework): # update_block causes the merkle root to get updated, even with no new # transactions, and updates the required state. b26 = self.update_block(26, []) - self.sync_blocks([b26], False, 16, b'bad-cb-length', reconnect=True) + self.sync_blocks([b26], success=False, reject_reason='bad-cb-length', reconnect=True) # Extend the b26 chain to make sure bitcoind isn't accepting b26 b27 = self.next_block(27, spend=out[7]) @@ -316,7 +319,7 @@ class FullBlockTest(BitcoinTestFramework): b28.vtx[0].vin[0].scriptSig = b'\x00' * 101 b28.vtx[0].rehash() b28 = self.update_block(28, []) - self.sync_blocks([b28], False, 16, b'bad-cb-length', reconnect=True) + self.sync_blocks([b28], success=False, reject_reason='bad-cb-length', reconnect=True) # Extend the b28 chain to make sure bitcoind isn't accepting b28 b29 = self.next_block(29, spend=out[7]) @@ -352,7 +355,7 @@ class FullBlockTest(BitcoinTestFramework): too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20)) b32 = self.next_block(32, spend=out[9], script=too_many_multisigs) assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1) - self.sync_blocks([b32], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b32], success=False, reject_reason='bad-blk-sigops', reconnect=True) # CHECKMULTISIGVERIFY self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops") @@ -365,7 +368,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops") too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20)) b34 = self.next_block(34, spend=out[10], script=too_many_multisigs) - self.sync_blocks([b34], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b34], success=False, reject_reason='bad-blk-sigops', reconnect=True) # CHECKSIGVERIFY self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops") @@ -378,7 +381,7 @@ class FullBlockTest(BitcoinTestFramework): self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops") too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS)) b36 = self.next_block(36, spend=out[11], script=too_many_checksigs) - self.sync_blocks([b36], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b36], success=False, reject_reason='bad-blk-sigops', reconnect=True) # Check spending of a transaction in a block which failed to connect # @@ -395,12 +398,12 @@ class FullBlockTest(BitcoinTestFramework): txout_b37 = b37.vtx[1] tx = self.create_and_sign_transaction(out[11], 0) b37 = self.update_block(37, [tx]) - self.sync_blocks([b37], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b37], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid self.move_tip(35) b38 = self.next_block(38, spend=txout_b37) - self.sync_blocks([b38], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b38], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # Check P2SH SigOp counting # @@ -492,7 +495,7 @@ class FullBlockTest(BitcoinTestFramework): tx.rehash() new_txs.append(tx) self.update_block(40, new_txs) - self.sync_blocks([b40], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b40], success=False, reject_reason='bad-blk-sigops', reconnect=True) # same as b40, but one less sigop self.log.info("Accept a block with the max number of P2SH sigops") @@ -555,7 +558,7 @@ class FullBlockTest(BitcoinTestFramework): self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1 self.tip = b45 self.blocks[45] = b45 - self.sync_blocks([b45], False, 16, b'bad-cb-missing', reconnect=True) + self.sync_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True) self.log.info("Reject a block with no transactions") self.move_tip(44) @@ -570,7 +573,7 @@ class FullBlockTest(BitcoinTestFramework): self.tip = b46 assert 46 not in self.blocks self.blocks[46] = b46 - self.sync_blocks([b46], False, 16, b'bad-blk-length', reconnect=True) + self.sync_blocks([b46], success=False, reject_reason='bad-blk-length', reconnect=True) self.log.info("Reject a block with invalid work") self.move_tip(44) @@ -593,7 +596,7 @@ class FullBlockTest(BitcoinTestFramework): b49 = self.next_block(49) b49.hashMerkleRoot += 1 b49.solve() - self.sync_blocks([b49], False, 16, b'bad-txnmrklroot', reconnect=True) + self.sync_blocks([b49], success=False, reject_reason='bad-txnmrklroot', reconnect=True) self.log.info("Reject a block with incorrect POW limit") self.move_tip(44) @@ -607,7 +610,7 @@ class FullBlockTest(BitcoinTestFramework): b51 = self.next_block(51) cb2 = create_coinbase(51, self.coinbase_pubkey) b51 = self.update_block(51, [cb2]) - self.sync_blocks([b51], False, 16, b'bad-cb-multiple', reconnect=True) + self.sync_blocks([b51], success=False, reject_reason='bad-cb-multiple', reconnect=True) self.log.info("Reject a block with duplicate transactions") # Note: txns have to be in the right position in the merkle tree to trigger this error @@ -615,7 +618,7 @@ class FullBlockTest(BitcoinTestFramework): b52 = self.next_block(52, spend=out[15]) tx = self.create_tx(b52.vtx[1], 0, 1) b52 = self.update_block(52, [tx, tx]) - self.sync_blocks([b52], False, 16, b'bad-txns-duplicate', reconnect=True) + self.sync_blocks([b52], success=False, reject_reason='bad-txns-duplicate', reconnect=True) # Test block timestamps # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) @@ -682,7 +685,7 @@ class FullBlockTest(BitcoinTestFramework): assert_equal(len(b56.vtx), 3) b56 = self.update_block(56, [tx1]) assert_equal(b56.hash, b57.hash) - self.sync_blocks([b56], False, 16, b'bad-txns-duplicate', reconnect=True) + self.sync_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True) # b57p2 - a good block with 6 tx'es, don't submit until end self.move_tip(55) @@ -702,7 +705,7 @@ class FullBlockTest(BitcoinTestFramework): assert_equal(b56p2.hash, b57p2.hash) assert_equal(len(b56p2.vtx), 6) b56p2 = self.update_block("b56p2", [tx3, tx4]) - self.sync_blocks([b56p2], False, 16, b'bad-txns-duplicate', reconnect=True) + self.sync_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True) self.move_tip("57p2") self.sync_blocks([b57p2], True) @@ -727,7 +730,7 @@ class FullBlockTest(BitcoinTestFramework): tx.vout.append(CTxOut(0, b"")) tx.calc_sha256() b58 = self.update_block(58, [tx]) - self.sync_blocks([b58], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b58], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # tx with output value > input value self.log.info("Reject a block with a transaction with outputs > inputs") @@ -735,7 +738,7 @@ class FullBlockTest(BitcoinTestFramework): b59 = self.next_block(59) tx = self.create_and_sign_transaction(out[17], 51 * COIN) b59 = self.update_block(59, [tx]) - self.sync_blocks([b59], False, 16, b'bad-txns-in-belowout', reconnect=True) + self.sync_blocks([b59], success=False, reject_reason='bad-txns-in-belowout', reconnect=True) # reset to good chain self.move_tip(57) @@ -759,7 +762,7 @@ class FullBlockTest(BitcoinTestFramework): b61.vtx[0].rehash() b61 = self.update_block(61, []) assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize()) - self.sync_blocks([b61], False, 16, b'bad-txns-BIP30', reconnect=True) + self.sync_blocks([b61], success=False, reject_reason='bad-txns-BIP30', reconnect=True) # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests) # @@ -776,7 +779,7 @@ class FullBlockTest(BitcoinTestFramework): assert(tx.vin[0].nSequence < 0xffffffff) tx.calc_sha256() b62 = self.update_block(62, [tx]) - self.sync_blocks([b62], False, 16, b'bad-txns-nonfinal') + self.sync_blocks([b62], success=False, reject_reason='bad-txns-nonfinal') # Test a non-final coinbase is also rejected # @@ -790,7 +793,7 @@ class FullBlockTest(BitcoinTestFramework): b63.vtx[0].vin[0].nSequence = 0xDEADBEEF b63.vtx[0].rehash() b63 = self.update_block(63, []) - self.sync_blocks([b63], False, 16, b'bad-txns-nonfinal') + self.sync_blocks([b63], success=False, reject_reason='bad-txns-nonfinal') # This checks that a block with a bloated VARINT between the block_header and the array of tx such that # the block is > MAX_BLOCK_BASE_SIZE with the bloated varint, but <= MAX_BLOCK_BASE_SIZE without the bloated varint, @@ -824,7 +827,7 @@ class FullBlockTest(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0))) b64a = self.update_block("64a", [tx]) assert_equal(len(b64a.serialize()), MAX_BLOCK_BASE_SIZE + 8) - self.sync_blocks([b64a], False, 1, b'error parsing message') + self.sync_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize(): iostream error') # bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently # resend the header message, it won't send us the getdata message again. Just @@ -866,7 +869,7 @@ class FullBlockTest(BitcoinTestFramework): tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue) tx2 = self.create_and_sign_transaction(tx1, 1) b66 = self.update_block(66, [tx2, tx1]) - self.sync_blocks([b66], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b66], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # Attempt to double-spend a transaction created in a block # @@ -881,7 +884,7 @@ class FullBlockTest(BitcoinTestFramework): tx2 = self.create_and_sign_transaction(tx1, 1) tx3 = self.create_and_sign_transaction(tx1, 2) b67 = self.update_block(67, [tx1, tx2, tx3]) - self.sync_blocks([b67], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b67], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # More tests of block subsidy # @@ -900,7 +903,7 @@ class FullBlockTest(BitcoinTestFramework): b68 = self.next_block(68, additional_coinbase_value=10) tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 9) b68 = self.update_block(68, [tx]) - self.sync_blocks([b68], False, 16, b'bad-cb-amount', reconnect=True) + self.sync_blocks([b68], success=False, reject_reason='bad-cb-amount', reconnect=True) self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction") self.move_tip(65) @@ -924,7 +927,7 @@ class FullBlockTest(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff)) tx.vout.append(CTxOut(1, b"")) b70 = self.update_block(70, [tx]) - self.sync_blocks([b70], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b70], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) # @@ -949,7 +952,7 @@ class FullBlockTest(BitcoinTestFramework): assert_equal(b72.sha256, b71.sha256) self.move_tip(71) - self.sync_blocks([b71], False, 16, b'bad-txns-duplicate', reconnect=True) + self.sync_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True) self.move_tip(72) self.sync_blocks([b72], True) @@ -987,9 +990,9 @@ class FullBlockTest(BitcoinTestFramework): tx = self.create_and_sign_transaction(out[22], 1, CScript(a)) b73 = self.update_block(73, [tx]) assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1) - self.sync_blocks([b73], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b73], success=False, reject_reason='bad-blk-sigops', reconnect=True) - # b74/75 - if we push an invalid script element, all prevous sigops are counted, + # b74/75 - if we push an invalid script element, all previous sigops are counted, # but sigops after the element are not counted. # # The invalid script element is that the push_data indicates that @@ -1011,7 +1014,7 @@ class FullBlockTest(BitcoinTestFramework): a[MAX_BLOCK_SIGOPS + 4] = 0xff tx = self.create_and_sign_transaction(out[22], 1, CScript(a)) b74 = self.update_block(74, [tx]) - self.sync_blocks([b74], False, 16, b'bad-blk-sigops', reconnect=True) + self.sync_blocks([b74], success=False, reject_reason='bad-blk-sigops', reconnect=True) self.move_tip(72) b75 = self.next_block(75) @@ -1160,7 +1163,7 @@ class FullBlockTest(BitcoinTestFramework): b89a = self.next_block("89a", spend=out[32]) tx = self.create_tx(tx1, 0, 0, CScript([OP_TRUE])) b89a = self.update_block("89a", [tx]) - self.sync_blocks([b89a], False, 16, b'bad-txns-inputs-missingorspent', reconnect=True) + self.sync_blocks([b89a], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)") @@ -1309,11 +1312,11 @@ class FullBlockTest(BitcoinTestFramework): self.nodes[0].disconnect_p2ps() self.bootstrap_p2p() - def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True, reconnect=False, timeout=60): + def sync_blocks(self, blocks, success=True, reject_reason=None, request_block=True, reconnect=False, timeout=60): """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. Call with success = False if the tip shouldn't advance to the most recent block.""" - self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, reject_reason=reject_reason, request_block=request_block, timeout=timeout) + self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, request_block=request_block, timeout=timeout, expect_disconnect=reconnect) if reconnect: self.reconnect_p2p() diff --git a/test/bitcoin_functional/functional/feature_blocksdir.py b/test/bitcoin_functional/functional/feature_blocksdir.py index b282126f2d..824f0d7e09 100755 --- a/test/bitcoin_functional/functional/feature_blocksdir.py +++ b/test/bitcoin_functional/functional/feature_blocksdir.py @@ -16,20 +16,23 @@ class BlocksdirTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.stop_node(0) shutil.rmtree(self.nodes[0].datadir) - initialize_datadir(self.options.tmpdir, 0, self.chain) - self.log.info("Starting with non exiting blocksdir ...") + initialize_datadir(self.options.tmpdir, 0) + self.log.info("Starting with nonexistent blocksdir ...") blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir') self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path)) os.mkdir(blocksdir_path) - self.log.info("Starting with exiting blocksdir ...") + self.log.info("Starting with existing blocksdir ...") self.start_node(0, ["-blocksdir=" + blocksdir_path]) self.log.info("mining blocks..") self.nodes[0].generate(10) - assert os.path.isfile(os.path.join(blocksdir_path, self.chain, "blocks", "blk00000.dat")) - assert os.path.isdir(os.path.join(self.nodes[0].datadir, self.chain, "blocks", "index")) + assert os.path.isfile(os.path.join(blocksdir_path, "regtest", "blocks", "blk00000.dat")) + assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks", "index")) if __name__ == '__main__': diff --git a/test/bitcoin_functional/functional/feature_cltv.py b/test/bitcoin_functional/functional/feature_cltv.py index 8460291831..f84b08a199 100755 --- a/test/bitcoin_functional/functional/feature_cltv.py +++ b/test/bitcoin_functional/functional/feature_cltv.py @@ -10,10 +10,14 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height from test_framework.blocktools import create_coinbase, create_block, create_transaction from test_framework.messages import CTransaction, msg_block, ToHex -from test_framework.mininode import mininode_lock, P2PInterface +from test_framework.mininode import P2PInterface from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP, CScriptNum from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, bytes_to_hex_str, hex_str_to_bytes, wait_until +from test_framework.util import ( + assert_equal, + bytes_to_hex_str, + hex_str_to_bytes, +) from io import BytesIO @@ -51,12 +55,16 @@ def cltv_validate(node, tx, height): list(CScript(new_tx.vin[0].scriptSig))) return new_tx + class BIP65Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-whitelist=127.0.0.1']] + self.extra_args = [['-whitelist=127.0.0.1', '-par=1']] # Use only one script thread to get the exact reject reason for testing self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.nodes[0].add_p2p_connection(P2PInterface()) @@ -88,15 +96,11 @@ class BIP65Test(BitcoinTestFramework): block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time) block.nVersion = 3 block.solve() - self.nodes[0].p2p.send_and_ping(msg_block(block)) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) - wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock) - with mininode_lock: - assert_equal(self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE) - assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000003)') - assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256) - del self.nodes[0].p2p.last_message["reject"] + with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000003)'.format(block.hash)]): + self.nodes[0].p2p.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + self.nodes[0].p2p.sync_with_ping() self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block") block.nVersion = 4 @@ -118,18 +122,10 @@ class BIP65Test(BitcoinTestFramework): block.hashMerkleRoot = block.calc_merkle_root() block.solve() - self.nodes[0].p2p.send_and_ping(msg_block(block)) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) - - wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock) - with mininode_lock: - assert self.nodes[0].p2p.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD] - assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256) - if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID: - # Generic rejection when a block is invalid - assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'block-validation-failed') - else: - assert b'Negative locktime' in self.nodes[0].p2p.last_message["reject"].reason + with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]): + self.nodes[0].p2p.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + self.nodes[0].p2p.sync_with_ping() self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1) diff --git a/test/bitcoin_functional/functional/feature_config_args.py b/test/bitcoin_functional/functional/feature_config_args.py index 3c10b255d0..1124119e2b 100755 --- a/test/bitcoin_functional/functional/feature_config_args.py +++ b/test/bitcoin_functional/functional/feature_config_args.py @@ -14,6 +14,9 @@ class ConfArgsTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def test_config_file_parser(self): # Assume node is stopped @@ -65,13 +68,13 @@ class ConfArgsTest(BitcoinTestFramework): # Temporarily disabled, because this test would access the user's home dir (~/.bitcoin) #self.start_node(0, ['-conf='+conf_file, '-wallet=w1']) #self.stop_node(0) - #assert os.path.exists(os.path.join(new_data_dir, self.chain, 'wallets', 'w1')) + #assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'wallets', 'w1')) # Ensure command line argument overrides datadir in conf os.mkdir(new_data_dir_2) self.nodes[0].datadir = new_data_dir_2 self.start_node(0, ['-datadir='+new_data_dir_2, '-conf='+conf_file, '-wallet=w2']) - assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'wallets', 'w2')) + assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'wallets', 'w2')) if __name__ == '__main__': ConfArgsTest().main() diff --git a/test/bitcoin_functional/functional/feature_csv_activation.py b/test/bitcoin_functional/functional/feature_csv_activation.py index af14feb471..df79c4312c 100755 --- a/test/bitcoin_functional/functional/feature_csv_activation.py +++ b/test/bitcoin_functional/functional/feature_csv_activation.py @@ -145,6 +145,9 @@ class BIP68_112_113Test(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4', '-addresstype=legacy']] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def generate_blocks(self, number, version, test_blocks=None): if test_blocks is None: test_blocks = [] @@ -165,11 +168,11 @@ class BIP68_112_113Test(BitcoinTestFramework): block.solve() return block - def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True): + def sync_blocks(self, blocks, success=True): """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. Call with success = False if the tip shouldn't advance to the most recent block.""" - self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, reject_reason=reject_reason, request_block=request_block) + self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success) def run_test(self): self.nodes[0].add_p2p_connection(P2PDataStore()) diff --git a/test/bitcoin_functional/functional/feature_dbcrash.py b/test/bitcoin_functional/functional/feature_dbcrash.py index d612dbe2bc..ae1eacf2d7 100755 --- a/test/bitcoin_functional/functional/feature_dbcrash.py +++ b/test/bitcoin_functional/functional/feature_dbcrash.py @@ -63,6 +63,9 @@ class ChainstateWriteCrashTest(BitcoinTestFramework): self.node3_args = ["-blockmaxweight=4000000"] self.extra_args = [self.node0_args, self.node1_args, self.node2_args, self.node3_args] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.add_nodes(self.num_nodes, extra_args=self.extra_args) self.start_nodes() diff --git a/test/bitcoin_functional/functional/feature_dersig.py b/test/bitcoin_functional/functional/feature_dersig.py index 53e94c436a..16272877e7 100755 --- a/test/bitcoin_functional/functional/feature_dersig.py +++ b/test/bitcoin_functional/functional/feature_dersig.py @@ -12,7 +12,11 @@ from test_framework.messages import msg_block from test_framework.mininode import mininode_lock, P2PInterface from test_framework.script import CScript from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, bytes_to_hex_str, wait_until +from test_framework.util import ( + assert_equal, + bytes_to_hex_str, + wait_until, +) DERSIG_HEIGHT = 1251 @@ -42,9 +46,12 @@ def unDERify(tx): class BIP66Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-whitelist=127.0.0.1']] + self.extra_args = [['-whitelist=127.0.0.1', '-par=1', '-enablebip61']] # Use only one script thread to get the exact reject reason for testing self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.nodes[0].add_p2p_connection(P2PInterface()) @@ -78,15 +85,11 @@ class BIP66Test(BitcoinTestFramework): block.nVersion = 2 block.rehash() block.solve() - self.nodes[0].p2p.send_and_ping(msg_block(block)) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) - wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock) - with mininode_lock: - assert_equal(self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE) - assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000002)') - assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256) - del self.nodes[0].p2p.last_message["reject"] + with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000002)'.format(block.hash)]): + self.nodes[0].p2p.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + self.nodes[0].p2p.sync_with_ping() self.log.info("Test that transactions with non-DER signatures cannot appear in a block") block.nVersion = 3 @@ -109,23 +112,16 @@ class BIP66Test(BitcoinTestFramework): block.rehash() block.solve() - self.nodes[0].p2p.send_and_ping(msg_block(block)) - assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]): + self.nodes[0].p2p.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) + self.nodes[0].p2p.sync_with_ping() wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock) with mininode_lock: - # We can receive different reject messages depending on whether - # bitcoind is running with multiple script check threads. If script - # check threads are not in use, then transaction script validation - # happens sequentially, and bitcoind produces more specific reject - # reasons. assert self.nodes[0].p2p.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD] assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256) - if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID: - # Generic rejection when a block is invalid - assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'block-validation-failed') - else: - assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason + assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted") block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=1.0) diff --git a/test/bitcoin_functional/functional/feature_fee_estimation.py b/test/bitcoin_functional/functional/feature_fee_estimation.py index 709910f2e4..aaab4279b5 100755 --- a/test/bitcoin_functional/functional/feature_fee_estimation.py +++ b/test/bitcoin_functional/functional/feature_fee_estimation.py @@ -126,6 +126,9 @@ class EstimateFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 3 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): """ We'll setup the network to have 3 nodes that all mine with different parameters. @@ -168,6 +171,11 @@ class EstimateFeeTest(BitcoinTestFramework): 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/bitcoin_functional/functional/feature_logging.py b/test/bitcoin_functional/functional/feature_logging.py index 441716ab0b..a74c413440 100755 --- a/test/bitcoin_functional/functional/feature_logging.py +++ b/test/bitcoin_functional/functional/feature_logging.py @@ -15,8 +15,11 @@ class LoggingTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def relative_log_path(self, name): - return os.path.join(self.nodes[0].datadir, self.chain, name) + return os.path.join(self.nodes[0].datadir, "regtest", name) def run_test(self): # test default log file name diff --git a/test/bitcoin_functional/functional/feature_maxuploadtarget.py b/test/bitcoin_functional/functional/feature_maxuploadtarget.py index a81ebb4220..87c318de9a 100755 --- a/test/bitcoin_functional/functional/feature_maxuploadtarget.py +++ b/test/bitcoin_functional/functional/feature_maxuploadtarget.py @@ -40,6 +40,9 @@ class MaxUploadTest(BitcoinTestFramework): # Cache for utxos, as the listunspent may take a long time later in the test self.utxo_cache = [] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Before we connect anything, we first set the time on the node # to be in the past, otherwise things break because the CNode diff --git a/test/bitcoin_functional/functional/feature_notifications.py b/test/bitcoin_functional/functional/feature_notifications.py index 71e5e493aa..25a7329a0d 100755 --- a/test/bitcoin_functional/functional/feature_notifications.py +++ b/test/bitcoin_functional/functional/feature_notifications.py @@ -13,6 +13,9 @@ class NotificationsTest(BitcoinTestFramework): self.num_nodes = 2 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") self.block_filename = os.path.join(self.options.tmpdir, "blocks.txt") diff --git a/test/bitcoin_functional/functional/feature_nulldummy.py b/test/bitcoin_functional/functional/feature_nulldummy.py index 9d1805ec2d..a79cc3d34b 100755 --- a/test/bitcoin_functional/functional/feature_nulldummy.py +++ b/test/bitcoin_functional/functional/feature_nulldummy.py @@ -44,9 +44,12 @@ class NULLDUMMYTest(BitcoinTestFramework): # normal segwit activation here (and don't use the default always-on behaviour). self.extra_args = [['-whitelist=127.0.0.1', '-vbparams=segwit:0:999999999999', '-addresstype=legacy', "-deprecatedrpc=addwitnessaddress"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.address = self.nodes[0].getnewaddress() - self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address])['address'] + self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address])['address'] self.wit_address = self.nodes[0].addwitnessaddress(self.address) self.wit_ms_address = self.nodes[0].addmultisigaddress(1, [self.address], '', 'p2sh-segwit')['address'] diff --git a/test/bitcoin_functional/functional/feature_pruning.py b/test/bitcoin_functional/functional/feature_pruning.py index bcf14a7b16..772151dc4b 100755 --- a/test/bitcoin_functional/functional/feature_pruning.py +++ b/test/bitcoin_functional/functional/feature_pruning.py @@ -33,20 +33,25 @@ class PruneTest(BitcoinTestFramework): # Create nodes 0 and 1 to mine. # Create node 2 to test pruning. - self.full_node_default_args = ["-maxreceivebuffer=20000", "-checkblocks=5", "-limitdescendantcount=100", "-limitdescendantsize=5000", "-limitancestorcount=100", "-limitancestorsize=5000" ] + self.full_node_default_args = ["-maxreceivebuffer=20000", "-checkblocks=5", "-limitdescendantcount=100", "-limitdescendantsize=5000", "-limitancestorcount=100", "-limitancestorsize=5000"] # Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later) # Create nodes 5 to test wallet in prune mode, but do not connect - self.extra_args = [self.full_node_default_args, - self.full_node_default_args, - ["-maxreceivebuffer=20000", "-prune=550"], - ["-maxreceivebuffer=20000"], - ["-maxreceivebuffer=20000"], - ["-prune=550"]] + self.extra_args = [ + self.full_node_default_args, + self.full_node_default_args, + ["-maxreceivebuffer=20000", "-prune=550"], + ["-maxreceivebuffer=20000"], + ["-maxreceivebuffer=20000"], + ["-prune=550"], + ] + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() def setup_network(self): self.setup_nodes() - self.prunedir = os.path.join(self.nodes[2].datadir, self.chain, 'blocks', '') + self.prunedir = os.path.join(self.nodes[2].datadir, 'regtest', 'blocks', '') connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[1], 2) @@ -257,7 +262,7 @@ class PruneTest(BitcoinTestFramework): assert_equal(ret, expected_ret) def has_block(index): - return os.path.isfile(os.path.join(self.nodes[node_number].datadir, self.chain, "blocks", "blk{:05}.dat".format(index))) + return os.path.isfile(os.path.join(self.nodes[node_number].datadir, "regtest", "blocks", "blk{:05}.dat".format(index))) # should not prune because chain tip of node 3 (995) < PruneAfterHeight (1000) assert_raises_rpc_error(-1, "Blockchain is too short for pruning", node.pruneblockchain, height(500)) diff --git a/test/bitcoin_functional/functional/feature_rbf.py b/test/bitcoin_functional/functional/feature_rbf.py index 6105da810c..ff7c2b23bf 100755 --- a/test/bitcoin_functional/functional/feature_rbf.py +++ b/test/bitcoin_functional/functional/feature_rbf.py @@ -61,17 +61,26 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): return COutPoint(int(txid, 16), 0) -class ReplaceByFeeTest(BitcoinTestFramework): +class ReplaceByFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 - self.extra_args= [["-maxorphantx=1000", - "-whitelist=127.0.0.1", - "-limitancestorcount=50", - "-limitancestorsize=101", - "-limitdescendantcount=200", - "-limitdescendantsize=101"], - ["-mempoolreplacement=0"]] + self.extra_args = [ + [ + "-maxorphantx=1000", + "-whitelist=127.0.0.1", + "-limitancestorcount=50", + "-limitancestorsize=101", + "-limitdescendantcount=200", + "-limitdescendantsize=101", + ], + [ + "-mempoolreplacement=0", + ], + ] + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() def run_test(self): # Leave IBD @@ -429,6 +438,9 @@ class ReplaceByFeeTest(BitcoinTestFramework): tx1a_hex = txToHex(tx1a) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + # This transaction isn't shown as replaceable + assert_equal(self.nodes[0].getmempoolentry(tx1a_txid)['bip125-replaceable'], False) + # Shouldn't be able to double-spend tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] @@ -469,7 +481,10 @@ class ReplaceByFeeTest(BitcoinTestFramework): tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))] tx3a_hex = txToHex(tx3a) - self.nodes[0].sendrawtransaction(tx3a_hex, True) + tx3a_txid = self.nodes[0].sendrawtransaction(tx3a_hex, True) + + # This transaction is shown as replaceable + assert_equal(self.nodes[0].getmempoolentry(tx3a_txid)['bip125-replaceable'], True) tx3b = CTransaction() tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] diff --git a/test/bitcoin_functional/functional/feature_reindex.py b/test/bitcoin_functional/functional/feature_reindex.py index f30e1191e3..3727eeaeae 100755 --- a/test/bitcoin_functional/functional/feature_reindex.py +++ b/test/bitcoin_functional/functional/feature_reindex.py @@ -18,6 +18,9 @@ class ReindexTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def reindex(self, justchainstate=False): self.nodes[0].generate(3) blockcount = self.nodes[0].getblockcount() diff --git a/test/bitcoin_functional/functional/feature_segwit.py b/test/bitcoin_functional/functional/feature_segwit.py index 13d7758e13..2cbfc26e89 100755 --- a/test/bitcoin_functional/functional/feature_segwit.py +++ b/test/bitcoin_functional/functional/feature_segwit.py @@ -46,9 +46,30 @@ class SegWitTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 # This test tests SegWit both pre and post-activation, so use the normal BIP9 activation. - self.extra_args = [["-rpcserialversion=0", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"], - ["-blockversion=4", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"], - ["-blockversion=536870915", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]] + self.extra_args = [ + [ + "-rpcserialversion=0", + "-vbparams=segwit:0:999999999999", + "-addresstype=legacy", + "-deprecatedrpc=addwitnessaddress", + ], + [ + "-blockversion=4", + "-rpcserialversion=1", + "-vbparams=segwit:0:999999999999", + "-addresstype=legacy", + "-deprecatedrpc=addwitnessaddress", + ], + [ + "-blockversion=536870915", + "-vbparams=segwit:0:999999999999", + "-addresstype=legacy", + "-deprecatedrpc=addwitnessaddress", + ], + ] + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() def setup_network(self): super().setup_network() diff --git a/test/bitcoin_functional/functional/feature_versionbits_warning.py b/test/bitcoin_functional/functional/feature_versionbits_warning.py index 896c36fa53..cf77720437 100755 --- a/test/bitcoin_functional/functional/feature_versionbits_warning.py +++ b/test/bitcoin_functional/functional/feature_versionbits_warning.py @@ -31,6 +31,9 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file diff --git a/test/bitcoin_functional/functional/interface_bitcoin_cli.py b/test/bitcoin_functional/functional/interface_bitcoin_cli.py index 251ee0dcc4..f311858bee 100755 --- a/test/bitcoin_functional/functional/interface_bitcoin_cli.py +++ b/test/bitcoin_functional/functional/interface_bitcoin_cli.py @@ -12,6 +12,9 @@ class TestBitcoinCli(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): """Main test logic""" @@ -28,7 +31,7 @@ class TestBitcoinCli(BitcoinTestFramework): rpc_response = self.nodes[0].getblockchaininfo() assert_equal(cli_response, rpc_response) - user, password = get_auth_cookie(self.nodes[0].datadir, self.chain) + user, password = get_auth_cookie(self.nodes[0].datadir) self.log.info("Test -stdinrpcpass option") assert_equal(0, self.nodes[0].cli('-rpcuser=%s' % user, '-stdinrpcpass', input=password).getblockcount()) diff --git a/test/bitcoin_functional/functional/interface_rest.py b/test/bitcoin_functional/functional/interface_rest.py index 41a1b4a35d..afa9de580f 100755 --- a/test/bitcoin_functional/functional/interface_rest.py +++ b/test/bitcoin_functional/functional/interface_rest.py @@ -43,6 +43,9 @@ class RESTTest (BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [["-rest"], []] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def test_rest_request(self, uri, http_method='GET', req_type=ReqType.JSON, body='', status=200, ret_type=RetType.JSON): rest_uri = '/rest' + uri if req_type == ReqType.JSON: diff --git a/test/bitcoin_functional/functional/interface_zmq.py b/test/bitcoin_functional/functional/interface_zmq.py index 72de696259..1c518eab75 100755 --- a/test/bitcoin_functional/functional/interface_zmq.py +++ b/test/bitcoin_functional/functional/interface_zmq.py @@ -5,15 +5,16 @@ """Test the ZMQ notification interface.""" import struct -from test_framework.test_framework import ( - BitcoinTestFramework, skip_if_no_bitcoind_zmq, skip_if_no_py3_zmq) +from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import CTransaction -from test_framework.util import (assert_equal, - bytes_to_hex_str, - hash256, - ) +from test_framework.util import ( + assert_equal, + bytes_to_hex_str, + hash256, +) from io import BytesIO + class ZMQSubscriber: def __init__(self, socket, topic): self.sequence = 0 @@ -37,9 +38,12 @@ class ZMQTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_py3_zmq() + self.skip_if_no_bitcoind_zmq() + self.skip_if_no_wallet() + def setup_nodes(self): - skip_if_no_py3_zmq() - skip_if_no_bitcoind_zmq(self) import zmq # Initialize ZMQ context and socket. @@ -59,7 +63,10 @@ class ZMQTest (BitcoinTestFramework): 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.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.start_nodes() diff --git a/test/bitcoin_functional/functional/mempool_accept.py b/test/bitcoin_functional/functional/mempool_accept.py index 44426a0ff7..8847777ba7 100755 --- a/test/bitcoin_functional/functional/mempool_accept.py +++ b/test/bitcoin_functional/functional/mempool_accept.py @@ -40,6 +40,9 @@ class MempoolAcceptanceTest(BitcoinTestFramework): '-acceptnonstdtxn=0', # Try to mimic main-net ]] * self.num_nodes + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def check_mempool_result(self, result_expected, *args, **kwargs): """Wrapper to check result of testmempoolaccept on node_0's mempool""" result_test = self.nodes[0].testmempoolaccept(*args, **kwargs) diff --git a/test/bitcoin_functional/functional/mempool_limit.py b/test/bitcoin_functional/functional/mempool_limit.py index 55422b67df..c0918893cd 100755 --- a/test/bitcoin_functional/functional/mempool_limit.py +++ b/test/bitcoin_functional/functional/mempool_limit.py @@ -15,6 +15,9 @@ class MempoolLimitTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [["-maxmempool=5", "-spendzeroconfchange=0"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): txouts = gen_return_txouts() relayfee = self.nodes[0].getnetworkinfo()['relayfee'] diff --git a/test/bitcoin_functional/functional/mempool_packages.py b/test/bitcoin_functional/functional/mempool_packages.py index da254181fe..9336547a6b 100755 --- a/test/bitcoin_functional/functional/mempool_packages.py +++ b/test/bitcoin_functional/functional/mempool_packages.py @@ -18,6 +18,9 @@ class MempoolPackagesTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [["-maxorphantx=1000"], ["-maxorphantx=1000", "-limitancestorcount=5"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + # Build a transaction that spends parent_txid:vout # Return amount sent def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs): @@ -34,7 +37,7 @@ class MempoolPackagesTest(BitcoinTestFramework): 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/bitcoin_functional/functional/mempool_persist.py b/test/bitcoin_functional/functional/mempool_persist.py index 724022635a..b4e9d967fd 100755 --- a/test/bitcoin_functional/functional/mempool_persist.py +++ b/test/bitcoin_functional/functional/mempool_persist.py @@ -47,6 +47,9 @@ class MempoolPersistTest(BitcoinTestFramework): self.num_nodes = 3 self.extra_args = [[], ["-persistmempool=0"], []] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): chain_height = self.nodes[0].getblockcount() assert_equal(chain_height, 200) @@ -94,8 +97,8 @@ class MempoolPersistTest(BitcoinTestFramework): self.start_node(0) wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5) - mempooldat0 = os.path.join(self.nodes[0].datadir, self.chain, 'mempool.dat') - mempooldat1 = os.path.join(self.nodes[1].datadir, self.chain, 'mempool.dat') + mempooldat0 = os.path.join(self.nodes[0].datadir, 'regtest', 'mempool.dat') + mempooldat1 = os.path.join(self.nodes[1].datadir, 'regtest', 'mempool.dat') self.log.debug("Remove the mempool.dat file. Verify that savemempool to disk via RPC re-creates it") os.remove(mempooldat0) self.nodes[0].savemempool() diff --git a/test/bitcoin_functional/functional/mempool_reorg.py b/test/bitcoin_functional/functional/mempool_reorg.py index faa00d56cf..123f0b4c28 100755 --- a/test/bitcoin_functional/functional/mempool_reorg.py +++ b/test/bitcoin_functional/functional/mempool_reorg.py @@ -17,6 +17,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + alert_filename = None # Set by setup_network def run_test(self): diff --git a/test/bitcoin_functional/functional/mempool_resurrect.py b/test/bitcoin_functional/functional/mempool_resurrect.py index 23939f0be5..d035ca907a 100755 --- a/test/bitcoin_functional/functional/mempool_resurrect.py +++ b/test/bitcoin_functional/functional/mempool_resurrect.py @@ -13,6 +13,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node0_address = self.nodes[0].getnewaddress() # Spend block 1/2/3's coinbase transactions diff --git a/test/bitcoin_functional/functional/mempool_spend_coinbase.py b/test/bitcoin_functional/functional/mempool_spend_coinbase.py index ce3bc3b7e0..854d506f0d 100755 --- a/test/bitcoin_functional/functional/mempool_spend_coinbase.py +++ b/test/bitcoin_functional/functional/mempool_spend_coinbase.py @@ -21,6 +21,9 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): chain_height = self.nodes[0].getblockcount() assert_equal(chain_height, 200) diff --git a/test/bitcoin_functional/functional/mining_basic.py b/test/bitcoin_functional/functional/mining_basic.py index a99c2fc8d4..f95ad31e7c 100755 --- a/test/bitcoin_functional/functional/mining_basic.py +++ b/test/bitcoin_functional/functional/mining_basic.py @@ -9,16 +9,23 @@ - submitblock""" import copy -from binascii import b2a_hex from decimal import Decimal from test_framework.blocktools import create_coinbase -from test_framework.messages import CBlock +from test_framework.messages import ( + CBlock, + CBlockHeader, +) +from test_framework.mininode import ( + P2PDataStore, +) from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_raises_rpc_error +from test_framework.util import ( + assert_equal, + assert_raises_rpc_error, + bytes_to_hex_str as b2x, +) -def b2x(b): - return b2a_hex(b).decode('ascii') def assert_template(node, block, expect, rehash=True): if rehash: @@ -31,13 +38,22 @@ class MiningTest(BitcoinTestFramework): self.num_nodes = 2 self.setup_clean_chain = False + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node = self.nodes[0] + def assert_submitblock(block, result_str_1, result_str_2=None): + block.solve() + result_str_2 = result_str_2 or 'duplicate-invalid' + assert_equal(result_str_1, node.submitblock(hexdata=b2x(block.serialize()))) + assert_equal(result_str_2, node.submitblock(hexdata=b2x(block.serialize()))) + self.log.info('getmininginfo') mining_info = node.getmininginfo() assert_equal(mining_info['blocks'], 200) - assert_equal(mining_info['chain'], self.chain) + assert_equal(mining_info['chain'], 'regtest') assert_equal(mining_info['currentblocktx'], 0) assert_equal(mining_info['currentblockweight'], 0) assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10')) @@ -86,6 +102,7 @@ class MiningTest(BitcoinTestFramework): bad_block = copy.deepcopy(block) bad_block.vtx.append(bad_block.vtx[0]) assert_template(node, bad_block, 'bad-txns-duplicate') + assert_submitblock(bad_block, 'bad-txns-duplicate', 'bad-txns-duplicate') self.log.info("getblocktemplate: Test invalid transaction") bad_block = copy.deepcopy(block) @@ -94,12 +111,14 @@ class MiningTest(BitcoinTestFramework): bad_tx.rehash() bad_block.vtx.append(bad_tx) assert_template(node, bad_block, 'bad-txns-inputs-missingorspent') + assert_submitblock(bad_block, 'bad-txns-inputs-missingorspent') self.log.info("getblocktemplate: Test nonfinal transaction") bad_block = copy.deepcopy(block) bad_block.vtx[0].nLockTime = 2 ** 32 - 1 bad_block.vtx[0].rehash() assert_template(node, bad_block, 'bad-txns-nonfinal') + assert_submitblock(bad_block, 'bad-txns-nonfinal') self.log.info("getblocktemplate: Test bad tx count") # The tx count is immediately after the block header @@ -118,18 +137,88 @@ class MiningTest(BitcoinTestFramework): bad_block = copy.deepcopy(block) bad_block.hashMerkleRoot += 1 assert_template(node, bad_block, 'bad-txnmrklroot', False) + assert_submitblock(bad_block, 'bad-txnmrklroot', 'bad-txnmrklroot') self.log.info("getblocktemplate: Test bad timestamps") bad_block = copy.deepcopy(block) bad_block.nTime = 2 ** 31 - 1 assert_template(node, bad_block, 'time-too-new') + assert_submitblock(bad_block, 'time-too-new', 'time-too-new') bad_block.nTime = 0 assert_template(node, bad_block, 'time-too-old') + assert_submitblock(bad_block, 'time-too-old', 'time-too-old') self.log.info("getblocktemplate: Test not best block") bad_block = copy.deepcopy(block) bad_block.hashPrevBlock = 123 assert_template(node, bad_block, 'inconclusive-not-best-prevblk') + assert_submitblock(bad_block, 'prev-blk-not-found', 'prev-blk-not-found') + + self.log.info('submitheader tests') + assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='xx' * 80)) + assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='ff' * 78)) + assert_raises_rpc_error(-25, 'Must submit previous header', lambda: node.submitheader(hexdata='ff' * 80)) + + block.nTime += 1 + block.solve() + + def chain_tip(b_hash, *, status='headers-only', branchlen=1): + return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status} + + assert chain_tip(block.hash) not in node.getchaintips() + node.submitheader(hexdata=b2x(block.serialize())) + assert chain_tip(block.hash) in node.getchaintips() + node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) # Noop + assert chain_tip(block.hash) in node.getchaintips() + + bad_block_root = copy.deepcopy(block) + bad_block_root.hashMerkleRoot += 2 + bad_block_root.solve() + assert chain_tip(bad_block_root.hash) not in node.getchaintips() + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert chain_tip(bad_block_root.hash) in node.getchaintips() + # Should still reject invalid blocks, even if we have the header: + assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'bad-txnmrklroot') + assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'bad-txnmrklroot') + assert chain_tip(bad_block_root.hash) in node.getchaintips() + # We know the header for this invalid block, so should just return early without error: + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert chain_tip(bad_block_root.hash) in node.getchaintips() + + bad_block_lock = copy.deepcopy(block) + bad_block_lock.vtx[0].nLockTime = 2**32 - 1 + bad_block_lock.vtx[0].rehash() + bad_block_lock.hashMerkleRoot = bad_block_lock.calc_merkle_root() + bad_block_lock.solve() + assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'bad-txns-nonfinal') + assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'duplicate-invalid') + # Build a "good" block on top of the submitted bad block + bad_block2 = copy.deepcopy(block) + bad_block2.hashPrevBlock = bad_block_lock.sha256 + bad_block2.solve() + assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) + + # Should reject invalid header right away + bad_block_time = copy.deepcopy(block) + bad_block_time.nTime = 1 + bad_block_time.solve() + assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize()))) + + # Should ask for the block from a p2p node, if they announce the header as well: + node.add_p2p_connection(P2PDataStore()) + node.p2p.wait_for_getheaders(timeout=5) # Drop the first getheaders + node.p2p.send_blocks_and_test(blocks=[block], node=node) + # Must be active now: + assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips() + + # Building a few blocks should give the same results + node.generate(10) + assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize()))) + assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) + node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) + node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize())) + assert_equal(node.submitblock(hexdata=b2x(block.serialize())), 'duplicate') # valid + if __name__ == '__main__': MiningTest().main() diff --git a/test/bitcoin_functional/functional/mining_getblocktemplate_longpoll.py b/test/bitcoin_functional/functional/mining_getblocktemplate_longpoll.py index 2bcbe8db7b..9a3c15a4a7 100755 --- a/test/bitcoin_functional/functional/mining_getblocktemplate_longpoll.py +++ b/test/bitcoin_functional/functional/mining_getblocktemplate_longpoll.py @@ -15,8 +15,8 @@ class LongpollThread(threading.Thread): def __init__(self, node): threading.Thread.__init__(self) # query current longpollid - templat = node.getblocktemplate() - self.longpollid = templat['longpollid'] + template = node.getblocktemplate() + self.longpollid = template['longpollid'] # create a new connection to the node, we can't use the same # connection from two threads self.node = get_rpc_proxy(node.url, 1, timeout=600, coveragedir=node.coverage_dir) @@ -28,14 +28,17 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.log.info("Warning: this test will take about 70 seconds in the best case. Be patient.") self.nodes[0].generate(10) - templat = self.nodes[0].getblocktemplate() - longpollid = templat['longpollid'] + template = self.nodes[0].getblocktemplate() + longpollid = template['longpollid'] # longpollid should not change between successive invocations if nothing else happens - templat2 = self.nodes[0].getblocktemplate() - assert(templat2['longpollid'] == longpollid) + template2 = self.nodes[0].getblocktemplate() + assert(template2['longpollid'] == longpollid) # Test 1: test that the longpolling wait if we do nothing thr = LongpollThread(self.nodes[0]) @@ -70,4 +73,3 @@ class GetBlockTemplateLPTest(BitcoinTestFramework): if __name__ == '__main__': GetBlockTemplateLPTest().main() - diff --git a/test/bitcoin_functional/functional/mining_prioritisetransaction.py b/test/bitcoin_functional/functional/mining_prioritisetransaction.py index bb0cc082ab..92590717f3 100755 --- a/test/bitcoin_functional/functional/mining_prioritisetransaction.py +++ b/test/bitcoin_functional/functional/mining_prioritisetransaction.py @@ -16,6 +16,9 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [["-printpriority=1"], ["-printpriority=1"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Test `prioritisetransaction` required parameters assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction) diff --git a/test/bitcoin_functional/functional/p2p_compactblocks.py b/test/bitcoin_functional/functional/p2p_compactblocks.py index 5cec5dc6f0..3a5bdf806b 100755 --- a/test/bitcoin_functional/functional/p2p_compactblocks.py +++ b/test/bitcoin_functional/functional/p2p_compactblocks.py @@ -102,6 +102,9 @@ class CompactBlocksTest(BitcoinTestFramework): self.extra_args = [["-vbparams=segwit:0:0"], ["-vbparams=segwit:0:999999999999", "-txindex", "-deprecatedrpc=addwitnessaddress"]] self.utxos = [] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def build_block_on_tip(self, node, segwit=False): height = node.getblockcount() tip = node.getbestblockhash() diff --git a/test/bitcoin_functional/functional/p2p_feefilter.py b/test/bitcoin_functional/functional/p2p_feefilter.py index 3bc7734e75..d589519e45 100755 --- a/test/bitcoin_functional/functional/p2p_feefilter.py +++ b/test/bitcoin_functional/functional/p2p_feefilter.py @@ -42,6 +42,9 @@ class FeeFilterTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node1 = self.nodes[1] node0 = self.nodes[0] diff --git a/test/bitcoin_functional/functional/p2p_fingerprint.py b/test/bitcoin_functional/functional/p2p_fingerprint.py index 4a6ffced93..884fb4b063 100755 --- a/test/bitcoin_functional/functional/p2p_fingerprint.py +++ b/test/bitcoin_functional/functional/p2p_fingerprint.py @@ -30,6 +30,9 @@ class P2PFingerprintTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + # Build a chain of blocks on top of given one def build_chain(self, nblocks, prev_hash, prev_height, prev_median_time): blocks = [] diff --git a/test/bitcoin_functional/functional/p2p_invalid_block.py b/test/bitcoin_functional/functional/p2p_invalid_block.py index 1534f362e3..fd6b84f8b2 100755 --- a/test/bitcoin_functional/functional/p2p_invalid_block.py +++ b/test/bitcoin_functional/functional/p2p_invalid_block.py @@ -24,6 +24,9 @@ class InvalidBlockRequestTest(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [["-whitelist=127.0.0.1"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Add p2p connection to node0 node = self.nodes[0] # convenience reference to the node @@ -42,7 +45,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework): # Save the coinbase for later block1 = block tip = block.sha256 - node.p2p.send_blocks_and_test([block1], node, True) + node.p2p.send_blocks_and_test([block1], node, success=True) self.log.info("Mature the block.") node.generate(100) @@ -79,17 +82,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework): assert_equal(orig_hash, block2.rehash()) assert(block2_orig.vtx != block2.vtx) - node.p2p.send_blocks_and_test([block2], node, False, False, 16, b'bad-txns-duplicate') - - # Check transactions for duplicate inputs - self.log.info("Test duplicate input block.") - - block2_orig.vtx[2].vin.append(block2_orig.vtx[2].vin[0]) - block2_orig.vtx[2].rehash() - block2_orig.hashMerkleRoot = block2_orig.calc_merkle_root() - block2_orig.rehash() - block2_orig.solve() - node.p2p.send_blocks_and_test([block2_orig], node, success=False, request_block=False, reject_reason=b'bad-txns-inputs-duplicate') + node.p2p.send_blocks_and_test([block2], node, success=False, request_block=False, reject_reason='bad-txns-duplicate') self.log.info("Test very broken block.") @@ -102,7 +95,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework): block3.rehash() block3.solve() - node.p2p.send_blocks_and_test([block3], node, False, False, 16, b'bad-cb-amount') + node.p2p.send_blocks_and_test([block3], node, success=False, request_block=False, reject_reason='bad-cb-amount') if __name__ == '__main__': InvalidBlockRequestTest().main() diff --git a/test/bitcoin_functional/functional/p2p_invalid_locator.py b/test/bitcoin_functional/functional/p2p_invalid_locator.py index 3b1654f920..4cc43a4fa4 100755 --- a/test/bitcoin_functional/functional/p2p_invalid_locator.py +++ b/test/bitcoin_functional/functional/p2p_invalid_locator.py @@ -15,6 +15,9 @@ class InvalidLocatorTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = False + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node = self.nodes[0] # convenience reference to the node node.generate(1) # Get node out of IBD diff --git a/test/bitcoin_functional/functional/p2p_invalid_tx.py b/test/bitcoin_functional/functional/p2p_invalid_tx.py index 0aa5e21103..2f19b4d933 100755 --- a/test/bitcoin_functional/functional/p2p_invalid_tx.py +++ b/test/bitcoin_functional/functional/p2p_invalid_tx.py @@ -26,6 +26,9 @@ class InvalidTxRequestTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def bootstrap_p2p(self, *, num_connections=1): """Add a P2P connection to the node. @@ -76,7 +79,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): self.reconnect_p2p(num_connections=2) self.log.info('Test orphan transaction handling ... ') - # Create a root transaction that we withhold until all dependend transactions + # Create a root transaction that we withhold until all dependent transactions # are sent out and in the orphan cache SCRIPT_PUB_KEY_OP_TRUE = b'\x51\x75' * 15 + b'\x51' tx_withhold = CTransaction() @@ -116,7 +119,8 @@ class InvalidTxRequestTest(BitcoinTestFramework): assert_equal(2, len(node.getpeerinfo())) # p2ps[1] is still connected self.log.info('Send the withhold tx ... ') - node.p2p.send_txs_and_test([tx_withhold], node, success=True) + with node.assert_debug_log(expected_msgs=["bad-txns-in-belowout"]): + node.p2p.send_txs_and_test([tx_withhold], node, success=True) # Transactions that should end up in the mempool expected_mempool = { @@ -134,13 +138,6 @@ class InvalidTxRequestTest(BitcoinTestFramework): wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected assert_equal(expected_mempool, set(node.getrawmempool())) - # restart node with sending BIP61 messages disabled, check that it disconnects without sending the reject message - self.log.info('Test a transaction that is rejected, with BIP61 disabled') - self.restart_node(0, ['-enablebip61=0','-persistmempool=0']) - self.reconnect_p2p(num_connections=1) - node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True) - # send_txs_and_test will have waited for disconnect, so we can safely check that no reject has been received - assert_equal(node.p2p.reject_code_received, None) if __name__ == '__main__': InvalidTxRequestTest().main() diff --git a/test/bitcoin_functional/functional/p2p_leak.py b/test/bitcoin_functional/functional/p2p_leak.py index dcbf833e7c..05354d17e1 100755 --- a/test/bitcoin_functional/functional/p2p_leak.py +++ b/test/bitcoin_functional/functional/p2p_leak.py @@ -93,6 +93,9 @@ class P2PLeakTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [['-banscore=' + str(banscore)]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): no_version_bannode = self.nodes[0].add_p2p_connection(CNodeNoVersionBan(), send_version=False, wait_for_verack=False) no_version_idlenode = self.nodes[0].add_p2p_connection(CNodeNoVersionIdle(), send_version=False, wait_for_verack=False) diff --git a/test/bitcoin_functional/functional/p2p_node_network_limited.py b/test/bitcoin_functional/functional/p2p_node_network_limited.py index c987bf4b05..a16c6a1d47 100755 --- a/test/bitcoin_functional/functional/p2p_node_network_limited.py +++ b/test/bitcoin_functional/functional/p2p_node_network_limited.py @@ -34,6 +34,9 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): self.num_nodes = 3 self.extra_args = [['-prune=550', '-addrmantest'], [], []] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def disconnect_all(self): disconnect_nodes(self.nodes[0], 1) disconnect_nodes(self.nodes[1], 0) @@ -89,7 +92,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): sync_blocks([self.nodes[0], self.nodes[2]], timeout=5) except: pass - # node2 must remain at heigh 0 + # node2 must remain at height 0 assert_equal(self.nodes[2].getblockheader(self.nodes[2].getbestblockhash())['height'], 0) # now connect also to node 1 (non pruned) diff --git a/test/bitcoin_functional/functional/p2p_segwit.py b/test/bitcoin_functional/functional/p2p_segwit.py index be79a13237..de12ab1ed6 100755 --- a/test/bitcoin_functional/functional/p2p_segwit.py +++ b/test/bitcoin_functional/functional/p2p_segwit.py @@ -41,7 +41,6 @@ from test_framework.messages import ( from test_framework.mininode import ( P2PInterface, mininode_lock, - wait_until, ) from test_framework.script import ( CScript, @@ -119,37 +118,28 @@ def get_virtual_size(witness_block): vsize = int((3 * base_size + total_size + 3) / 4) return vsize -def test_transaction_acceptance(rpc, p2p, tx, with_witness, accepted, reason=None): +def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=None): """Send a transaction to the node and check that it's accepted to the mempool - Submit the transaction over the p2p interface - use the getrawmempool rpc to check for acceptance.""" - tx_message = msg_tx(tx) - if with_witness: - tx_message = msg_witness_tx(tx) - p2p.send_message(tx_message) - p2p.sync_with_ping() - assert_equal(tx.hash in rpc.getrawmempool(), accepted) - if (reason is not None and not accepted): - # Check the rejection reason as well. - with mininode_lock: - assert_equal(p2p.last_message["reject"].reason, reason) + reason = [reason] if reason else [] + with node.assert_debug_log(expected_msgs=reason): + p2p.send_message(msg_witness_tx(tx) if with_witness else msg_tx(tx)) + p2p.sync_with_ping() + assert_equal(tx.hash in node.getrawmempool(), accepted) -def test_witness_block(rpc, p2p, block, accepted, with_witness=True, reason=None): +def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=None): """Send a block to the node and check that it's accepted - Submit the block over the p2p interface - use the getbestblockhash rpc to check for acceptance.""" - if with_witness: - p2p.send_message(msg_witness_block(block)) - else: - p2p.send_message(msg_block(block)) - p2p.sync_with_ping() - assert_equal(rpc.getbestblockhash() == block.hash, accepted) - if (reason is not None and not accepted): - # Check the rejection reason as well. - with mininode_lock: - assert_equal(p2p.last_message["reject"].reason, reason) + reason = [reason] if reason else [] + with node.assert_debug_log(expected_msgs=reason): + p2p.send_message(msg_witness_block(block) if with_witness else msg_block(block)) + p2p.sync_with_ping() + assert_equal(node.getbestblockhash() == block.hash, accepted) + class TestP2PConn(P2PInterface): def __init__(self): @@ -198,6 +188,9 @@ class SegWitTest(BitcoinTestFramework): # This test tests SegWit both pre and post-activation, so use the normal BIP9 activation. self.extra_args = [["-whitelist=127.0.0.1", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-acceptnonstdtxn=0", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-vbparams=segwit:0:0"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() connect_nodes(self.nodes[0], 1) @@ -349,8 +342,7 @@ class SegWitTest(BitcoinTestFramework): self.update_witness_block_with_transactions(block, [tx]) # Sending witness data before activation is not allowed (anti-spam # rule). - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) - wait_until(lambda: 'reject' in self.test_node.last_message and self.test_node.last_message["reject"].reason == b"unexpected-witness") + test_witness_block(self.nodes[0], self.test_node, block, accepted=False, reason='unexpected-witness') # But it should not be permanently marked bad... # Resend without witness information. @@ -380,20 +372,20 @@ class SegWitTest(BitcoinTestFramework): self.test_node.announce_block_and_wait_for_getdata(block1, use_header=False) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block1, True) + test_witness_block(self.nodes[0], self.test_node, block1, True) block2 = self.build_next_block(version=4) block2.solve() self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, True) + test_witness_block(self.nodes[0], self.test_node, block2, True) block3 = self.build_next_block(version=(VB_TOP_BITS | (1 << 15))) block3.solve() self.test_node.announce_block_and_wait_for_getdata(block3, use_header=True) assert(self.test_node.last_message["getdata"].inv[0].type == blocktype) - test_witness_block(self.nodes[0].rpc, self.test_node, block3, True) + test_witness_block(self.nodes[0], self.test_node, block3, True) # Check that we can getdata for witness blocks or regular blocks, # and the right thing happens. @@ -423,7 +415,7 @@ class SegWitTest(BitcoinTestFramework): # This gives us a witness commitment. assert(len(block.vtx[0].wit.vtxinwit) == 1) assert(len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack) == 1) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Now try to retrieve it... rpc_block = self.nodes[0].getblock(block.hash, False) non_wit_block = self.test_node.request_block(block.sha256, 2) @@ -471,7 +463,7 @@ class SegWitTest(BitcoinTestFramework): blocks are permitted to contain witnesses).""" # node2 doesn't need to be connected for this test. - # (If it's connected, node0 may propogate an invalid block to it over + # (If it's connected, node0 may propagate an invalid block to it over # compact blocks and the nodes would have inconsistent tips.) disconnect_nodes(self.nodes[0], 2) @@ -497,7 +489,7 @@ class SegWitTest(BitcoinTestFramework): self.update_witness_block_with_transactions(block, [tx]) # Verify that segwit isn't activated. A block serialized with witness # should be rejected prior to activation. - test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason=b'unexpected-witness') + test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason='unexpected-witness') # Now send the block without witness. It should be accepted test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=False) @@ -523,7 +515,7 @@ class SegWitTest(BitcoinTestFramework): # When the block is serialized with a witness, the block will be rejected because witness # data isn't allowed in blocks that don't commit to witness data. - test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason=b'unexpected-witness') + test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason='unexpected-witness') # When the block is serialized without witness, validation fails because the transaction is # invalid (transactions are always validated with SCRIPT_VERIFY_WITNESS so a segwit v0 transaction @@ -640,11 +632,11 @@ class SegWitTest(BitcoinTestFramework): # its from) assert_equal(len(self.nodes[0].getrawmempool()), 0) assert_equal(len(self.nodes[1].getrawmempool()), 0) - test_transaction_acceptance(self.nodes[0].rpc, self.old_node, tx, with_witness=True, accepted=False) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.old_node, tx, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=False) # But eliminating the witness should fix it - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True) # Cleanup: mine the first transaction and update utxo self.nodes[0].generate(1) @@ -674,7 +666,7 @@ class SegWitTest(BitcoinTestFramework): p2sh_tx.rehash() # Mine it on test_node to create the confirmed output. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_tx, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_tx, with_witness=True, accepted=True) self.nodes[0].generate(1) sync_blocks(self.nodes) @@ -689,7 +681,7 @@ class SegWitTest(BitcoinTestFramework): # This is always accepted, since the mempool policy is to consider segwit as always active # and thus allow segwit outputs - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=True) # Now create something that looks like a P2PKH output. This won't be spendable. script_pubkey = CScript([OP_0, hash160(witness_hash)]) @@ -701,7 +693,7 @@ class SegWitTest(BitcoinTestFramework): tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] tx2.rehash() - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=True) # Now update self.utxo for later tests. tx3 = CTransaction() @@ -723,7 +715,7 @@ class SegWitTest(BitcoinTestFramework): tx3.vout = [tx3_out] tx3.rehash() assert_equal(self.nodes[0].testmempoolaccept([bytes_to_hex_str(tx3.serialize_with_witness())]), [{'txid': tx3.hash, 'allowed': True}]) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True) self.nodes[0].generate(1) sync_blocks(self.nodes) @@ -760,10 +752,10 @@ class SegWitTest(BitcoinTestFramework): tx.rehash() # Verify mempool acceptance and block validity - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True) block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True, with_witness=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=True) sync_blocks(self.nodes) # Now test attempts to spend the output. @@ -777,12 +769,12 @@ class SegWitTest(BitcoinTestFramework): # will require a witness to spend a witness program regardless of # segwit activation. Note that older bitcoind's that are not # segwit-aware would also reject this for failing CLEANSTACK. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) # Try to put the witness script in the script_sig, should also fail. spend_tx.vin[0].script_sig = CScript([p2wsh_pubkey, b'a']) spend_tx.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=False, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False) # Now put the witness script in the witness, should succeed after # segwit activates. @@ -792,7 +784,7 @@ class SegWitTest(BitcoinTestFramework): spend_tx.wit.vtxinwit[0].scriptWitness.stack = [b'a', witness_program] # Verify mempool acceptance - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, spend_tx, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=True, accepted=True) block = self.build_next_block() self.update_witness_block_with_transactions(block, [spend_tx]) @@ -800,7 +792,7 @@ class SegWitTest(BitcoinTestFramework): # This no longer works before activation, because SCRIPT_VERIFY_WITNESS # is always set. # TODO: rewrite this test to make clear that it only works after activation. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Update self.utxo self.utxo.pop(0) @@ -821,7 +813,7 @@ class SegWitTest(BitcoinTestFramework): assert(msg_witness_block(block).serialize() != msg_block(block).serialize()) # This empty block should be valid. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Try to tweak the nonce block_2 = self.build_next_block() @@ -832,7 +824,7 @@ class SegWitTest(BitcoinTestFramework): assert(block_2.vtx[0].vout[-1] != block.vtx[0].vout[-1]) # This should also be valid. - test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_2, accepted=True) # Now test commitments with actual transactions tx = CTransaction() @@ -864,7 +856,7 @@ class SegWitTest(BitcoinTestFramework): block_3.rehash() block_3.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False) # Add a different commitment with different nonce, but in the # right location, and with some funds burned(!). @@ -878,7 +870,7 @@ class SegWitTest(BitcoinTestFramework): block_3.rehash() assert(len(block_3.vtx[0].vout) == 4) # 3 OP_returns block_3.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_3, accepted=True) # Finally test that a block with no witness transactions can # omit the commitment. @@ -890,7 +882,7 @@ class SegWitTest(BitcoinTestFramework): block_4.vtx.append(tx3) block_4.hashMerkleRoot = block_4.calc_merkle_root() block_4.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block_4, with_witness=False, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_4, with_witness=False, accepted=True) # Update available utxo's for use in later test. self.utxo.pop(0) @@ -930,11 +922,11 @@ class SegWitTest(BitcoinTestFramework): # Change the nonce -- should not cause the block to be permanently # failed block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(1)] - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Changing the witness reserved value doesn't change the block hash block.vtx[0].wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)] - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) @subtest def test_witness_block_size(self): @@ -998,7 +990,7 @@ class SegWitTest(BitcoinTestFramework): # limit assert(len(block.serialize(True)) > 2 * 1024 * 1024) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now resize the second transaction to make the block fit. cur_length = len(block.vtx[-1].wit.vtxinwit[0].scriptWitness.stack[0]) @@ -1008,7 +1000,7 @@ class SegWitTest(BitcoinTestFramework): block.solve() assert(get_virtual_size(block) == MAX_BLOCK_BASE_SIZE) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Update available utxo's self.utxo.pop(0) @@ -1071,7 +1063,7 @@ class SegWitTest(BitcoinTestFramework): self.update_witness_block_with_transactions(block, [tx]) # Extra witness data should not be allowed. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Try extra signature data. Ok if we're not spending a witness output. block.vtx[1].wit.vtxinwit = [] @@ -1080,7 +1072,7 @@ class SegWitTest(BitcoinTestFramework): add_witness_commitment(block) block.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Now try extra witness/signature data on an input that DOES require a # witness @@ -1096,7 +1088,7 @@ class SegWitTest(BitcoinTestFramework): self.update_witness_block_with_transactions(block, [tx2]) # This has extra witness data, so it should fail. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now get rid of the extra witness, but add extra scriptSig data tx2.vin[0].scriptSig = CScript([OP_TRUE]) @@ -1108,7 +1100,7 @@ class SegWitTest(BitcoinTestFramework): block.solve() # This has extra signature data for a witness input, so it should fail. - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now get rid of the extra scriptsig on the witness input, and verify # success (even with extra scriptsig data in the non-witness input) @@ -1117,7 +1109,7 @@ class SegWitTest(BitcoinTestFramework): add_witness_commitment(block) block.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Update utxo for later tests self.utxo.pop(0) @@ -1147,14 +1139,14 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now reduce the length of the stack element tx2.wit.vtxinwit[0].scriptWitness.stack[0] = b'a' * (MAX_SCRIPT_ELEMENT_SIZE) add_witness_commitment(block) block.solve() - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Update the utxo for later tests self.utxo.pop() @@ -1188,7 +1180,7 @@ class SegWitTest(BitcoinTestFramework): self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Try again with one less byte in the witness program witness_program = CScript([b'a' * 520] * 19 + [OP_DROP] * 62 + [OP_TRUE]) @@ -1203,7 +1195,7 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() block.vtx = [block.vtx[0]] self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) self.utxo.pop() self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) @@ -1227,7 +1219,7 @@ class SegWitTest(BitcoinTestFramework): block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Try various ways to spend tx that should all break. # This "broken" transaction serializer will not normalize @@ -1262,7 +1254,7 @@ class SegWitTest(BitcoinTestFramework): block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now try using a too short vtxinwit tx2.wit.vtxinwit.pop() @@ -1270,7 +1262,7 @@ class SegWitTest(BitcoinTestFramework): block.vtx = [block.vtx[0]] self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now make one of the intermediate witnesses be incorrect tx2.wit.vtxinwit.append(CTxInWitness()) @@ -1279,13 +1271,13 @@ class SegWitTest(BitcoinTestFramework): block.vtx = [block.vtx[0]] self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Fix the broken witness and the block should be accepted. tx2.wit.vtxinwit[5].scriptWitness.stack = [b'a', witness_program] block.vtx = [block.vtx[0]] self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) self.utxo.pop() self.utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) @@ -1314,11 +1306,11 @@ class SegWitTest(BitcoinTestFramework): # Verify that unnecessary witnesses are rejected. self.test_node.announce_tx_and_wait_for_getdata(tx) assert_equal(len(self.nodes[0].getrawmempool()), 0) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=False) # Verify that removing the witness succeeds. self.test_node.announce_tx_and_wait_for_getdata(tx) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True) # Now try to add extra witness data to a valid witness tx. witness_program = CScript([OP_TRUE]) @@ -1343,24 +1335,24 @@ class SegWitTest(BitcoinTestFramework): # Node will not be blinded to the transaction self.std_node.announce_tx_and_wait_for_getdata(tx3) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size') + test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, 'tx-size') self.std_node.announce_tx_and_wait_for_getdata(tx3) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx3, True, False, b'tx-size') + test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, 'tx-size') # Remove witness stuffing, instead add extra witness push on stack tx3.vout[0] = CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])) tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program] tx3.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False) # Get rid of the extra witness, and verify acceptance. tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program] # Also check that old_node gets a tx announcement, even though this is # a witness transaction. self.old_node.wait_for_inv([CInv(1, tx2.sha256)]) # wait until tx2 was inv'ed - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=True) self.old_node.wait_for_inv([CInv(1, tx3.sha256)]) # Test that getrawtransaction returns correct witness information @@ -1400,7 +1392,7 @@ class SegWitTest(BitcoinTestFramework): tx.rehash() block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) self.utxo.pop(0) for i in range(NUM_SEGWIT_VERSIONS): self.utxo.append(UTXO(tx.sha256, i, split_value)) @@ -1417,8 +1409,8 @@ class SegWitTest(BitcoinTestFramework): tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] tx.vout = [CTxOut(self.utxo[0].nValue - 1000, script_pubkey)] tx.rehash() - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx, with_witness=True, accepted=False) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=True) self.utxo.pop(0) temp_utxo.append(UTXO(tx.sha256, 0, tx.vout[0].nValue)) @@ -1437,8 +1429,8 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() # Gets accepted to test_node, because standardness of outputs isn't # checked with fRequireStandard - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, with_witness=True, accepted=True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, with_witness=True, accepted=False) + test_transaction_acceptance(self.nodes[0], self.test_node, tx2, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[1], self.std_node, tx2, with_witness=True, accepted=False) temp_utxo.pop() # last entry in temp_utxo was the output we just spent temp_utxo.append(UTXO(tx2.sha256, 0, tx2.vout[0].nValue)) @@ -1454,15 +1446,12 @@ class SegWitTest(BitcoinTestFramework): tx3.rehash() # Spending a higher version witness output is not allowed by policy, # even with fRequireStandard=false. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, with_witness=True, accepted=False) - self.test_node.sync_with_ping() - with mininode_lock: - assert(b"reserved for soft-fork upgrades" in self.test_node.last_message["reject"].reason) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False, reason="reserved for soft-fork upgrades") # Building a block with the transaction must be valid, however. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx2, tx3]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) sync_blocks(self.nodes) # Add utxo to our list @@ -1480,7 +1469,7 @@ class SegWitTest(BitcoinTestFramework): # This next line will rehash the coinbase and update the merkle # root, and solve. self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) spend_tx = CTransaction() spend_tx.vin = [CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")] @@ -1494,13 +1483,13 @@ class SegWitTest(BitcoinTestFramework): sync_blocks(self.nodes) block2 = self.build_next_block() self.update_witness_block_with_transactions(block2, [spend_tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block2, accepted=False) # Advancing one more block should allow the spend. self.nodes[0].generate(1) block2 = self.build_next_block() self.update_witness_block_with_transactions(block2, [spend_tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block2, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block2, accepted=True) sync_blocks(self.nodes) @subtest @@ -1532,7 +1521,7 @@ class SegWitTest(BitcoinTestFramework): # Confirm it in a block. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Now try to spend it. Send it to a P2WSH output, which we'll # use in the next test. @@ -1551,11 +1540,11 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') # But passes consensus. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Test 2: P2WSH # Try to spend the P2WSH output created in last test. @@ -1571,11 +1560,11 @@ class SegWitTest(BitcoinTestFramework): sign_p2pk_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') # But passes consensus. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx3]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Test 3: P2SH(P2WSH) # Try to spend the P2SH output created in the last test. @@ -1588,10 +1577,10 @@ class SegWitTest(BitcoinTestFramework): sign_p2pk_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) # Should fail policy test. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx4]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Test 4: Uncompressed pubkeys should still be valid in non-segwit # transactions. @@ -1603,10 +1592,10 @@ class SegWitTest(BitcoinTestFramework): tx5.vin[0].scriptSig = CScript([signature, pubkey]) tx5.rehash() # Should pass policy and consensus. - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx5, True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx5, True, True) block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx5]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) self.utxo.append(UTXO(tx5.sha256, 0, tx5.vout[0].nValue)) @subtest @@ -1626,11 +1615,11 @@ class SegWitTest(BitcoinTestFramework): tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey)) tx.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=True, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=True, accepted=True) # Mine this transaction in preparation for following tests. block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) sync_blocks(self.nodes) self.utxo.pop(0) @@ -1647,19 +1636,19 @@ class SegWitTest(BitcoinTestFramework): # Too-large input value sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue + 1, key) self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Too-small input value sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue - 1, key) block.vtx.pop() # remove last tx self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Now try correct value sign_p2pk_witness_input(witness_program, tx, 0, hashtype, prev_utxo.nValue, key) block.vtx.pop() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue) @@ -1683,7 +1672,7 @@ class SegWitTest(BitcoinTestFramework): block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) block = self.build_next_block() used_sighash_single_out_of_bounds = False @@ -1725,7 +1714,7 @@ class SegWitTest(BitcoinTestFramework): # Test the block periodically, if we're close to maxblocksize if (get_virtual_size(block) > MAX_BLOCK_BASE_SIZE - 1000): self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) block = self.build_next_block() if (not used_sighash_single_out_of_bounds): @@ -1733,7 +1722,7 @@ class SegWitTest(BitcoinTestFramework): # Test the transactions we've added to the block if (len(block.vtx) > 1): self.update_witness_block_with_transactions(block, []) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) # Now test witness version 0 P2PKH transactions pubkeyhash = hash160(pubkey) @@ -1755,7 +1744,7 @@ class SegWitTest(BitcoinTestFramework): tx2.vin[0].scriptSig = CScript([signature, pubkey]) block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx, tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block, accepted=False) # Move the signature to the witness. block.vtx.pop() @@ -1765,7 +1754,7 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() self.update_witness_block_with_transactions(block, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) temp_utxos.pop(0) @@ -1786,7 +1775,7 @@ class SegWitTest(BitcoinTestFramework): index += 1 block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block, accepted=True) for i in range(len(tx.vout)): self.utxo.append(UTXO(tx.sha256, i, tx.vout[i].nValue)) @@ -1808,7 +1797,7 @@ class SegWitTest(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey)) tx.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, False, True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, False, True) self.nodes[0].generate(1) sync_blocks(self.nodes) @@ -1825,18 +1814,18 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() # This will be rejected due to a policy check: # No witness is allowed, since it is not a witness program but a p2sh program - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, True, False, b'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[1], self.std_node, tx2, True, False, 'bad-witness-nonstandard') # If we send without witness, it should be accepted. - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, tx2, False, True) + test_transaction_acceptance(self.nodes[1], self.std_node, tx2, False, True) # Now create a new anyone-can-spend utxo for the next test. tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) tx3.rehash() - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx2, False, True) - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx3, False, True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx2, False, True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx3, False, True) self.nodes[0].generate(1) sync_blocks(self.nodes) @@ -1872,7 +1861,7 @@ class SegWitTest(BitcoinTestFramework): tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL]))) tx.rehash() txid = tx.sha256 - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, tx, with_witness=False, accepted=True) + test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True) self.nodes[0].generate(1) sync_blocks(self.nodes) @@ -1897,45 +1886,45 @@ class SegWitTest(BitcoinTestFramework): # Testing native P2WSH # Witness stack size, excluding witnessScript, over 100 is non-standard p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[0], True, False, b'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, 'bad-witness-nonstandard') # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[0], True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[0], True, True) # Stack element size over 80 bytes is non-standard p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, False, b'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, 'bad-witness-nonstandard') # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[1], True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[1], True, True) # Standard nodes should accept if element size is not over 80 bytes p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[1], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, True) # witnessScript size at 3600 bytes is standard p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[2], True, True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[2], True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[2], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[2], True, True) # witnessScript size at 3601 bytes is non-standard p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2wsh_txs[3], True, False, b'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, 'bad-witness-nonstandard') # Non-standard nodes should accept - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2wsh_txs[3], True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[3], True, True) # Repeating the same tests with P2SH-P2WSH p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[0], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[0], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, 'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[0], True, True) p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[1], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, 'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[1], True, True) p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[1], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, True) p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[2], True, True) - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[2], True, True) + test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[2], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[2], True, True) p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] - test_transaction_acceptance(self.nodes[1].rpc, self.std_node, p2sh_txs[3], True, False, b'bad-witness-nonstandard') - test_transaction_acceptance(self.nodes[0].rpc, self.test_node, p2sh_txs[3], True, True) + test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, 'bad-witness-nonstandard') + test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[3], True, True) self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node # Valid but non-standard transactions in a block should be accepted by standard node @@ -2011,7 +2000,7 @@ class SegWitTest(BitcoinTestFramework): block_1 = self.build_next_block() self.update_witness_block_with_transactions(block_1, [tx]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_1, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_1, accepted=True) tx2 = CTransaction() # If we try to spend the first n-1 outputs from tx, that should be @@ -2028,7 +2017,7 @@ class SegWitTest(BitcoinTestFramework): block_2 = self.build_next_block() self.update_witness_block_with_transactions(block_2, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_2, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block_2, accepted=False) # Try dropping the last input in tx2, and add an output that has # too many sigops (contributing to legacy sigop count). @@ -2041,14 +2030,14 @@ class SegWitTest(BitcoinTestFramework): tx2.rehash() block_3 = self.build_next_block() self.update_witness_block_with_transactions(block_3, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_3, accepted=False) + test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False) # If we drop the last checksig in this output, the tx should succeed. block_4 = self.build_next_block() tx2.vout[-1].scriptPubKey = CScript([OP_CHECKSIG] * (checksig_count - 1)) tx2.rehash() self.update_witness_block_with_transactions(block_4, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_4, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_4, accepted=True) # Reset the tip back down for the next test sync_blocks(self.nodes) @@ -2064,7 +2053,7 @@ class SegWitTest(BitcoinTestFramework): tx2.wit.vtxinwit[-1].scriptWitness.stack = [witness_program_justright] tx2.rehash() self.update_witness_block_with_transactions(block_5, [tx2]) - test_witness_block(self.nodes[0].rpc, self.test_node, block_5, accepted=True) + test_witness_block(self.nodes[0], self.test_node, block_5, accepted=True) # TODO: test p2sh sigop counting diff --git a/test/bitcoin_functional/functional/p2p_sendheaders.py b/test/bitcoin_functional/functional/p2p_sendheaders.py index 9cc496d510..9a782c0bb9 100755 --- a/test/bitcoin_functional/functional/p2p_sendheaders.py +++ b/test/bitcoin_functional/functional/p2p_sendheaders.py @@ -208,6 +208,9 @@ class SendHeadersTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def mine_blocks(self, count): """Mine count blocks and return the new tip.""" diff --git a/test/bitcoin_functional/functional/p2p_unrequested_blocks.py b/test/bitcoin_functional/functional/p2p_unrequested_blocks.py index 2e86954aba..232274f59e 100755 --- a/test/bitcoin_functional/functional/p2p_unrequested_blocks.py +++ b/test/bitcoin_functional/functional/p2p_unrequested_blocks.py @@ -66,6 +66,9 @@ class AcceptBlockTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [[], ["-minimumchainwork=0x10"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): # Node0 will be used to test behavior of processing unrequested blocks # from peers which are not whitelisted, while Node1 will be used for diff --git a/test/bitcoin_functional/functional/rpc_bind.py b/test/bitcoin_functional/functional/rpc_bind.py index c151094ff7..53916d5290 100755 --- a/test/bitcoin_functional/functional/rpc_bind.py +++ b/test/bitcoin_functional/functional/rpc_bind.py @@ -52,7 +52,7 @@ class RPCBindTest(BitcoinTestFramework): self.nodes[0].rpchost = None self.start_nodes([base_args]) # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(self.nodes[0].datadir, 0, self.chain, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) + node = get_rpc_proxy(rpc_url(self.nodes[0].datadir, 0, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) node.getnetworkinfo() self.stop_nodes() diff --git a/test/bitcoin_functional/functional/rpc_blockchain.py b/test/bitcoin_functional/functional/rpc_blockchain.py index d681cdc8ab..00317a2c08 100755 --- a/test/bitcoin_functional/functional/rpc_blockchain.py +++ b/test/bitcoin_functional/functional/rpc_blockchain.py @@ -47,9 +47,13 @@ from test_framework.mininode import ( class BlockchainTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-stopatheight=207', '-prune=1']] + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() 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 +173,7 @@ class BlockchainTest(BitcoinTestFramework): 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/bitcoin_functional/functional/rpc_createmultisig.py b/test/bitcoin_functional/functional/rpc_createmultisig.py index f346e1ebfc..3cc35a7b9a 100755 --- a/test/bitcoin_functional/functional/rpc_createmultisig.py +++ b/test/bitcoin_functional/functional/rpc_createmultisig.py @@ -12,8 +12,11 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def get_keys(self): - node0,node1,node2 = self.nodes + node0, node1, node2 = self.nodes self.add = [node1.getnewaddress() for _ in range(self.nkeys)] self.pub = [node1.getaddressinfo(a)["pubkey"] for a in self.add] self.priv = [node1.dumpprivkey(a) for a in self.add] diff --git a/test/bitcoin_functional/functional/rpc_deprecated.py b/test/bitcoin_functional/functional/rpc_deprecated.py index deffe4e6bd..58074803cc 100755 --- a/test/bitcoin_functional/functional/rpc_deprecated.py +++ b/test/bitcoin_functional/functional/rpc_deprecated.py @@ -4,13 +4,12 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test deprecation of RPC calls.""" from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_raises_rpc_error class DeprecatedRpcTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [[], ["-deprecatedrpc=validateaddress", "-deprecatedrpc=accounts"]] + self.extra_args = [[], ["-deprecatedrpc=validateaddress"]] def run_test(self): # This test should be used to verify correct behaviour of deprecated @@ -19,90 +18,7 @@ class DeprecatedRpcTest(BitcoinTestFramework): # self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") # assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) # self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) - - self.log.info("Test validateaddress deprecation") - SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress - dep_validate_address = self.nodes[0].validateaddress(SOME_ADDRESS) - assert "ismine" not in dep_validate_address - not_dep_val = self.nodes[1].validateaddress(SOME_ADDRESS) - assert "ismine" in not_dep_val - - self.log.info("Test accounts deprecation") - # The following account RPC methods are deprecated: - # - getaccount - # - getaccountaddress - # - getaddressesbyaccount - # - getreceivedbyaccount - # - listaccouts - # - listreceivedbyaccount - # - move - # - setaccount - # - # The following 'label' RPC methods are usable both with and without the - # -deprecatedrpc=accounts switch enabled. - # - getaddressesbylabel - # - getreceivedbylabel - # - listlabels - # - listreceivedbylabel - # - setlabel - # - address0 = self.nodes[0].getnewaddress() - self.nodes[0].generatetoaddress(101, address0) - self.sync_all() - address1 = self.nodes[1].getnewaddress() - self.nodes[1].generatetoaddress(101, address1) - - self.log.info("- getaccount") - assert_raises_rpc_error(-32, "getaccount is deprecated", self.nodes[0].getaccount, address0) - self.nodes[1].getaccount(address1) - - self.log.info("- setaccount") - assert_raises_rpc_error(-32, "setaccount is deprecated", self.nodes[0].setaccount, address0, "label0") - self.nodes[1].setaccount(address1, "label1") - - self.log.info("- setlabel") - self.nodes[0].setlabel(address0, "label0") - self.nodes[1].setlabel(address1, "label1") - - self.log.info("- getaccountaddress") - assert_raises_rpc_error(-32, "getaccountaddress is deprecated", self.nodes[0].getaccountaddress, "label0") - self.nodes[1].getaccountaddress("label1") - - self.log.info("- getaddressesbyaccount") - assert_raises_rpc_error(-32, "getaddressesbyaccount is deprecated", self.nodes[0].getaddressesbyaccount, "label0") - self.nodes[1].getaddressesbyaccount("label1") - - self.log.info("- getaddressesbylabel") - self.nodes[0].getaddressesbylabel("label0") - self.nodes[1].getaddressesbylabel("label1") - - self.log.info("- getreceivedbyaccount") - assert_raises_rpc_error(-32, "getreceivedbyaccount is deprecated", self.nodes[0].getreceivedbyaccount, "label0") - self.nodes[1].getreceivedbyaccount("label1") - - self.log.info("- getreceivedbylabel") - self.nodes[0].getreceivedbylabel("label0") - self.nodes[1].getreceivedbylabel("label1") - - self.log.info("- listaccounts") - assert_raises_rpc_error(-32, "listaccounts is deprecated", self.nodes[0].listaccounts) - self.nodes[1].listaccounts() - - self.log.info("- listlabels") - self.nodes[0].listlabels() - self.nodes[1].listlabels() - - self.log.info("- listreceivedbyaccount") - assert_raises_rpc_error(-32, "listreceivedbyaccount is deprecated", self.nodes[0].listreceivedbyaccount) - self.nodes[1].listreceivedbyaccount() - - self.log.info("- listreceivedbylabel") - self.nodes[0].listreceivedbylabel() - self.nodes[1].listreceivedbylabel() - - self.log.info("- move") - assert_raises_rpc_error(-32, "move is deprecated", self.nodes[0].move, "label0", "label0b", 10) - self.nodes[1].move("label1", "label1b", 10) + pass if __name__ == '__main__': DeprecatedRpcTest().main() diff --git a/test/bitcoin_functional/functional/rpc_fundrawtransaction.py b/test/bitcoin_functional/functional/rpc_fundrawtransaction.py index a806de43b4..0c61e9ab62 100755 --- a/test/bitcoin_functional/functional/rpc_fundrawtransaction.py +++ b/test/bitcoin_functional/functional/rpc_fundrawtransaction.py @@ -29,6 +29,9 @@ class RawTransactionsTest(BitcoinTestFramework): self.num_nodes = 4 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self, split=False): self.setup_nodes() @@ -475,10 +478,8 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################################ # locked wallet test - self.stop_node(0) - self.nodes[1].node_encrypt_wallet("test") - self.stop_node(2) - self.stop_node(3) + self.nodes[1].encryptwallet("test") + self.stop_nodes() self.start_nodes() # This test is not meant to test fee estimation and we'd like diff --git a/test/bitcoin_functional/functional/rpc_getchaintips.py b/test/bitcoin_functional/functional/rpc_getchaintips.py index 07929ca0a1..bc19c60dde 100755 --- a/test/bitcoin_functional/functional/rpc_getchaintips.py +++ b/test/bitcoin_functional/functional/rpc_getchaintips.py @@ -17,15 +17,18 @@ class GetChainTipsTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 - def run_test (self): - tips = self.nodes[0].getchaintips () - assert_equal (len (tips), 1) - assert_equal (tips[0]['branchlen'], 0) - assert_equal (tips[0]['height'], 200) - assert_equal (tips[0]['status'], 'active') + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def run_test(self): + tips = self.nodes[0].getchaintips() + assert_equal(len(tips), 1) + assert_equal(tips[0]['branchlen'], 0) + assert_equal(tips[0]['height'], 200) + assert_equal(tips[0]['status'], 'active') # Split the network and build two chains of different lengths. - self.split_network () + self.split_network() self.nodes[0].generate(10) self.nodes[2].generate(20) self.sync_all([self.nodes[:2], self.nodes[2:]]) diff --git a/test/bitcoin_functional/functional/rpc_help.py b/test/bitcoin_functional/functional/rpc_help.py new file mode 100755 index 0000000000..be096af892 --- /dev/null +++ b/test/bitcoin_functional/functional/rpc_help.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 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 RPC help output.""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_raises_rpc_error + + +class HelpRpcTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + + def run_test(self): + node = self.nodes[0] + + # wrong argument count + assert_raises_rpc_error(-1, 'help', node.help, 'foo', 'bar') + + # invalid argument + assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0) + + # help of unknown command + assert_equal(node.help('foo'), 'help: unknown command: foo') + + # command titles + titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')] + + components = ['Blockchain', 'Control', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util'] + + if self.is_wallet_compiled(): + components.append('Wallet') + + if self.is_zmq_compiled(): + components.append('Zmq') + + assert_equal(titles, components) + + +if __name__ == '__main__': + HelpRpcTest().main() diff --git a/test/bitcoin_functional/functional/rpc_invalidateblock.py b/test/bitcoin_functional/functional/rpc_invalidateblock.py index f40710ef74..84f7cd05fb 100755 --- a/test/bitcoin_functional/functional/rpc_invalidateblock.py +++ b/test/bitcoin_functional/functional/rpc_invalidateblock.py @@ -14,6 +14,9 @@ class InvalidateTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() diff --git a/test/bitcoin_functional/functional/rpc_net.py b/test/bitcoin_functional/functional/rpc_net.py index 02114eca76..a46518200c 100755 --- a/test/bitcoin_functional/functional/rpc_net.py +++ b/test/bitcoin_functional/functional/rpc_net.py @@ -7,6 +7,8 @@ Tests correspond to code in rpc/net.cpp. """ +from decimal import Decimal + from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -21,6 +23,7 @@ class NetTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 + self.extra_args = [["-minrelaytxfee=0.00001000"],["-minrelaytxfee=0.00000500"]] def run_test(self): self._test_connection_count() @@ -95,6 +98,8 @@ class NetTest(BitcoinTestFramework): # the address bound to on one side will be the source address for the other node assert_equal(peer_info[0][0]['addrbind'], peer_info[1][0]['addr']) assert_equal(peer_info[1][0]['addrbind'], peer_info[0][0]['addr']) + assert_equal(peer_info[0][0]['minfeefilter'], Decimal("0.00000500")) + assert_equal(peer_info[1][0]['minfeefilter'], Decimal("0.00001000")) if __name__ == '__main__': NetTest().main() diff --git a/test/bitcoin_functional/functional/rpc_preciousblock.py b/test/bitcoin_functional/functional/rpc_preciousblock.py index 1e20d1a046..f383b82bb5 100755 --- a/test/bitcoin_functional/functional/rpc_preciousblock.py +++ b/test/bitcoin_functional/functional/rpc_preciousblock.py @@ -38,6 +38,9 @@ class PreciousTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() diff --git a/test/bitcoin_functional/functional/rpc_psbt.py b/test/bitcoin_functional/functional/rpc_psbt.py index d558de5fe1..54dc871448 100755 --- a/test/bitcoin_functional/functional/rpc_psbt.py +++ b/test/bitcoin_functional/functional/rpc_psbt.py @@ -20,6 +20,9 @@ class PSBTTest(BitcoinTestFramework): self.setup_clean_chain = False self.num_nodes = 3 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Create and fund a raw tx for sending 10 BTC psbtx1 = self.nodes[0].walletcreatefundedpsbt([], {self.nodes[2].getnewaddress():10})['psbt'] @@ -105,7 +108,7 @@ class PSBTTest(BitcoinTestFramework): signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex']) assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].converttopsbt, signedtx['hex']) - # Explicilty allow converting non-empty txs + # Explicitly allow converting non-empty txs new_psbt = self.nodes[0].converttopsbt(rawtx['hex']) self.nodes[0].decodepsbt(new_psbt) diff --git a/test/bitcoin_functional/functional/rpc_rawtransaction.py b/test/bitcoin_functional/functional/rpc_rawtransaction.py index 1e3ada26f8..d86b546c7d 100755 --- a/test/bitcoin_functional/functional/rpc_rawtransaction.py +++ b/test/bitcoin_functional/functional/rpc_rawtransaction.py @@ -44,6 +44,9 @@ class RawTransactionsTest(BitcoinTestFramework): self.num_nodes = 3 self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"], ["-addresstype=legacy"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self, split=False): super().setup_network() connect_nodes_bi(self.nodes, 0, 2) @@ -358,7 +361,7 @@ class RawTransactionsTest(BitcoinTestFramework): # decoderawtransaction tests # witness transaction - encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000000000000" + encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000" decrawtx = self.nodes[0].decoderawtransaction(encrawtx, True) # decode as witness transaction assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000')) assert_raises_rpc_error(-22, 'TX decode failed', self.nodes[0].decoderawtransaction, encrawtx, False) # force decode as non-witness transaction diff --git a/test/bitcoin_functional/functional/rpc_scantxoutset.py b/test/bitcoin_functional/functional/rpc_scantxoutset.py index c338418703..96f9ccdbdb 100755 --- a/test/bitcoin_functional/functional/rpc_scantxoutset.py +++ b/test/bitcoin_functional/functional/rpc_scantxoutset.py @@ -14,6 +14,10 @@ class ScantxoutsetTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.log.info("Mining blocks...") self.nodes[0].generate(110) @@ -47,7 +51,7 @@ class ScantxoutsetTest(BitcoinTestFramework): self.log.info("Stop node, remove wallet, mine again some blocks...") self.stop_node(0) - shutil.rmtree(os.path.join(self.nodes[0].datadir, self.chain, 'wallets')) + shutil.rmtree(os.path.join(self.nodes[0].datadir, "regtest", 'wallets')) self.start_node(0) self.nodes[0].generate(110) diff --git a/test/bitcoin_functional/functional/rpc_signmessage.py b/test/bitcoin_functional/functional/rpc_signmessage.py index 449c4075bd..ad0e29b451 100755 --- a/test/bitcoin_functional/functional/rpc_signmessage.py +++ b/test/bitcoin_functional/functional/rpc_signmessage.py @@ -13,6 +13,9 @@ class SignMessagesTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [["-addresstype=legacy"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): message = 'This is just a test message' diff --git a/test/bitcoin_functional/functional/rpc_signrawtransaction.py b/test/bitcoin_functional/functional/rpc_signrawtransaction.py index 32b099294f..5c07f2ccae 100755 --- a/test/bitcoin_functional/functional/rpc_signrawtransaction.py +++ b/test/bitcoin_functional/functional/rpc_signrawtransaction.py @@ -14,6 +14,9 @@ class SignRawTransactionsTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [["-deprecatedrpc=signrawtransaction"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def successful_signing_test(self): """Create and sign a valid raw transaction with one input. @@ -42,10 +45,6 @@ class SignRawTransactionsTest(BitcoinTestFramework): # 2) No script verification error occurred assert 'errors' not in rawTxSigned - # Perform the same test on signrawtransaction - rawTxSigned2 = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys) - assert_equal(rawTxSigned, rawTxSigned2) - def script_verification_error_test(self): """Create and sign a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script. @@ -112,10 +111,6 @@ class SignRawTransactionsTest(BitcoinTestFramework): assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout']) assert not rawTxSigned['errors'][0]['witness'] - # Perform same test with signrawtransaction - rawTxSigned2 = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys) - assert_equal(rawTxSigned, rawTxSigned2) - # Now test signing failure for transaction with input witnesses p2wpkh_raw_tx = "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000" @@ -140,10 +135,6 @@ class SignRawTransactionsTest(BitcoinTestFramework): assert_equal(rawTxSigned['errors'][1]['witness'], ["304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01", "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357"]) assert not rawTxSigned['errors'][0]['witness'] - # Perform same test with signrawtransaction - rawTxSigned2 = self.nodes[0].signrawtransaction(p2wpkh_raw_tx) - assert_equal(rawTxSigned, rawTxSigned2) - def run_test(self): self.successful_signing_test() self.script_verification_error_test() diff --git a/test/bitcoin_functional/functional/rpc_txoutproof.py b/test/bitcoin_functional/functional/rpc_txoutproof.py index f9f8574646..867ba25022 100755 --- a/test/bitcoin_functional/functional/rpc_txoutproof.py +++ b/test/bitcoin_functional/functional/rpc_txoutproof.py @@ -15,6 +15,9 @@ class MerkleBlockTest(BitcoinTestFramework): # Nodes 0/1 are "wallet" nodes, Nodes 2/3 are used for testing self.extra_args = [[], [], [], ["-txindex"]] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() connect_nodes(self.nodes[0], 1) diff --git a/test/bitcoin_functional/functional/rpc_zmq.py b/test/bitcoin_functional/functional/rpc_zmq.py index 6dbc726d5e..bfa6b06f67 100755 --- a/test/bitcoin_functional/functional/rpc_zmq.py +++ b/test/bitcoin_functional/functional/rpc_zmq.py @@ -4,8 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test for the ZMQ RPC methods.""" -from test_framework.test_framework import ( - BitcoinTestFramework, skip_if_no_py3_zmq, skip_if_no_bitcoind_zmq) +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -17,9 +16,11 @@ class RPCZMQTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_py3_zmq() + self.skip_if_no_bitcoind_zmq() + def run_test(self): - skip_if_no_py3_zmq() - skip_if_no_bitcoind_zmq(self) self._test_getzmqnotifications() def _test_getzmqnotifications(self): diff --git a/test/bitcoin_functional/functional/test_framework/blocktools.py b/test/bitcoin_functional/functional/test_framework/blocktools.py index 987ade4044..35004fb588 100644 --- a/test/bitcoin_functional/functional/test_framework/blocktools.py +++ b/test/bitcoin_functional/functional/test_framework/blocktools.py @@ -122,7 +122,7 @@ def create_tx_with_script(prevtx, n, script_sig=b"", *, amount, script_pub_key=C """Return one-input, one-output transaction object spending the prevtx's n-th output with the given amount. - Can optionally pass scriptPubKey and scriptSig, default is anyone-can-spend ouput. + Can optionally pass scriptPubKey and scriptSig, default is anyone-can-spend output. """ tx = CTransaction() assert(n < len(prevtx.vout)) diff --git a/test/bitcoin_functional/functional/test_framework/messages.py b/test/bitcoin_functional/functional/test_framework/messages.py index 7276f6b450..0a3907cba4 100755 --- a/test/bitcoin_functional/functional/test_framework/messages.py +++ b/test/bitcoin_functional/functional/test_framework/messages.py @@ -904,28 +904,17 @@ class msg_version(): def deserialize(self, f): self.nVersion = struct.unpack("= 106: - self.addrFrom = CAddress() - self.addrFrom.deserialize(f, False) - self.nNonce = struct.unpack("= 209: - self.nStartingHeight = struct.unpack("= 70001: # Relay field is optional for version 70001 onwards diff --git a/test/bitcoin_functional/functional/test_framework/mininode.py b/test/bitcoin_functional/functional/test_framework/mininode.py index d1ddbbe8ee..f8caa57250 100755 --- a/test/bitcoin_functional/functional/test_framework/mininode.py +++ b/test/bitcoin_functional/functional/test_framework/mininode.py @@ -425,8 +425,6 @@ class P2PDataStore(P2PInterface): def __init__(self): super().__init__() - self.reject_code_received = None - self.reject_reason_received = None # store of blocks. key is block hash, value is a CBlock object self.block_store = {} self.last_block_hash = '' @@ -477,12 +475,7 @@ class P2PDataStore(P2PInterface): if response is not None: self.send_message(response) - def on_reject(self, message): - """Store reject reason and code for testing.""" - self.reject_code_received = message.code - self.reject_reason_received = message.reason - - def send_blocks_and_test(self, blocks, rpc, success=True, request_block=True, reject_code=None, reject_reason=None, timeout=60): + def send_blocks_and_test(self, blocks, node, *, success=True, request_block=True, reject_reason=None, expect_disconnect=False, timeout=60): """Send blocks to test node and test whether the tip advances. - add all blocks to our block_store @@ -492,66 +485,59 @@ class P2PDataStore(P2PInterface): ensure that any getdata messages are responded to - if success is True: assert that the node's tip advances to the most recent block - if success is False: assert that the node's tip doesn't advance - - if reject_code and reject_reason are set: assert that the correct reject message is received""" + - if reject_reason is set: assert that the correct reject message is logged""" with mininode_lock: - self.reject_code_received = None - self.reject_reason_received = None - for block in blocks: self.block_store[block.sha256] = block self.last_block_hash = block.sha256 - self.send_message(msg_headers([CBlockHeader(blocks[-1])])) + reject_reason = [reject_reason] if reject_reason else [] + with node.assert_debug_log(expected_msgs=reject_reason): + self.send_message(msg_headers([CBlockHeader(blocks[-1])])) - if request_block: - wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock) + if request_block: + wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock) - if success: - wait_until(lambda: rpc.getbestblockhash() == blocks[-1].hash, timeout=timeout) - else: - assert rpc.getbestblockhash() != blocks[-1].hash + if expect_disconnect: + self.wait_for_disconnect() + else: + self.sync_with_ping() - if reject_code is not None: - wait_until(lambda: self.reject_code_received == reject_code, lock=mininode_lock) - if reject_reason is not None: - wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock) + if success: + wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout) + else: + assert node.getbestblockhash() != blocks[-1].hash - def send_txs_and_test(self, txs, rpc, success=True, expect_disconnect=False, reject_code=None, reject_reason=None): + def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None): """Send txs to test node and test whether they're accepted to the mempool. - add all txs to our tx_store - send tx messages for all txs - if success is True/False: assert that the txs are/are not accepted to the mempool - if expect_disconnect is True: Skip the sync with ping - - if reject_code and reject_reason are set: assert that the correct reject message is received.""" + - if reject_reason is set: assert that the correct reject message is logged.""" with mininode_lock: - self.reject_code_received = None - self.reject_reason_received = None - for tx in txs: self.tx_store[tx.sha256] = tx - for tx in txs: - self.send_message(msg_tx(tx)) - - if expect_disconnect: - self.wait_for_disconnect() - else: - self.sync_with_ping() - - raw_mempool = rpc.getrawmempool() - if success: - # Check that all txs are now in the mempool + reject_reason = [reject_reason] if reject_reason else [] + with node.assert_debug_log(expected_msgs=reject_reason): for tx in txs: - assert tx.hash in raw_mempool, "{} not found in mempool".format(tx.hash) - else: - # Check that none of the txs are now in the mempool - for tx in txs: - assert tx.hash not in raw_mempool, "{} tx found in mempool".format(tx.hash) + self.send_message(msg_tx(tx)) - if reject_code is not None: - wait_until(lambda: self.reject_code_received == reject_code, lock=mininode_lock) - if reject_reason is not None: - wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock) + if expect_disconnect: + self.wait_for_disconnect() + else: + self.sync_with_ping() + + raw_mempool = node.getrawmempool() + if success: + # Check that all txs are now in the mempool + for tx in txs: + assert tx.hash in raw_mempool, "{} not found in mempool".format(tx.hash) + else: + # Check that none of the txs are now in the mempool + for tx in txs: + assert tx.hash not in raw_mempool, "{} tx found in mempool".format(tx.hash) diff --git a/test/bitcoin_functional/functional/test_framework/test_framework.py b/test/bitcoin_functional/functional/test_framework/test_framework.py index 976b8f84e8..57c985b2a2 100755 --- a/test/bitcoin_functional/functional/test_framework/test_framework.py +++ b/test/bitcoin_functional/functional/test_framework/test_framework.py @@ -44,6 +44,13 @@ TEST_EXIT_FAILED = 1 TEST_EXIT_SKIPPED = 77 +class SkipTest(Exception): + """This exception is raised to skip a test""" + + def __init__(self, message): + self.message = message + + class BitcoinTestMetaClass(type): """Metaclass for BitcoinTestFramework. @@ -82,7 +89,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): def __init__(self): """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method""" - self.chain = 'regtest2' self.setup_clean_chain = False self.nodes = [] self.network_thread = None @@ -114,7 +120,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): parser.add_argument("--coveragedir", dest="coveragedir", help="Write tested RPC commands into this directory") parser.add_argument("--configfile", dest="configfile", - default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../../config.ini"), + default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../config.ini"), help="Location of the test framework config file (default: %(default)s)") parser.add_argument("--pdbonfailure", dest="pdbonfailure", default=False, action="store_true", help="Attach a python debugger if test fails") @@ -157,8 +163,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): try: if self.options.usecli and not self.supports_cli: raise SkipTest("--usecli specified but test does not support using CLI") + self.skip_test_if_missing_module() self.setup_chain() self.setup_network() + self.import_deterministic_coinbase_privkeys() self.run_test() success = TestStatus.PASSED except JSONRPCException as e: @@ -221,6 +229,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): """Override this method to add command-line options to the test""" pass + def skip_test_if_missing_module(self): + """Override this method to skip a test if a module is not compiled""" + pass + def setup_chain(self): """Override this method to customize blockchain setup""" self.log.info("Initializing test directory " + self.options.tmpdir) @@ -248,6 +260,19 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): 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 @@ -268,7 +293,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): assert_equal(len(extra_args), num_nodes) assert_equal(len(binary), num_nodes) for i in range(num_nodes): - self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), self.chain, rpchost=rpchost, timewait=self.rpc_timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli)) + self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=self.rpc_timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli)) def start_node(self, i, *args, **kwargs): """Start a bitcoind""" @@ -415,11 +440,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): # Create cache directories, run bitcoinds: for i in range(MAX_NODES): - datadir = initialize_datadir(self.options.cachedir, i, self.chain) - args = [self.options.bitcoind, "-datadir=" + datadir] + datadir = initialize_datadir(self.options.cachedir, i) + 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), self.chain, 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)) + 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)) self.nodes[i].args = args self.start_node(i) @@ -440,7 +465,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): 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) @@ -451,18 +476,19 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): self.disable_mocktime() def cache_path(n, *paths): - return os.path.join(get_datadir_path(self.options.cachedir, n), self.chain, *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): from_dir = get_datadir_path(self.options.cachedir, i) to_dir = get_datadir_path(self.options.tmpdir, i) shutil.copytree(from_dir, to_dir) - initialize_datadir(self.options.tmpdir, i, self.chain) # Overwrite port/rpcport in bitcoin.conf + initialize_datadir(self.options.tmpdir, i) # Overwrite port/rpcport in bitcoin.conf def _initialize_chain_clean(self): """Initialize empty blockchain for use by the test. @@ -470,27 +496,47 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): Create an empty blockchain and num_nodes wallets. Useful if a test case wants complete control over initialization.""" for i in range(self.num_nodes): - initialize_datadir(self.options.tmpdir, i, self.chain) + initialize_datadir(self.options.tmpdir, i) + def skip_if_no_py3_zmq(self): + """Attempt to import the zmq package and skip the test if the import fails.""" + try: + import zmq # noqa + except ImportError: + raise SkipTest("python3-zmq module not available.") -class SkipTest(Exception): - """This exception is raised to skip a test""" - def __init__(self, message): - self.message = message + def skip_if_no_bitcoind_zmq(self): + """Skip the running test if bitcoind has not been compiled with zmq support.""" + if not self.is_zmq_compiled(): + raise SkipTest("bitcoind has not been built with zmq enabled.") + def skip_if_no_wallet(self): + """Skip the running test if wallet has not been compiled.""" + if not self.is_wallet_compiled(): + raise SkipTest("wallet has not been compiled.") -def skip_if_no_py3_zmq(): - """Attempt to import the zmq package and skip the test if the import fails.""" - try: - import zmq # noqa - except ImportError: - raise SkipTest("python3-zmq module not available.") + def skip_if_no_cli(self): + """Skip the running test if bitcoin-cli has not been compiled.""" + if not self.is_cli_compiled(): + raise SkipTest("bitcoin-cli has not been compiled.") + def is_cli_compiled(self): + """Checks whether bitcoin-cli was compiled.""" + config = configparser.ConfigParser() + config.read_file(open(self.options.configfile)) -def skip_if_no_bitcoind_zmq(test_instance): - """Skip the running test if bitcoind has not been compiled with zmq support.""" - config = configparser.ConfigParser() - config.read_file(open(test_instance.options.configfile)) + return config["components"].getboolean("ENABLE_UTILS") - if not config["components"].getboolean("ENABLE_ZMQ"): - raise SkipTest("bitcoind has not been built with zmq enabled.") + def is_wallet_compiled(self): + """Checks whether the wallet module was compiled.""" + config = configparser.ConfigParser() + config.read_file(open(self.options.configfile)) + + return config["components"].getboolean("ENABLE_WALLET") + + def is_zmq_compiled(self): + """Checks whether the zmq module was compiled.""" + config = configparser.ConfigParser() + config.read_file(open(self.options.configfile)) + + return config["components"].getboolean("ENABLE_ZMQ") diff --git a/test/bitcoin_functional/functional/test_framework/test_node.py b/test/bitcoin_functional/functional/test_framework/test_node.py index d400a50bd2..c267f7f24f 100755 --- a/test/bitcoin_functional/functional/test_framework/test_node.py +++ b/test/bitcoin_functional/functional/test_framework/test_node.py @@ -4,6 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Class for bitcoind node under test""" +import contextlib import decimal import errno from enum import Enum @@ -57,12 +58,11 @@ class TestNode(): To make things easier for the test writer, any unrecognised messages will be dispatched to the RPC connection.""" - def __init__(self, i, datadir, chain, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False): + def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False): self.index = i self.datadir = datadir self.stdout_dir = os.path.join(self.datadir, "stdout") self.stderr_dir = os.path.join(self.datadir, "stderr") - self.chain = chain self.rpchost = rpchost self.rpc_timeout = timewait self.binary = bitcoind @@ -84,7 +84,7 @@ class TestNode(): "-uacomment=testnode%d" % i ] - self.cli = TestNodeCLI(bitcoin_cli, self.datadir, self.chain) + self.cli = TestNodeCLI(bitcoin_cli, self.datadir) self.use_cli = use_cli self.running = False @@ -97,6 +97,22 @@ class TestNode(): 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 %d] %s" % (self.index, msg) @@ -139,7 +155,7 @@ class TestNode(): # Delete any existing cookie file -- if such a file exists (eg due to # unclean shutdown), it will get overwritten anyway by bitcoind, and # potentially interfere with our attempt to authenticate - delete_cookie_file(self.datadir, self.chain) + delete_cookie_file(self.datadir) # add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1") @@ -158,7 +174,7 @@ class TestNode(): raise FailedToStartError(self._node_msg( 'bitcoind exited with status {} during initialization'.format(self.process.returncode))) try: - self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.chain, self.rpchost), self.index, timeout=self.rpc_timeout, coveragedir=self.coverage_dir) + self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.rpchost), self.index, timeout=self.rpc_timeout, coveragedir=self.coverage_dir) self.rpc.getblockcount() # If the call to getblockcount() succeeds then the RPC connection is up self.rpc_connected = True @@ -230,6 +246,23 @@ class TestNode(): def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): wait_until(self.is_node_stopped, timeout=timeout) + @contextlib.contextmanager + def assert_debug_log(self, expected_msgs): + debug_log = os.path.join(self.datadir, 'regtest', 'debug.log') + with open(debug_log, encoding='utf-8') as dl: + dl.seek(0, 2) + prev_size = dl.tell() + try: + yield + finally: + with open(debug_log, encoding='utf-8') as dl: + dl.seek(prev_size) + log = dl.read() + print_log = " - " + "\n - ".join(log.splitlines()) + for expected_msg in expected_msgs: + if re.search(re.escape(expected_msg), log, flags=re.MULTILINE) is None: + self._raise_assertion_error('Expected message "{}" does not partially match log:\n\n{}\n\n'.format(expected_msg, print_log)) + def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, match=ErrorMatch.FULL_TEXT, *args, **kwargs): """Attempt to start the node and expect it to raise an error. @@ -272,14 +305,6 @@ class TestNode(): assert_msg = "bitcoind should have exited with expected error " + expected_msg self._raise_assertion_error(assert_msg) - def node_encrypt_wallet(self, passphrase): - """"Encrypts the wallet. - - This causes bitcoind to shutdown, so this method takes - care of cleaning up resources.""" - self.encryptwallet(passphrase) - self.wait_until_stopped() - def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs): """Add a p2p connection to the node. @@ -326,17 +351,16 @@ class TestNodeCLIAttr: class TestNodeCLI(): """Interface to bitcoin-cli for an individual node""" - def __init__(self, binary, datadir, chain): + def __init__(self, binary, datadir): self.options = [] self.binary = binary self.datadir = datadir - self.chain = chain self.input = None self.log = logging.getLogger('TestFramework.bitcoincli') def __call__(self, *options, input=None): # TestNodeCLI is callable with bitcoin-cli command-line options - cli = TestNodeCLI(self.binary, self.datadir, self.chain) + cli = TestNodeCLI(self.binary, self.datadir) cli.options = [str(o) for o in options] cli.input = input return cli @@ -358,7 +382,7 @@ class TestNodeCLI(): pos_args = [str(arg).lower() if type(arg) is bool else str(arg) for arg in args] named_args = [str(key) + "=" + str(value) for (key, value) in kwargs.items()] assert not (pos_args and named_args), "Cannot use positional arguments and named arguments in the same bitcoin-cli call" - p_args = [self.binary, "-datadir=" + self.datadir, "-chain=" + self.chain] + self.options + p_args = [self.binary, "-datadir=" + self.datadir] + self.options if named_args: p_args += ["-named"] if command is not None: diff --git a/test/bitcoin_functional/functional/test_framework/util.py b/test/bitcoin_functional/functional/test_framework/util.py index a27a407c88..b355816d8b 100644 --- a/test/bitcoin_functional/functional/test_framework/util.py +++ b/test/bitcoin_functional/functional/test_framework/util.py @@ -273,8 +273,8 @@ def p2p_port(n): def rpc_port(n): return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) -def rpc_url(datadir, i, chain, rpchost=None): - rpc_u, rpc_p = get_auth_cookie(datadir, chain) +def rpc_url(datadir, i, rpchost=None): + rpc_u, rpc_p = get_auth_cookie(datadir) host = '127.0.0.1' port = rpc_port(i) if rpchost: @@ -288,16 +288,13 @@ def rpc_url(datadir, i, chain, rpchost=None): # Node functions ################ -def get_datadir_path(dirname, n): - return os.path.join(dirname, "node" + str(n)) - -def initialize_datadir(dirname, n, chain): +def initialize_datadir(dirname, n): datadir = get_datadir_path(dirname, n) if not os.path.isdir(datadir): os.makedirs(datadir) with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f: - f.write("chain=%s\n" % chain) - f.write("[%s]\n" % chain) + f.write("regtest=1\n") + f.write("[regtest]\n") f.write("port=" + str(p2p_port(n)) + "\n") f.write("rpcport=" + str(rpc_port(n)) + "\n") f.write("server=1\n") @@ -305,28 +302,19 @@ def initialize_datadir(dirname, n, chain): f.write("discover=0\n") f.write("listenonion=0\n") f.write("printtoconsole=0\n") - # Elements: - f.write("con_blocksubsidy=5000000000\n") - f.write("con_connect_coinbase=0\n") - f.write("anyonecanspendaremine=0\n") - f.write("con_blockheightinheader=0\n") - f.write("con_signed_blocks=0\n") - f.write("multi_data_permitted=0\n") - f.write("walletrbf=0\n") # Default is 1 in Elements - f.write("con_bip34height=100000000\n") - f.write("con_bip65height=1351\n") - f.write("con_bip66height=1251\n") - f.write("con_genesis_style=bitcoin\n") os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True) os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True) return datadir +def get_datadir_path(dirname, n): + return os.path.join(dirname, "node" + str(n)) + def append_config(datadir, options): with open(os.path.join(datadir, "bitcoin.conf"), 'a', encoding='utf8') as f: for option in options: f.write(option + "\n") -def get_auth_cookie(datadir, chain): +def get_auth_cookie(datadir): user = None password = None if os.path.isfile(os.path.join(datadir, "bitcoin.conf")): @@ -338,8 +326,8 @@ def get_auth_cookie(datadir, chain): if line.startswith("rpcpassword="): assert password is None # Ensure that there is only one rpcpassword line password = line.split("=")[1].strip("\n") - if os.path.isfile(os.path.join(datadir, chain, ".cookie")): - with open(os.path.join(datadir, chain, ".cookie"), 'r', encoding="ascii") as f: + if os.path.isfile(os.path.join(datadir, "regtest", ".cookie")): + with open(os.path.join(datadir, "regtest", ".cookie"), 'r', encoding="ascii") as f: userpass = f.read() split_userpass = userpass.split(':') user = split_userpass[0] @@ -349,10 +337,10 @@ def get_auth_cookie(datadir, chain): return user, password # If a cookie file exists in the given datadir, delete it. -def delete_cookie_file(datadir, chain): - if os.path.isfile(os.path.join(datadir, chain, ".cookie")): +def delete_cookie_file(datadir): + if os.path.isfile(os.path.join(datadir, "regtest", ".cookie")): logger.debug("Deleting leftover cookie file") - os.remove(os.path.join(datadir, chain, ".cookie")) + os.remove(os.path.join(datadir, "regtest", ".cookie")) def get_bip9_status(node, key): info = node.getblockchaininfo() diff --git a/test/bitcoin_functional/functional/test_runner.py b/test/bitcoin_functional/functional/test_runner.py index e7b61ddb4a..37a3c1c602 100755 --- a/test/bitcoin_functional/functional/test_runner.py +++ b/test/bitcoin_functional/functional/test_runner.py @@ -58,9 +58,12 @@ TRAVIS_TIMEOUT_DURATION = 20 * 60 BASE_SCRIPTS = [ # Scripts that are run by the travis build process. # Longest test should go first, to favor running tests in parallel + 'feature_fee_estimation.py', 'wallet_hd.py', 'wallet_backup.py', # vv Tests less than 5m vv + 'mining_getblocktemplate_longpoll.py', + 'feature_maxuploadtarget.py', 'feature_block.py', 'rpc_fundrawtransaction.py', 'p2p_compactblocks.py', @@ -69,6 +72,7 @@ BASE_SCRIPTS = [ 'wallet_basic.py', 'wallet_labels.py', 'p2p_segwit.py', + 'p2p_timeouts.py', 'wallet_dump.py', 'wallet_listtransactions.py', # vv Tests less than 60s vv @@ -82,6 +86,8 @@ BASE_SCRIPTS = [ 'feature_csv_activation.py', 'rpc_rawtransaction.py', 'wallet_address_types.py', + 'feature_bip68_sequence.py', + 'p2p_feefilter.py', 'feature_reindex.py', # vv Tests less than 30s vv 'wallet_keypool_topup.py', @@ -118,6 +124,14 @@ BASE_SCRIPTS = [ 'p2p_invalid_locator.py', 'p2p_invalid_block.py', 'p2p_invalid_tx.py', + 'feature_assumevalid.py', + 'example_test.py', + 'wallet_txn_doublespend.py', + 'wallet_txn_clone.py --mineblock', + 'feature_notifications.py', + 'rpc_invalidateblock.py', + 'feature_rbf.py', + 'mempool_packages.py', 'rpc_createmultisig.py', 'feature_versionbits_warning.py', 'rpc_preciousblock.py', @@ -152,6 +166,7 @@ BASE_SCRIPTS = [ 'p2p_node_network_limited.py', 'feature_blocksdir.py', 'feature_config_args.py', + 'rpc_help.py', 'feature_help.py', # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time @@ -161,26 +176,7 @@ EXTENDED_SCRIPTS = [ # These tests are not run by the travis build process. # Longest test should go first, to favor running tests in parallel 'feature_pruning.py', - # vv Tests less than 20m vv - 'feature_fee_estimation.py', - # vv Tests less than 5m vv - 'feature_maxuploadtarget.py', - 'mempool_packages.py', 'feature_dbcrash.py', - # vv Tests less than 2m vv - 'feature_bip68_sequence.py', - 'mining_getblocktemplate_longpoll.py', - 'p2p_timeouts.py', - # vv Tests less than 60s vv - 'p2p_feefilter.py', - # vv Tests less than 30s vv - 'feature_assumevalid.py', - 'example_test.py', - 'wallet_txn_doublespend.py', - 'wallet_txn_clone.py --mineblock', - 'feature_notifications.py', - 'rpc_invalidateblock.py', - 'feature_rbf.py', ] # Place EXTENDED_SCRIPTS first since it has the 3 longest running tests @@ -220,7 +216,7 @@ def main(): # Read config generated by configure. config = configparser.ConfigParser() - configfile = os.path.abspath(os.path.dirname(__file__)) + "/../../config.ini" + configfile = os.path.abspath(os.path.dirname(__file__)) + "/../config.ini" config.read_file(open(configfile, encoding="utf8")) passon_args.append("--configfile=%s" % configfile) @@ -235,8 +231,6 @@ def main(): logging.debug("Temporary test directory at %s" % tmpdir) - enable_wallet = config["components"].getboolean("ENABLE_WALLET") - enable_utils = config["components"].getboolean("ENABLE_UTILS") enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") if config["environment"]["EXEEXT"] == ".exe" and not args.force: @@ -245,9 +239,9 @@ def main(): print("Tests currently disabled on Windows by default. Use --force option to enable") sys.exit(0) - if not (enable_wallet and enable_utils and enable_bitcoind): - print("No functional tests to run. Wallet, utils, and bitcoind must all be enabled") - print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + if not enable_bitcoind: + print("No functional tests to run.") + print("Rerun ./configure with --with-daemon and then make") sys.exit(0) # Build list of tests @@ -285,7 +279,7 @@ def main(): if args.help: # Print help for test_runner.py, then print help of the first script (with args removed) and exit. parser.print_help() - subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'bitcoin_functional', 'functional', test_list[0].split()[0]), '-h']) + subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'functional', test_list[0].split()[0]), '-h']) sys.exit(0) check_script_list(config["environment"]["SRCDIR"]) @@ -321,7 +315,7 @@ def run_tests(test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=Fal if os.path.isdir(cache_dir): print("%sWARNING!%s There is a cache directory here: %s. If tests fail unexpectedly, try deleting the cache directory." % (BOLD[1], BOLD[0], cache_dir)) - tests_dir = src_dir + '/test/bitcoin_functional/functional/' + tests_dir = src_dir + '/test/functional/' flags = ['--cachedir={}'.format(cache_dir)] + args @@ -537,7 +531,7 @@ def check_script_list(src_dir): Check that there are no scripts in the functional tests directory which are not being run by pull-tester.py.""" - script_dir = src_dir + '/test/bitcoin_functional/functional/' + script_dir = src_dir + '/test/functional/' python_files = set([test_file for test_file in os.listdir(script_dir) if test_file.endswith(".py")]) missed_tests = list(python_files - set(map(lambda x: x.split()[0], ALL_SCRIPTS + NON_SCRIPTS))) if len(missed_tests) != 0: diff --git a/test/bitcoin_functional/functional/wallet_abandonconflict.py b/test/bitcoin_functional/functional/wallet_abandonconflict.py index 8a57b55ca9..e5ac2c8bd4 100755 --- a/test/bitcoin_functional/functional/wallet_abandonconflict.py +++ b/test/bitcoin_functional/functional/wallet_abandonconflict.py @@ -20,6 +20,9 @@ class AbandonConflictTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [["-minrelaytxfee=0.00001"], []] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.nodes[1].generate(100) sync_blocks(self.nodes) diff --git a/test/bitcoin_functional/functional/wallet_address_types.py b/test/bitcoin_functional/functional/wallet_address_types.py index 01c7b6366a..0f75045c9d 100755 --- a/test/bitcoin_functional/functional/wallet_address_types.py +++ b/test/bitcoin_functional/functional/wallet_address_types.py @@ -63,6 +63,7 @@ from test_framework.util import ( sync_mempools, ) + class AddressTypeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 6 @@ -72,9 +73,12 @@ class AddressTypeTest(BitcoinTestFramework): ["-addresstype=p2sh-segwit", "-changetype=bech32"], ["-addresstype=bech32"], ["-changetype=p2sh-segwit"], - [] + [], ] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() @@ -143,7 +147,7 @@ class AddressTypeTest(BitcoinTestFramework): assert(False) def test_change_output_type(self, node_sender, destinations, expected_type): - txid = self.nodes[node_sender].sendmany(fromaccount="", amounts=dict.fromkeys(destinations, 0.001)) + txid = self.nodes[node_sender].sendmany(dummy="", amounts=dict.fromkeys(destinations, 0.001)) raw_tx = self.nodes[node_sender].getrawtransaction(txid) tx = self.nodes[node_sender].decoderawtransaction(raw_tx) diff --git a/test/bitcoin_functional/functional/wallet_backup.py b/test/bitcoin_functional/functional/wallet_backup.py index 5d3366f238..32ec385fa1 100755 --- a/test/bitcoin_functional/functional/wallet_backup.py +++ b/test/bitcoin_functional/functional/wallet_backup.py @@ -45,6 +45,9 @@ class WalletBackupTest(BitcoinTestFramework): # nodes 1, 2,3 are spenders, let's give them a keypool=100 self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self, split=False): self.setup_nodes() connect_nodes(self.nodes[0], 3) @@ -92,9 +95,9 @@ class WalletBackupTest(BitcoinTestFramework): self.stop_node(2) def erase_three(self): - os.remove(os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat')) - os.remove(os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat')) - os.remove(os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat')) def run_test(self): self.log.info("Generating initial blockchain") @@ -152,13 +155,13 @@ class WalletBackupTest(BitcoinTestFramework): self.erase_three() # Start node2 with no chain - shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks')) - shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate')) # Restore wallets from backup - shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat')) - shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat')) - shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat')) self.log.info("Re-starting nodes") self.start_three() @@ -173,8 +176,8 @@ class WalletBackupTest(BitcoinTestFramework): self.erase_three() #start node2 with no chain - shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks')) - shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate')) self.start_three() @@ -194,10 +197,10 @@ class WalletBackupTest(BitcoinTestFramework): # Backup to source wallet file must fail sourcePaths = [ - os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat'), - os.path.join(self.nodes[0].datadir, self.chain, '.', 'wallets', 'wallet.dat'), - os.path.join(self.nodes[0].datadir, self.chain, 'wallets', ''), - os.path.join(self.nodes[0].datadir, self.chain, 'wallets')] + os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat'), + os.path.join(self.nodes[0].datadir, 'regtest', '.', 'wallets', 'wallet.dat'), + os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', ''), + os.path.join(self.nodes[0].datadir, 'regtest', 'wallets')] for sourcePath in sourcePaths: assert_raises_rpc_error(-4, "backup failed", self.nodes[0].backupwallet, sourcePath) diff --git a/test/bitcoin_functional/functional/wallet_basic.py b/test/bitcoin_functional/functional/wallet_basic.py index ea0346543a..4079d05491 100755 --- a/test/bitcoin_functional/functional/wallet_basic.py +++ b/test/bitcoin_functional/functional/wallet_basic.py @@ -23,6 +23,9 @@ class WalletTest(BitcoinTestFramework): self.num_nodes = 4 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.add_nodes(4) self.start_node(0) diff --git a/test/bitcoin_functional/functional/wallet_bumpfee.py b/test/bitcoin_functional/functional/wallet_bumpfee.py index dd95bb5e22..67ee00871d 100755 --- a/test/bitcoin_functional/functional/wallet_bumpfee.py +++ b/test/bitcoin_functional/functional/wallet_bumpfee.py @@ -31,13 +31,18 @@ class BumpFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [["-deprecatedrpc=addwitnessaddress", "-walletrbf={}".format(i)] - for i in range(self.num_nodes)] + self.extra_args = [[ + "-deprecatedrpc=addwitnessaddress", + "-walletrbf={}".format(i), + "-mintxfee=0.00002", + ] for i in range(self.num_nodes)] + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() def run_test(self): # Encrypt wallet for test_locked_wallet_fails test - self.nodes[1].node_encrypt_wallet(WALLET_PASSPHRASE) - self.start_node(1) + self.nodes[1].encryptwallet(WALLET_PASSPHRASE) self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) connect_nodes_bi(self.nodes, 0, 1) @@ -190,6 +195,8 @@ def test_dust_to_fee(rbf_node, dest_address): def test_settxfee(rbf_node, dest_address): + assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.000005')) + assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015')) # check that bumpfee reacts correctly to the use of settxfee (paytxfee) rbfid = spend_one_input(rbf_node, dest_address) requested_feerate = Decimal("0.00025000") diff --git a/test/bitcoin_functional/functional/wallet_disableprivatekeys.py b/test/bitcoin_functional/functional/wallet_disableprivatekeys.py index 0ba2cfe9be..34ff525255 100755 --- a/test/bitcoin_functional/functional/wallet_disableprivatekeys.py +++ b/test/bitcoin_functional/functional/wallet_disableprivatekeys.py @@ -17,6 +17,9 @@ class DisablePrivateKeysTest(BitcoinTestFramework): self.num_nodes = 1 self.supports_cli = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node = self.nodes[0] self.log.info("Test disableprivatekeys creation.") diff --git a/test/bitcoin_functional/functional/wallet_dump.py b/test/bitcoin_functional/functional/wallet_dump.py index 63316d9644..b1db1e4ab9 100755 --- a/test/bitcoin_functional/functional/wallet_dump.py +++ b/test/bitcoin_functional/functional/wallet_dump.py @@ -29,50 +29,58 @@ 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] + + imported_key = date == '1970-01-01T00:00:01Z' + if imported_key: + # Imported keys have multiple addresses, no label (keypath) and timestamp + # Skip them + 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] + 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 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 + # 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 @@ -83,6 +91,9 @@ class WalletDumpTest(BitcoinTestFramework): self.extra_args = [["-keypool=90", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]] self.rpc_timeout = 120 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self, split=False): self.add_nodes(self.num_nodes, extra_args=self.extra_args) self.start_nodes() @@ -116,13 +127,12 @@ class WalletDumpTest(BitcoinTestFramework): 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') - self.start_node(0) + self.nodes[0].encryptwallet('test') self.nodes[0].walletpassphrase('test', 10) # Should be a no-op: self.nodes[0].keypoolrefill() @@ -132,8 +142,8 @@ class WalletDumpTest(BitcoinTestFramework): 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/bitcoin_functional/functional/wallet_encryption.py b/test/bitcoin_functional/functional/wallet_encryption.py index cec9660259..ab9ebed8d4 100755 --- a/test/bitcoin_functional/functional/wallet_encryption.py +++ b/test/bitcoin_functional/functional/wallet_encryption.py @@ -19,6 +19,9 @@ class WalletEncryptionTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): passphrase = "WalletPassphrase" passphrase2 = "SecondWalletPassphrase" @@ -30,8 +33,7 @@ class WalletEncryptionTest(BitcoinTestFramework): assert_equal(len(privkey), 52) # Encrypt the wallet - self.nodes[0].node_encrypt_wallet(passphrase) - self.start_node(0) + self.nodes[0].encryptwallet(passphrase) # Test that the wallet is encrypted assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].dumpprivkey, address) diff --git a/test/bitcoin_functional/functional/wallet_fallbackfee.py b/test/bitcoin_functional/functional/wallet_fallbackfee.py index 91dbae8939..0c67982bbe 100755 --- a/test/bitcoin_functional/functional/wallet_fallbackfee.py +++ b/test/bitcoin_functional/functional/wallet_fallbackfee.py @@ -11,6 +11,9 @@ class WalletRBFTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.nodes[0].generate(101) diff --git a/test/bitcoin_functional/functional/wallet_groups.py b/test/bitcoin_functional/functional/wallet_groups.py index 12dac145bd..9d61483868 100755 --- a/test/bitcoin_functional/functional/wallet_groups.py +++ b/test/bitcoin_functional/functional/wallet_groups.py @@ -23,7 +23,10 @@ class WalletGroupTest(BitcoinTestFramework): self.extra_args = [[], [], ['-avoidpartialspends']] self.rpc_timewait = 120 - def run_test (self): + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def run_test(self): # Mine some coins self.nodes[0].generate(110) diff --git a/test/bitcoin_functional/functional/wallet_hd.py b/test/bitcoin_functional/functional/wallet_hd.py index 9a03cc3d17..48e71f6c40 100755 --- a/test/bitcoin_functional/functional/wallet_hd.py +++ b/test/bitcoin_functional/functional/wallet_hd.py @@ -21,6 +21,9 @@ class WalletHDTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [[], ['-keypool=0']] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Make sure can't switch off usehd after wallet creation self.stop_node(1) @@ -72,11 +75,11 @@ class WalletHDTest(BitcoinTestFramework): self.log.info("Restore backup ...") self.stop_node(1) - # we need to delete the complete chain directory + # 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, self.chain, "blocks")) - shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate")) - shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) + 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 @@ -98,9 +101,9 @@ class WalletHDTest(BitcoinTestFramework): # Try a RPC based rescan self.stop_node(1) - shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "blocks")) - shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate")) - shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) + 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, 1) self.sync_all() diff --git a/test/bitcoin_functional/functional/wallet_import_rescan.py b/test/bitcoin_functional/functional/wallet_import_rescan.py index 0c6359976a..f043a544fc 100755 --- a/test/bitcoin_functional/functional/wallet_import_rescan.py +++ b/test/bitcoin_functional/functional/wallet_import_rescan.py @@ -26,7 +26,7 @@ import collections import enum import itertools -Call = enum.Enum("Call", "single multi") +Call = enum.Enum("Call", "single multiaddress multiscript") Data = enum.Enum("Data", "address pub priv") Rescan = enum.Enum("Rescan", "no yes late_timestamp") @@ -53,11 +53,11 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")): response = self.try_rpc(self.node.importprivkey, privkey=self.key, rescan=rescan) assert_equal(response, None) - elif self.call == Call.multi: + elif self.call in (Call.multiaddress, Call.multiscript): response = self.node.importmulti([{ "scriptPubKey": { "address": self.address["address"] - }, + } if self.call == Call.multiaddress else self.address["scriptPubKey"], "timestamp": timestamp + TIMESTAMP_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0), "pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [], "keys": [self.key] if self.data == Data.priv else [], @@ -109,6 +109,9 @@ class ImportRescanTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + len(IMPORT_NODES) + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)] for i, import_node in enumerate(IMPORT_NODES, 2): @@ -116,17 +119,26 @@ class ImportRescanTest(BitcoinTestFramework): extra_args[i] += ["-prune=1"] self.add_nodes(self.num_nodes, extra_args=extra_args) + + # Import keys with pruning disabled + 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. for i, variant in enumerate(IMPORT_VARIANTS): variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress()) variant.key = self.nodes[1].dumpprivkey(variant.address["address"]) - variant.initial_amount = 10 - (i + 1) / 4.0 + variant.initial_amount = 1 - (i + 1) / 64 variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount) # Generate a block containing the initial transactions, then another @@ -156,7 +168,7 @@ class ImportRescanTest(BitcoinTestFramework): # Create new transactions sending to each address. for i, variant in enumerate(IMPORT_VARIANTS): - variant.sent_amount = 10 - (2 * i + 1) / 8.0 + variant.sent_amount = 1 - (2 * i + 1) / 128 variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount) # Generate a block containing the new transactions. diff --git a/test/bitcoin_functional/functional/wallet_importmulti.py b/test/bitcoin_functional/functional/wallet_importmulti.py index 5f19e1e2c6..f78ff19791 100755 --- a/test/bitcoin_functional/functional/wallet_importmulti.py +++ b/test/bitcoin_functional/functional/wallet_importmulti.py @@ -3,15 +3,26 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the importmulti RPC.""" -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_greater_than, assert_raises_rpc_error -class ImportMultiTest (BitcoinTestFramework): +from test_framework import script +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_greater_than, + assert_raises_rpc_error, + bytes_to_hex_str, +) + + +class ImportMultiTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"]] self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def setup_network(self): self.setup_nodes() @@ -79,16 +90,17 @@ class ImportMultiTest (BitcoinTestFramework): assert_equal(address_assert['ismine'], False) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + !internal - self.log.info("Should not import a scriptPubKey without internal flag") + # Nonstandard scriptPubKey + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal flag") + nonstandardScriptPubKey = address['scriptPubKey'] + bytes_to_hex_str(script.CScript([script.OP_NOP])) address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -128,18 +140,18 @@ class ImportMultiTest (BitcoinTestFramework): assert_equal(address_assert['ismine'], False) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Public key + !internal - self.log.info("Should not import a scriptPubKey without internal and with public key") + # Nonstandard scriptPubKey + Public key + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal and with public key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) request = [{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "pubkeys": [ address['pubkey'] ] }] result = self.nodes[1].importmulti(request) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -207,17 +219,17 @@ class ImportMultiTest (BitcoinTestFramework): assert_equal(address_assert['ismine'], True) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Private key + !internal - self.log.info("Should not import a scriptPubKey without internal and with private key") + # Nonstandard scriptPubKey + Private key + !internal + self.log.info("Should not import a nonstandard scriptPubKey without internal and with private key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey') + assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) diff --git a/test/bitcoin_functional/functional/wallet_importprunedfunds.py b/test/bitcoin_functional/functional/wallet_importprunedfunds.py index 57fc754d35..26b181db33 100755 --- a/test/bitcoin_functional/functional/wallet_importprunedfunds.py +++ b/test/bitcoin_functional/functional/wallet_importprunedfunds.py @@ -16,6 +16,9 @@ class ImportPrunedFundsTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.log.info("Mining blocks...") self.nodes[0].generate(101) diff --git a/test/bitcoin_functional/functional/wallet_keypool.py b/test/bitcoin_functional/functional/wallet_keypool.py index f52dce04dd..51afa0cb1a 100755 --- a/test/bitcoin_functional/functional/wallet_keypool.py +++ b/test/bitcoin_functional/functional/wallet_keypool.py @@ -13,6 +13,9 @@ class KeyPoolTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): nodes = self.nodes addr_before_encrypting = nodes[0].getnewaddress() @@ -22,9 +25,7 @@ class KeyPoolTest(BitcoinTestFramework): assert(addr_before_encrypting_data['hdseedid'] == wallet_info_old['hdseedid']) # Encrypt wallet and wait to terminate - nodes[0].node_encrypt_wallet('test') - # Restart node 0 - self.start_node(0) + nodes[0].encryptwallet('test') # Keep creating keys addr = nodes[0].getnewaddress() addr_data = nodes[0].getaddressinfo(addr) diff --git a/test/bitcoin_functional/functional/wallet_keypool_topup.py b/test/bitcoin_functional/functional/wallet_keypool_topup.py index a05c0193c9..f1a441c399 100755 --- a/test/bitcoin_functional/functional/wallet_keypool_topup.py +++ b/test/bitcoin_functional/functional/wallet_keypool_topup.py @@ -27,8 +27,11 @@ class KeypoolRestoreTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [[], ['-keypool=100']] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): - wallet_path = os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat") + wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat") wallet_backup_path = os.path.join(self.nodes[1].datadir, "wallet.bak") self.nodes[0].generate(101) diff --git a/test/bitcoin_functional/functional/wallet_labels.py b/test/bitcoin_functional/functional/wallet_labels.py index 0817054149..8d7c77bb96 100755 --- a/test/bitcoin_functional/functional/wallet_labels.py +++ b/test/bitcoin_functional/functional/wallet_labels.py @@ -5,15 +5,9 @@ """Test label RPCs. RPCs tested are: - - getaccountaddress - - getaddressesbyaccount/getaddressesbylabel + - getaddressesbylabel - listaddressgroupings - setlabel - - sendfrom (with account arguments) - - move (with account arguments) - -Run the test twice - once using the accounts API and once using the labels API. -The accounts API test can be removed in V0.18. """ from collections import defaultdict @@ -23,22 +17,14 @@ from test_framework.util import assert_equal, assert_raises_rpc_error class WalletLabelsTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True - self.num_nodes = 2 - self.extra_args = [['-deprecatedrpc=accounts'], []] + self.num_nodes = 1 - def setup_network(self): - """Don't connect nodes.""" - self.setup_nodes() + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() def run_test(self): - """Run the test twice - once using the accounts API and once using the labels API.""" - self.log.info("Test accounts API") - self._run_subtest(True, self.nodes[0]) - self.log.info("Test labels API") - self._run_subtest(False, self.nodes[1]) - - def _run_subtest(self, accounts_api, node): - # Check that there's no UTXO on any of the nodes + # Check that there's no UTXO on the node + node = self.nodes[0] assert_equal(len(node.listunspent()), 0) # Note each time we call generate, all generated coins go into @@ -61,17 +47,12 @@ class WalletLabelsTest(BitcoinTestFramework): linked_addresses.add(address_group[0][0]) # send 50 from each address to a third address not in this wallet - # There's some fee that will come back to us when the miner reward - # matures. common_address = "msf4WtN1YQKXvNtvdFYt9JBnUD2FB41kjr" - txid = node.sendmany( - fromaccount="", + node.sendmany( amounts={common_address: 100}, subtractfeefrom=[common_address], minconf=1, ) - tx_details = node.gettransaction(txid) - fee = -tx_details['details'][0]['fee'] # there should be 1 address group, with the previously # unlinked addresses now linked (they both have 0 balance) address_groups = node.listaddressgroupings() @@ -85,32 +66,22 @@ class WalletLabelsTest(BitcoinTestFramework): # we want to reset so that the "" label has what's expected. # otherwise we're off by exactly the fee amount as that's mined # and matures in the next 100 blocks - if accounts_api: - node.sendfrom("", common_address, fee) amount_to_send = 1.0 # Create labels and make sure subsequent label API calls # recognize the label/address associations. - labels = [Label(name, accounts_api) for name in ("a", "b", "c", "d", "e")] + labels = [Label(name) for name in ("a", "b", "c", "d", "e")] for label in labels: - if accounts_api: - address = node.getaccountaddress(label.name) - else: - address = node.getnewaddress(label.name) + address = node.getnewaddress(label.name) label.add_receive_address(address) label.verify(node) # Check all labels are returned by listlabels. assert_equal(node.listlabels(), [label.name for label in labels]) - # Send a transaction to each label, and make sure this forces - # getaccountaddress to generate a new receiving address. + # Send a transaction to each label. for label in labels: - if accounts_api: - node.sendtoaddress(label.receive_address, amount_to_send) - label.add_receive_address(node.getaccountaddress(label.name)) - else: - node.sendtoaddress(label.addresses[0], amount_to_send) + node.sendtoaddress(label.addresses[0], amount_to_send) label.verify(node) # Check the amounts received. @@ -120,32 +91,17 @@ class WalletLabelsTest(BitcoinTestFramework): node.getreceivedbyaddress(label.addresses[0]), amount_to_send) assert_equal(node.getreceivedbylabel(label.name), amount_to_send) - # Check that sendfrom label reduces listaccounts balances. for i, label in enumerate(labels): to_label = labels[(i + 1) % len(labels)] - if accounts_api: - node.sendfrom(label.name, to_label.receive_address, amount_to_send) - else: - node.sendtoaddress(to_label.addresses[0], amount_to_send) + node.sendtoaddress(to_label.addresses[0], amount_to_send) node.generate(1) for label in labels: - if accounts_api: - address = node.getaccountaddress(label.name) - else: - address = node.getnewaddress(label.name) + address = node.getnewaddress(label.name) label.add_receive_address(address) label.verify(node) assert_equal(node.getreceivedbylabel(label.name), 2) - if accounts_api: - node.move(label.name, "", node.getbalance(label.name)) label.verify(node) node.generate(101) - expected_account_balances = {"": 5200} - for label in labels: - expected_account_balances[label.name] = 0 - if accounts_api: - assert_equal(node.listaccounts(), expected_account_balances) - assert_equal(node.getbalance(""), 5200) # Check that setlabel can assign a label to a new unused address. for label in labels: @@ -153,10 +109,7 @@ class WalletLabelsTest(BitcoinTestFramework): node.setlabel(address, label.name) label.add_address(address) label.verify(node) - if accounts_api: - assert address not in node.getaddressesbyaccount("") - else: - assert_raises_rpc_error(-11, "No addresses with label", node.getaddressesbylabel, "") + assert_raises_rpc_error(-11, "No addresses with label", node.getaddressesbylabel, "") # Check that addmultisigaddress can assign labels. for label in labels: @@ -167,35 +120,20 @@ class WalletLabelsTest(BitcoinTestFramework): label.add_address(multisig_address) label.purpose[multisig_address] = "send" label.verify(node) - if accounts_api: - node.sendfrom("", multisig_address, 50) node.generate(101) - if accounts_api: - for label in labels: - assert_equal(node.getbalance(label.name), 50) # Check that setlabel can change the label of an address from a # different label. - change_label(node, labels[0].addresses[0], labels[0], labels[1], accounts_api) + change_label(node, labels[0].addresses[0], labels[0], labels[1]) # Check that setlabel can set the label of an address already # in the label. This is a no-op. - change_label(node, labels[2].addresses[0], labels[2], labels[2], accounts_api) - - if accounts_api: - # Check that setaccount can change the label of an address which - # is the receiving address of a different label. - change_label(node, labels[0].receive_address, labels[0], labels[1], accounts_api) - - # Check that setaccount can set the label of an address which is - # already the receiving address of the label. This is a no-op. - change_label(node, labels[2].receive_address, labels[2], labels[2], accounts_api) + change_label(node, labels[2].addresses[0], labels[2], labels[2]) class Label: - def __init__(self, name, accounts_api): + def __init__(self, name): # Label name self.name = name - self.accounts_api = accounts_api # Current receiving address associated with this label. self.receive_address = None # List of all addresses assigned with this label @@ -209,56 +147,31 @@ class Label: def add_receive_address(self, address): self.add_address(address) - if self.accounts_api: - self.receive_address = address def verify(self, node): if self.receive_address is not None: assert self.receive_address in self.addresses - if self.accounts_api: - assert_equal(node.getaccountaddress(self.name), self.receive_address) for address in self.addresses: assert_equal( node.getaddressinfo(address)['labels'][0], {"name": self.name, "purpose": self.purpose[address]}) - if self.accounts_api: - assert_equal(node.getaccount(address), self.name) - else: - assert_equal(node.getaddressinfo(address)['label'], self.name) + assert_equal(node.getaddressinfo(address)['label'], self.name) assert_equal( node.getaddressesbylabel(self.name), {address: {"purpose": self.purpose[address]} for address in self.addresses}) - if self.accounts_api: - assert_equal(set(node.getaddressesbyaccount(self.name)), set(self.addresses)) - -def change_label(node, address, old_label, new_label, accounts_api): +def change_label(node, address, old_label, new_label): assert_equal(address in old_label.addresses, True) - if accounts_api: - node.setaccount(address, new_label.name) - else: - node.setlabel(address, new_label.name) + node.setlabel(address, new_label.name) old_label.addresses.remove(address) new_label.add_address(address) - # Calling setaccount on an address which was previously the receiving - # address of a different account should reset the receiving address of - # the old account, causing getaccountaddress to return a brand new - # address. - if accounts_api: - if old_label.name != new_label.name and address == old_label.receive_address: - new_address = node.getaccountaddress(old_label.name) - assert_equal(new_address not in old_label.addresses, True) - assert_equal(new_address not in new_label.addresses, True) - old_label.add_receive_address(new_address) - old_label.verify(node) new_label.verify(node) - if __name__ == '__main__': WalletLabelsTest().main() diff --git a/test/bitcoin_functional/functional/wallet_listreceivedby.py b/test/bitcoin_functional/functional/wallet_listreceivedby.py index 09a7c72347..3485c4470f 100755 --- a/test/bitcoin_functional/functional/wallet_listreceivedby.py +++ b/test/bitcoin_functional/functional/wallet_listreceivedby.py @@ -18,6 +18,14 @@ 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 skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Generate block to get out of IBD self.nodes[0].generate(1) @@ -64,7 +72,7 @@ class ReceivedByTest(BitcoinTestFramework): 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 +89,7 @@ class ReceivedByTest(BitcoinTestFramework): 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 diff --git a/test/bitcoin_functional/functional/wallet_listsinceblock.py b/test/bitcoin_functional/functional/wallet_listsinceblock.py index 847b48aa89..53e671cd3b 100755 --- a/test/bitcoin_functional/functional/wallet_listsinceblock.py +++ b/test/bitcoin_functional/functional/wallet_listsinceblock.py @@ -12,6 +12,9 @@ class ListSinceBlockTest (BitcoinTestFramework): self.num_nodes = 4 self.setup_clean_chain = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.nodes[2].generate(101) self.sync_all() diff --git a/test/bitcoin_functional/functional/wallet_listtransactions.py b/test/bitcoin_functional/functional/wallet_listtransactions.py index 4dc3ff4b26..5a17395abd 100755 --- a/test/bitcoin_functional/functional/wallet_listtransactions.py +++ b/test/bitcoin_functional/functional/wallet_listtransactions.py @@ -27,6 +27,9 @@ class ListTransactionsTest(BitcoinTestFramework): self.num_nodes = 2 self.enable_mocktime() + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) diff --git a/test/bitcoin_functional/functional/wallet_multiwallet.py b/test/bitcoin_functional/functional/wallet_multiwallet.py index 0ac42e5d7f..435821ec48 100755 --- a/test/bitcoin_functional/functional/wallet_multiwallet.py +++ b/test/bitcoin_functional/functional/wallet_multiwallet.py @@ -23,10 +23,13 @@ class MultiWalletTest(BitcoinTestFramework): self.num_nodes = 2 self.supports_cli = True + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): node = self.nodes[0] - data_dir = lambda *p: os.path.join(node.datadir, self.chain, *p) + data_dir = lambda *p: os.path.join(node.datadir, 'regtest', *p) wallet_dir = lambda *p: data_dir('wallets', *p) wallet = lambda name: node.get_wallet_rpc(name) @@ -168,7 +171,7 @@ class MultiWalletTest(BitcoinTestFramework): assert_equal(w4.getbalance(), 3) batch = w1.batch([w1.getblockchaininfo.get_request(), w1.getwalletinfo.get_request()]) - assert_equal(batch[0]["result"]["chain"], self.chain) + assert_equal(batch[0]["result"]["chain"], "regtest") assert_equal(batch[1]["result"]["walletname"], "w1") self.log.info('Check for per-wallet settxfee call') diff --git a/test/bitcoin_functional/functional/wallet_resendwallettransactions.py b/test/bitcoin_functional/functional/wallet_resendwallettransactions.py index 8995aa743f..00bf58d709 100755 --- a/test/bitcoin_functional/functional/wallet_resendwallettransactions.py +++ b/test/bitcoin_functional/functional/wallet_resendwallettransactions.py @@ -12,6 +12,9 @@ class ResendWalletTransactionsTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [['--walletbroadcast=false']] + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): # Should raise RPC_WALLET_ERROR (-4) if walletbroadcast is disabled. assert_raises_rpc_error(-4, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast", self.nodes[0].resendwallettransactions) diff --git a/test/bitcoin_functional/functional/wallet_txn_clone.py b/test/bitcoin_functional/functional/wallet_txn_clone.py index 4ca4ee14e9..d78c105c17 100755 --- a/test/bitcoin_functional/functional/wallet_txn_clone.py +++ b/test/bitcoin_functional/functional/wallet_txn_clone.py @@ -16,6 +16,9 @@ class TxnMallTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def add_options(self, parser): parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true", help="Test double-spend of 1-confirmed transaction") diff --git a/test/bitcoin_functional/functional/wallet_txn_doublespend.py b/test/bitcoin_functional/functional/wallet_txn_doublespend.py index 6811f6ab73..f114d5ab68 100755 --- a/test/bitcoin_functional/functional/wallet_txn_doublespend.py +++ b/test/bitcoin_functional/functional/wallet_txn_doublespend.py @@ -18,6 +18,9 @@ class TxnMallTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def add_options(self, parser): parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true", help="Test double-spend of 1-confirmed transaction") diff --git a/test/bitcoin_functional/functional/wallet_zapwallettxes.py b/test/bitcoin_functional/functional/wallet_zapwallettxes.py index cbd142d1ee..adebff360a 100755 --- a/test/bitcoin_functional/functional/wallet_zapwallettxes.py +++ b/test/bitcoin_functional/functional/wallet_zapwallettxes.py @@ -26,6 +26,9 @@ class ZapWalletTXesTest (BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 2 + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + def run_test(self): self.log.info("Mining blocks...") self.nodes[0].generate(1)