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;
91 : chainparams{chainstate.m_chainman.GetParams()},
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");
111void BlockAssembler::resetBlock()
114 nBlockWeight = *
Assert(m_options.block_reserved_weight);
115 nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
122std::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);
239bool BlockAssembler::TestChunkBlockLimits(
FeePerWeight chunk_feerate, int64_t chunk_sigops_cost)
const
241 if (nBlockWeight + chunk_feerate.
size >= m_options.nBlockMaxWeight) {
252bool 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",
279void 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};
461 if (timeout < 0ms) timeout = 0ms;
462 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
463 auto deadline{std::chrono::steady_clock::now() + timeout};
471 return kernel_notifications.TipBlock() || chainman.m_interrupt;
477 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
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(FeeRateFormat fee_rate_format=FeeRateFormat::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...
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
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...
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 constexpr unsigned int DEFAULT_BLOCK_RESERVED_WEIGHT
Default for -blockreservedweight.
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.
std::optional< 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.