diff --git a/Cargo.lock b/Cargo.lock index f29e2fb56..edf96ad8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8308,6 +8308,7 @@ dependencies = [ "reth-network-p2p", "reth-nippy-jar", "reth-node-types", + "reth-optimism-primitives", "reth-primitives", "reth-prune-types", "reth-stages-types", diff --git a/book/run/sync-op-mainnet.md b/book/run/sync-op-mainnet.md index 75b6bb161..ebdacdf61 100644 --- a/book/run/sync-op-mainnet.md +++ b/book/run/sync-op-mainnet.md @@ -2,10 +2,10 @@ To sync OP mainnet, bedrock state needs to be imported as a starting point. There are currently two ways: -* Minimal bootstrap: only state snapshot at Bedrock block is imported without any OVM historical data. -* Full bootstrap: state, blocks and receipts are imported. +* Minimal bootstrap **(recommended)**: only state snapshot at Bedrock block is imported without any OVM historical data. +* Full bootstrap **(not recommended)**: state, blocks and receipts are imported. *Not recommended for now: [storage consistency issue](https://github.com/paradigmxyz/reth/pull/11099) tldr: sudden crash may break the node -## Minimal bootstrap +## Minimal bootstrap (recommended) **The state snapshot at Bedrock block is required.** It can be exported from [op-geth](https://github.com/testinprod-io/op-erigon/blob/pcw109550/bedrock-db-migration/bedrock-migration.md#export-state) (**.jsonl**) or downloaded directly from [here](https://mega.nz/file/GdZ1xbAT#a9cBv3AqzsTGXYgX7nZc_3fl--tcBmOAIwIA5ND6kwc). @@ -16,7 +16,9 @@ $ op-reth node --chain optimism --datadir op-mainnet --debug.tip 0x098f87b75c8b8 ``` -## Full bootstrap +## Full bootstrap (not recommended) + +**Not recommended for now**: [storage consistency issue](https://github.com/paradigmxyz/reth/pull/11099) tldr: sudden crash may break the node. ### Import state diff --git a/crates/optimism/primitives/src/bedrock.rs b/crates/optimism/primitives/src/bedrock.rs index 774eb70f8..00c8093dd 100644 --- a/crates/optimism/primitives/src/bedrock.rs +++ b/crates/optimism/primitives/src/bedrock.rs @@ -55,6 +55,10 @@ pub fn is_dup_tx(block_number: u64) -> bool { false } +/// OVM Header #1 hash. +pub const OVM_HEADER_1_HASH: B256 = + b256!("bee7192e575af30420cae0c7776304ac196077ee72b048970549e4f08e875453"); + /// Bedrock hash on Optimism Mainnet. pub const BEDROCK_HEADER_HASH: B256 = b256!("dbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3"); diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index ea04ac8c6..7524fde6a 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -40,6 +40,9 @@ alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true revm.workspace = true +# optimism +reth-optimism-primitives = { workspace = true, optional = true } + # async tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] } @@ -79,7 +82,7 @@ once_cell.workspace = true eyre.workspace = true [features] -optimism = ["reth-primitives/optimism", "reth-execution-types/optimism"] +optimism = ["reth-primitives/optimism", "reth-execution-types/optimism", "reth-optimism-primitives"] serde = ["reth-execution-types/serde"] test-utils = [ "reth-db/test-utils", diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 3ad294f0e..77c87664b 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -12,7 +12,7 @@ use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNum use dashmap::DashMap; use notify::{RecommendedWatcher, RecursiveMode, Watcher}; use parking_lot::RwLock; -use reth_chainspec::{Chain, ChainInfo, ChainSpecProvider, EthChainSpec}; +use reth_chainspec::{ChainInfo, ChainSpecProvider}; use reth_db::{ lockfile::StorageLock, static_file::{iter_static_files, HeaderMask, ReceiptMask, StaticFileCursor, TransactionMask}, @@ -632,14 +632,23 @@ impl StaticFileProvider { where Provider: DBProvider + BlockReader + StageCheckpointReader + ChainSpecProvider, { - // OVM chain contains duplicate transactions, so is inconsistent by default since reth db - // not designed for duplicate transactions (see ). Undefined behaviour for queries - // to OVM chain is also in op-erigon. - if provider.chain_spec().chain() == Chain::optimism_mainnet() { + // OVM historical import is broken and does not work with this check. It's importing + // duplicated receipts resulting in having more receipts than the expected transaction + // range. + // + // If we detect an OVM import was done (block #1 ), skip it. + // More on [#11099](https://github.com/paradigmxyz/reth/pull/11099). + #[cfg(feature = "optimism")] + if reth_chainspec::EthChainSpec::chain(&provider.chain_spec()) == + reth_chainspec::Chain::optimism_mainnet() && + provider + .block_number(reth_optimism_primitives::bedrock::OVM_HEADER_1_HASH)? + .is_some() + { info!(target: "reth::cli", "Skipping storage verification for OP mainnet, expected inconsistency in OVM chain" ); - return Ok(None); + return Ok(None) } info!(target: "reth::cli", "Verifying storage consistency.");