Skip to content

Commit 01ed492

Browse files
committed
Merge bitcoin/bitcoin#30412: MiniMiner: use FeeFrac in AncestorFeerateComparator
0937052 fuzz: mini_miner_selection fixups. (glozow) de273d5 MiniMiner: use FeeFrac in AncestorFeerateComparator (glozow) Pull request description: Closes #30284. Closes #30367, see bitcoin/bitcoin#30367 (comment) Previously, we were only comparing feerates up to 1/1000 precision, since CFeeRate comparison just looks at their respective nSatoshisPerK. This could lead to MiniMiner selecting packages in the wrong order (i.e. by txid) if their feerates were less than 0.001sat/vB different. Fix this by creating + comparing `FeeFrac`s instead. Also, `FeeFrac::Mul` doesn't have the overflow problem. Also added a few minor fuzzer fixups that caught my eye while I was debugging this. ACKs for top commit: ismaelsadeeq: Tested ACK 0937052 murchandamus: ACK 0937052 with nits dergoegge: tACK 0937052 Tree-SHA512: e5b6d6c3f7289f30cd8280d0a47cd852d0180b83d1b27ff9514f50c97103b0f069484e48cba2ca3a57419beadc1996c1b9dd8d0a0f34bc4f4223d8adaf414ce5
2 parents ff100bb + 0937052 commit 01ed492

File tree

2 files changed

+10
-18
lines changed

2 files changed

+10
-18
lines changed

src/node/mini_miner.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ MiniMiner::MiniMiner(const std::vector<MiniMinerMempoolEntry>& manual_entries,
174174
SanityCheck();
175175
}
176176

177-
// Compare by min(ancestor feerate, individual feerate), then iterator
177+
// Compare by min(ancestor feerate, individual feerate), then txid
178178
//
179179
// Under the ancestor-based mining approach, high-feerate children can pay for parents, but high-feerate
180180
// parents do not incentive inclusion of their children. Therefore the mining algorithm only considers
@@ -183,21 +183,13 @@ struct AncestorFeerateComparator
183183
{
184184
template<typename I>
185185
bool operator()(const I& a, const I& b) const {
186-
auto min_feerate = [](const MiniMinerMempoolEntry& e) -> CFeeRate {
187-
const CAmount ancestor_fee{e.GetModFeesWithAncestors()};
188-
const int64_t ancestor_size{e.GetSizeWithAncestors()};
189-
const CAmount tx_fee{e.GetModifiedFee()};
190-
const int64_t tx_size{e.GetTxSize()};
191-
// Comparing ancestor feerate with individual feerate:
192-
// ancestor_fee / ancestor_size <= tx_fee / tx_size
193-
// Avoid division and possible loss of precision by
194-
// multiplying both sides by the sizes:
195-
return ancestor_fee * tx_size < tx_fee * ancestor_size ?
196-
CFeeRate(ancestor_fee, ancestor_size) :
197-
CFeeRate(tx_fee, tx_size);
186+
auto min_feerate = [](const MiniMinerMempoolEntry& e) -> FeeFrac {
187+
FeeFrac self_feerate(e.GetModifiedFee(), e.GetTxSize());
188+
FeeFrac ancestor_feerate(e.GetModFeesWithAncestors(), e.GetSizeWithAncestors());
189+
return std::min(ancestor_feerate, self_feerate);
198190
};
199-
CFeeRate a_feerate{min_feerate(a->second)};
200-
CFeeRate b_feerate{min_feerate(b->second)};
191+
FeeFrac a_feerate{min_feerate(a->second)};
192+
FeeFrac b_feerate{min_feerate(b->second)};
201193
if (a_feerate != b_feerate) {
202194
return a_feerate > b_feerate;
203195
}

src/test/fuzz/mini_miner.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ FUZZ_TARGET(mini_miner_selection, .init = initialize_miner)
188188
auto mock_template_txids = mini_miner.GetMockTemplateTxids();
189189
// MiniMiner doesn't add a coinbase tx.
190190
assert(mock_template_txids.count(blocktemplate->block.vtx[0]->GetHash()) == 0);
191-
mock_template_txids.emplace(blocktemplate->block.vtx[0]->GetHash());
192-
assert(mock_template_txids.size() <= blocktemplate->block.vtx.size());
193-
assert(mock_template_txids.size() >= blocktemplate->block.vtx.size());
191+
auto [iter, new_entry] = mock_template_txids.emplace(blocktemplate->block.vtx[0]->GetHash());
192+
assert(new_entry);
193+
194194
assert(mock_template_txids.size() == blocktemplate->block.vtx.size());
195195
for (const auto& tx : blocktemplate->block.vtx) {
196196
assert(mock_template_txids.count(tx->GetHash()));

0 commit comments

Comments
 (0)