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;
161 coinbaseTx.
vin.resize(1);
162 coinbaseTx.
vin[0].prevout.SetNull();
164 coinbaseTx.
vout.resize(1);
165 coinbaseTx.
vout[0].scriptPubKey = m_options.coinbase_output_script;
171 pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
173 LogPrintf(
"CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n",
GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
177 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
181 if (m_options.test_block_validity) {
183 throw std::runtime_error(
strprintf(
"TestBlockValidity failed: %s", state.ToString()));
186 const auto time_2{SteadyClock::now()};
189 Ticks<MillisecondsDouble>(time_1 - time_start),
190 Ticks<MillisecondsDouble>(time_2 - time_1),
191 Ticks<MillisecondsDouble>(time_2 - time_start));
193 return std::move(pblocktemplate);
196bool BlockAssembler::TestPackage(
FeePerWeight package_feerate, int64_t packageSigOpsCost)
const
198 if (nBlockWeight + package_feerate.
size >= m_options.nBlockMaxWeight) {
209bool BlockAssembler::TestPackageTransactions(
const std::vector<CTxMemPoolEntryRef>& txs)
const
211 for (
const auto tx : txs) {
221 pblocktemplate->block.vtx.emplace_back(entry.
GetSharedTx());
222 pblocktemplate->vTxFees.push_back(entry.
GetFee());
223 pblocktemplate->vTxSigOpsCost.push_back(entry.
GetSigOpCost());
229 if (m_options.print_modified_fee) {
236void BlockAssembler::addChunks()
241 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
242 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
243 int64_t nConsecutiveFailed = 0;
245 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> selected_transactions;
250 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
253 while (selected_transactions.size() > 0) {
255 if (chunk_feerate.
fee < m_options.blockMinFeeRate.GetFee(chunk_feerate_vsize.
size)) {
260 int64_t package_sig_ops = 0;
261 for (
const auto& tx : selected_transactions) {
262 package_sig_ops += tx.get().GetSigOpCost();
266 if (!TestPackage(chunk_feerate, package_sig_ops) || !TestPackageTransactions(selected_transactions)) {
268 m_mempool->SkipBuilderChunk();
269 ++nConsecutiveFailed;
271 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
272 BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.nBlockMaxWeight) {
277 m_mempool->IncludeBuilderChunk();
280 nConsecutiveFailed = 0;
281 for (
const auto& tx : selected_transactions) {
284 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
287 selected_transactions.clear();
288 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
295 if (block.
vtx.size() == 0) {
296 block.
vtx.emplace_back(coinbase);
298 block.
vtx[0] = coinbase;
301 block.
nTime = timestamp;
314 interrupt_wait =
true;
315 kernel_notifications.m_tip_block_cv.notify_all();
321 const std::unique_ptr<CBlockTemplate>& block_template,
324 bool& interrupt_wait)
333 const auto deadline = now + options.
timeout;
338 bool tip_changed{
false};
343 AssertLockHeld(kernel_notifications.m_tip_block_mutex);
344 const auto tip_block{kernel_notifications.TipBlock()};
348 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
349 return tip_changed || chainman.
m_interrupt || interrupt_wait;
351 if (interrupt_wait) {
352 interrupt_wait =
false;
365 if (!tip_changed && allow_min_difficulty) {
367 if (now > tip_time + 20min) {
388 if (tip_changed)
return new_tmpl;
391 if (current_fees == -1) {
392 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
396 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
398 if (new_fees >= current_fees + options.
fee_threshold)
return new_tmpl;
402 }
while (now < deadline);
412 return BlockRef{tip->GetBlockHash(), tip->nHeight};
418 if (timeout < 0ms) timeout = 0ms;
419 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
420 auto deadline{std::chrono::steady_clock::now() + timeout};
428 return kernel_notifications.TipBlock() || chainman.m_interrupt;
434 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.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
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...
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 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 GetMinimumTime(const CBlockIndex *pindexPrev, const int64_t difficulty_adjustment_interval)
Get the minimum time a miner should use in the next block.
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 ...
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 ...
#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.