Skip to content

Commit 678978f

Browse files
committed
Policy: Restore support for mining based on coin-age priority
This reverts commit 7036cf5 (and much more).
1 parent 3b7028b commit 678978f

22 files changed

+404
-16
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ BITCOIN_CORE_H = \
243243
node/warnings.h \
244244
noui.h \
245245
outputtype.h \
246+
policy/coin_age_priority.h \
246247
policy/feerate.h \
247248
policy/fees.h \
248249
policy/fees_args.h \
@@ -445,6 +446,7 @@ libbitcoin_node_a_SOURCES = \
445446
node/utxo_snapshot.cpp \
446447
node/warnings.cpp \
447448
noui.cpp \
449+
policy/coin_age_priority.cpp \
448450
policy/fees.cpp \
449451
policy/fees_args.cpp \
450452
policy/packages.cpp \

src/bench/mempool_eviction.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212
static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
1313
{
1414
int64_t nTime = 0;
15+
double dPriority = 10.0;
1516
unsigned int nHeight = 1;
1617
uint64_t sequence = 0;
1718
bool spendsCoinbase = false;
1819
unsigned int sigOpCost = 4;
1920
LockPoints lp;
2021
pool.addUnchecked(CTxMemPoolEntry(
21-
tx, nFee, nTime, nHeight, sequence,
22+
tx, nFee, nTime, dPriority, nHeight, sequence,
23+
tx->GetValueOut(),
2224
spendsCoinbase, sigOpCost, lp));
2325
}
2426

src/bench/mempool_stress.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
1717
{
1818
int64_t nTime = 0;
19+
const double coinage_priority = 10.0;
1920
unsigned int nHeight = 1;
2021
uint64_t sequence = 0;
2122
bool spendsCoinbase = false;
2223
unsigned int sigOpCost = 4;
2324
LockPoints lp;
24-
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp));
25+
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, coinage_priority, nHeight, sequence, tx->GetValueOut(), spendsCoinbase, sigOpCost, lp));
2526
}
2627

