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
249 Assert(m_options.block_max_weight);
250 if (nBlockWeight + chunk_feerate.
size >= *m_options.block_max_weight) {
261bool BlockAssembler::TestChunkTransactions(
const std::vector<CTxMemPoolEntryRef>& txs)
const
263 for (
const auto tx : txs) {
273 pblocktemplate->block.vtx.emplace_back(entry.
GetSharedTx());
274 pblocktemplate->vTxFees.push_back(entry.
GetFee());
275 pblocktemplate->vTxSigOpsCost.push_back(entry.
GetSigOpCost());
281 if (*m_options.print_modified_fee) {
282 LogInfo(
"fee rate %s txid %s\n",
288void BlockAssembler::addChunks()
293 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
294 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
295 int64_t nConsecutiveFailed = 0;
297 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> selected_transactions;
302 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
305 while (selected_transactions.size() > 0) {
307 if (
ByRatio{chunk_feerate_vsize} <
ByRatio{m_options.block_min_fee_rate->GetFeePerVSize()}) {
312 int64_t chunk_sig_ops = 0;
313 for (
const auto& tx : selected_transactions) {
314 chunk_sig_ops += tx.get().GetSigOpCost();
318 if (!TestChunkBlockLimits(chunk_feerate, chunk_sig_ops) || !TestChunkTransactions(selected_transactions)) {
320 m_mempool->SkipBuilderChunk();
321 ++nConsecutiveFailed;
324 Assert(m_options.block_max_weight);
325 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
326 BLOCK_FULL_ENOUGH_WEIGHT_DELTA > *m_options.block_max_weight) {
331 m_mempool->IncludeBuilderChunk();
334 nConsecutiveFailed = 0;
335 for (
const auto& tx : selected_transactions) {
338 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
341 selected_transactions.clear();
342 chunk_feerate = m_mempool->GetBlockBuilderChunk(selected_transactions);
349 if (block.
vtx.size() == 0) {
350 block.
vtx.emplace_back(coinbase);
352 block.
vtx[0] = coinbase;
355 block.
nTime = timestamp;
373 explicit SubmitBlockStateCatcher(
const uint256& hash) :
m_hash{hash} {}
378 if (block->GetHash() !=
m_hash)
return;
400 auto sc = std::make_shared<SubmitBlockStateCatcher>(block->GetHash());
402 bool accepted = chainman.
ProcessNewBlock(block,
true,
true, new_block);
405 if (new_block && !*new_block && accepted) {
406 reason =
"duplicate";
407 }
else if (!sc->m_found) {
413 reason =
"inconclusive";
414 }
else if (!sc->m_state.IsValid()) {
415 reason = sc->m_state.GetRejectReason();
416 debug = sc->m_state.GetDebugMessage();
424 interrupt_wait =
true;
425 kernel_notifications.m_tip_block_cv.notify_all();
431 const std::unique_ptr<CBlockTemplate>& block_template,
434 bool& interrupt_wait)
443 const auto deadline = now + wait_options.
timeout;
448 bool tip_changed{
false};
453 AssertLockHeld(kernel_notifications.m_tip_block_mutex);
454 const auto tip_block{kernel_notifications.TipBlock()};
458 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
459 return tip_changed || chainman.
m_interrupt || interrupt_wait;
461 if (interrupt_wait) {
462 interrupt_wait =
false;
475 if (!tip_changed && allow_min_difficulty) {
477 if (now > tip_time + 20min) {
498 if (tip_changed)
return new_tmpl;
501 if (current_fees == -1) {
502 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
506 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
508 if (new_fees >= current_fees + wait_options.
fee_threshold)
return new_tmpl;
512 }
while (now < deadline);
522 return BlockRef{tip->GetBlockHash(), tip->nHeight};
529 while (
const std::optional<int> remaining = chainman.BlocksAheadOfTip()) {
530 const int cooldown_seconds = std::clamp(*remaining, 3, 20);
536 const auto tip_block = kernel_notifications.TipBlock();
537 return chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);
540 interrupt_mining =
false;
545 const auto tip_block = kernel_notifications.
TipBlock();
546 if (tip_block && *tip_block != last_tip_hash) {
547 last_tip_hash = *tip_block;
562 if (timeout < 0ms) timeout = 0ms;
563 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
564 auto deadline{std::chrono::steady_clock::now() + timeout};
572 return kernel_notifications.TipBlock() || chainman.m_interrupt || interrupt;
581 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.