27#include <condition_variable>
39 : m_mempool(mempool), m_chainman(chainman),
m_notifications(notifications), m_block_create_args(
std::move(block_create_args))
63 auto sc = std::make_shared<BlockValidationStateCatcher>(block->GetHash());
71 if (!new_block && accepted) {
73 }
else if (!accepted && (!sc->m_state || sc->m_state->IsValid())) {
78 reason =
"inconclusive";
79 }
else if (!sc->m_state) {
82 reason =
"inconclusive";
83 }
else if (!sc->m_state->IsValid()) {
84 reason = sc->m_state->GetRejectReason();
85 debug = sc->m_state->GetDebugMessage();
87 const bool result{accepted && new_block && reason.empty()};
97 return BlockRef{tip->GetBlockHash(), tip->nHeight};
103 interrupt_wait =
true;
108 const std::unique_ptr<CBlockTemplate>& block_template,
111 bool& interrupt_wait)
120 const auto deadline = now + wait_options.
timeout;
125 bool tip_changed{
false};
130 AssertLockHeld(m_notifications.m_tip_block_mutex);
131 const auto tip_block{m_notifications.TipBlock()};
135 tip_changed =
Assume(tip_block) && tip_block != block_template->block.hashPrevBlock;
138 if (interrupt_wait) {
139 interrupt_wait =
false;
152 if (!tip_changed && allow_min_difficulty) {
154 if (now > tip_time + 20min) {
171 if (tip_changed)
return new_tmpl;
174 if (current_fees == -1) {
175 current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(),
CAmount{0});
179 const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(),
CAmount{0});
181 if (new_fees >= current_fees + wait_options.
fee_threshold)
return new_tmpl;
185 }
while (now < deadline);
190bool BlockTemplateManager::CooldownIfHeadersAhead(
const BlockRef& last_tip,
bool& interrupt_mining)
194 while (
const std::optional<int> remaining = m_chainman.BlocksAheadOfTip()) {
195 const int cooldown_seconds = std::clamp(*remaining, 3, 20);
201 const auto tip_block = m_notifications.TipBlock();
202 return m_chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);
204 if (m_chainman.m_interrupt || interrupt_mining) {
205 interrupt_mining =
false;
211 if (tip_block && *tip_block != last_tip_hash) {
212 last_tip_hash = *tip_block;
226 bool interrupt_wait{
false};
227 return WaitTipChanged(current_tip, timeout, interrupt_wait);
233 if (timeout < 0ms) timeout = 0ms;
234 if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100};
235 auto deadline{std::chrono::steady_clock::now() + timeout};
243 AssertLockHeld(m_notifications.m_tip_block_mutex);
244 return m_notifications.TipBlock() || m_chainman.m_interrupt || interrupt;
246 if (m_chainman.m_interrupt || interrupt) {
253 return Assume(m_notifications.TipBlock()) != current_tip || m_chainman.m_interrupt || interrupt;
255 if (m_chainman.m_interrupt || interrupt) {
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 Assume(val)
Assume is the identity function.
The block chain is a tree shaped structure starting with the genesis block at the root,...
int64_t GetBlockTime() const
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
const Consensus::Params & GetConsensus() const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
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
CChain & ActiveChain() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Generate a new block, without valid proof-of-work.
BlockTemplateManager(CTxMemPool &mempool, ChainstateManager &chainman, KernelNotifications ¬ifications, BlockCreateOptions block_create_args={})
std::unique_ptr< CBlockTemplate > CreateNewTemplate(const BlockCreateOptions &options)
Create a fresh block template, applying init-time defaults to any unset options.
bool SubmitBlock(const std::shared_ptr< const CBlock > &block, std::string &reason, std::string &debug)
Submit a block via ProcessNewBlock and capture validation state.
std::optional< interfaces::BlockRef > GetTip()
Locks cs_main.
const BlockCreateOptions m_block_create_args
ChainstateManager & m_chainman
KernelNotifications & m_notifications
void InterruptWait(bool &interrupt_wait)
Interrupt a blocking wait.
std::unique_ptr< CBlockTemplate > WaitAndCreateNewBlock(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 nullptr ...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
BlockCreateOptions MergeMiningOptions(BlockCreateOptions x, const BlockCreateOptions &y)
Merge two BlockCreateOptions structs, replacing null values in x with non-null values from y.
std::shared_ptr< Chain::Notifications > m_notifications
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.
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 ...
#define WAIT_LOCK(cs, name)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble