Skip to content

Commit 2cad722

Browse files
committed
Merge bitcoin/bitcoin#32799: mempool: use FeeFrac for ancestor/descendant score comparators
922adf6 mempool: use `FeeFrac` for calculating regular score (Sebastian Falbesoner) 3322b3a mempool: use `FeeFrac` for calculating ancestor score (Sebastian Falbesoner) ac9c113 mempool: 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, commit ce8e225 ACKs for top commit: ismaelsadeeq: Code review ACK 922adf6 glozow: ACK 922adf6 Tree-SHA512: 6c3a9436f2be668aa8561b40c1b93efa7dc97b4ef354e98233ac3d3286a88804668164a55f2fcce4239fee5830e4e70f520e6285b667b87baa65c7cec09159cf
2 parents 2d59977 + 922adf6 commit 2cad722

File tree

1 file changed

+19
-43
lines changed

1 file changed

+19
-43
lines changed

src/txmempool.h

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -93,36 +93,24 @@ class CompareTxMemPoolEntryByDescendantScore
9393
public:
9494
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
9595
{
96-
double a_mod_fee, a_size, b_mod_fee, b_size;
96+
FeeFrac f1 = GetModFeeAndSize(a);
97+
FeeFrac f2 = GetModFeeAndSize(b);
9798

98-
GetModFeeAndSize(a, a_mod_fee, a_size);
99-
GetModFeeAndSize(b, b_mod_fee, b_size);
100-
101-
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
102-
double f1 = a_mod_fee * b_size;
103-
double f2 = a_size * b_mod_fee;
104-
105-
if (f1 == f2) {
99+
if (FeeRateCompare(f1, f2) == 0) {
106100
return a.GetTime() >= b.GetTime();
107101
}
108102
return f1 < f2;
109103
}
110104

111105
// Return the fee/size we're using for sorting this entry.
112-
void GetModFeeAndSize(const CTxMemPoolEntry &a, double &mod_fee, double &size) const
106+
FeeFrac GetModFeeAndSize(const CTxMemPoolEntry &a) const
113107
{
114108
// Compare feerate with descendants to feerate of the transaction, and
115109
// return the fee/size for the max.
116-
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
117-
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
118-
119-
if (f2 > f1) {
120-
mod_fee = a.GetModFeesWithDescendants();
121-
size = a.GetSizeWithDescendants();
122-
} else {
123-
mod_fee = a.GetModifiedFee();
124-
size = a.GetTxSize();
125-
}
110+
return std::max<FeeFrac>(
111+
FeeFrac(a.GetModFeesWithDescendants(), a.GetSizeWithDescendants()),
112+
FeeFrac(a.GetModifiedFee(), a.GetTxSize())
113+
);
126114
}
127115
};
128116

@@ -138,9 +126,9 @@ class CompareTxMemPoolEntryByScore
138126
public:
139127
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
140128
{
141-
double f1 = (double)a.GetFee() * b.GetTxSize();
142-
double f2 = (double)b.GetFee() * a.GetTxSize();
143-
if (f1 == f2) {
129+
FeeFrac f1(a.GetFee(), a.GetTxSize());
130+
FeeFrac f2(b.GetFee(), b.GetTxSize());
131+
if (FeeRateCompare(f1, f2) == 0) {
144132
return b.GetTx().GetHash() < a.GetTx().GetHash();
145133
}
146134
return f1 > f2;
@@ -166,37 +154,25 @@ class CompareTxMemPoolEntryByAncestorFee
166154
template<typename T>
167155
bool operator()(const T& a, const T& b) const
168156
{
169-
double a_mod_fee, a_size, b_mod_fee, b_size;
157+
FeeFrac f1 = GetModFeeAndSize(a);
158+
FeeFrac f2 = GetModFeeAndSize(b);
170159

171-
GetModFeeAndSize(a, a_mod_fee, a_size);
172-
GetModFeeAndSize(b, b_mod_fee, b_size);
173-
174-
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
175-
double f1 = a_mod_fee * b_size;
176-
double f2 = a_size * b_mod_fee;
177-
178-
if (f1 == f2) {
160+
if (FeeRateCompare(f1, f2) == 0) {
179161
return a.GetTx().GetHash() < b.GetTx().GetHash();
180162
}
181163
return f1 > f2;
182164
}
183165

184166
// Return the fee/size we're using for sorting this entry.
185167
template <typename T>
186-
void GetModFeeAndSize(const T &a, double &mod_fee, double &size) const
168+
FeeFrac GetModFeeAndSize(const T &a) const
187169
{
188170
// Compare feerate with ancestors to feerate of the transaction, and
189171
// return the fee/size for the min.
190-
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithAncestors();
191-
double f2 = (double)a.GetModFeesWithAncestors() * a.GetTxSize();
192-
193-
if (f1 > f2) {
194-
mod_fee = a.GetModFeesWithAncestors();
195-
size = a.GetSizeWithAncestors();
196-
} else {
197-
mod_fee = a.GetModifiedFee();
198-
size = a.GetTxSize();
199-
}
172+
return std::min<FeeFrac>(
173+
FeeFrac(a.GetModFeesWithAncestors(), a.GetSizeWithAncestors()),
174+
FeeFrac(a.GetModifiedFee(), a.GetTxSize())
175+
);
200176
}
201177
};
202178

0 commit comments

Comments
 (0)