Merge bitcoin/bitcoin#32799: mempool: use FeeFrac for ancestor/descendant score comparators
922adf66acmempool: use `FeeFrac` for calculating regular score (Sebastian Falbesoner)3322b3a059mempool: use `FeeFrac` for calculating ancestor score (Sebastian Falbesoner)ac9c113bd2mempool: use `FeeFrac` for calculating descendant score (Sebastian Falbesoner) Pull request description: Rather than determining fee-rates for the mempool index scores and comparators manually in a rather tedious way (even involving floating-points), use the `FeeFrac` class [1] to simplify and deduplicate the code. Note that though this is intended to be a refactoring PR, there might be subtle differences in behaviour due to floating-point arithmetic involved in the original code (to avoid overflows at the cost of precision loss), but these shouldn't matter. [1] introduced in PR #29242, commitce8e22542eACKs for top commit: ismaelsadeeq: Code review ACK922adf66acglozow: ACK922adf66acTree-SHA512: 6c3a9436f2be668aa8561b40c1b93efa7dc97b4ef354e98233ac3d3286a88804668164a55f2fcce4239fee5830e4e70f520e6285b667b87baa65c7cec09159cf
This commit is contained in:
1 file changed
+19
-43
+19
-43
@@ -93,36 +93,24 @@ class CompareTxMemPoolEntryByDescendantScore
|
|||||||
public:
|
public:
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
||||||
{
|
{
|
||||||
double a_mod_fee, a_size, b_mod_fee, b_size;
|
FeeFrac f1 = GetModFeeAndSize(a);
|
||||||
|
FeeFrac f2 = GetModFeeAndSize(b);
|
||||||
|
|
||||||
GetModFeeAndSize(a, a_mod_fee, a_size);
|
if (FeeRateCompare(f1, f2) == 0) {
|
||||||
GetModFeeAndSize(b, b_mod_fee, b_size);
|
|
||||||
|
|
||||||
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
|
|
||||||
double f1 = a_mod_fee * b_size;
|
|
||||||
double f2 = a_size * b_mod_fee;
|
|
||||||
|
|
||||||
if (f1 == f2) {
|
|
||||||
return a.GetTime() >= b.GetTime();
|
return a.GetTime() >= b.GetTime();
|
||||||
}
|
}
|
||||||
return f1 < f2;
|
return f1 < f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the fee/size we're using for sorting this entry.
|
// Return the fee/size we're using for sorting this entry.
|
||||||
void GetModFeeAndSize(const CTxMemPoolEntry &a, double &mod_fee, double &size) const
|
FeeFrac GetModFeeAndSize(const CTxMemPoolEntry &a) const
|
||||||
{
|
{
|
||||||
// Compare feerate with descendants to feerate of the transaction, and
|
// Compare feerate with descendants to feerate of the transaction, and
|
||||||
// return the fee/size for the max.
|
// return the fee/size for the max.
|
||||||
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
|
return std::max<FeeFrac>(
|
||||||
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
|
FeeFrac(a.GetModFeesWithDescendants(), a.GetSizeWithDescendants()),
|
||||||
|
FeeFrac(a.GetModifiedFee(), a.GetTxSize())
|
||||||
if (f2 > f1) {
|
);
|
||||||
mod_fee = a.GetModFeesWithDescendants();
|
|
||||||
size = a.GetSizeWithDescendants();
|
|
||||||
} else {
|
|
||||||
mod_fee = a.GetModifiedFee();
|
|
||||||
size = a.GetTxSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,9 +126,9 @@ class CompareTxMemPoolEntryByScore
|
|||||||
public:
|
public:
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
||||||
{
|
{
|
||||||
double f1 = (double)a.GetFee() * b.GetTxSize();
|
FeeFrac f1(a.GetFee(), a.GetTxSize());
|
||||||
double f2 = (double)b.GetFee() * a.GetTxSize();
|
FeeFrac f2(b.GetFee(), b.GetTxSize());
|
||||||
if (f1 == f2) {
|
if (FeeRateCompare(f1, f2) == 0) {
|
||||||
return b.GetTx().GetHash() < a.GetTx().GetHash();
|
return b.GetTx().GetHash() < a.GetTx().GetHash();
|
||||||
}
|
}
|
||||||
return f1 > f2;
|
return f1 > f2;
|
||||||
@@ -166,16 +154,10 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator()(const T& a, const T& b) const
|
bool operator()(const T& a, const T& b) const
|
||||||
{
|
{
|
||||||
double a_mod_fee, a_size, b_mod_fee, b_size;
|
FeeFrac f1 = GetModFeeAndSize(a);
|
||||||
|
FeeFrac f2 = GetModFeeAndSize(b);
|
||||||
|
|
||||||
GetModFeeAndSize(a, a_mod_fee, a_size);
|
if (FeeRateCompare(f1, f2) == 0) {
|
||||||
GetModFeeAndSize(b, b_mod_fee, b_size);
|
|
||||||
|
|
||||||
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
|
|
||||||
double f1 = a_mod_fee * b_size;
|
|
||||||
double f2 = a_size * b_mod_fee;
|
|
||||||
|
|
||||||
if (f1 == f2) {
|
|
||||||
return a.GetTx().GetHash() < b.GetTx().GetHash();
|
return a.GetTx().GetHash() < b.GetTx().GetHash();
|
||||||
}
|
}
|
||||||
return f1 > f2;
|
return f1 > f2;
|
||||||
@@ -183,20 +165,14 @@ public:
|
|||||||
|
|
||||||
// Return the fee/size we're using for sorting this entry.
|
// Return the fee/size we're using for sorting this entry.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void GetModFeeAndSize(const T &a, double &mod_fee, double &size) const
|
FeeFrac GetModFeeAndSize(const T &a) const
|
||||||
{
|
{
|
||||||
// Compare feerate with ancestors to feerate of the transaction, and
|
// Compare feerate with ancestors to feerate of the transaction, and
|
||||||
// return the fee/size for the min.
|
// return the fee/size for the min.
|
||||||
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithAncestors();
|
return std::min<FeeFrac>(
|
||||||
double f2 = (double)a.GetModFeesWithAncestors() * a.GetTxSize();
|
FeeFrac(a.GetModFeesWithAncestors(), a.GetSizeWithAncestors()),
|
||||||
|
FeeFrac(a.GetModifiedFee(), a.GetTxSize())
|
||||||
if (f1 > f2) {
|
);
|
||||||
mod_fee = a.GetModFeesWithAncestors();
|
|
||||||
size = a.GetSizeWithAncestors();
|
|
||||||
} else {
|
|
||||||
mod_fee = a.GetModifiedFee();
|
|
||||||
size = a.GetTxSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user