9 #include <chainparams.h> 27 #include <util/time.h> 40 const int height{pindexPrev->
nHeight + 1};
43 if (height % difficulty_adjustment_interval == 0) {
51 int64_t nOldTime = pblock->
nTime;
55 if (nOldTime < nNewTime) {
56 pblock->
nTime = nNewTime;
64 return nNewTime - nOldTime;
92 m_mempool{options.use_mempool ? mempool :
nullptr},
93 m_chainstate{chainstate},
102 if (
const auto blockmintxfee{
args.
GetArg(
"-blockmintxfee")}) {
105 options.print_modified_fee =
args.
GetBoolArg(
"-printpriority", options.print_modified_fee);
106 if (!options.block_reserved_weight) {
107 options.block_reserved_weight =
args.
GetIntArg(
"-blockreservedweight");
111 void BlockAssembler::resetBlock()
114 nBlockWeight = *
Assert(m_options.block_reserved_weight);
115 nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
122 std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
124 const auto time_start{SteadyClock::now()};
129 CBlock*
const pblock = &pblocktemplate->block;
133 pblock->
vtx.emplace_back();
136 CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
137 assert(pindexPrev !=
nullptr);
140 pblock->
nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
143 if (chainparams.MineBlocksOnDemand()) {
152 m_mempool->StartBlockBuilding();
154 m_mempool->StopBlockBuilding();
157 const auto time_1{SteadyClock::now()};
159 m_last_block_num_txs = nBlockTx;
160 m_last_block_weight = nBlockWeight;
166 CoinbaseTx& coinbase_tx{pblocktemplate->m_coinbase_tx};
169 coinbaseTx.
vin.resize(1);
170 coinbaseTx.
vin[0].prevout.SetNull();
172 coinbase_tx.sequence = coinbaseTx.
vin[0].nSequence;
175 coinbaseTx.
vout.resize(1);
176 coinbaseTx.
vout[0].scriptPubKey = m_options.coinbase_output_script;
179 coinbaseTx.
vout[0].nValue = block_reward;
180 coinbase_tx.block_reward_remaining = block_reward;
187 if (m_options.include_dummy_extranonce) {
192 coinbaseTx.
vin[0].scriptSig <<
OP_0;
194 coinbase_tx.script_sig_prefix = coinbaseTx.
vin[0].scriptSig;
197 coinbase_tx.lock_time = coinbaseTx.
nLockTime;
200 m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
203 if (final_coinbase->HasWitness()) {
204 const auto& witness_stack{final_coinbase->vin[0].scriptWitness.stack};
207 Assert(witness_stack.size() == 1 && witness_stack[0].size() == 32);
208 coinbase_tx.witness =
uint256(witness_stack[0]);
211 Assert(witness_index >= 0 && static_cast<size_t>(witness_index) < final_coinbase->vout.size());
212 coinbase_tx.required_outputs.push_back(final_coinbase->vout[witness_index]);
215 LogInfo(
"CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n",
GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
219 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
223 if (m_options.test_block_validity) {
226 throw std::runtime_error(
strprintf(
"TestBlockValidity failed: %s", state.ToString()));
229 const auto time_2{SteadyClock::now()};
232 Ticks<MillisecondsDouble>(time_1 - time_start),
233 Ticks<MillisecondsDouble>(time_2 - time_1),
234 Ticks<MillisecondsDouble>(time_2 - time_start));
236 return std::move(pblocktemplate);
239 bool BlockAssembler::TestChunkBlockLimits(
FeePerWeight chunk_feerate, int64_t chunk_sigops_cost)
const 241 if (nBlockWeight + chunk_feerate.
size >= m_options.nBlockMaxWeight) {
252 bool BlockAssembler::TestChunkTransactions(
const std::vector<CTxMemPoolEntryRef>& txs)
const 254 for (
const auto tx : txs) {
264 pblocktemplate->block.vtx.emplace_back(entry.
GetSharedTx());
265 pblocktemplate->vTxFees.push_back(entry.
GetFee());
266 pblocktemplate->vTxSigOpsCost.push_back(entry.
GetSigOpCost());
272 if (m_options.print_modified_fee) {
273 LogInfo(
"fee rate %s txid %s\n",
279 void BlockAssembler::addChunks()
284 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
285 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
286 int64_t nConsecutiveFailed = 0;
288 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> selected_transactions;
293 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
296 while (selected_transactions.size() > 0) {
298 if (chunk_feerate_vsize << m_options.blockMinFeeRate.GetFeePerVSize()) {
303 int64_t chunk_sig_ops = 0;
304 for (
const auto& tx : selected_transactions) {
305 chunk_sig_ops += tx.get().GetSigOpCost();
309 if (!TestChunkBlockLimits(chunk_feerate, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
311 m_mempool->SkipBuilderChunk();
312 ++nConsecutiveFailed;
314 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
315 BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.nBlockMaxWeight) {
320 m_mempool->IncludeBuilderChunk();
323 nConsecutiveFailed = 0;
324 for (
const auto& tx : selected_transactions) {
327 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
330 selected_transactions.clear();
331 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
338 if (block.
vtx.size() == 0) {
339 block.
vtx.emplace_back(coinbase);
341 block.
vtx[0] = coinbase;
344 block.
nTime = timestamp;
357 interrupt_wait =
true;
358 kernel_notifications.m_tip_block_cv.notify_all();
364 const std::unique_ptr<CBlockTemplate>& block_template,
367 bool& interrupt_wait)
376 const auto deadline = now + options.
timeout;
381 bool tip_changed{
false};
386 AssertLockHeld(kernel_notifications.m_tip_block_mutex);
387 const auto tip_block{kernel_notifications.TipBlock()};
391 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
392 return tip_changed || chainman.
m_interrupt || interrupt_wait;
394 if (interrupt_wait) {
395 interrupt_wait =
false;
408 if (!tip_changed && allow_min_difficulty) {
410 if (now > tip_time + 20min) {
431 if (tip_changed)
return new_tmpl;
434 if (current_fees == -1) {
435 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
439 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
441 if (new_fees >= current_fees + options.
fee_threshold)
return new_tmpl;
445 }
while (now < deadline);
455 return BlockRef{tip->GetBlockHash(), tip->nHeight};
462 while (
const std::optional<int> remaining = chainman.BlocksAheadOfTip()) {
463 const int cooldown_seconds = std::clamp(*remaining, 3, 20);
469 const auto tip_block = kernel_notifications.TipBlock();
470 return chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);
473 interrupt_mining =
false;
478 const auto tip_block = kernel_notifications.
TipBlock();
479 if (tip_block && *tip_block != last_tip_hash) {
480 last_tip_hash = *tip_block;
495 if (timeout < 0ms) timeout = 0ms;
496 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
497 auto deadline{std::chrono::steady_clock::now() + timeout};
505 return kernel_notifications.TipBlock() || chainman.m_interrupt || interrupt;
514 return Assume(kernel_notifications.TipBlock()) != current_tip || chainman.m_interrupt || interrupt;
std::shared_ptr< const CTransaction > CTransactionRef
int32_t GetTxWeight() const
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
static time_point now() noexcept
Return current system time or mocked time, if set.
static constexpr unsigned MAX_CLUSTER_COUNT_LIMIT
std::chrono::time_point< NodeClock > time_point
std::optional< uint256 > TipBlock() EXCLUSIVE_LOCKS_REQUIRED(m_tip_block_mutex)
The block for which the last blockTip notification was received.
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
int64_t GetBlockTime() const
Generate a new block, without valid proof-of-work.
int32_t GetTxSize() const
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
static constexpr unsigned int DEFAULT_BLOCK_RESERVED_WEIGHT
Default for -blockreservedweight.
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
std::optional< BlockRef > GetTip(ChainstateManager &chainman)
void GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev) const
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
Hash/height pair to help track and identify blocks.
bool fPowAllowMinDifficultyBlocks
std::optional< BlockRef > WaitTipChanged(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const uint256 ¤t_tip, MillisecondsDouble &timeout, bool &interrupt)
size_t coinbase_output_max_additional_sigops
The maximum additional sigops which the pool will add in coinbase transaction outputs.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
util::Result< void > ApplyArgsManOptions(const ArgsManager &args, BlockManager::Options &opts)
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction. ...
Tagged wrapper around FeeFrac to avoid unit confusion.
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule) ...
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
CAmount GetModifiedFee() const
const util::SignalInterrupt & m_interrupt
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
int64_t CAmount
Amount in satoshis (Can be negative)
uint256 GetBlockHash() const
CAmount fee_threshold
The wait method will not return a new template unless it has fees at least fee_threshold sats higher ...
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
Chainstate stores and provides an API to update our local knowledge of the current best chain...
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
const CAmount & GetFee() const
CTransactionRef GetSharedTx() const
Template containing all coinbase transaction fields that are set by our miner code.
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
std::string ToString() const
void InterruptWait(KernelNotifications &kernel_notifications, bool &interrupt_wait)
#define WAIT_LOCK(cs, name)
Parameters that influence chain consensus.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::vector< CTxOut > vout
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define Assume(val)
Assume is the identity function.
int64_t GetMedianTimePast() const
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static FeePerVSize ToFeePerVSize(FeePerWeight feerate)
int64_t DifficultyAdjustmentInterval() const
int64_t GetMinimumTime(const CBlockIndex *pindexPrev, const int64_t difficulty_adjustment_interval)
Get the minimum time a miner should use in the next block.
const CChainParams & GetParams() const
#define LogDebug(category,...)
static time_point now() noexcept
Return current system time or mocked time, if set.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
The block chain is a tree shaped structure starting with the genesis block at the root...
Serialized script, used inside transaction inputs and outputs.
const CTransaction & GetTx() const
BlockAssembler(Chainstate &chainstate, const CTxMemPool *mempool, const Options &options)
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac...
bool m_checked_witness_commitment
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
int64_t GetSigOpCost() const
bool CooldownIfHeadersAhead(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const BlockRef &last_tip, bool &interrupt_mining)
Wait while the best known header extends the current chain tip AND at least one block is being added ...
A mutable version of CTransaction.
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time...
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65)...
int nHeight
height of the entry in the chain. The genesis block has height 0
const Consensus::Params & GetConsensus() const
BlockValidationState TestBlockValidity(Chainstate &chainstate, const CBlock &block, const bool check_pow, const bool check_merkle_root)
Verify a block, including transactions.
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found.
std::unique_ptr< CBlockTemplate > WaitAndCreateNewBlock(ChainstateManager &chainman, KernelNotifications &kernel_notifications, CTxMemPool *mempool, const std::unique_ptr< CBlockTemplate > &block_template, const BlockWaitOptions &options, const BlockAssembler::Options &assemble_options, bool &interrupt_wait)
Return a new block template when fees rise to a certain threshold or after a new tip; return nullopt ...
static int64_t GetBlockWeight(const CBlock &block)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
void RegenerateCommitments(CBlock &block, ChainstateManager &chainman)
Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed...
static constexpr unsigned int MINIMUM_BLOCK_RESERVED_WEIGHT
This accounts for the block header, var_int encoding of the transaction count and a minimally viable ...
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define Assert(val)
Identity function.
MillisecondsDouble timeout
How long to wait before returning nullptr instead of a new template.
const Txid & GetHash() const LIFETIMEBOUND
bool m_checked_merkle_root
std::optional< size_t > block_reserved_weight
The default reserved weight for the fixed-size block header, transaction count and coinbase transacti...
static constexpr int64_t MAX_TIMEWARP
Maximum number of seconds that the timestamp of the first block of a difficulty adjustment period is ...