2728
struct Available {

src/bench/rpc_mempool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
1717
{
1818
LockPoints lp;
19-
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
19+
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_priority=*/0, /*entry_height=*/0, /*entry_sequence=*/0, /*in_chain_input_value=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
2020
}
2121

2222
static void RpcMempool(benchmark::Bench& bench)

src/init.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ void SetupServerArgs(ArgsManager& argsman)
631631
strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)",
632632
Ticks<std::chrono::seconds>(DEFAULT_MAX_TIP_AGE)),
633633
ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
634-
argsman.AddArg("-printpriority", strprintf("Log transaction fee rate in " + CURRENCY_UNIT + "/kvB when mining blocks (default: %u)", DEFAULT_PRINT_MODIFIED_FEE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
634+
argsman.AddArg("-printpriority", strprintf("Log transaction priority and fee rate in " + CURRENCY_UNIT + "/kvB when mining blocks (default: %u)", DEFAULT_PRINT_MODIFIED_FEE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
635635
argsman.AddArg("-uaappend=<cmt>", "Append literal to the user agent string (should only be used for software embedding)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
636636
argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
637637

@@ -660,6 +660,7 @@ void SetupServerArgs(ArgsManager& argsman)
660660
argsman.AddArg("-blockmaxsize=<n>", strprintf("Set maximum block size in bytes (default: %d)", DEFAULT_BLOCK_MAX_SIZE), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
661661
argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
662662
argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
663+
argsman.AddArg("-blockprioritysize=<n>", strprintf("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)", DEFAULT_BLOCK_PRIORITY_SIZE), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
663664
argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
664665

665666
argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);

src/kernel/mempool_entry.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
#include <consensus/amount.h>
99
#include <consensus/validation.h>
1010
#include <core_memusage.h>
11+
#include <policy/coin_age_priority.h>
1112
#include <policy/policy.h>
1213
#include <policy/settings.h>
1314
#include <primitives/transaction.h>
1415
#include <util/epochguard.h>
1516
#include <util/overflow.h>
1617

18+
#include <cassert>
1719
#include <chrono>
1820
#include <functional>
1921
#include <memory>
@@ -84,9 +86,14 @@ class CTxMemPoolEntry
8486
const size_t nUsageSize; //!< ... and total memory usage
8587
const int64_t nTime; //!< Local time when entering the mempool
8688
const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
89+
const double entryPriority; //!< Priority when entering the mempool
8790
const unsigned int entryHeight; //!< Chain height when entering the mempool
91+
double cachedPriority; //!< Last calculated priority
92+
unsigned int cachedHeight; //!< Height at which priority was last calculated
93+
CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain
8894
const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
8995
const int64_t sigOpCost; //!< Total sigop cost
96+
const size_t nModSize; //!< Cached modified size for priority
9097
CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
9198
mutable LockPoints lockPoints; //!< Track the height and time at which tx was final
9299

@@ -107,7 +114,8 @@ class CTxMemPoolEntry
107114

108115
public:
109116
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
110-
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
117+
int64_t time, double entry_priority, unsigned int entry_height, uint64_t entry_sequence,
118+
CAmount in_chain_input_value,
111119
bool spends_coinbase,
112120
int64_t sigops_cost, LockPoints lp)
113121
: tx{tx},
@@ -116,16 +124,25 @@ class CTxMemPoolEntry
116124
nUsageSize{RecursiveDynamicUsage(tx)},
117125
nTime{time},
118126
entry_sequence{entry_sequence},
127+
entryPriority{entry_priority},
119128
entryHeight{entry_height},
129+
cachedPriority{entry_priority},
130+
// Since entries arrive *after* the tip's height, their entry priority is for the height+1
131+
cachedHeight{entry_height + 1},
132+
inChainInputValue{in_chain_input_value},
120133
spendsCoinbase{spends_coinbase},
121134
sigOpCost{sigops_cost},
135+
nModSize{CalculateModifiedSize(*tx, GetTxSize())},
122136
m_modified_fee{nFee},
123137
lockPoints{lp},
124138
nSizeWithDescendants{GetTxSize()},
125139
nModFeesWithDescendants{nFee},
126140
nSizeWithAncestors{GetTxSize()},
127141
nModFeesWithAncestors{nFee},
128-
nSigOpCostWithAncestors{sigOpCost} {}
142+
nSigOpCostWithAncestors{sigOpCost} {
143+
CAmount nValueIn = tx->GetValueOut() + nFee;
144+
assert(inChainInputValue <= nValueIn);
145+
}
129146

130147
CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
131148
CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
@@ -136,6 +153,17 @@ class CTxMemPoolEntry
136153

137154
const CTransaction& GetTx() const { return *this->tx; }
138155
CTransactionRef GetSharedTx() const { return this->tx; }
156+
double GetStartingPriority() const {return entryPriority; }
157+
/**
158+
* Fast calculation of priority as update from cached value, but only valid if
159+
* currentHeight is greater than last height it was recalculated.
160+
*/
161+
double GetPriority(unsigned int currentHeight) const;
162+
/**
163+
* Recalculate the cached priority as of currentHeight and adjust inChainInputValue by
164+
* valueInCurrentBlock which represents input that was just added to or removed from the blockchain.
165+
*/
166+
void UpdateCachedPriority(unsigned int currentHeight, CAmount valueInCurrentBlock);
139167
const CAmount& GetFee() const { return nFee; }
140168
int32_t GetTxSize() const
141169
{

src/node/interfaces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ class ChainImpl : public Chain
726726
{
727727
if (!m_node.mempool) return {};
728728
LockPoints lp;
729-
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, false, 0, lp);
729+
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, 0, 0, false, 0, lp);
730730
LOCK(m_node.mempool->cs);
731731
return m_node.mempool->CheckPackageLimits({tx}, entry.GetTxSize());
732732
}

src/node/miner.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ void BlockAssembler::resetBlock()
124124
// These counters do not include coinbase tx
125125
nBlockTx = 0;
126126
nFees = 0;
127+
128+
lastFewTxs = 0;
129+
blockFinished = false;
127130
}
128131

