Browse Source

Use mempool's ancestor sort in transaction selection

Transaction selection for mining tracks ancestor feerates that are
modified based on transactions that have already been selected.  This
commit de-duplicates the code so that the ancestor feerate sorting used
by the mempool can also be directly applied to the miner.
0.16
Suhas Daftuar 7 years ago
parent
commit
0a22a52918
  1. 2
      src/miner.cpp
  2. 23
      src/miner.h
  3. 6
      src/txmempool.h

2
src/miner.cpp

@ -352,7 +352,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda @@ -352,7 +352,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
// Try to compare the mapTx entry to the mapModifiedTx entry
iter = mempool.mapTx.project<0>(mi);
if (modit != mapModifiedTx.get<ancestor_score>().end() &&
CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) {
CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
// The best entry in mapModifiedTx has higher score
// than the one from mapTx.
// Switch which transaction (package) to consider

23
src/miner.h

@ -41,6 +41,12 @@ struct CTxMemPoolModifiedEntry { @@ -41,6 +41,12 @@ struct CTxMemPoolModifiedEntry {
nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
}
int64_t GetModifiedFee() const { return iter->GetModifiedFee(); }
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
size_t GetTxSize() const { return iter->GetTxSize(); }
const CTransaction& GetTx() const { return iter->GetTx(); }
CTxMemPool::txiter iter;
uint64_t nSizeWithAncestors;
CAmount nModFeesWithAncestors;
@ -67,21 +73,6 @@ struct modifiedentry_iter { @@ -67,21 +73,6 @@ struct modifiedentry_iter {
}
};
// This matches the calculation in CompareTxMemPoolEntryByAncestorFee,
// except operating on CTxMemPoolModifiedEntry.
// TODO: refactor to avoid duplication of this logic.
struct CompareModifiedEntry {
bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) const
{
double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors;
double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors;
if (f1 == f2) {
return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter);
}
return f1 > f2;
}
};
// A comparator that sorts transactions based on number of ancestors.
// This is sufficient to sort an ancestor package in an order that is valid
// to appear in a block.
@ -106,7 +97,7 @@ typedef boost::multi_index_container< @@ -106,7 +97,7 @@ typedef boost::multi_index_container<
// Reuse same tag from CTxMemPool's similar index
boost::multi_index::tag<ancestor_score>,
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
CompareModifiedEntry
CompareTxMemPoolEntryByAncestorFee
>
>
> indexed_modified_transaction_set;

6
src/txmempool.h

@ -273,7 +273,8 @@ public: @@ -273,7 +273,8 @@ public:
class CompareTxMemPoolEntryByAncestorFee
{
public:
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
template<typename T>
bool operator()(const T& a, const T& b) const
{
double a_mod_fee, a_size, b_mod_fee, b_size;
@ -291,7 +292,8 @@ public: @@ -291,7 +292,8 @@ public:
}
// Return the fee/size we're using for sorting this entry.
void GetModFeeAndSize(const CTxMemPoolEntry &a, double &mod_fee, double &size) const
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.

Loading…
Cancel
Save