9#include <chainparams.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;
90 : chainparams{chainstate.m_chainman.GetParams()},
91 m_mempool{options.use_mempool ? mempool : nullptr},
92 m_chainstate{chainstate},
101 if (
const auto blockmintxfee{
args.
GetArg(
"-blockmintxfee")}) {
104 options.print_modified_fee =
args.
GetBoolArg(
"-printpriority", options.print_modified_fee);
105 options.block_reserved_weight =
args.
GetIntArg(
"-blockreservedweight", options.block_reserved_weight);
108void BlockAssembler::resetBlock()
111 nBlockWeight = m_options.block_reserved_weight;
112 nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
119std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
121 const auto time_start{SteadyClock::now()};
126 CBlock*
const pblock = &pblocktemplate->block;
130 pblock->
vtx.emplace_back();
133 CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
134 assert(pindexPrev !=
nullptr);
137 pblock->
nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
140 if (chainparams.MineBlocksOnDemand()) {
149 m_mempool->StartBlockBuilding();
151 m_mempool->StopBlockBuilding();
154 const auto time_1{SteadyClock::now()};
156 m_last_block_num_txs = nBlockTx;
157 m_last_block_weight = nBlockWeight;
163 CoinbaseTx& coinbase_tx{pblocktemplate->m_coinbase_tx};
166 coinbaseTx.
vin.resize(1);
167 coinbaseTx.
vin[0].prevout.SetNull();
169 coinbase_tx.sequence = coinbaseTx.
vin[0].nSequence;
172 coinbaseTx.
vout.resize(1);
173 coinbaseTx.
vout[0].scriptPubKey = m_options.coinbase_output_script;
176 coinbaseTx.
vout[0].nValue = block_reward;
177 coinbase_tx.block_reward_remaining = block_reward;
184 if (m_options.include_dummy_extranonce) {
189 coinbaseTx.
vin[0].scriptSig <<
OP_0;
191 coinbase_tx.script_sig_prefix = coinbaseTx.
vin[0].scriptSig;
194 coinbase_tx.lock_time = coinbaseTx.
nLockTime;
197 pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
200 if (final_coinbase->HasWitness()) {
201 const auto& witness_stack{final_coinbase->vin[0].scriptWitness.stack};
204 Assert(witness_stack.size() == 1 && witness_stack[0].size() == 32);
205 coinbase_tx.witness =
uint256(witness_stack[0]);
208 Assert(witness_index >= 0 &&
static_cast<size_t>(witness_index) < final_coinbase->vout.size());
209 coinbase_tx.required_outputs.push_back(final_coinbase->vout[witness_index]);
212 LogInfo(
"CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n",
GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
216 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
220 if (m_options.test_block_validity) {
223 throw std::runtime_error(
strprintf(
"TestBlockValidity failed: %s", state.ToString()));
226 const auto time_2{SteadyClock::now()};
229 Ticks<MillisecondsDouble>(time_1 - time_start),
230 Ticks<MillisecondsDouble>(time_2 - time_1),
231 Ticks<MillisecondsDouble>(time_2 - time_start));
233 return std::move(pblocktemplate);
236bool BlockAssembler::TestChunkBlockLimits(
FeePerWeight chunk_feerate, int64_t chunk_sigops_cost)
const
238 if (nBlockWeight + chunk_feerate.
size >= m_options.nBlockMaxWeight) {
249bool BlockAssembler::TestChunkTransactions(
const std::vector<CTxMemPoolEntryRef>& txs)
const
251 for (
const auto tx : txs) {
261 pblocktemplate->block.vtx.emplace_back(entry.
GetSharedTx());
262 pblocktemplate->vTxFees.push_back(entry.
GetFee());
263 pblocktemplate->vTxSigOpsCost.push_back(entry.
GetSigOpCost());
269 if (m_options.print_modified_fee) {
270 LogInfo(
"fee rate %s txid %s\n",
276void BlockAssembler::addChunks()
281 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
282 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
283 int64_t nConsecutiveFailed = 0;
285 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> selected_transactions;
290 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
293 while (selected_transactions.size() > 0) {
295 if (chunk_feerate_vsize << m_options.blockMinFeeRate.GetFeePerVSize()) {
300 int64_t chunk_sig_ops = 0;
301 for (
const auto& tx : selected_transactions) {
302 chunk_sig_ops += tx.get().GetSigOpCost();
306 if (!TestChunkBlockLimits(chunk_feerate, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
308 m_mempool->SkipBuilderChunk();
309 ++nConsecutiveFailed;
311 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
312 BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.nBlockMaxWeight) {
317 m_mempool->IncludeBuilderChunk();
320 nConsecutiveFailed = 0;
321 for (
const auto& tx : selected_transactions) {
324 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
327 selected_transactions.clear();
328 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
335 if (block.
vtx.size() == 0) {
336 block.
vtx.emplace_back(coinbase);
338 block.
vtx[0] = coinbase;
341 block.
nTime = timestamp;
354 interrupt_wait =
true;
355 kernel_notifications.m_tip_block_cv.notify_all();
361 const std::unique_ptr<CBlockTemplate>& block_template,
364 bool& interrupt_wait)
373 const auto deadline = now + options.
timeout;
378 bool tip_changed{
false};
383 AssertLockHeld(kernel_notifications.m_tip_block_mutex);
384 const auto tip_block{kernel_notifications.TipBlock()};
388 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
389 return tip_changed || chainman.
m_interrupt || interrupt_wait;
391 if (interrupt_wait) {
392 interrupt_wait =
false;
405 if (!tip_changed && allow_min_difficulty) {
407 if (now > tip_time + 20min) {
428 if (tip_changed)
return new_tmpl;
431 if (current_fees == -1) {
432 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
436 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
438 if (new_fees >= current_fees + options.
fee_threshold)
return new_tmpl;
442 }
while (now < deadline);
452 return BlockRef{tip->GetBlockHash(), tip->nHeight};
458 if (timeout < 0ms) timeout = 0ms;
459 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
460 auto deadline{std::chrono::steady_clock::now() + timeout};
468 return kernel_notifications.TipBlock() || chainman.m_interrupt;
474 return Assume(kernel_notifications.TipBlock()) != current_tip || chainman.m_interrupt;
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
int64_t CAmount
Amount in satoshis (Can be negative)
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool m_checked_merkle_root
std::vector< CTransactionRef > vtx
bool m_checked_witness_commitment
The block chain is a tree shaped structure starting with the genesis block at the root,...
uint256 GetBlockHash() const
int64_t GetBlockTime() const
int64_t GetMedianTimePast() const
int nHeight
height of the entry in the chain. The genesis block has height 0
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
const Consensus::Params & GetConsensus() const
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
Serialized script, used inside transaction inputs and outputs.
const Txid & GetHash() const LIFETIMEBOUND
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65).
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
const CTransaction & GetTx() const
int32_t GetTxWeight() const
int64_t GetSigOpCost() const
CTransactionRef GetSharedTx() const
int32_t GetTxSize() const
const CAmount & GetFee() const
CAmount GetModifiedFee() const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev) const
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
const util::SignalInterrupt & m_interrupt
const CChainParams & GetParams() const
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
Generate a new block, without valid proof-of-work.
BlockAssembler(Chainstate &chainstate, const CTxMemPool *mempool, const Options &options)
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::string ToString() const
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction.
static int64_t GetBlockWeight(const CBlock &block)
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs,...
static constexpr int64_t MAX_TIMEWARP
Maximum number of seconds that the timestamp of the first block of a difficulty adjustment period is ...
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
#define LogDebug(category,...)
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
void RegenerateCommitments(CBlock &block, ChainstateManager &chainman)
Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed.
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
util::Result< void > ApplyArgsManOptions(const ArgsManager &args, BlockManager::Options &opts)
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 ...
int64_t GetMinimumTime(const CBlockIndex *pindexPrev, const int64_t difficulty_adjustment_interval)
Get the minimum time a miner should use in the next block.
std::optional< BlockRef > WaitTipChanged(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const uint256 ¤t_tip, MillisecondsDouble &timeout)
void InterruptWait(KernelNotifications &kernel_notifications, bool &interrupt_wait)
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
std::optional< BlockRef > GetTip(ChainstateManager &chainman)
static FeePerVSize ToFeePerVSize(FeePerWeight feerate)
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 ...
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
A mutable version of CTransaction.
std::vector< CTxOut > vout
Parameters that influence chain consensus.
int64_t DifficultyAdjustmentInterval() const
bool fPowAllowMinDifficultyBlocks
Tagged wrapper around FeeFrac to avoid unit confusion.
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::time_point< NodeClock > time_point
Hash/height pair to help track and identify blocks.
size_t block_reserved_weight
The default reserved weight for the fixed-size block header, transaction count and coinbase transacti...
size_t coinbase_output_max_additional_sigops
The maximum additional sigops which the pool will add in coinbase transaction outputs.
MillisecondsDouble timeout
How long to wait before returning nullptr instead of a new template.
CAmount fee_threshold
The wait method will not return a new template unless it has fees at least fee_threshold sats higher ...
Template containing all coinbase transaction fields that are set by our miner code.
#define WAIT_LOCK(cs, name)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
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 constexpr unsigned MAX_CLUSTER_COUNT_LIMIT
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
BlockValidationState TestBlockValidity(Chainstate &chainstate, const CBlock &block, const bool check_pow, const bool check_merkle_root)
Verify a block, including transactions.