From f252e687ec94b6ccafb5bc44b7df3daeb473fdea Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Mon, 5 Feb 2024 16:16:14 -0500 Subject: [PATCH] assumeutxo test: Add RPC test for fake nTx and nChainTx values The fake values will be removed in an upcoming commit, so it is useful to have test coverage confirming the change in behavior. --- test/functional/feature_assumeutxo.py | 42 ++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index a9ed4a09cea..a29ee8be8b1 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -34,6 +34,7 @@ Interesting starting states could be loading a snapshot when the current chain t """ from shutil import rmtree +from dataclasses import dataclass from test_framework.messages import tx_from_hex from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -174,10 +175,18 @@ class AssumeutxoTest(BitcoinTestFramework): # Generate a series of blocks that `n0` will have in the snapshot, # but that n1 and n2 don't yet see. + assert n0.getblockcount() == START_HEIGHT + blocks = {START_HEIGHT: Block(n0.getbestblockhash(), 1, START_HEIGHT + 1)} for i in range(100): + block_tx = 1 if i % 3 == 0: self.mini_wallet.send_self_transfer(from_node=n0) + block_tx += 1 self.generate(n0, nblocks=1, sync_fun=self.no_op) + height = n0.getblockcount() + hash = n0.getbestblockhash() + blocks[height] = Block(hash, block_tx, blocks[height-1].chain_tx + block_tx) + self.log.info("-- Testing assumeutxo + some indexes + pruning") @@ -207,7 +216,7 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal( dump_output['txoutset_hash'], "a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27") - assert_equal(dump_output["nchaintx"], 334) + assert_equal(dump_output["nchaintx"], blocks[SNAPSHOT_BASE_HEIGHT].chain_tx) assert_equal(n0.getblockchaininfo()["blocks"], SNAPSHOT_BASE_HEIGHT) # Mine more blocks on top of the snapshot that n1 hasn't yet seen. This @@ -228,6 +237,30 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal(loaded['coins_loaded'], SNAPSHOT_BASE_HEIGHT) assert_equal(loaded['base_height'], SNAPSHOT_BASE_HEIGHT) + def check_tx_counts(final: bool) -> None: + """Check nTx and nChainTx intermediate values right after loading + the snapshot, and final values after the snapshot is validated.""" + for height, block in blocks.items(): + tx = n1.getblockheader(block.hash)["nTx"] + chain_tx = n1.getchaintxstats(nblocks=1, blockhash=block.hash)["txcount"] + + # Intermediate nTx of the starting block should be real, but nTx of + # later blocks should be fake 1 values set by snapshot loading code. + if final or height == START_HEIGHT: + assert_equal(tx, block.tx) + else: + assert_equal(tx, 1) + + # Intermediate nChainTx of the starting block and snapshot block + # should be real, but others will be fake values set by snapshot + # loading code. + if final or height in (START_HEIGHT, SNAPSHOT_BASE_HEIGHT): + assert_equal(chain_tx, block.chain_tx) + else: + assert_equal(chain_tx, height + 1) + + check_tx_counts(final=False) + normal, snapshot = n1.getchainstates()["chainstates"] assert_equal(normal['blocks'], START_HEIGHT) assert_equal(normal.get('snapshot_blockhash'), None) @@ -291,6 +324,8 @@ class AssumeutxoTest(BitcoinTestFramework): } self.wait_until(lambda: n1.getindexinfo() == completed_idx_state) + self.log.info("Re-check nTx and nChainTx values") + check_tx_counts(final=True) for i in (0, 1): n = self.nodes[i] @@ -365,6 +400,11 @@ class AssumeutxoTest(BitcoinTestFramework): self.connect_nodes(0, 2) self.wait_until(lambda: n2.getblockcount() == FINAL_HEIGHT) +@dataclass +class Block: + hash: str + tx: int + chain_tx: int if __name__ == '__main__': AssumeutxoTest().main()