9#include <chainparams.h>
42#include <versionbits.h>
46#include <condition_variable>
61 const int height{pindexPrev->
nHeight + 1};
64 if (height % difficulty_adjustment_interval == 0) {
72 int64_t nOldTime = pblock->
nTime;
76 if (nOldTime < nNewTime) {
77 pblock->
nTime = nNewTime;
85 return nNewTime - nOldTime;
103 : chainparams{chainstate.m_chainman.GetParams()},
104 m_mempool{options.use_mempool ? mempool : nullptr},
105 m_chainstate{chainstate},
115void BlockAssembler::resetBlock()
118 nBlockWeight = *
Assert(m_options.block_reserved_weight);
119 nBlockSigOpsCost = m_options.coinbase_output_max_additional_sigops;
126std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
128 const auto time_start{SteadyClock::now()};
133 CBlock*
const pblock = &pblocktemplate->block;
137 pblock->
vtx.emplace_back();
140 CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
141 assert(pindexPrev !=
nullptr);
144 pblock->
nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
147 if (chainparams.MineBlocksOnDemand()) {
156 m_mempool->StartBlockBuilding();
158 m_mempool->StopBlockBuilding();
161 const auto time_1{SteadyClock::now()};
163 m_last_block_num_txs = nBlockTx;
164 m_last_block_weight = nBlockWeight;
170 CoinbaseTx& coinbase_tx{pblocktemplate->m_coinbase_tx};
173 coinbaseTx.
vin.resize(1);
174 coinbaseTx.
vin[0].prevout.SetNull();
176 coinbase_tx.sequence = coinbaseTx.
vin[0].nSequence;
179 coinbaseTx.
vout.resize(1);
180 coinbaseTx.
vout[0].scriptPubKey = m_options.coinbase_output_script;
183 coinbaseTx.
vout[0].nValue = block_reward;
184 coinbase_tx.block_reward_remaining = block_reward;
195 coinbase_tx.script_sig_prefix = coinbaseTx.
vin[0].scriptSig;
201 coinbaseTx.
vin[0].scriptSig <<
OP_0;
205 coinbase_tx.lock_time = coinbaseTx.
nLockTime;
208 m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
211 if (final_coinbase->HasWitness()) {
212 const auto& witness_stack{final_coinbase->vin[0].scriptWitness.stack};
215 Assert(witness_stack.size() == 1 && witness_stack[0].size() == 32);
216 coinbase_tx.witness =
uint256(witness_stack[0]);
219 Assert(witness_index >= 0 &&
static_cast<size_t>(witness_index) < final_coinbase->vout.size());
220 coinbase_tx.required_outputs.push_back(final_coinbase->vout[witness_index]);
223 LogInfo(
"CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n",
GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
227 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
231 if (m_options.test_block_validity) {
233 throw std::runtime_error(
strprintf(
"TestBlockValidity failed: %s", state.ToString()));
236 const auto time_2{SteadyClock::now()};
239 Ticks<MillisecondsDouble>(time_1 - time_start),
240 Ticks<MillisecondsDouble>(time_2 - time_1),
241 Ticks<MillisecondsDouble>(time_2 - time_start));
243 return std::move(pblocktemplate);
246bool BlockAssembler::TestChunkBlockLimits(
FeePerWeight chunk_feerate, int64_t chunk_sigops_cost)
const
248 if (nBlockWeight + chunk_feerate.
size >= m_options.block_max_weight) {
259bool BlockAssembler::TestChunkTransactions(
const std::vector<CTxMemPoolEntryRef>& txs)
const
261 for (
const auto tx : txs) {
271 pblocktemplate->block.vtx.emplace_back(entry.
GetSharedTx());
272 pblocktemplate->vTxFees.push_back(entry.
GetFee());
273 pblocktemplate->vTxSigOpsCost.push_back(entry.
GetSigOpCost());
279 if (*m_options.print_modified_fee) {
280 LogInfo(
"fee rate %s txid %s\n",
286void BlockAssembler::addChunks()
291 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
292 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
293 int64_t nConsecutiveFailed = 0;
295 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> selected_transactions;
300 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
303 while (selected_transactions.size() > 0) {
305 if (
ByRatio{chunk_feerate_vsize} <
ByRatio{m_options.block_min_fee_rate->GetFeePerVSize()}) {
310 int64_t chunk_sig_ops = 0;
311 for (
const auto& tx : selected_transactions) {
312 chunk_sig_ops += tx.get().GetSigOpCost();
316 if (!TestChunkBlockLimits(chunk_feerate, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
318 m_mempool->SkipBuilderChunk();
319 ++nConsecutiveFailed;
321 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
322 BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.block_max_weight) {
327 m_mempool->IncludeBuilderChunk();
330 nConsecutiveFailed = 0;
331 for (
const auto& tx : selected_transactions) {
334 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
337 selected_transactions.clear();
338 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
345 if (block.
vtx.size() == 0) {
346 block.
vtx.emplace_back(coinbase);
348 block.
vtx[0] = coinbase;
351 block.
nTime = timestamp;
369 explicit SubmitBlockStateCatcher(
const uint256& hash) :
m_hash{hash} {}
374 if (block->GetHash() !=
m_hash)
return;
396 auto sc = std::make_shared<SubmitBlockStateCatcher>(block->GetHash());
398 bool accepted = chainman.
ProcessNewBlock(block,
true,
true, new_block);
401 if (new_block && !*new_block && accepted) {
402 reason =
"duplicate";
403 }
else if (!sc->m_found) {
409 reason =
"inconclusive";
410 }
else if (!sc->m_state.IsValid()) {
411 reason = sc->m_state.GetRejectReason();
412 debug = sc->m_state.GetDebugMessage();
420 interrupt_wait =
true;
421 kernel_notifications.m_tip_block_cv.notify_all();
427 const std::unique_ptr<CBlockTemplate>& block_template,
430 bool& interrupt_wait)
439 const auto deadline = now + wait_options.
timeout;
444 bool tip_changed{
false};
449 AssertLockHeld(kernel_notifications.m_tip_block_mutex);
450 const auto tip_block{kernel_notifications.TipBlock()};
454 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
455 return tip_changed || chainman.
m_interrupt || interrupt_wait;
457 if (interrupt_wait) {
458 interrupt_wait =
false;
471 if (!tip_changed && allow_min_difficulty) {
473 if (now > tip_time + 20min) {
494 if (tip_changed)
return new_tmpl;
497 if (current_fees == -1) {
498 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
502 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
504 if (new_fees >= current_fees + wait_options.
fee_threshold)
return new_tmpl;
508 }
while (now < deadline);
518 return BlockRef{tip->GetBlockHash(), tip->nHeight};
525 while (
const std::optional<int> remaining = chainman.BlocksAheadOfTip()) {
526 const int cooldown_seconds = std::clamp(*remaining, 3, 20);
532 const auto tip_block = kernel_notifications.TipBlock();
533 return chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);
536 interrupt_mining =
false;
541 const auto tip_block = kernel_notifications.
TipBlock();
542 if (tip_block && *tip_block != last_tip_hash) {
543 last_tip_hash = *tip_block;
558 if (timeout < 0ms) timeout = 0ms;
559 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
560 auto deadline{std::chrono::steady_clock::now() + timeout};
568 return kernel_notifications.TipBlock() || chainman.m_interrupt || interrupt;
577 return Assume(kernel_notifications.TipBlock()) != current_tip || chainman.m_interrupt || 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 CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Wrapper around FeeFrac & derived types, which adds a feerate-based ordering which treats equal-feerat...
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 ...
Implement this to subscribe to events generated in validation and mempool.
virtual void BlockChecked(const std::shared_ptr< const CBlock > &, const BlockValidationState &)
Notifies listeners of a block validation result.
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...
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &block, bool force_processing, bool min_pow_checked, bool *new_block) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
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, BlockCreateOptions create_options)
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::optional< uint256 > TipBlock() EXCLUSIVE_LOCKS_REQUIRED(m_tip_block_mutex)
The block for which the last blockTip notification was received.
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 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,...)
BlockValidationState m_state
is used externally by mining IPC clients, so it should only declare simple data definitions.
void RegenerateCommitments(CBlock &block, ChainstateManager &chainman)
Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed.
std::optional< BlockRef > WaitTipChanged(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const uint256 ¤t_tip, MillisecondsDouble &timeout, bool &interrupt)
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
bool SubmitBlock(ChainstateManager &chainman, const std::shared_ptr< const CBlock > &block, bool *new_block, std::string &reason, std::string &debug)
Submit a block and capture the validation state via the BlockChecked callback.
BlockCreateOptions FlattenMiningOptions(BlockCreateOptions options)
Replace null optional values with their hardcoded defaults.
int64_t GetMinimumTime(const CBlockIndex *pindexPrev, const int64_t difficulty_adjustment_interval)
Get the minimum time a miner should use in the next block.
void InterruptWait(KernelNotifications &kernel_notifications, bool &interrupt_wait)
std::unique_ptr< CBlockTemplate > WaitAndCreateNewBlock(ChainstateManager &chainman, KernelNotifications &kernel_notifications, CTxMemPool *mempool, const std::unique_ptr< CBlockTemplate > &block_template, const BlockWaitOptions &wait_options, const BlockCreateOptions &create_options, bool &interrupt_wait)
Return a new block template when fees rise to a certain threshold or after a new tip; return nullopt ...
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
Result< void > CheckMiningOptions(BlockCreateOptions options, bool use_argnames)
Check option values for validity.
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 ...
std::optional< BlockRef > GetTip(ChainstateManager &chainman)
bilingual_str ErrorString(const Result< T > &result)
static FeePerVSize ToFeePerVSize(FeePerWeight feerate)
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.
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.
ValidationSignals * signals
Block template creation options.
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.