9#include <chainparams.h>
40 const int height{pindexPrev->
nHeight + 1};
43 if (height % difficulty_adjustment_interval == 0) {
44 min_time = std::max<int64_t>(min_time, pindexPrev->
GetBlockTime() - MAX_TIMEWARP);
51 int64_t nOldTime = pblock->
nTime;
55 if (nOldTime < nNewTime) {
56 pblock->
nTime = nNewTime;
64 return nNewTime - nOldTime;
71 block.
vtx.at(0) = MakeTransactionRef(tx);
92 m_mempool{options.use_mempool ? mempool : nullptr},
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");
124 const auto time_start{SteadyClock::now()};
133 pblock->
vtx.emplace_back();
137 assert(pindexPrev !=
nullptr);
157 const auto time_1{SteadyClock::now()};
169 coinbaseTx.
vin.resize(1);
170 coinbaseTx.
vin[0].prevout.SetNull();
172 coinbase_tx.
sequence = coinbaseTx.
vin[0].nSequence;
175 coinbaseTx.
vout.resize(1);
179 coinbaseTx.
vout[0].nValue = block_reward;
192 coinbaseTx.
vin[0].scriptSig <<
OP_0;
199 pblock->
vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
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);
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]);
226 throw std::runtime_error(
strprintf(
"TestBlockValidity failed: %s", state.ToString()));
229 const auto time_2{SteadyClock::now()};
254 for (
const auto tx : txs) {
273 LogInfo(
"fee rate %s txid %s\n",
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;
289 selected_transactions.reserve(MAX_CLUSTER_COUNT_LIMIT);
294 FeePerVSize chunk_feerate_vsize = ToFeePerVSize(chunk_feerate);
296 while (selected_transactions.size() > 0) {
303 int64_t chunk_sig_ops = 0;
304 for (
const auto& tx : selected_transactions) {
305 chunk_sig_ops += tx.get().GetSigOpCost();
312 ++nConsecutiveFailed;
314 if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES &&
nBlockWeight +
323 nConsecutiveFailed = 0;
324 for (
const auto& tx : selected_transactions) {
327 pblocktemplate->m_package_feerates.emplace_back(chunk_feerate_vsize);
330 selected_transactions.clear();
332 chunk_feerate_vsize = ToFeePerVSize(chunk_feerate);
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);
462 while (
const std::optional<int> remaining = chainman.BlocksAheadOfTip()) {
463 const int cooldown_seconds = std::clamp(*remaining, 3, 20);
469 const auto tip_block = kernel_notifications.TipBlock();
470 return chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);
473 interrupt_mining =
false;
478 const auto tip_block = kernel_notifications.
TipBlock();
479 if (tip_block && *tip_block != last_tip_hash) {
480 last_tip_hash = *tip_block;
495 if (timeout < 0ms) timeout = 0ms;
496 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
497 auto deadline{std::chrono::steady_clock::now() + timeout};
505 return kernel_notifications.TipBlock() || chainman.m_interrupt || interrupt;
514 return Assume(kernel_notifications.TipBlock()) != current_tip || chainman.m_interrupt || interrupt;
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.
void resetBlock()
Clear the block's state and prepare for assembling a new block.
bool TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const
Test if a new chunk would "fit" in the block.
bool TestChunkTransactions(const std::vector< CTxMemPoolEntryRef > &txs) const
Perform locktime checks on each transaction in a chunk: This check should always succeed,...
void AddToBlock(const CTxMemPoolEntry &entry)
Add a tx to the block.
std::unique_ptr< CBlockTemplate > CreateNewBlock()
Construct a new block template.
void addChunks() EXCLUSIVE_LOCKS_REQUIRED(m_mempool -> cs)
Add transactions based on chunk feerate.
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
bool MineBlocksOnDemand() const
Whether it is possible to mine blocks on demand (no retargeting).
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
CFeeRate()=default
Fee rate of 0 satoshis per 0 vB.
FeePerVSize GetFeePerVSize() const
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 ...
void StopBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs)
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void StartBlockBuilding() const EXCLUSIVE_LOCKS_REQUIRED(cs)
void IncludeBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs)
void SkipBuilderChunk() const EXCLUSIVE_LOCKS_REQUIRED(cs)
FeePerWeight GetBlockBuilderChunk(std::vector< CTxMemPoolEntry::CTxMemPoolEntryRef > &entries) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Chainstate stores and provides an API to update our local knowledge of the current best chain.
ChainstateManager & m_chainman
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
Chainstate & ActiveChainstate() const
const util::SignalInterrupt & m_interrupt
VersionBitsCache m_versionbitscache
Track versionbit status.
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
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Determine what nVersion a new block should use.
Generate a new block, without valid proof-of-work.
Chainstate & m_chainstate
void resetBlock()
Clear the block's state and prepare for assembling a new block.
const CTxMemPool *const m_mempool
bool TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const
Test if a new chunk would "fit" in the block.
bool TestChunkTransactions(const std::vector< CTxMemPoolEntryRef > &txs) const
Perform locktime checks on each transaction in a chunk: This check should always succeed,...
const CChainParams & chainparams
void AddToBlock(const CTxMemPoolEntry &entry)
Add a tx to the block.
uint64_t nBlockSigOpsCost
int64_t m_lock_time_cutoff
std::unique_ptr< CBlockTemplate > pblocktemplate
static std::optional< int64_t > m_last_block_num_txs
The number of transactions in the last assembled block (excluding coinbase transaction).
BlockAssembler(Chainstate &chainstate, const CTxMemPool *mempool, const Options &options)
std::unique_ptr< CBlockTemplate > CreateNewBlock()
Construct a new block template.
static std::optional< int64_t > m_last_block_weight
The weight of the last assembled block (including reserved weight for block header,...
void addChunks() EXCLUSIVE_LOCKS_REQUIRED(m_mempool -> cs)
Add transactions based on chunk feerate.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::optional< uint256 > TipBlock() EXCLUSIVE_LOCKS_REQUIRED(m_tip_block_mutex)
std::string ToString() const
constexpr uint256()=default
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs,...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
FeePerUnit< VSizeTag > FeePerVSize
FeePerUnit< WeightTag > FeePerWeight
#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.
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)
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.
void InterruptWait(KernelNotifications &kernel_notifications, bool &interrupt_wait)
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
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)
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
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
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.
bool include_dummy_extranonce
Whether to include an OP_0 as a dummy extraNonce in the template's coinbase.
std::optional< size_t > block_reserved_weight
The default reserved weight for the fixed-size block header, transaction count and coinbase transacti...
CScript coinbase_output_script
Script to put in the coinbase transaction.
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.
CScript script_sig_prefix
Prefix which needs to be placed at the beginning of the scriptSig.
CAmount block_reward_remaining
Block subsidy plus fees, minus any non-zero required_outputs.
std::vector< CTxOut > required_outputs
std::optional< uint256 > witness
The first (and only) witness stack element of the coinbase input.
#define WAIT_LOCK(cs, name)
#define WITH_LOCK(cs, code)
#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.
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
constexpr auto TicksSinceEpoch(Timepoint t)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
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.