Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.h
Show First 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | |||||
/** \class CompareTxMemPoolEntryByDescendantScore | /** \class CompareTxMemPoolEntryByDescendantScore | ||||
* | * | ||||
* Sort an entry by max(score/size of entry's tx, score/size with all | * Sort an entry by max(score/size of entry's tx, score/size with all | ||||
* descendants). | * descendants). | ||||
*/ | */ | ||||
class CompareTxMemPoolEntryByDescendantScore { | class CompareTxMemPoolEntryByDescendantScore { | ||||
public: | public: | ||||
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const { | bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const { | ||||
bool fUseADescendants = UseDescendantScore(a); | double a_mod_fee, a_size, b_mod_fee, b_size; | ||||
bool fUseBDescendants = UseDescendantScore(b); | |||||
double aModFee = (fUseADescendants ? a.GetModFeesWithDescendants() | GetModFeeAndSize(a, a_mod_fee, a_size); | ||||
: a.GetModifiedFee()) / | GetModFeeAndSize(b, b_mod_fee, b_size); | ||||
SATOSHI; | |||||
double aSize = | |||||
fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); | |||||
double bModFee = (fUseBDescendants ? b.GetModFeesWithDescendants() | |||||
: b.GetModifiedFee()) / | |||||
SATOSHI; | |||||
double bSize = | |||||
fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize(); | |||||
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b). | // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). | ||||
double f1 = aModFee * bSize; | double f1 = a_mod_fee * b_size; | ||||
double f2 = aSize * bModFee; | double f2 = a_size * b_mod_fee; | ||||
if (f1 == f2) { | if (f1 == f2) { | ||||
return a.GetTime() >= b.GetTime(); | return a.GetTime() >= b.GetTime(); | ||||
} | } | ||||
return f1 < f2; | return f1 < f2; | ||||
} | } | ||||
// Calculate which score to use for an entry (avoiding division). | // Return the fee/size we're using for sorting this entry. | ||||
bool UseDescendantScore(const CTxMemPoolEntry &a) const { | void GetModFeeAndSize(const CTxMemPoolEntry &a, double &mod_fee, | ||||
double &size) const { | |||||
// Compare feerate with descendants to feerate of the transaction, and | |||||
// return the fee/size for the max. | |||||
double f1 = a.GetSizeWithDescendants() * (a.GetModifiedFee() / SATOSHI); | double f1 = a.GetSizeWithDescendants() * (a.GetModifiedFee() / SATOSHI); | ||||
double f2 = a.GetTxSize() * (a.GetModFeesWithDescendants() / SATOSHI); | double f2 = a.GetTxSize() * (a.GetModFeesWithDescendants() / SATOSHI); | ||||
return f2 > f1; | |||||
if (f2 > f1) { | |||||
mod_fee = a.GetModFeesWithDescendants() / SATOSHI; | |||||
size = a.GetSizeWithDescendants(); | |||||
} else { | |||||
mod_fee = a.GetModifiedFee() / SATOSHI; | |||||
size = a.GetTxSize(); | |||||
} | |||||
} | } | ||||
}; | }; | ||||
/** \class CompareTxMemPoolEntryByScore | /** \class CompareTxMemPoolEntryByScore | ||||
* | * | ||||
* Sort by score of entry ((fee+delta)/size) in descending order | * Sort by score of entry ((fee+delta)/size) in descending order | ||||
*/ | */ | ||||
class CompareTxMemPoolEntryByScore { | class CompareTxMemPoolEntryByScore { | ||||
Show All 10 Lines | |||||
class CompareTxMemPoolEntryByEntryTime { | class CompareTxMemPoolEntryByEntryTime { | ||||
public: | public: | ||||
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const { | bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const { | ||||
return a.GetTime() < b.GetTime(); | return a.GetTime() < b.GetTime(); | ||||
} | } | ||||
}; | }; | ||||
/** \class CompareTxMemPoolEntryByAncestorScore | |||||
* | |||||
* Sort an entry by min(score/size of entry's tx, score/size with all | |||||
* ancestors). | |||||
*/ | |||||
class CompareTxMemPoolEntryByAncestorFee { | class CompareTxMemPoolEntryByAncestorFee { | ||||
public: | public: | ||||
bool operator()(const CTxMemPoolEntry &a, const CTxMemPoolEntry &b) const { | template <typename T> bool operator()(const T &a, const T &b) const { | ||||
double aFees = a.GetModFeesWithAncestors() / SATOSHI; | double a_mod_fee, a_size, b_mod_fee, b_size; | ||||
double aSize = a.GetSizeWithAncestors(); | |||||
double bFees = b.GetModFeesWithAncestors() / SATOSHI; | GetModFeeAndSize(a, a_mod_fee, a_size); | ||||
double bSize = b.GetSizeWithAncestors(); | GetModFeeAndSize(b, b_mod_fee, b_size); | ||||
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b). | // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). | ||||
double f1 = aFees * bSize; | double f1 = a_mod_fee * b_size; | ||||
double f2 = aSize * bFees; | double f2 = a_size * b_mod_fee; | ||||
if (f1 == f2) { | if (f1 == f2) { | ||||
return a.GetTx().GetId() < b.GetTx().GetId(); | return a.GetTx().GetId() < b.GetTx().GetId(); | ||||
} | } | ||||
return f1 > f2; | return f1 > f2; | ||||
} | } | ||||
// Return the fee/size we're using for sorting this entry. | |||||
template <typename T> | |||||
void GetModFeeAndSize(const T &a, double &mod_fee, double &size) const { | |||||
// Compare feerate with ancestors to feerate of the transaction, and | |||||
// return the fee/size for the min. | |||||
double f1 = a.GetSizeWithAncestors() * (a.GetModifiedFee() / SATOSHI); | |||||
double f2 = a.GetTxSize() * (a.GetModFeesWithAncestors() / SATOSHI); | |||||
if (f1 > f2) { | |||||
mod_fee = a.GetModFeesWithAncestors() / SATOSHI; | |||||
size = a.GetSizeWithAncestors(); | |||||
} else { | |||||
mod_fee = a.GetModifiedFee() / SATOSHI; | |||||
size = a.GetTxSize(); | |||||
} | |||||
} | |||||
}; | }; | ||||
// Multi_index tag names | // Multi_index tag names | ||||
struct descendant_score {}; | struct descendant_score {}; | ||||
struct entry_time {}; | struct entry_time {}; | ||||
struct ancestor_score {}; | struct ancestor_score {}; | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 590 Lines • Show Last 20 Lines |