v29.4-roots.1 · Commit 3: [PATCH 03/13] policy: restore conservative relay and network controls
src/node/miner.cpp
Before: src/node/miner.cpp · After: src/node/miner.cpp
File metadata
index b9ecd855f0a60fce28f8395c94a4eae8ee6458b6..aabe3fef4d97e3fb612f1a37d4e40ef3b3be6ea9 100644
Download original patch · Release notes
Diff rows 1–107 of 107. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/node/miner.cpp
CHANGED
|
@@ -77,6 +77,7 @@ static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
|
|
| 77 |
Assert(options.block_reserved_weight <= MAX_BLOCK_WEIGHT);
|
| 78 |
Assert(options.block_reserved_weight >= MINIMUM_BLOCK_RESERVED_WEIGHT);
|
| 79 |
Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST);
|
|
|
|
| 80 |
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
|
| 81 |
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.
|
| 82 |
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, options.block_reserved_weight, MAX_BLOCK_WEIGHT);
|
|
@@ -89,12 +90,26 @@ BlockAssembler::BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool
|
|
| 89 |
m_chainstate{chainstate},
|
| 90 |
m_options{ClampOptions(options)}
|
| 91 |
{
|
|
|
|
| 92 |
}
|
| 93 |
|
| 94 |
void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& options)
|
| 95 |
{
|
| 96 |
// Block resource limits
|
| 97 |
-
options.nBlockMaxWeight = args.GetIntArg("-blockmaxweight", options.nBlockMaxWeight);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
if (const auto blockmintxfee{args.GetArg("-blockmintxfee")}) {
|
| 99 |
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
|
| 100 |
}
|
|
@@ -107,6 +122,7 @@ void BlockAssembler::resetBlock()
|
|
| 107 |
inBlock.clear();
|
| 108 |
|
| 109 |
// Reserve space for fixed-size block header, txs count, and coinbase tx.
|
|
|
|
| 110 |
nBlockWeight = m_options.block_reserved_weight;
|
| 111 |
nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
|
| 112 |
|
|
@@ -147,6 +163,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
|
|
| 147 |
int nPackagesSelected = 0;
|
| 148 |
int nDescendantsUpdated = 0;
|
| 149 |
if (m_mempool) {
|
|
|
|
|
|
|
|
|
|
| 150 |
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
|
| 151 |
}
|
| 152 |
|
|
@@ -195,7 +214,7 @@ void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet)
|
|
| 195 |
{
|
| 196 |
for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) {
|
| 197 |
// Only test txs not already in the block
|
| 198 |
-
if (inBlock.count((*iit)->GetSharedTx()->GetHash())) {
|
| 199 |
testSet.erase(iit++);
|
| 200 |
} else {
|
| 201 |
iit++;
|
|
@@ -217,12 +236,21 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
|
|
| 217 |
|
| 218 |
// Perform transaction-level checks before adding to block:
|
| 219 |
// - transaction finality (locktime)
|
|
|
|
| 220 |
bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) const
|
| 221 |
{
|
|
|
|
| 222 |
for (CTxMemPool::txiter it : package) {
|
| 223 |
if (!IsFinalTx(it->GetTx(), nHeight, m_lock_time_cutoff)) {
|
| 224 |
return false;
|
| 225 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
}
|
| 227 |
return true;
|
| 228 |
}
|
|
@@ -233,10 +261,11 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
|
|
| 233 |
pblocktemplate->vTxFees.push_back(iter->GetFee());
|
| 234 |
pblocktemplate->vTxSigOpsCost.push_back(iter->GetSigOpCost());
|
| 235 |
nBlockWeight += iter->GetTxWeight();
|
|
|
|
| 236 |
++nBlockTx;
|
| 237 |
nBlockSigOpsCost += iter->GetSigOpCost();
|
| 238 |
nFees += iter->GetFee();
|
| 239 |
-
inBlock.insert(iter->GetSharedTx()->GetHash());
|
| 240 |
|
| 241 |
if (m_options.print_modified_fee) {
|
| 242 |
LogPrintf("fee rate %s txid %s\n",
|
|
@@ -333,7 +362,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
|
|
| 333 |
if (mi != mempool.mapTx.get<ancestor_score>().end()) {
|
| 334 |
auto it = mempool.mapTx.project<0>(mi);
|
| 335 |
assert(it != mempool.mapTx.end());
|
| 336 |
-
if (mapModifiedTx.count(it) || inBlock.count(it->GetSharedTx()->GetHash()) || failedTx.count(it->GetSharedTx()->GetHash())) {
|
| 337 |
++mi;
|
| 338 |
continue;
|
| 339 |
}
|
|
@@ -367,7 +396,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
|
|
| 367 |
|
| 368 |
// We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
|
| 369 |
// contain anything that is inBlock.
|
| 370 |
-
assert(!inBlock.count(iter->GetSharedTx()->GetHash()));
|
| 371 |
|
| 372 |
uint64_t packageSize = iter->GetSizeWithAncestors();
|
| 373 |
CAmount packageFees = iter->GetModFeesWithAncestors();
|
|
|
|
| 77 |
Assert(options.block_reserved_weight <= MAX_BLOCK_WEIGHT);
|
| 78 |
Assert(options.block_reserved_weight >= MINIMUM_BLOCK_RESERVED_WEIGHT);
|
| 79 |
Assert(options.coinbase_output_max_additional_sigops <= MAX_BLOCK_SIGOPS_COST);
|
| 80 |
+
options.nBlockMaxSize = std::clamp<size_t>(options.nBlockMaxSize, DEFAULT_BLOCK_RESERVED_SIZE, MAX_BLOCK_SERIALIZED_SIZE);
|
| 81 |
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
|
| 82 |
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.
|
| 83 |
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, options.block_reserved_weight, MAX_BLOCK_WEIGHT);
|
|
|
|
| 90 |
m_chainstate{chainstate},
|
| 91 |
m_options{ClampOptions(options)}
|
| 92 |
{
|
| 93 |
+
fNeedSizeAccounting = m_options.nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE;
|
| 94 |
}
|
| 95 |
|
| 96 |
void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& options)
|
| 97 |
{
|
| 98 |
// Block resource limits
|
| 99 |
+
// If only one resource limit is set, leave the other unrestricted. If
|
| 100 |
+
// neither is set, retain the conservative default weight limit.
|
| 101 |
+
bool weight_set{false};
|
| 102 |
+
if (args.IsArgSet("-blockmaxweight")) {
|
| 103 |
+
options.nBlockMaxWeight = args.GetIntArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
|
| 104 |
+
options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE;
|
| 105 |
+
weight_set = true;
|
| 106 |
+
}
|
| 107 |
+
if (args.IsArgSet("-blockmaxsize")) {
|
| 108 |
+
options.nBlockMaxSize = args.GetIntArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
|
| 109 |
+
if (!weight_set) {
|
| 110 |
+
options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
if (const auto blockmintxfee{args.GetArg("-blockmintxfee")}) {
|
| 114 |
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
|
| 115 |
}
|
|
|
|
| 122 |
inBlock.clear();
|
| 123 |
|
| 124 |
// Reserve space for fixed-size block header, txs count, and coinbase tx.
|
| 125 |
+
nBlockSize = 1000;
|
| 126 |
nBlockWeight = m_options.block_reserved_weight;
|
| 127 |
nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
|
| 128 |
|
|
|
|
| 163 |
int nPackagesSelected = 0;
|
| 164 |
int nDescendantsUpdated = 0;
|
| 165 |
if (m_mempool) {
|
| 166 |
+
LOCK(m_mempool->cs);
|
| 167 |
+
addPriorityTxs(*m_mempool, nPackagesSelected);
|
| 168 |
+
// addPackageTxs acquires the same recursive mempool lock.
|
| 169 |
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
|
| 170 |
}
|
| 171 |
|
|
|
|
| 214 |
{
|
| 215 |
for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) {
|
| 216 |
// Only test txs not already in the block
|
| 217 |
+
if (inBlock.count(*iit)) {
|
| 218 |
testSet.erase(iit++);
|
| 219 |
} else {
|
| 220 |
iit++;
|
|
|
|
| 236 |
|
| 237 |
// Perform transaction-level checks before adding to block:
|
| 238 |
// - transaction finality (locktime)
|
| 239 |
+
// - serialized size when -blockmaxsize is in use
|
| 240 |
bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) const
|
| 241 |
{
|
| 242 |
+
uint64_t potential_block_size{nBlockSize};
|
| 243 |
for (CTxMemPool::txiter it : package) {
|
| 244 |
if (!IsFinalTx(it->GetTx(), nHeight, m_lock_time_cutoff)) {
|
| 245 |
return false;
|
| 246 |
}
|
| 247 |
+
if (fNeedSizeAccounting) {
|
| 248 |
+
const uint64_t tx_size{::GetSerializeSize(TX_WITH_WITNESS(it->GetTx()))};
|
| 249 |
+
if (potential_block_size + tx_size >= m_options.nBlockMaxSize) {
|
| 250 |
+
return false;
|
| 251 |
+
}
|
| 252 |
+
potential_block_size += tx_size;
|
| 253 |
+
}
|
| 254 |
}
|
| 255 |
return true;
|
| 256 |
}
|
|
|
|
| 261 |
pblocktemplate->vTxFees.push_back(iter->GetFee());
|
| 262 |
pblocktemplate->vTxSigOpsCost.push_back(iter->GetSigOpCost());
|
| 263 |
nBlockWeight += iter->GetTxWeight();
|
| 264 |
+
nBlockSize += GetSerializeSize(TX_WITH_WITNESS(iter->GetTx()));
|
| 265 |
++nBlockTx;
|
| 266 |
nBlockSigOpsCost += iter->GetSigOpCost();
|
| 267 |
nFees += iter->GetFee();
|
| 268 |
+
inBlock.insert(iter);
|
| 269 |
|
| 270 |
if (m_options.print_modified_fee) {
|
| 271 |
LogPrintf("fee rate %s txid %s\n",
|
|
|
|
| 362 |
if (mi != mempool.mapTx.get<ancestor_score>().end()) {
|
| 363 |
auto it = mempool.mapTx.project<0>(mi);
|
| 364 |
assert(it != mempool.mapTx.end());
|
| 365 |
+
if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it->GetSharedTx()->GetHash())) {
|
| 366 |
++mi;
|
| 367 |
continue;
|
| 368 |
}
|
|
|
|
| 396 |
|
| 397 |
// We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
|
| 398 |
// contain anything that is inBlock.
|
| 399 |
+
assert(!inBlock.count(iter));
|
| 400 |
|
| 401 |
uint64_t packageSize = iter->GetSizeWithAncestors();
|
| 402 |
CAmount packageFees = iter->GetModFeesWithAncestors();
|