43 int main(
int argc,
char* argv[])
54 <<
"Usage: " << argv[0] <<
" DATADIR" << std::endl
55 <<
"Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl
57 <<
"IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl
58 <<
" BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl;
72 ValidationSignals validation_signals{std::make_unique<util::ImmediateTaskRunner>()};
79 std::cout <<
"Block tip changed" << std::endl;
84 std::cout <<
"Header tip changed: " << height <<
", " << timestamp <<
", " << presync << std::endl;
88 std::cout <<
"Progress: " << title.
original <<
", " << progress_percent <<
", " << resume_possible << std::endl;
92 std::cout <<
"Warning " <<
static_cast<int>(id) <<
" set: " << message.
original << std::endl;
96 std::cout <<
"Warning " <<
static_cast<int>(id) <<
" unset" << std::endl;
100 std::cerr <<
"Error flushing block data to disk: " << message.
original << std::endl;
104 std::cerr <<
"Error: " << message.
original << std::endl;
107 auto notifications = std::make_unique<KernelNotifications>();
114 .datadir = abs_datadir,
115 .notifications = *notifications,
116 .signals = &validation_signals,
120 .blocks_dir = abs_datadir /
"blocks",
121 .notifications = chainman_opts.notifications,
129 cache_sizes.
coins = (450 << 20) - (2 << 20) - (2 << 22);
133 std::cerr <<
"Failed to load Chain state from your datadir." << std::endl;
138 std::cerr <<
"Failed to verify loaded Chain state from your datadir." << std::endl;
145 if (!chainstate->ActivateBestChain(state,
nullptr)) {
146 std::cerr <<
"Failed to connect best block (" << state.
ToString() <<
")" << std::endl;
153 <<
"Hello! I'm going to print out some information about your datadir." << std::endl
155 <<
"Path: " << abs_datadir << std::endl;
157 LOCK(chainman.GetMutex());
159 <<
"\t" <<
"Blockfiles Indexed: " << std::boolalpha << chainman.m_blockman.m_blockfiles_indexed.load() << std::noboolalpha << std::endl
160 <<
"\t" <<
"Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
161 <<
"\t" <<
"Active Height: " << chainman.ActiveHeight() << std::endl
162 <<
"\t" <<
"Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;
165 std::cout <<
"\t" << tip->
ToString() << std::endl;
169 for (std::string line; std::getline(std::cin, line);) {
171 std::cerr <<
"Empty line found" << std::endl;
175 std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
176 CBlock& block = *blockptr;
179 std::cerr <<
"Block decode failed" << std::endl;
183 if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
184 std::cerr <<
"Block does not start with a coinbase" << std::endl;
188 uint256 hash = block.GetHash();
191 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
194 std::cerr <<
"duplicate" << std::endl;
198 std::cerr <<
"duplicate-invalid" << std::endl;
206 const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
208 chainman.UpdateUncommittedBlockStructures(block, pindex);
233 auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
234 validation_signals.RegisterSharedValidationInterface(sc);
235 bool accepted = chainman.ProcessNewBlock(blockptr,
true,
true, &new_block);
236 validation_signals.UnregisterSharedValidationInterface(sc);
237 if (!new_block && accepted) {
238 std::cerr <<
"duplicate" << std::endl;
242 std::cerr <<
"inconclusive" << std::endl;
245 std::cout << sc->state.
ToString() << std::endl;
246 switch (sc->state.GetResult()) {
248 std::cerr <<
"initial value. Block has not yet been rejected" << std::endl;
251 std::cerr <<
"the block header may be on a too-little-work chain" << std::endl;
254 std::cerr <<
"invalid by consensus rules (excluding any below reasons)" << std::endl;
257 std::cerr <<
"Invalid by a change to consensus rules more recent than SegWit." << std::endl;
260 std::cerr <<
"this block was cached as being invalid and we didn't store the reason why" << std::endl;
263 std::cerr <<
"invalid proof of work or time too old" << std::endl;
266 std::cerr <<
"the block's data didn't match the data committed to by the PoW" << std::endl;
269 std::cerr <<
"We don't have the previous block the checked one is built on" << std::endl;
272 std::cerr <<
"A block this one builds on is invalid" << std::endl;
275 std::cerr <<
"block timestamp was > 2 hours in the future (or our clock is bad)" << std::endl;
278 std::cerr <<
"the block failed to meet one of our checkpoints" << std::endl;
286 if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
288 validation_signals.FlushBackgroundCallbacks();
291 for (
Chainstate* chainstate : chainman.GetAll()) {
292 if (chainstate->CanFlushToDisk()) {
293 chainstate->ForceFlushStateToDisk();
294 chainstate->ResetCoinsViews();
void DisableLogging() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Disable logging This offers a slight speedup and slightly smaller memory usage compared to leaving th...
virtual void warningUnset(Warning id)
std::string ToString() const
bool DecodeHexBlk(CBlock &, const std::string &strHexBlk)
SynchronizationState
Current sync state passed to tip changed callbacks.
BCLog::Logger & LogInstance()
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)
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...
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[])
submitblock_StateCatcher(const uint256 &hashIn)
Implement this to subscribe to events generated in validation and mempool.
static std::unique_ptr< const CChainParams > Main()
virtual void fatalError(const bilingual_str &message)
The fatal error notification is sent to notify the user when an error occurs in kernel code that can'...
initial value. Block has not yet been rejected
virtual void flushError(const bilingual_str &message)
The flush error notification is sent to notify the user that an error occurred while flushing block d...
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...
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
const CChainParams & chainparams
virtual void warningSet(Warning id, const bilingual_str &message)
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.
This header provides an interface and simple implementation for a task runner.
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.
invalid by consensus rules (excluding any below reasons)
the block's data didn't match the data committed to by the PoW
The block chain is a tree shaped structure starting with the genesis block at the root...
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:
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)