41 int main(
int argc,
char* argv[])
46 <<
"Usage: " << argv[0] <<
" DATADIR" << std::endl
47 <<
"Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl
49 <<
"IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl
50 <<
" BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl;
87 std::cout <<
"Block tip changed" << std::endl;
92 std::cout <<
"Header tip changed: " << height <<
", " << timestamp <<
", " << presync << std::endl;
96 std::cout <<
"Progress: " << title.
original <<
", " << progress_percent <<
", " << resume_possible << std::endl;
100 std::cout <<
"Warning: " << warning.
original << std::endl;
102 void flushError(
const std::string& debug_message)
override
104 std::cerr <<
"Error flushing block data to disk: " << debug_message << std::endl;
108 std::cerr <<
"Error: " << debug_message << std::endl;
109 std::cerr << (user_message.
empty() ?
"A fatal internal error occurred." : user_message.
original) << std::endl;
112 auto notifications = std::make_unique<KernelNotifications>();
119 .datadir = abs_datadir,
121 .notifications = *notifications,
125 .blocks_dir = abs_datadir /
"blocks",
126 .notifications = chainman_opts.notifications,
128 ChainstateManager chainman{kernel_context.interrupt, chainman_opts, blockman_opts};
133 cache_sizes.
coins = (450 << 20) - (2 << 20) - (2 << 22);
138 std::cerr <<
"Failed to load Chain state from your datadir." << std::endl;
143 std::cerr <<
"Failed to verify loaded Chain state from your datadir." << std::endl;
150 if (!chainstate->ActivateBestChain(state,
nullptr)) {
151 std::cerr <<
"Failed to connect best block (" << state.
ToString() <<
")" << std::endl;
158 <<
"Hello! I'm going to print out some information about your datadir." << std::endl
160 <<
"Path: " << abs_datadir << std::endl;
162 LOCK(chainman.GetMutex());
164 <<
"\t" <<
"Reindexing: " << std::boolalpha <<
node::fReindex.load() << std::noboolalpha << std::endl
165 <<
"\t" <<
"Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
166 <<
"\t" <<
"Active Height: " << chainman.ActiveHeight() << std::endl
167 <<
"\t" <<
"Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;
170 std::cout <<
"\t" << tip->
ToString() << std::endl;
174 for (std::string line; std::getline(std::cin, line);) {
176 std::cerr <<
"Empty line found" << std::endl;
180 std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
181 CBlock& block = *blockptr;
184 std::cerr <<
"Block decode failed" << std::endl;
188 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase()) {
189 std::cerr <<
"Block does not start with a coinbase" << std::endl;
196 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
199 std::cerr <<
"duplicate" << std::endl;
203 std::cerr <<
"duplicate-invalid" << std::endl;
213 chainman.UpdateUncommittedBlockStructures(block, pindex);
238 auto sc = std::make_shared<submitblock_StateCatcher>(block.
GetHash());
240 bool accepted = chainman.ProcessNewBlock(blockptr,
true,
true, &new_block);
242 if (!new_block && accepted) {
243 std::cerr <<
"duplicate" << std::endl;
247 std::cerr <<
"inconclusive" << std::endl;
250 std::cout << sc->state.ToString() << std::endl;
251 switch (sc->state.GetResult()) {
253 std::cerr <<
"initial value. Block has not yet been rejected" << std::endl;
256 std::cerr <<
"the block header may be on a too-little-work chain" << std::endl;
259 std::cerr <<
"invalid by consensus rules (excluding any below reasons)" << std::endl;
262 std::cerr <<
"Invalid by a change to consensus rules more recent than SegWit." << std::endl;
265 std::cerr <<
"this block was cached as being invalid and we didn't store the reason why" << std::endl;
268 std::cerr <<
"invalid proof of work or time too old" << std::endl;
271 std::cerr <<
"the block's data didn't match the data committed to by the PoW" << std::endl;
274 std::cerr <<
"We don't have the previous block the checked one is built on" << std::endl;
277 std::cerr <<
"A block this one builds on is invalid" << std::endl;
280 std::cerr <<
"block timestamp was > 2 hours in the future (or our clock is bad)" << std::endl;
283 std::cerr <<
"the block failed to meet one of our checkpoints" << std::endl;
292 if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
298 for (
Chainstate* chainstate : chainman.GetAll()) {
299 if (chainstate->CanFlushToDisk()) {
300 chainstate->ForceFlushStateToDisk();
301 chainstate->ResetCoinsViews();
int main(int argc, char *argv[])
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are either at least VALID_SCRIPTS, or are ASSUMED_VALID.
#define Assert(val)
Identity function.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
std::string ToString() const
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
static std::unique_ptr< const CChainParams > Main()
void UnregisterBackgroundSignalScheduler()
Unregister a CScheduler to give callbacks which should run in the background - these callbacks will n...
void RegisterBackgroundSignalScheduler(CScheduler &scheduler)
Register a CScheduler to give callbacks which should run in the background (may only be called once)
void FlushBackgroundCallbacks()
Call any remaining callbacks on the calling thread.
Simple class for background tasks that should be run periodically or once "after a while".
std::thread m_service_thread
Implement this to subscribe to events generated in validation.
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...
std::string ToString() const
A base class defining functions for notifying about certain kernel events.
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync)
virtual void flushError(const std::string &debug_message)
The flush error notification is sent to notify the user that an error occurred while flushing block d...
virtual void fatalError(const std::string &debug_message, const bilingual_str &user_message={})
The fatal error notification is sent to notify the user when an error occurs in kernel code that can'...
virtual void warning(const bilingual_str &warning)
virtual void progress(const bilingual_str &title, int progress_percent, bool resume_possible)
virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex &index)
void BlockChecked(const CBlock &block, const BlockValidationState &stateIn) override
Notifies listeners of a block validation result.
submitblock_StateCatcher(const uint256 &hashIn)
BlockValidationState state
@ BLOCK_CHECKPOINT
the block failed to meet one of our checkpoints
@ BLOCK_RECENT_CONSENSUS_CHANGE
Invalid by a change to consensus rules more recent than SegWit.
@ BLOCK_HEADER_LOW_WORK
the block header may be on a too-little-work chain
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
@ BLOCK_RESULT_UNSET
initial value. Block has not yet been rejected
bool DecodeHexBlk(CBlock &, const std::string &strHexBlk)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
bool error(const char *fmt, const Args &... args)
static path absolute(const path &p)
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
std::variant< std::monostate, Interrupted > InterruptResult
Simple result type for functions that need to propagate an interrupt status and don't have other retu...
util::Result< void > SanityChecks(const Context &)
Ensure a usable environment with all necessary library support.
ChainstateLoadResult LoadChainstate(ChainstateManager &chainman, const CacheSizes &cache_sizes, const ChainstateLoadOptions &options)
This sequence can have 4 types of outcomes:
ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager &chainman, const ChainstateLoadOptions &options)
std::atomic_bool fReindex
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
bool InitSignatureCache(size_t max_size_bytes)
static time_point now() noexcept
Return current system time or mocked time, if set.
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
const CChainParams & chainparams
An options struct for ChainstateManager, more ergonomically referred to as ChainstateManager::Options...
const CChainParams & chainparams
Context struct holding the kernel library's logically global state, and passed to external libbitcoin...
std::function< bool()> check_interrupt
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool InitScriptExecutionCache(size_t max_size_bytes)
Initializes the script-execution cache.
void StopScriptCheckWorkerThreads()
Stop all of the script checking worker threads.
SynchronizationState
Current sync state passed to tip changed callbacks.
CMainSignals & GetMainSignals()
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.