aboutsummaryrefslogtreecommitdiff
path: root/test/functional/feature_assumeutxo.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/feature_assumeutxo.py')
-rwxr-xr-xtest/functional/feature_assumeutxo.py34
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)