Skip to content

Commit de273d5

Browse files
committed
MiniMiner: use FeeFrac in AncestorFeerateComparator
Comparing using FeeFracs is more precise, allows us to simply the code since FeeFrac comparison internally does cross-multiplication, and avoids potential overflow in the multiplication. Previously, we were only comparing feerates up to 0.001sat/vB 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.
1 parent 1f9d307 commit de273d5

File tree

1 file changed

+7
-15
lines changed

1 file changed

+7
-15
lines changed

src/node/mini_miner.cpp

+7-15
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
}

0 commit comments

Comments
 (0)