Merge #13020: Consistently log CValidationState on call failure
e4d0b44
Consistently log CValidationState on failure (Ben Woosley)
Pull request description:
This replaces potential silent failures and partial logging with full logging. Seems providing at least minimal visibility to the failure is a good practice. E.g. `FlushStateToDisk` can return a rare but meaningful out of disk space error that would be better to note than leave out.
Note many of these are related to `ActivateBestChain` or `FlushStateToDisk`. Only a few cases of ignored state remain, e.g. LoadExternalBlockFile and RelayWalletTransaction, where I expect logging would likely be spammy.
Tree-SHA512: fb0e521039e5a5250cd9c82e7a8676423b5e3899d495649c0e71752059d1984e5175f556386ade048f51a7d59f5c8e467df7fe91d746076f97d24c000ccf7891
This commit is contained in:
commit
4741ca5dc8
4 changed files with 29 additions and 15 deletions
|
@ -684,7 +684,7 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
|
||||||
// scan for better chains in the block chain database, that are not yet connected in the active best chain
|
// scan for better chains in the block chain database, that are not yet connected in the active best chain
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ActivateBestChain(state, chainparams)) {
|
if (!ActivateBestChain(state, chainparams)) {
|
||||||
LogPrintf("Failed to connect best block\n");
|
LogPrintf("Failed to connect best block (%s)\n", FormatStateMessage(state));
|
||||||
StartShutdown();
|
StartShutdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1100,8 +1100,10 @@ void static ProcessGetBlockData(CNode* pfrom, const Consensus::Params& consensus
|
||||||
}
|
}
|
||||||
} // release cs_main before calling ActivateBestChain
|
} // release cs_main before calling ActivateBestChain
|
||||||
if (need_activate_chain) {
|
if (need_activate_chain) {
|
||||||
CValidationState dummy;
|
CValidationState state;
|
||||||
ActivateBestChain(dummy, Params(), a_recent_block);
|
if (!ActivateBestChain(state, Params(), a_recent_block)) {
|
||||||
|
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", FormatStateMessage(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
@ -1992,8 +1994,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
||||||
LOCK(cs_most_recent_block);
|
LOCK(cs_most_recent_block);
|
||||||
a_recent_block = most_recent_block;
|
a_recent_block = most_recent_block;
|
||||||
}
|
}
|
||||||
CValidationState dummy;
|
CValidationState state;
|
||||||
ActivateBestChain(dummy, Params(), a_recent_block);
|
if (!ActivateBestChain(state, Params(), a_recent_block)) {
|
||||||
|
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", FormatStateMessage(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
|
@ -85,7 +85,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
||||||
{
|
{
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ActivateBestChain(state, chainparams)) {
|
if (!ActivateBestChain(state, chainparams)) {
|
||||||
throw std::runtime_error("ActivateBestChain failed.");
|
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nScriptCheckThreads = 3;
|
nScriptCheckThreads = 3;
|
||||||
|
|
|
@ -2206,14 +2206,18 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
|
||||||
void FlushStateToDisk() {
|
void FlushStateToDisk() {
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS);
|
if (!FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS)) {
|
||||||
|
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PruneAndFlush() {
|
void PruneAndFlush() {
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
fCheckForPruning = true;
|
fCheckForPruning = true;
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
|
if (!FlushStateToDisk(chainparams, state, FlushStateMode::NONE)) {
|
||||||
|
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoWarning(const std::string& strWarning)
|
static void DoWarning(const std::string& strWarning)
|
||||||
|
@ -3520,7 +3524,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons
|
||||||
}
|
}
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GetMainSignals().BlockChecked(*pblock, state);
|
GetMainSignals().BlockChecked(*pblock, state);
|
||||||
return error("%s: AcceptBlock FAILED (%s)", __func__, state.GetDebugMessage());
|
return error("%s: AcceptBlock FAILED (%s)", __func__, FormatStateMessage(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3528,7 +3532,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons
|
||||||
|
|
||||||
CValidationState state; // Only used to report errors, not invalidity - ignore it
|
CValidationState state; // Only used to report errors, not invalidity - ignore it
|
||||||
if (!g_chainstate.ActivateBestChain(state, chainparams, pblock))
|
if (!g_chainstate.ActivateBestChain(state, chainparams, pblock))
|
||||||
return error("%s: ActivateBestChain failed", __func__);
|
return error("%s: ActivateBestChain failed (%s)", __func__, FormatStateMessage(state));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3646,7 +3650,9 @@ void PruneBlockFilesManual(int nManualPruneHeight)
|
||||||
{
|
{
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
FlushStateToDisk(chainparams, state, FlushStateMode::NONE, nManualPruneHeight);
|
if (!FlushStateToDisk(chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
|
||||||
|
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3900,6 +3906,7 @@ bool LoadChainTip(const CChainParams& chainparams)
|
||||||
LogPrintf("%s: Connecting genesis block...\n", __func__);
|
LogPrintf("%s: Connecting genesis block...\n", __func__);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ActivateBestChain(state, chainparams)) {
|
if (!ActivateBestChain(state, chainparams)) {
|
||||||
|
LogPrintf("%s: failed to activate chain (%s)\n", __func__, FormatStateMessage(state));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4014,7 +4021,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
|
||||||
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
|
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
|
||||||
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||||
if (!g_chainstate.ConnectBlock(block, state, pindex, coins, chainparams))
|
if (!g_chainstate.ConnectBlock(block, state, pindex, coins, chainparams))
|
||||||
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4144,12 +4151,14 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!DisconnectTip(state, params, nullptr)) {
|
if (!DisconnectTip(state, params, nullptr)) {
|
||||||
return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
|
return error("RewindBlockIndex: unable to disconnect block at height %i (%s)", pindex->nHeight, FormatStateMessage(state));
|
||||||
}
|
}
|
||||||
// Occasionally flush state to disk.
|
// Occasionally flush state to disk.
|
||||||
if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC))
|
if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC)) {
|
||||||
|
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reduce validity flag and have-data flags.
|
// Reduce validity flag and have-data flags.
|
||||||
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
|
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
|
||||||
|
@ -4214,6 +4223,7 @@ bool RewindBlockIndex(const CChainParams& params) {
|
||||||
// it'll get called a bunch real soon.
|
// it'll get called a bunch real soon.
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!FlushStateToDisk(params, state, FlushStateMode::ALWAYS)) {
|
if (!FlushStateToDisk(params, state, FlushStateMode::ALWAYS)) {
|
||||||
|
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4300,7 +4310,7 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
|
||||||
CBlockIndex *pindex = AddToBlockIndex(block);
|
CBlockIndex *pindex = AddToBlockIndex(block);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus()))
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus()))
|
||||||
return error("%s: genesis block not accepted", __func__);
|
return error("%s: genesis block not accepted (%s)", __func__, FormatStateMessage(state));
|
||||||
} catch (const std::runtime_error& e) {
|
} catch (const std::runtime_error& e) {
|
||||||
return error("%s: failed to write genesis block: %s", __func__, e.what());
|
return error("%s: failed to write genesis block: %s", __func__, e.what());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue