diff options
Diffstat (limited to 'test/functional/feature_assumeutxo.py')
-rwxr-xr-x | test/functional/feature_assumeutxo.py | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index ab2e6c4d0b..f26a300f70 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -11,7 +11,6 @@ The assumeutxo value generated and used here is committed to in ## Possible test improvements -- TODO: test submitting a transaction and verifying it appears in mempool - TODO: test what happens with -reindex and -reindex-chainstate before the snapshot is validated, and make sure it's deleted successfully. @@ -35,11 +34,14 @@ Interesting starting states could be loading a snapshot when the current chain t """ from shutil import rmtree +from test_framework.messages import tx_from_hex from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_raises_rpc_error, ) +from test_framework.wallet import getnewdestination + START_HEIGHT = 199 SNAPSHOT_BASE_HEIGHT = 299 @@ -75,7 +77,7 @@ class AssumeutxoTest(BitcoinTestFramework): with self.nodes[1].assert_debug_log([log_msg]): assert_raises_rpc_error(-32603, f"Unable to load UTXO snapshot{rpc_details}", self.nodes[1].loadtxoutset, bad_snapshot_path) - self.log.info(" - snapshot file refering to a block that is not in the assumeutxo parameters") + self.log.info(" - snapshot file referring to a block that is not in the assumeutxo parameters") prev_block_hash = self.nodes[0].getblockhash(SNAPSHOT_BASE_HEIGHT - 1) bogus_block_hash = "0" * 64 # Represents any unknown block hash for bad_block_hash in [bogus_block_hash, prev_block_hash]: @@ -112,14 +114,20 @@ class AssumeutxoTest(BitcoinTestFramework): def test_invalid_chainstate_scenarios(self): self.log.info("Test different scenarios of invalid snapshot chainstate in datadir") - self.log.info(" - snapshot chainstate refering to a block that is not in the assumeutxo parameters") + self.log.info(" - snapshot chainstate referring to a block that is not in the assumeutxo parameters") self.stop_node(0) chainstate_snapshot_path = self.nodes[0].chain_path / "chainstate_snapshot" chainstate_snapshot_path.mkdir() with open(chainstate_snapshot_path / "base_blockhash", 'wb') as f: f.write(b'z' * 32) - expected_error = f"Error: A fatal internal error occurred, see debug.log for details" - self.nodes[0].assert_start_raises_init_error(expected_msg=expected_error) + + def expected_error(log_msg="", error_msg=""): + with self.nodes[0].assert_debug_log([log_msg]): + self.nodes[0].assert_start_raises_init_error(expected_msg=error_msg) + + expected_error_msg = f"Error: A fatal internal error occurred, see debug.log for details" + error_details = f"Assumeutxo data not found for the given blockhash" + expected_error(log_msg=error_details, error_msg=expected_error_msg) # resurrect node again rmtree(chainstate_snapshot_path) @@ -201,6 +209,22 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal(n1.getblockchaininfo()["blocks"], SNAPSHOT_BASE_HEIGHT) + self.log.info("Submit a spending transaction for a snapshot chainstate coin to the mempool") + # spend the coinbase output of the first block that is not available on node1 + spend_coin_blockhash = n1.getblockhash(START_HEIGHT + 1) + assert_raises_rpc_error(-1, "Block not found on disk", n1.getblock, spend_coin_blockhash) + prev_tx = n0.getblock(spend_coin_blockhash, 3)['tx'][0] + prevout = {"txid": prev_tx['txid'], "vout": 0, "scriptPubKey": prev_tx['vout'][0]['scriptPubKey']['hex']} + privkey = n0.get_deterministic_priv_key().key + raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: 24.99}) + signed_tx = n1.signrawtransactionwithkey(raw_tx, [privkey], [prevout])['hex'] + signed_txid = tx_from_hex(signed_tx).rehash() + + assert n1.gettxout(prev_tx['txid'], 0) is not None + n1.sendrawtransaction(signed_tx) + assert signed_txid in n1.getrawmempool() + assert not n1.gettxout(prev_tx['txid'], 0) + PAUSE_HEIGHT = FINAL_HEIGHT - 40 self.log.info("Restarting node to stop at height %d", PAUSE_HEIGHT) |