Repository: bitcoin/bitcoin
File: test/functional/feature_assumeutxo.py (Python)

Code before:

        self.log.info(f"Loading snapshot into second node from {dump_output['path']}")
        # This node's tip is on an ancestor block of the snapshot, which should
        # be the normal case
        loaded = n1.loadtxoutset(dump_output['path'])
        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"]
                stats = n1.getchaintxstats(nblocks=1, blockhash=block.hash)
                chain_tx = stats.get("txcount", None)
                window_tx_count = stats.get("window_tx_count", None)
                tx_rate = stats.get("txrate", None)
                window_interval = stats.get("window_interval")

                # Intermediate nTx of the starting block should be set, but nTx of
                # later blocks should be 0 before they are downloaded.
                # The window_tx_count of one block is equal to the blocks tx count.
                # If the window tx count is unknown, the value is missing.
                # The tx_rate is calculated from window_tx_count and window_interval
                # when possible.
                if final or height == START_HEIGHT:
                    assert_equal(tx, block.tx)
                    assert_equal(window_tx_count, tx)
                    if window_interval > 0:
                        assert_approx(tx_rate, window_tx_count / window_interval, vspan=0.1)
                    else:
                        assert_equal(tx_rate, None)
                else:
                    assert_equal(tx, 0)
                    assert_equal(window_tx_count, None)

                # Intermediate nChainTx of the starting block and snapshot block
                # should be set, but others should be None until they are downloaded.
                if final or height in (START_HEIGHT, SNAPSHOT_BASE_HEIGHT):
                    assert_equal(chain_tx, block.chain_tx)
                else:
                    assert_equal(chain_tx, None)

        check_tx_counts(final=False)

        normal, snapshot = n1.getchainstates()["chainstates"]
        assert_equal(normal['blocks'], START_HEIGHT)
        assert_equal(normal.get('snapshot_blockhash'), None)
        assert_equal(normal['validated'], True)
        assert_equal(snapshot['blocks'], SNAPSHOT_BASE_HEIGHT)
        assert_equal(snapshot['snapshot_blockhash'], dump_output['base_hash'])

Review comment (suggestion):
nit

```suggestion
        assert_equal(scan_result['bestblock'], snapshot_hash)
```

Code after:

        self.log.info(f"Loading snapshot into second node from {dump_output['path']}")
        # This node's tip is on an ancestor block of the snapshot, which should
        # be the normal case
        loaded = n1.loadtxoutset(dump_output['path'])
        assert_equal(loaded['coins_loaded'], SNAPSHOT_BASE_HEIGHT)
        assert_equal(loaded['base_height'], SNAPSHOT_BASE_HEIGHT)

        self.log.info("Check that UTXO-querying RPCs operate on snapshot chainstate")
        snapshot_hash = loaded['tip_hash']
        snapshot_num_coins = loaded['coins_loaded']
        # coinstatsindex might be not caught up yet and is not relevant for this test, so don't use it
        utxo_info = n1.gettxoutsetinfo(use_index=False)
        assert_equal(utxo_info['txouts'], snapshot_num_coins)
        assert_equal(utxo_info['height'], SNAPSHOT_BASE_HEIGHT)
        assert_equal(utxo_info['bestblock'], snapshot_hash)

        # find coinbase output at snapshot height on node0 and scan for it on node1,
        # where the block is not available, but the snapshot was loaded successfully
        coinbase_tx = n0.getblock(snapshot_hash, verbosity=2)['tx'][0]
        assert_raises_rpc_error(-1, "Block not found on disk", n1.getblock, snapshot_hash)
        coinbase_output_descriptor = coinbase_tx['vout'][0]['scriptPubKey']['desc']
        scan_result = n1.scantxoutset('start', [coinbase_output_descriptor])
        assert_equal(scan_result['success'], True)
        assert_equal(scan_result['txouts'], snapshot_num_coins)
        assert_equal(scan_result['height'], SNAPSHOT_BASE_HEIGHT)
        assert_equal(scan_result['bestblock'], snapshot_hash)
        scan_utxos = [(coin['txid'], coin['vout']) for coin in scan_result['unspents']]
        assert (coinbase_tx['txid'], 0) in scan_utxos

        txout_result = n1.gettxout(coinbase_tx['txid'], 0)
        assert_equal(txout_result['scriptPubKey']['desc'], coinbase_output_descriptor)

        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"]
                stats = n1.getchaintxstats(nblocks=1, blockhash=block.hash)
                chain_tx = stats.get("txcount", None)
                window_tx_count = stats.get("window_tx_count", None)
                tx_rate = stats.get("txrate", None)
                window_interval = stats.get("window_interval")

                # Intermediate nTx of the starting block should be set, but nTx of
                # later blocks should be 0 before they are downloaded.
                # The window_tx_count of one block is equal to the blocks tx count.
                # If the window tx count is unknown, the value is missing.
                # The tx_rate is calculated from window_tx_count and window_interval
                # when possible.
                if final or height == START_HEIGHT: