Skip to content

Commit 41abd40

Browse files
committed
feat: change ordering to use ancestor feerate by discountvsize
This changes transaction ordering in the block template to use the ancestor feerate by _discounted_ vsize.
1 parent 8bafd0c commit 41abd40

File tree

6 files changed

+350
-94
lines changed

6 files changed

+350
-94
lines changed

src/node/miner.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already
320320
if (mit == mapModifiedTx.end()) {
321321
CTxMemPoolModifiedEntry modEntry(desc);
322322
modEntry.nSizeWithAncestors -= it->GetTxSize();
323+
modEntry.discountSizeWithAncestors -= it->GetDiscountTxSize();
323324
modEntry.nModFeesWithAncestors -= it->GetModifiedFee();
324325
modEntry.nSigOpCostWithAncestors -= it->GetSigOpCost();
325326
mapModifiedTx.insert(modEntry);
@@ -383,7 +384,8 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
383384
// and modifying them for their already included ancestors
384385
UpdatePackagesForAdded(inBlock, mapModifiedTx);
385386

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

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

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

407-
modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
408-
if (mi == m_mempool.mapTx.get<ancestor_score>().end()) {
409+
modconftxscoreiter modit = mapModifiedTx.get<confidential_score>().begin();
410+
if (mi == m_mempool.mapTx.get<confidential_score>().end()) {
409411
// We're out of entries in mapTx; use the entry from mapModifiedTx
410412
iter = modit->iter;
411413
fUsingModified = true;
412414
} else {
413415
// Try to compare the mapTx entry to the mapModifiedTx entry
414416
iter = m_mempool.mapTx.project<0>(mi);
415-
if (modit != mapModifiedTx.get<ancestor_score>().end() &&
416-
CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
417+
if (modit != mapModifiedTx.get<confidential_score>().end() &&
418+
CompareTxMemPoolEntryByConfidentialFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
417419
// The best entry in mapModifiedTx has higher score
418420
// than the one from mapTx.
419421
// Switch which transaction (package) to consider
@@ -455,7 +457,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
455457
// Since we always look at the best entry in mapModifiedTx,
456458
// we must erase failed entries so that we can consider the
457459
// next best entry on the next loop iteration
458-
mapModifiedTx.get<ancestor_score>().erase(modit);
460+
mapModifiedTx.get<confidential_score>().erase(modit);
459461
failedTx.insert(iter);
460462
}
461463

@@ -480,7 +482,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
480482
// Test if all tx's are Final
481483
if (!TestPackageTransactions(ancestors)) {
482484
if (fUsingModified) {
483-
mapModifiedTx.get<ancestor_score>().erase(modit);
485+
mapModifiedTx.get<confidential_score>().erase(modit);
484486
failedTx.insert(iter);
485487
}
486488
continue;

src/node/miner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,22 @@ struct CTxMemPoolModifiedEntry {
4141
{
4242
iter = entry;
4343
nSizeWithAncestors = entry->GetSizeWithAncestors();
44+
discountSizeWithAncestors = entry->GetDiscountSizeWithAncestors();
4445
nModFeesWithAncestors = entry->GetModFeesWithAncestors();
4546
nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
4647
}
4748

4849
int64_t GetModifiedFee() const { return iter->GetModifiedFee(); }
4950
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
51+
uint64_t GetDiscountSizeWithAncestors() const { return discountSizeWithAncestors; }
5052
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
5153
size_t GetTxSize() const { return iter->GetTxSize(); }
54+
size_t GetDiscountTxSize() const { return iter->GetDiscountTxSize(); }
5255
const CTransaction& GetTx() const { return iter->GetTx(); }
5356

5457
CTxMemPool::txiter iter;
5558
uint64_t nSizeWithAncestors;
59+
uint64_t discountSizeWithAncestors;
5660
CAmount nModFeesWithAncestors;
5761
int64_t nSigOpCostWithAncestors;
5862
};
@@ -103,12 +107,19 @@ typedef boost::multi_index_container<
103107
boost::multi_index::tag<ancestor_score>,
104108
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
105109
CompareTxMemPoolEntryByAncestorFee
110+
>,
111+
// ELEMENTS
112+
boost::multi_index::ordered_non_unique<
113+
boost::multi_index::tag<confidential_score>,
114+
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
115+
CompareTxMemPoolEntryByConfidentialFee
106116
>
107117
>
108118
> indexed_modified_transaction_set;
109119

110120
typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
111121
typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
122+
typedef indexed_modified_transaction_set::index<confidential_score>::type::iterator modconftxscoreiter; // ELEMENTS
112123

113124
struct update_for_parent_inclusion
114125
{

src/txmempool.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ struct update_descendant_state
4444

4545
struct update_ancestor_state
4646
{
47-
update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost) :
48-
modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost)
47+
update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost, int64_t _discountSize) :
48+
modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost),
49+
discountSize(_discountSize)
4950
{}
5051

5152
void operator() (CTxMemPoolEntry &e)
52-
{ e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost); }
53+
{ e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost, discountSize); }
5354

5455
private:
5556
int64_t modifySize;
5657
CAmount modifyFee;
5758
int64_t modifyCount;
5859
int64_t modifySigOpsCost;
60+
int64_t discountSize;
5961
};
6062

6163
struct update_fee_delta
@@ -103,6 +105,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
103105
nSizeWithAncestors{GetTxSize()},
104106
nModFeesWithAncestors{nFee},
105107
nSigOpCostWithAncestors{sigOpCost},
108+
discountSizeWithAncestors{GetDiscountTxSize()},
106109
setPeginsSpent(_setPeginsSpent) {}
107110

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

128+
size_t CTxMemPoolEntry::GetDiscountTxSize() const
129+
{
130+
return GetDiscountVirtualTransactionSize(*tx, sigOpCost, ::nBytesPerSigOp);
131+
}
132+
125133
void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants,
126134
const std::set<uint256>& setExclude, std::set<uint256>& descendants_to_remove,
127135
uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
@@ -160,7 +168,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendan
160168
modifyCount++;
161169
cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
162170
// Update ancestor state for each descendant
163-
mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost()));
171+
mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost(), updateIt->GetDiscountTxSize()));
164172
// Don't directly remove the transaction here -- doing so would
165173
// invalidate iterators in cachedDescendants. Mark it for removal
166174
// by inserting into descendants_to_remove.
@@ -371,12 +379,14 @@ void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncesto
371379
int64_t updateSize = 0;
372380
CAmount updateFee = 0;
373381
int64_t updateSigOpsCost = 0;
382+
int64_t discountSize = 0;
374383
for (txiter ancestorIt : setAncestors) {
375384
updateSize += ancestorIt->GetTxSize();
376385
updateFee += ancestorIt->GetModifiedFee();
377386
updateSigOpsCost += ancestorIt->GetSigOpCost();
387+
discountSize += ancestorIt->GetDiscountTxSize();
378388
}
379-
mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost));
389+
mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost, discountSize));
380390
}
381391

382392
void CTxMemPool::UpdateChildrenForRemoval(txiter it)
@@ -406,8 +416,9 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, b
406416
int64_t modifySize = -((int64_t)removeIt->GetTxSize());
407417
CAmount modifyFee = -removeIt->GetModifiedFee();
408418
int modifySigOps = -removeIt->GetSigOpCost();
419+
int64_t discountSize = -((int64_t)removeIt->GetDiscountTxSize());
409420
for (txiter dit : setDescendants) {
410-
mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps));
421+
mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps, discountSize));
411422
}
412423
}
413424
}
@@ -456,7 +467,7 @@ void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFe
456467
assert(int64_t(nCountWithDescendants) > 0);
457468
}
458469

459-
void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
470+
void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps, int64_t discountSize)
460471
{
461472
nSizeWithAncestors += modifySize;
462473
assert(int64_t(nSizeWithAncestors) > 0);
@@ -465,6 +476,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
465476
assert(int64_t(nCountWithAncestors) > 0);
466477
nSigOpCostWithAncestors += modifySigOps;
467478
assert(int(nSigOpCostWithAncestors) >= 0);
479+
discountSizeWithAncestors += discountSize;
468480
}
469481

470482
CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
@@ -1030,7 +1042,7 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeD
10301042
CalculateDescendants(it, setDescendants);
10311043
setDescendants.erase(it);
10321044
for (txiter descendantIt : setDescendants) {
1033-
mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0));
1045+
mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0, 0));
10341046
}
10351047
++nTransactionsUpdated;
10361048
}

0 commit comments

Comments
 (0)