mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
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.
This commit is contained in:
parent
1f9d30744d
commit
de273d5300
1 changed files with 7 additions and 15 deletions
|
@ -174,7 +174,7 @@ MiniMiner::MiniMiner(const std::vector<MiniMinerMempoolEntry>& manual_entries,
|
||||||
SanityCheck();
|
SanityCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare by min(ancestor feerate, individual feerate), then iterator
|
// Compare by min(ancestor feerate, individual feerate), then txid
|
||||||
//
|
//
|
||||||
// Under the ancestor-based mining approach, high-feerate children can pay for parents, but high-feerate
|
// Under the ancestor-based mining approach, high-feerate children can pay for parents, but high-feerate
|
||||||
// parents do not incentive inclusion of their children. Therefore the mining algorithm only considers
|
// parents do not incentive inclusion of their children. Therefore the mining algorithm only considers
|
||||||
|
@ -183,21 +183,13 @@ struct AncestorFeerateComparator
|
||||||
{
|
{
|
||||||
template<typename I>
|
template<typename I>
|
||||||
bool operator()(const I& a, const I& b) const {
|
bool operator()(const I& a, const I& b) const {
|
||||||
auto min_feerate = [](const MiniMinerMempoolEntry& e) -> CFeeRate {
|
auto min_feerate = [](const MiniMinerMempoolEntry& e) -> FeeFrac {
|
||||||
const CAmount ancestor_fee{e.GetModFeesWithAncestors()};
|
FeeFrac self_feerate(e.GetModifiedFee(), e.GetTxSize());
|
||||||
const int64_t ancestor_size{e.GetSizeWithAncestors()};
|
FeeFrac ancestor_feerate(e.GetModFeesWithAncestors(), e.GetSizeWithAncestors());
|
||||||
const CAmount tx_fee{e.GetModifiedFee()};
|
return std::min(ancestor_feerate, self_feerate);
|
||||||
const int64_t tx_size{e.GetTxSize()};
|
|
||||||
// Comparing ancestor feerate with individual feerate:
|
|
||||||
// ancestor_fee / ancestor_size <= tx_fee / tx_size
|
|
||||||
// Avoid division and possible loss of precision by
|
|
||||||
// multiplying both sides by the sizes:
|
|
||||||
return ancestor_fee * tx_size < tx_fee * ancestor_size ?
|
|
||||||
CFeeRate(ancestor_fee, ancestor_size) :
|
|
||||||
CFeeRate(tx_fee, tx_size);
|
|
||||||
};
|
};
|
||||||
CFeeRate a_feerate{min_feerate(a->second)};
|
FeeFrac a_feerate{min_feerate(a->second)};
|
||||||
CFeeRate b_feerate{min_feerate(b->second)};
|
FeeFrac b_feerate{min_feerate(b->second)};
|
||||||
if (a_feerate != b_feerate) {
|
if (a_feerate != b_feerate) {
|
||||||
return a_feerate > b_feerate;
|
return a_feerate > b_feerate;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue