Skip to content
Bitcoin Roots

v29.4-roots.2 · Commit 3: [PATCH 03/21] 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();