prioritisetransaction takes fee_delta as any int64. CTxMemPool::PrioritiseTransaction stacks deltas with SaturatingAdd, so the accumulated delta and the modified fee can go up to INT64_MAX. The cluster mempool then adds modified fees of several transactions together in FeeFrac (util/feefrac.h:108) without overflow checks.
For example, with a parent and child in the mempool:
prioritisetransaction <parent> 0 4611686018427387904
prioritisetransaction <child> 0 9223372036854775807
getmempoolclusterreportschunkfee: -46116860184.27356705getblocktemplatecontains neither transaction, and the next block mined has only the coinbase- UBSan:
feefrac.h:108:13: runtime error: signed integer overflow, reached from linearization viagetrawmempool
There's no use for a delta larger than the total money supply, so this:
- rejects
fee_deltaoutside-MAX_MONEY..MAX_MONEYin the RPC with "fee_delta out of range" - clamps the accumulated delta to
-MAX_MONEY..MAX_MONEYinPrioritiseTransaction, which also covers deltas loaded from mempool.dat, and updates the modified fee by the change in the clamped delta
With each modified fee bounded by 2 * MAX_MONEY, cluster sums stay far away from int64 limits.
The new test_fee_delta_limits in mining_prioritisetransaction.py checks the RPC range error, that stacked deltas stop at MAX_MONEY, that the chunk fees add up, and that both transactions are in the block template. It fails on master ("No exception raised"). mempool_persist.py, mempool_packages.py, rpc_packages.py and the miner/rbf/txpackage unit tests pass.
AI tools were used to help find this issue and to prepare the patch and test.