Skip to content

Commit

Permalink
feat: change ordering to use ancestor feerate by discountvsize
Browse files Browse the repository at this point in the history
This changes transaction ordering in the block template to use the
ancestor feerate by _discounted_ vsize.
  • Loading branch information
delta1 committed Mar 20, 2024
1 parent 8bafd0c commit 790af77
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 94 deletions.
20 changes: 11 additions & 9 deletions src/node/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already
if (mit == mapModifiedTx.end()) {
CTxMemPoolModifiedEntry modEntry(desc);
modEntry.nSizeWithAncestors -= it->GetTxSize();
modEntry.discountSizeWithAncestors -= it->GetDiscountTxSize();
modEntry.nModFeesWithAncestors -= it->GetModifiedFee();
modEntry.nSigOpCostWithAncestors -= it->GetSigOpCost();
mapModifiedTx.insert(modEntry);
Expand Down Expand Up @@ -383,7 +384,8 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
// and modifying them for their already included ancestors
UpdatePackagesForAdded(inBlock, mapModifiedTx);

CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = m_mempool.mapTx.get<ancestor_score>().begin();
// ELEMENTS: we use confidential_score instead of ancestor_score
CTxMemPool::indexed_transaction_set::index<confidential_score>::type::iterator mi = m_mempool.mapTx.get<confidential_score>().begin();
CTxMemPool::txiter iter;

// Limit the number of attempts to add transactions to the block when it is
Expand All @@ -392,9 +394,9 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
int64_t nConsecutiveFailed = 0;

while (mi != m_mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty()) {
while (mi != m_mempool.mapTx.get<confidential_score>().end() || !mapModifiedTx.empty()) {
// First try to find a new transaction in mapTx to evaluate.
if (mi != m_mempool.mapTx.get<ancestor_score>().end() &&
if (mi != m_mempool.mapTx.get<confidential_score>().end() &&
SkipMapTxEntry(m_mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) {
++mi;
continue;
Expand All @@ -404,16 +406,16 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
// the next entry from mapTx, or the best from mapModifiedTx?
bool fUsingModified = false;

modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
if (mi == m_mempool.mapTx.get<ancestor_score>().end()) {
modconftxscoreiter modit = mapModifiedTx.get<confidential_score>().begin();
if (mi == m_mempool.mapTx.get<confidential_score>().end()) {
// We're out of entries in mapTx; use the entry from mapModifiedTx
iter = modit->iter;
fUsingModified = true;
} else {
// Try to compare the mapTx entry to the mapModifiedTx entry
iter = m_mempool.mapTx.project<0>(mi);
if (modit != mapModifiedTx.get<ancestor_score>().end() &&
CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
if (modit != mapModifiedTx.get<confidential_score>().end() &&
CompareTxMemPoolEntryByConfidentialFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
// The best entry in mapModifiedTx has higher score
// than the one from mapTx.
// Switch which transaction (package) to consider
Expand Down Expand Up @@ -455,7 +457,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
// Since we always look at the best entry in mapModifiedTx,
// we must erase failed entries so that we can consider the
// next best entry on the next loop iteration
mapModifiedTx.get<ancestor_score>().erase(modit);
mapModifiedTx.get<confidential_score>().erase(modit);
failedTx.insert(iter);
}

Expand All @@ -480,7 +482,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
// Test if all tx's are Final
if (!TestPackageTransactions(ancestors)) {
if (fUsingModified) {
mapModifiedTx.get<ancestor_score>().erase(modit);
mapModifiedTx.get<confidential_score>().erase(modit);
failedTx.insert(iter);
}
continue;
Expand Down
11 changes: 11 additions & 0 deletions src/node/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,22 @@ struct CTxMemPoolModifiedEntry {
{
iter = entry;
nSizeWithAncestors = entry->GetSizeWithAncestors();
discountSizeWithAncestors = entry->GetDiscountSizeWithAncestors();
nModFeesWithAncestors = entry->GetModFeesWithAncestors();
nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
}

int64_t GetModifiedFee() const { return iter->GetModifiedFee(); }
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
uint64_t GetDiscountSizeWithAncestors() const { return discountSizeWithAncestors; }
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
size_t GetTxSize() const { return iter->GetTxSize(); }
size_t GetDiscountTxSize() const { return iter->GetDiscountTxSize(); }
const CTransaction& GetTx() const { return iter->GetTx(); }

CTxMemPool::txiter iter;
uint64_t nSizeWithAncestors;
uint64_t discountSizeWithAncestors;
CAmount nModFeesWithAncestors;
int64_t nSigOpCostWithAncestors;
};
Expand Down Expand Up @@ -103,12 +107,19 @@ typedef boost::multi_index_container<
boost::multi_index::tag<ancestor_score>,
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
CompareTxMemPoolEntryByAncestorFee
>,
// ELEMENTS
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<confidential_score>,
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
CompareTxMemPoolEntryByConfidentialFee
>
>
> indexed_modified_transaction_set;

typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
typedef indexed_modified_transaction_set::index<confidential_score>::type::iterator modconftxscoreiter; // ELEMENTS

struct update_for_parent_inclusion
{
Expand Down
28 changes: 20 additions & 8 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,20 @@ struct update_descendant_state

struct update_ancestor_state
{
update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost) :
modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost)
update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost, int64_t _discountSize) :
modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost),
discountSize(_discountSize)
{}

void operator() (CTxMemPoolEntry &e)
{ e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost); }
{ e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost, discountSize); }

private:
int64_t modifySize;
CAmount modifyFee;
int64_t modifyCount;
int64_t modifySigOpsCost;
int64_t discountSize;
};

struct update_fee_delta
Expand Down Expand Up @@ -103,6 +105,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
nSizeWithAncestors{GetTxSize()},
nModFeesWithAncestors{nFee},
nSigOpCostWithAncestors{sigOpCost},
discountSizeWithAncestors{GetDiscountTxSize()},
setPeginsSpent(_setPeginsSpent) {}

void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta)
Expand All @@ -122,6 +125,11 @@ size_t CTxMemPoolEntry::GetTxSize() const
return GetVirtualTransactionSize(nTxWeight, sigOpCost);
}

size_t CTxMemPoolEntry::GetDiscountTxSize() const
{
return GetDiscountVirtualTransactionSize(*tx, sigOpCost, ::nBytesPerSigOp);
}

void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants,
const std::set<uint256>& setExclude, std::set<uint256>& descendants_to_remove,
uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
Expand Down Expand Up @@ -160,7 +168,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendan
modifyCount++;
cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
// Update ancestor state for each descendant
mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost()));
mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost(), updateIt->GetDiscountTxSize()));
// Don't directly remove the transaction here -- doing so would
// invalidate iterators in cachedDescendants. Mark it for removal
// by inserting into descendants_to_remove.
Expand Down Expand Up @@ -371,12 +379,14 @@ void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncesto
int64_t updateSize = 0;
CAmount updateFee = 0;
int64_t updateSigOpsCost = 0;
int64_t discountSize = 0;
for (txiter ancestorIt : setAncestors) {
updateSize += ancestorIt->GetTxSize();
updateFee += ancestorIt->GetModifiedFee();
updateSigOpsCost += ancestorIt->GetSigOpCost();
discountSize += ancestorIt->GetDiscountTxSize();
}
mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost));
mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost, discountSize));
}

