Merge bitcoin/bitcoin#29215: test: assumeutxo: spend coin from snapshot chainstate after loading

931575418e test: assumeutxo: spend coin from snapshot chainstate after loading (Sebastian Falbesoner)

Pull request description:

  This PR extends the AssumeUTXO functional test by submitting a spending transaction for an UTXO that is only available in a the snapshot chainstate (after loading via `loadtxoutset`), i.e. it hasn't been seen in a block before. With that we can verify that snapshot coins are visible to the mempool.

  Note that we unfortunately can't use MiniWallet here, as the only available UTXO to spend from the snapshot chainstate is at height 200, where a P2PKH created from the test framework's deterministic private key is used (see `TestNode.generate(...)` and the `PRIV_KEYS` array). Coinbase outputs with smaller heights (<= 199) would be part of the pre-generated chain and hence not qualify for the "UTXO is only in snapshot chainstate and has never been seen in a block" scenario, coinbase outputs with larger heights (>= 201) can't be spent due to immaturity, as the snapshot chainstate block height is 299.

  One could of course mine a different chain with outputs that MiniWallet supports (e.g. taproot anyone-can-spend), but this would change the hardcoded AssumeUTXO hash, colliding with other PRs like #28838, so I wanted to avoid that.

ACKs for top commit:
  maflcko:
    lgtm ACK 931575418e
  jamesob:
    ACK 931575418e

Tree-SHA512: 0665868e1e91fe74f408d0a239cc264bbbc11a6b55bcc0e86cc8b4b2ec1f44977884b817dbe9065a7c768332cab464636656858bc8b9c8e7d7810498e0a17d78
This commit is contained in:
glozow 2024-01-10 16:50:34 +00:00
commit 632a2bb731
No known key found for this signature in database
GPG key ID: BA03F4DBE0C63FB4

View file

@ -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
@ -207,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)