129132
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
@@ -143,6 +146,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
143146
pblock->vtx.emplace_back();
144147
pblocktemplate->vTxFees.push_back(-1); // updated at end
145148
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
149+
if (m_options.print_modified_fee) {
150+
pblocktemplate->vTxPriorities.push_back(-1); // n/a
151+
}
146152

147153
LOCK(::cs_main);
148154
CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
@@ -163,6 +169,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
163169
int nDescendantsUpdated = 0;
164170
if (m_mempool) {
165171
LOCK(m_mempool->cs);
172+
addPriorityTxs(*m_mempool, nPackagesSelected);
166173
addPackageTxs(*m_mempool, nPackagesSelected, nDescendantsUpdated);
167174
}
168175

@@ -273,9 +280,12 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
273280
inBlock.insert(iter);
274281

275282
if (m_options.print_modified_fee) {
276-
LogPrintf("fee rate %s txid %s\n",
283+
double dPriority = iter->GetPriority(nHeight);
284+
LogPrintf("priority %.1f fee rate %s txid %s\n",
285+
dPriority,
277286
CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(),
278287
iter->GetTx().GetHash().ToString());
288+
pblocktemplate->vTxPriorities.push_back(dPriority);
279289
}
280290
}
281291

@@ -340,6 +350,9 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele
340350
// Keep track of entries that failed inclusion, to avoid duplicate work
341351
CTxMemPool::setEntries failedTx;
342352

353+
// Start by adding all descendants of previously added txs to mapModifiedTx
354+
// and modifying them for their already included ancestors
355+
nDescendantsUpdated += UpdatePackagesForAdded(mempool, inBlock, mapModifiedTx);
343356
CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = mempool.mapTx.get<ancestor_score>().begin();
344357
CTxMemPool::txiter iter;
345358

src/node/miner.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct CBlockTemplate
3838
CBlock block;
3939
std::vector<CAmount> vTxFees;
4040
std::vector<int64_t> vTxSigOpsCost;
41+
std::vector<double> vTxPriorities;
4142
std::vector<unsigned char> vchCoinbaseCommitment;
4243
};
4344

@@ -160,6 +161,10 @@ class BlockAssembler
160161
const CTxMemPool* const m_mempool;
161162
Chainstate& m_chainstate;
162163

164+
// Variables used for addPriorityTxs
165+
int lastFewTxs;
166+
bool blockFinished;
167+
163168
public:
164169
struct Options : BlockCreateOptions {
165170
// Configuration parameters for the block size
@@ -190,11 +195,19 @@ class BlockAssembler
190195
void AddToBlock(CTxMemPool::txiter iter);
191196

192197
// Methods for how to add transactions to a block.
198+
/** Add transactions based on tx "priority" */
199+
void addPriorityTxs(const CTxMemPool& mempool, int &nPackagesSelected) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
193200
/** Add transactions based on feerate including unconfirmed ancestors
194201
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
195202
* statistics from the package selection (for logging statistics). */
196203
void addPackageTxs(const CTxMemPool& mempool, int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
197204

205+
// helper function for addPriorityTxs
206+
/** Test if tx will still "fit" in the block */
207+
bool TestForBlock(CTxMemPool::txiter iter);
208+
/** Test if tx still has unconfirmed parents not yet in block */
209+
bool isStillDependent(const CTxMemPool& mempool, CTxMemPool::txiter iter) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
210+
198211
// helper functions for addPackageTxs()
199212
/** Remove confirmed (inBlock) entries from given set */
200213
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);

0 commit comments

Comments
 (0)