Repository: bitcoin/bitcoin
File: src/test/fuzz/utxo_total_supply.cpp (C++)

Code before:
    // Limit to avoid timeout, but enough to cover duplicate_coinbase_height
    // and CVE-2018-17144.
    LIMITED_WHILE(fuzzed_data_provider.remaining_bytes(), 2'00)
    {
        CallOneOf(
            fuzzed_data_provider,
            [&] {
                // Append an input-output pair to the last tx in the current block
                CMutableTransaction tx{*current_block->vtx.back()};
                AppendRandomTxo(tx);
                current_block->vtx.back() = MakeTransactionRef(tx);
                StoreLastTxo();
            },
            [&] {
                // Append a tx to the list of txs in the current block
                CMutableTransaction tx{};
                AppendRandomTxo(tx);
                current_block->vtx.push_back(MakeTransactionRef(tx));
                StoreLastTxo();
            },
            [&] {
                // Append the current block to the active chain
                node::RegenerateCommitments(*current_block, chainman);
                const bool was_valid = !MineBlock(node, current_block).IsNull();

                const auto prev_utxo_stats = utxo_stats;
                if (was_valid) {
                    if (duplicate_coinbase_height == ActiveHeight()) {
                        // we mined the duplicate coinbase
                        assert(current_block->vtx.at(0)->vin.at(0).scriptSig == duplicate_coinbase_script);
                    }

                    circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
                }

                UpdateUtxoStats();

                if (!was_valid) {
                    // utxo stats must not change
                    assert(prev_utxo_stats.hashSerialized == utxo_stats.hashSerialized);
                }

                current_block = PrepareNextBlock();
                StoreLastTxo();
            });
    }
}


Review comment (bug):
this looks like a false positive in clang-tidy and this looks like the wrong fix. `utxo_stats` is mutable, and taking a const reference does not make it immutable.

(In languages with a borrow checker, this wouldn't even compile, see https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8c78ddbe26b30473498b64a47ba2a6b)

The correct fix is to disable the clang-tidy rule in this line, or globally.

Code after:
    // Limit to avoid timeout, but enough to cover duplicate_coinbase_height
    // and CVE-2018-17144.
    LIMITED_WHILE(fuzzed_data_provider.remaining_bytes(), 2'00)
    {
        CallOneOf(
            fuzzed_data_provider,
            [&] {
                // Append an input-output pair to the last tx in the current block
                CMutableTransaction tx{*current_block->vtx.back()};
                AppendRandomTxo(tx);
                current_block->vtx.back() = MakeTransactionRef(tx);
                StoreLastTxo();
            },
            [&] {
                // Append a tx to the list of txs in the current block
                CMutableTransaction tx{};
                AppendRandomTxo(tx);
                current_block->vtx.push_back(MakeTransactionRef(tx));
                StoreLastTxo();
            },
            [&] {
                // Append the current block to the active chain
                node::RegenerateCommitments(*current_block, chainman);
                const bool was_valid = !MineBlock(node, current_block).IsNull();

                const uint256 prev_hash_serialized{utxo_stats.hashSerialized};
                if (was_valid) {
                    if (duplicate_coinbase_height == ActiveHeight()) {
                        // we mined the duplicate coinbase
                        assert(current_block->vtx.at(0)->vin.at(0).scriptSig == duplicate_coinbase_script);
                    }

                    circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
                }

                UpdateUtxoStats();

                if (!was_valid) {
                    // utxo stats must not change
                    assert(prev_hash_serialized == utxo_stats.hashSerialized);
                }

                current_block = PrepareNextBlock();
                StoreLastTxo();
            });
    }
}