feat: add thorough error message to state root error (#7607)

This commit is contained in:
Dan Cline
2024-04-24 16:23:45 -04:00
committed by GitHub
parent 659059c67f
commit 76a3d8278a
5 changed files with 79 additions and 3 deletions

View File

@ -21,6 +21,24 @@ use reth_trie::{IntermediateStateRootState, StateRoot, StateRootProgress};
use std::fmt::Debug;
use tracing::*;
// TODO: automate the process outlined below so the user can just send in a debugging package
/// The error message that we include in invalid state root errors to tell users what information
/// they should include in a bug report, since true state root errors can be impossible to debug
/// with just basic logs.
pub const INVALID_STATE_ROOT_ERROR_MESSAGE: &str = r#"
Invalid state root error on new payload!
This is an error that likely requires a report to the reth team with additional information.
Please include the following information in your report:
* This error message
* The state root of the block that was rejected
* The output of `reth db stats --checksum` from the database that was being used. This will take a long time to run!
* 50-100 lines of logs before and after the first occurrence of this log message. Please search your log output for the first observed occurrence of MAGIC_STATE_ROOT.
* The debug logs from __the same time period__. To find the default location for these logs, run:
`reth --help | grep -A 4 'log.file.directory'`
Once you have this information, please submit a github issue at https://github.com/paradigmxyz/reth/issues/new
"#;
/// The default threshold (in number of blocks) for switching from incremental trie building
/// of changes to whole rebuild.
pub const MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD: u64 = 5_000;
@ -196,7 +214,10 @@ impl<DB: Database> Stage<DB> for MerkleStage {
let progress = StateRoot::from_tx(tx)
.with_intermediate_state(checkpoint.map(IntermediateStateRootState::from))
.root_with_progress()
.map_err(|e| StageError::Fatal(Box::new(e)))?;
.map_err(|e| {
error!(target: "sync::stages::merkle", %e, ?current_block_number, ?to_block, "State root with progress failed! {INVALID_STATE_ROOT_ERROR_MESSAGE}");
StageError::Fatal(Box::new(e))
})?;
match progress {
StateRootProgress::Progress(state, hashed_entries_walked, updates) => {
updates.flush(tx)?;
@ -230,7 +251,10 @@ impl<DB: Database> Stage<DB> for MerkleStage {
debug!(target: "sync::stages::merkle::exec", current = ?current_block_number, target = ?to_block, "Updating trie");
let (root, updates) =
StateRoot::incremental_root_with_updates(provider.tx_ref(), range)
.map_err(|e| StageError::Fatal(Box::new(e)))?;
.map_err(|e| {
error!(target: "sync::stages::merkle", %e, ?current_block_number, ?to_block, "Incremental state root failed! {INVALID_STATE_ROOT_ERROR_MESSAGE}");
StageError::Fatal(Box::new(e))
})?;
updates.flush(provider.tx_ref())?;
let total_hashed_entries = (provider.count_entries::<tables::HashedAccounts>()? +
@ -325,7 +349,7 @@ fn validate_state_root(
if got == expected.state_root {
Ok(())
} else {
warn!(target: "sync::stages::merkle", ?target_block, ?got, ?expected, "Failed to verify block state root");
error!(target: "sync::stages::merkle", ?target_block, ?got, ?expected, "Failed to verify block state root! {INVALID_STATE_ROOT_ERROR_MESSAGE}");
Err(StageError::Block {
error: BlockErrorKind::Validation(ConsensusError::BodyStateRootDiff(
GotExpected { got, expected: expected.state_root }.into(),