https://github.com/bitcoin/bitcoin/blob/6d4048468430d9d1fe5e7c5fcda13708879d1083/src/index/coinstatsindex.h#L33-L35 https://github.com/bitcoin/bitcoin/blob/6d4048468430d9d1fe5e7c5fcda13708879d1083/src/kernel/coinstats.h#L54-L59
The values:
m_total_prevout_spent_amount
m_total_new_outputs_ex_coinbase_amount
m_total_coinbase_amount
are all subject to overflowing an int64_t
(ie, CAmount
). This is visible in practice as of signet block 112516; with total_prevout_spent
rolling over to -92230771076.81494784 (from from 92232270378.54920553 BTC at block 112515). With debug builds, this will cause a crash due to the -ftrapv
compiler option.
Making these just be per-block totals instead of cumulative totals should fix this in practice. I think that would require a full index rebuild, though?
Even then I think it would still be technically possible to overflow m_block_prevout_spent_amount
or m_total_new_outputs_ex_coinbase_amount
with a single block: you can fit over 15,000 65-byte transactions spending to padding DROP TRUE
in a block, and if you start with a utxo containing 6.15M BTC and chain it through 15,000 txs, then that will overflow a signed 64 bit counter. That’s not reproducible on regtest, though, since the halving schedule there limits the total supply to ~15,000 regtest-BTC, which means you need about 6.15M transactions to trigger the same overflow.
Since we don’t actually expose the cumulative totals; I observed the values above by patching gettxoutsetinfo in rpc/blockchain to add:
0/*line ~877*/ {RPCResult::Type::STR_AMOUNT, "total_prevout_spent", "Total amount of all prevouts spent up to this block"},
1/*line ~981*/ block_info.pushKV("total_prevout_spent", ValueFromAmount(stats.total_prevout_spent_amount));