Skip to content

Commit

Permalink
Use mempool's ancestor sort in transaction selection
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sdaftuar committed Jan 13, 2018
1 parent 7abfa53 commit 0a22a52
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/miner.cpp
Expand Up @@ -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
Expand Down
23 changes: 7 additions & 16 deletions src/miner.h
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/txmempool.h
Expand Up @@ -273,7 +273,8 @@ class CompareTxMemPoolEntryByEntryTime
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;

Expand All @@ -291,7 +292,8 @@ class CompareTxMemPoolEntryByAncestorFee
}

// 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.
Expand Down

0 comments on commit 0a22a52

Please sign in to comment.