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,
120 .notifications = *notifications,
124 .blocks_dir = abs_datadir /
"blocks",
125 .notifications = chainman_opts.notifications,
133 cache_sizes.
coins = (450 << 20) - (2 << 20) - (2 << 22);
137 std::cerr <<
"Failed to load Chain state from your datadir." << std::endl;
142 std::cerr <<
"Failed to verify loaded Chain state from your datadir." << std::endl;
149 if (!chainstate->ActivateBestChain(state,
nullptr)) {
150 std::cerr <<
"Failed to connect best block (" << state.
ToString() <<
")" << std::endl;
157 <<
"Hello! I'm going to print out some information about your datadir." << std::endl
159 <<
"Path: " << abs_datadir << std::endl;
161 LOCK(chainman.GetMutex());
163 <<
"\t" <<
"Reindexing: " << std::boolalpha <<
node::fReindex.load() << std::noboolalpha << std::endl
164 <<
"\t" <<
"Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
165 <<
"\t" <<
"Active Height: " << chainman.ActiveHeight() << std::endl
166 <<
"\t" <<
"Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;
169 std::cout <<
"\t" << tip->
ToString() << std::endl;
173 for (std::string line; std::getline(std::cin, line);) {
175 std::cerr <<
"Empty line found" << std::endl;
179 std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
180 CBlock& block = *blockptr;
183 std::cerr <<
"Block decode failed" << std::endl;
187 if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
188 std::cerr <<
"Block does not start with a coinbase" << std::endl;
192 uint256 hash = block.GetHash();
195 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
198 std::cerr <<
"duplicate" << std::endl;
202 std::cerr <<
"duplicate-invalid" << std::endl;
210 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
212 chainman.UpdateUncommittedBlockStructures(block, pindex);
237 auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
239 bool accepted = chainman.ProcessNewBlock(blockptr,
true,
true, &new_block);
241 if (!new_block && accepted) {
242 std::cerr <<
"duplicate" << std::endl;
246 std::cerr <<
"inconclusive" << std::endl;
249 std::cout << sc->state.ToString() << std::endl;
250 switch (sc->state.GetResult()) {
252 std::cerr <<
"initial value. Block has not yet been rejected" << std::endl;
255 std::cerr <<
"the block header may be on a too-little-work chain" << std::endl;
258 std::cerr <<
"invalid by consensus rules (excluding any below reasons)" << std::endl;
261 std::cerr <<
"Invalid by a change to consensus rules more recent than SegWit." << std::endl;
264 std::cerr <<
"this block was cached as being invalid and we didn't store the reason why" << std::endl;
267 std::cerr <<
"invalid proof of work or time too old" << std::endl;
270 std::cerr <<
"the block's data didn't match the data committed to by the PoW" << std::endl;
273 std::cerr <<
"We don't have the previous block the checked one is built on" << std::endl;
276 std::cerr <<
"A block this one builds on is invalid" << std::endl;
279 std::cerr <<
"block timestamp was > 2 hours in the future (or our clock is bad)" << std::endl;
282 std::cerr <<
"the block failed to meet one of our checkpoints" << std::endl;
291 if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
296 for (
Chainstate* chainstate : chainman.GetAll()) {
297 if (chainstate->CanFlushToDisk()) {
298 chainstate->ForceFlushStateToDisk();
299 chainstate->ResetCoinsViews();
std::string ToString() const
bool DecodeHexBlk(CBlock &, const std::string &strHexBlk)
SynchronizationState
Current sync state passed to tip changed callbacks.
std::atomic_bool fReindex
BlockValidationState state
ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager &chainman, const ChainstateLoadOptions &options)
We don't have the previous block the checked one is built on.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
invalid proof of work or time too old
std::variant< std::monostate, Interrupted > InterruptResult
Simple result type for functions that need to propagate an interrupt status and don't have other retu...
virtual void progress(const bilingual_str &title, int progress_percent, bool resume_possible)
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...
const CChainParams & chainparams
void BlockChecked(const CBlock &block, const BlockValidationState &stateIn) override
Notifies listeners of a block validation result.
An options struct for ChainstateManager, more ergonomically referred to as ChainstateManager::Options...
void UnregisterBackgroundSignalScheduler()
Unregister a CScheduler to give callbacks which should run in the background - these callbacks will n...
the block header may be on a too-little-work chain
util::Result< void > SanityChecks(const Context &)
Ensure a usable environment with all necessary library support.
int main(int argc, char *argv[])
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
submitblock_StateCatcher(const uint256 &hashIn)
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
Implement this to subscribe to events generated in validation and mempool.
static std::unique_ptr< const CChainParams > Main()
bool InitSignatureCache(size_t max_size_bytes)
initial value. Block has not yet been rejected
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync)
Chainstate stores and provides an API to update our local knowledge of the current best chain...
Scripts & signatures ok. Implies all parents are either at least VALID_SCRIPTS, or are ASSUMED_VALID...
this block was cached as being invalid and we didn't store the reason why
std::string ToString() const
the block failed to meet one of our checkpoints
CMainSignals & GetMainSignals()
bool InitScriptExecutionCache(size_t max_size_bytes)
Initializes the script-execution cache.
const CChainParams & chainparams
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...
A base class defining functions for notifying about certain kernel events.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
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.
void RegisterBackgroundSignalScheduler(CScheduler &scheduler)
Register a CScheduler to give callbacks which should run in the background (may only be called once) ...
invalid by consensus rules (excluding any below reasons)
std::thread m_service_thread
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'...
the block's data didn't match the data committed to by the PoW
virtual void warning(const bilingual_str &warning)
bool error(const char *fmt, const Args &... args)
The block chain is a tree shaped structure starting with the genesis block at the root...
void FlushBackgroundCallbacks()
Call any remaining callbacks on the calling thread.
A block this one builds on is invalid.
Context struct holding the kernel library's logically global state, and passed to external libbitcoin...
Invalid by a change to consensus rules more recent than SegWit.
block timestamp was > 2 hours in the future (or our clock is bad)
ChainstateLoadResult LoadChainstate(ChainstateManager &chainman, const CacheSizes &cache_sizes, const ChainstateLoadOptions &options)
This sequence can have 4 types of outcomes:
Simple class for background tasks that should be run periodically or once "after a while"...
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static path absolute(const path &p)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex &index)
#define Assert(val)
Identity function.
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.