void CTxMemPool::UpdateChildrenForRemoval(txiter it)
Expand Down Expand Up @@ -406,8 +416,9 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, b
int64_t modifySize = -((int64_t)removeIt->GetTxSize());
CAmount modifyFee = -removeIt->GetModifiedFee();
int modifySigOps = -removeIt->GetSigOpCost();
int64_t discountSize = -((int64_t)removeIt->GetDiscountTxSize());
for (txiter dit : setDescendants) {
mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps));
mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps, discountSize));
}
}
}
Expand Down Expand Up @@ -456,7 +467,7 @@ void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFe
assert(int64_t(nCountWithDescendants) > 0);
}

void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps, int64_t discountSize)
{
nSizeWithAncestors += modifySize;
assert(int64_t(nSizeWithAncestors) > 0);
Expand All @@ -465,6 +476,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
assert(int64_t(nCountWithAncestors) > 0);
nSigOpCostWithAncestors += modifySigOps;
assert(int(nSigOpCostWithAncestors) >= 0);
discountSizeWithAncestors += discountSize;
}

CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
Expand Down Expand Up @@ -1030,7 +1042,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeD
CalculateDescendants(it, setDescendants);
setDescendants.erase(it);
for (txiter descendantIt : setDescendants) {
mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0));
mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0, 0));
}
++nTransactionsUpdated;
}
Expand Down
Loading

0 comments on commit 790af77

Please sign in to comment.