diff --git a/Cargo.lock b/Cargo.lock index b7e25aa4afff4..b1bcf4a81549f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.4.3" @@ -147,7 +153,7 @@ dependencies = [ "alloy-sol-type-parser", "alloy-sol-types", "const-hex", - "derive_more", + "derive_more 0.99.18", "itoa", "serde", "serde_json", @@ -165,7 +171,7 @@ dependencies = [ "alloy-serde", "arbitrary", "c-kzg", - "derive_more", + "derive_more 0.99.18", "k256", "once_cell", "rand 0.8.5", @@ -270,7 +276,7 @@ dependencies = [ "cfg-if", "const-hex", "derive_arbitrary", - "derive_more", + "derive_more 0.99.18", "ethereum_ssz", "getrandom 0.2.15", "hex-literal", @@ -710,7 +716,7 @@ dependencies = [ "alloy-rlp", "arbitrary", "derive_arbitrary", - "derive_more", + "derive_more 0.99.18", "hashbrown 0.14.5", "nybbles", "proptest", @@ -1107,7 +1113,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -1552,9 +1558,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3054fea8a20d8ff3968d5b22cc27501d2b08dc4decdb31b184323f00c5ef23bb" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -2383,6 +2389,28 @@ dependencies = [ "syn 2.0.75", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.75", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -3103,12 +3131,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -3375,9 +3403,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -4054,7 +4082,7 @@ dependencies = [ "socket2 0.5.7", "widestring", "windows-sys 0.48.0", - "winreg 0.50.0", + "winreg", ] [[package]] @@ -4427,9 +4455,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.156" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libloading" @@ -4857,6 +4885,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "0.8.11" @@ -5215,7 +5252,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more", + "derive_more 0.99.18", "serde", ] @@ -6079,9 +6116,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", @@ -6144,9 +6181,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", @@ -6184,7 +6221,7 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "winreg 0.52.0", + "windows-registry", ] [[package]] @@ -6470,7 +6507,7 @@ dependencies = [ "alloy-signer", "alloy-signer-local", "auto_impl", - "derive_more", + "derive_more 1.0.0", "metrics", "parking_lot 0.12.3", "pin-project", @@ -6499,7 +6536,7 @@ dependencies = [ "alloy-rlp", "alloy-trie", "auto_impl", - "derive_more", + "derive_more 1.0.0", "once_cell", "op-alloy-rpc-types", "reth-ethereum-forks", @@ -6651,7 +6688,7 @@ name = "reth-consensus" version = "1.0.5" dependencies = [ "auto_impl", - "derive_more", + "derive_more 1.0.0", "reth-primitives", ] @@ -6697,7 +6734,7 @@ dependencies = [ "assert_matches", "bytes", "criterion", - "derive_more", + "derive_more 1.0.0", "eyre", "iai-callgrind", "metrics", @@ -6736,7 +6773,7 @@ dependencies = [ "assert_matches", "bytes", "criterion", - "derive_more", + "derive_more 1.0.0", "iai-callgrind", "metrics", "modular-bitfield", @@ -6830,7 +6867,7 @@ version = "1.0.5" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more", + "derive_more 1.0.0", "discv5", "enr", "futures", @@ -7108,7 +7145,7 @@ dependencies = [ "arbitrary", "async-stream", "bytes", - "derive_more", + "derive_more 1.0.0", "futures", "pin-project", "proptest", @@ -7142,7 +7179,7 @@ dependencies = [ "alloy-rlp", "arbitrary", "bytes", - "derive_more", + "derive_more 1.0.0", "proptest", "proptest-arbitrary-interop", "rand 0.8.5", @@ -7306,7 +7343,7 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", - "derive_more", + "derive_more 1.0.0", "nybbles", "reth-consensus", "reth-prune-types", @@ -7439,7 +7476,7 @@ dependencies = [ "byteorder", "criterion", "dashmap 6.0.1", - "derive_more", + "derive_more 1.0.0", "indexmap 2.4.0", "parking_lot 0.12.3", "pprof", @@ -7512,7 +7549,7 @@ dependencies = [ "aquamarine", "auto_impl", "criterion", - "derive_more", + "derive_more 1.0.0", "discv5", "enr", "futures", @@ -7566,7 +7603,7 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types-admin", "auto_impl", - "derive_more", + "derive_more 1.0.0", "enr", "futures", "reth-eth-wire-types", @@ -7586,7 +7623,7 @@ name = "reth-network-p2p" version = "1.0.5" dependencies = [ "auto_impl", - "derive_more", + "derive_more 1.0.0", "futures", "parking_lot 0.12.3", "reth-consensus", @@ -7635,7 +7672,7 @@ dependencies = [ "anyhow", "bincode", "cuckoofilter", - "derive_more", + "derive_more 1.0.0", "lz4_flex", "memmap2", "ph", @@ -7729,7 +7766,7 @@ dependencies = [ "alloy-rpc-types-engine", "clap", "const_format", - "derive_more", + "derive_more 1.0.0", "dirs-next", "eyre", "futures", @@ -7990,7 +8027,7 @@ name = "reth-optimism-rpc" version = "1.0.5" dependencies = [ "alloy-primitives", - "derive_more", + "derive_more 1.0.0", "jsonrpsee", "jsonrpsee-types", "parking_lot 0.12.3", @@ -8075,7 +8112,7 @@ dependencies = [ "bytes", "c-kzg", "criterion", - "derive_more", + "derive_more 1.0.0", "k256", "modular-bitfield", "once_cell", @@ -8113,7 +8150,7 @@ dependencies = [ "arbitrary", "byteorder", "bytes", - "derive_more", + "derive_more 1.0.0", "modular-bitfield", "proptest", "proptest-arbitrary-interop", @@ -8206,7 +8243,7 @@ dependencies = [ "arbitrary", "assert_matches", "bytes", - "derive_more", + "derive_more 1.0.0", "modular-bitfield", "proptest", "proptest-arbitrary-interop", @@ -8244,7 +8281,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "async-trait", - "derive_more", + "derive_more 1.0.0", "futures", "http", "http-body", @@ -8437,7 +8474,7 @@ name = "reth-rpc-eth-types" version = "1.0.5" dependencies = [ "alloy-sol-types", - "derive_more", + "derive_more 1.0.0", "futures", "jsonrpsee-core", "jsonrpsee-types", @@ -8654,7 +8691,7 @@ version = "1.0.5" dependencies = [ "alloy-primitives", "clap", - "derive_more", + "derive_more 1.0.0", "serde", "strum", ] @@ -8680,7 +8717,7 @@ name = "reth-storage-errors" version = "1.0.5" dependencies = [ "alloy-rlp", - "derive_more", + "derive_more 1.0.0", "reth-fs-util", "reth-primitives", ] @@ -8784,7 +8821,7 @@ dependencies = [ "alloy-rlp", "auto_impl", "criterion", - "derive_more", + "derive_more 1.0.0", "itertools 0.13.0", "metrics", "proptest", @@ -8819,7 +8856,7 @@ dependencies = [ "alloy-trie", "arbitrary", "bytes", - "derive_more", + "derive_more 1.0.0", "hash-db", "itertools 0.13.0", "nybbles", @@ -8841,7 +8878,7 @@ dependencies = [ "alloy-rlp", "auto_impl", "criterion", - "derive_more", + "derive_more 1.0.0", "itertools 0.13.0", "metrics", "proptest", @@ -8874,7 +8911,7 @@ version = "1.0.5" dependencies = [ "alloy-rlp", "criterion", - "derive_more", + "derive_more 1.0.0", "itertools 0.13.0", "metrics", "proptest", @@ -8971,7 +9008,7 @@ dependencies = [ "bitvec", "c-kzg", "cfg-if", - "derive_more", + "derive_more 0.99.18", "dyn-clone", "enumn", "hashbrown 0.14.5", @@ -9177,9 +9214,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" +checksum = "04182dffc9091a404e0fc069ea5cd60e5b866c3adf881eff99a32d048242dffa" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -9965,6 +10002,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -10744,9 +10784,9 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "universal-hash" @@ -11088,7 +11128,7 @@ checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ "windows-implement", "windows-interface", - "windows-result", + "windows-result 0.1.2", "windows-targets 0.52.6", ] @@ -11114,6 +11154,17 @@ dependencies = [ "syn 2.0.75", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result 0.2.0", + "windows-strings", + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -11123,6 +11174,25 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -11299,16 +11369,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "write16" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 9abb32a0d76d7..0278ae35ccc77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -439,7 +439,7 @@ bytes = "1.5" clap = "4" const_format = { version = "0.2.32", features = ["rust_1_64"] } dashmap = "6.0" -derive_more = "0.99.17" +derive_more = { version = "1", features = ["full"] } dyn-clone = "1.0.17" eyre = "0.6" fdlimit = "0.3.0" diff --git a/crates/chain-state/src/chain_info.rs b/crates/chain-state/src/chain_info.rs index 142d19703b3f2..5a9725e25e094 100644 --- a/crates/chain-state/src/chain_info.rs +++ b/crates/chain-state/src/chain_info.rs @@ -123,12 +123,12 @@ impl ChainInfoTracker { } /// Subscribe to the finalized block. - pub fn subscribe_to_finalized_block(&self) -> watch::Receiver> { + pub fn subscribe_finalized_block(&self) -> watch::Receiver> { self.inner.finalized_block.subscribe() } /// Subscribe to the safe block. - pub fn subscribe_to_safe_block(&self) -> watch::Receiver> { + pub fn subscribe_safe_block(&self) -> watch::Receiver> { self.inner.safe_block.subscribe() } } diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 3ef9fceb864b8..8be431e98b89e 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -111,8 +111,8 @@ impl InMemoryState { /// Returns the pending state corresponding to the current head plus one, /// from the payload received in newPayload that does not have a FCU yet. - pub(crate) fn pending_state(&self) -> Option> { - self.pending.borrow().as_ref().map(|state| Arc::new(state.clone())) + pub(crate) fn pending_state(&self) -> Option { + self.pending.borrow().clone() } #[cfg(test)] @@ -347,7 +347,7 @@ impl CanonicalInMemoryState { } /// Returns the in memory pending state. - pub fn pending_state(&self) -> Option> { + pub fn pending_state(&self) -> Option { self.inner.in_memory_state.pending_state() } @@ -465,12 +465,12 @@ impl CanonicalInMemoryState { /// Subscribe to new safe block events. pub fn subscribe_safe_block(&self) -> watch::Receiver> { - self.inner.chain_info_tracker.subscribe_to_safe_block() + self.inner.chain_info_tracker.subscribe_safe_block() } /// Subscribe to new finalized block events. pub fn subscribe_finalized_block(&self) -> watch::Receiver> { - self.inner.chain_info_tracker.subscribe_to_finalized_block() + self.inner.chain_info_tracker.subscribe_finalized_block() } /// Attempts to send a new [`CanonStateNotification`] to all active Receiver handles. @@ -1131,7 +1131,7 @@ mod tests { // Check the pending state assert_eq!( state.pending_state().unwrap(), - Arc::new(BlockState::with_parent(block2.clone(), Some(BlockState::new(block1)))) + BlockState::with_parent(block2.clone(), Some(BlockState::new(block1))) ); // Check the pending block diff --git a/crates/chain-state/src/notifications.rs b/crates/chain-state/src/notifications.rs index a4ab993d8e732..f754bf6132165 100644 --- a/crates/chain-state/src/notifications.rs +++ b/crates/chain-state/src/notifications.rs @@ -146,14 +146,19 @@ pub struct ForkChoiceNotifications(pub watch::Receiver>); /// and get notified when a new fork choice is available. pub trait ForkChoiceSubscriptions: Send + Sync { /// Get notified when a new safe block of the chain is selected. - fn subscribe_to_safe_block(&self) -> ForkChoiceNotifications; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications; /// Get notified when a new finalized block of the chain is selected. - fn subscribe_to_finalized_block(&self) -> ForkChoiceNotifications; + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications; /// Convenience method to get a stream of the new safe blocks of the chain. - fn fork_choice_stream(&self) -> ForkChoiceStream { - ForkChoiceStream { st: WatchStream::new(self.subscribe_to_safe_block().0) } + fn safe_block_stream(&self) -> ForkChoiceStream { + ForkChoiceStream { st: WatchStream::new(self.subscribe_safe_block().0) } + } + + /// Convenience method to get a stream of the new finalized blocks of the chain. + fn finalized_block_stream(&self) -> ForkChoiceStream { + ForkChoiceStream { st: WatchStream::new(self.subscribe_finalized_block().0) } } } diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index a6740ef97fa48..a0c23810184d7 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -130,7 +130,7 @@ pub trait Consensus: Debug + Send + Sync { #[derive(Debug, PartialEq, Eq, Clone, derive_more::Display)] pub enum ConsensusError { /// Error when the gas used in the header exceeds the gas limit. - #[display(fmt = "block used gas ({gas_used}) is greater than gas limit ({gas_limit})")] + #[display("block used gas ({gas_used}) is greater than gas limit ({gas_limit})")] HeaderGasUsedExceedsGasLimit { /// The gas used in the block header. gas_used: u64, @@ -140,7 +140,7 @@ pub enum ConsensusError { /// Error when block gas used doesn't match expected value #[display( - fmt = "block gas used mismatch: {gas}; gas spent by each transaction: {gas_spent_by_tx:?}" + "block gas used mismatch: {gas}; gas spent by each transaction: {gas_spent_by_tx:?}" )] BlockGasUsed { /// The gas diff. @@ -150,38 +150,38 @@ pub enum ConsensusError { }, /// Error when the hash of block ommer is different from the expected hash. - #[display(fmt = "mismatched block ommer hash: {_0}")] + #[display("mismatched block ommer hash: {_0}")] BodyOmmersHashDiff(GotExpectedBoxed), /// Error when the state root in the block is different from the expected state root. - #[display(fmt = "mismatched block state root: {_0}")] + #[display("mismatched block state root: {_0}")] BodyStateRootDiff(GotExpectedBoxed), /// Error when the transaction root in the block is different from the expected transaction /// root. - #[display(fmt = "mismatched block transaction root: {_0}")] + #[display("mismatched block transaction root: {_0}")] BodyTransactionRootDiff(GotExpectedBoxed), /// Error when the receipt root in the block is different from the expected receipt root. - #[display(fmt = "receipt root mismatch: {_0}")] + #[display("receipt root mismatch: {_0}")] BodyReceiptRootDiff(GotExpectedBoxed), /// Error when header bloom filter is different from the expected bloom filter. - #[display(fmt = "header bloom filter mismatch: {_0}")] + #[display("header bloom filter mismatch: {_0}")] BodyBloomLogDiff(GotExpectedBoxed), /// Error when the withdrawals root in the block is different from the expected withdrawals /// root. - #[display(fmt = "mismatched block withdrawals root: {_0}")] + #[display("mismatched block withdrawals root: {_0}")] BodyWithdrawalsRootDiff(GotExpectedBoxed), /// Error when the requests root in the block is different from the expected requests /// root. - #[display(fmt = "mismatched block requests root: {_0}")] + #[display("mismatched block requests root: {_0}")] BodyRequestsRootDiff(GotExpectedBoxed), /// Error when a block with a specific hash and number is already known. - #[display(fmt = "block with [hash={hash}, number={number}] is already known")] + #[display("block with [hash={hash}, number={number}] is already known")] BlockKnown { /// The hash of the known block. hash: BlockHash, @@ -190,7 +190,7 @@ pub enum ConsensusError { }, /// Error when the parent hash of a block is not known. - #[display(fmt = "block parent [hash={hash}] is not known")] + #[display("block parent [hash={hash}] is not known")] ParentUnknown { /// The hash of the unknown parent block. hash: BlockHash, @@ -198,7 +198,7 @@ pub enum ConsensusError { /// Error when the block number does not match the parent block number. #[display( - fmt = "block number {block_number} does not match parent block number {parent_block_number}" + "block number {block_number} does not match parent block number {parent_block_number}" )] ParentBlockNumberMismatch { /// The parent block number. @@ -208,12 +208,12 @@ pub enum ConsensusError { }, /// Error when the parent hash does not match the expected parent hash. - #[display(fmt = "mismatched parent hash: {_0}")] + #[display("mismatched parent hash: {_0}")] ParentHashMismatch(GotExpectedBoxed), /// Error when the block timestamp is in the future compared to our clock time. #[display( - fmt = "block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}" + "block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}" )] TimestampIsInFuture { /// The block's timestamp. @@ -223,84 +223,82 @@ pub enum ConsensusError { }, /// Error when the base fee is missing. - #[display(fmt = "base fee missing")] + #[display("base fee missing")] BaseFeeMissing, /// Error when there is a transaction signer recovery error. - #[display(fmt = "transaction signer recovery error")] + #[display("transaction signer recovery error")] TransactionSignerRecoveryError, /// Error when the extra data length exceeds the maximum allowed. - #[display(fmt = "extra data {len} exceeds max length")] + #[display("extra data {len} exceeds max length")] ExtraDataExceedsMax { /// The length of the extra data. len: usize, }, /// Error when the difficulty after a merge is not zero. - #[display(fmt = "difficulty after merge is not zero")] + #[display("difficulty after merge is not zero")] TheMergeDifficultyIsNotZero, /// Error when the nonce after a merge is not zero. - #[display(fmt = "nonce after merge is not zero")] + #[display("nonce after merge is not zero")] TheMergeNonceIsNotZero, /// Error when the ommer root after a merge is not empty. - #[display(fmt = "ommer root after merge is not empty")] + #[display("ommer root after merge is not empty")] TheMergeOmmerRootIsNotEmpty, /// Error when the withdrawals root is missing. - #[display(fmt = "missing withdrawals root")] + #[display("missing withdrawals root")] WithdrawalsRootMissing, /// Error when the requests root is missing. - #[display(fmt = "missing requests root")] + #[display("missing requests root")] RequestsRootMissing, /// Error when an unexpected withdrawals root is encountered. - #[display(fmt = "unexpected withdrawals root")] + #[display("unexpected withdrawals root")] WithdrawalsRootUnexpected, /// Error when an unexpected requests root is encountered. - #[display(fmt = "unexpected requests root")] + #[display("unexpected requests root")] RequestsRootUnexpected, /// Error when withdrawals are missing. - #[display(fmt = "missing withdrawals")] + #[display("missing withdrawals")] BodyWithdrawalsMissing, /// Error when requests are missing. - #[display(fmt = "missing requests")] + #[display("missing requests")] BodyRequestsMissing, /// Error when blob gas used is missing. - #[display(fmt = "missing blob gas used")] + #[display("missing blob gas used")] BlobGasUsedMissing, /// Error when unexpected blob gas used is encountered. - #[display(fmt = "unexpected blob gas used")] + #[display("unexpected blob gas used")] BlobGasUsedUnexpected, /// Error when excess blob gas is missing. - #[display(fmt = "missing excess blob gas")] + #[display("missing excess blob gas")] ExcessBlobGasMissing, /// Error when unexpected excess blob gas is encountered. - #[display(fmt = "unexpected excess blob gas")] + #[display("unexpected excess blob gas")] ExcessBlobGasUnexpected, /// Error when the parent beacon block root is missing. - #[display(fmt = "missing parent beacon block root")] + #[display("missing parent beacon block root")] ParentBeaconBlockRootMissing, /// Error when an unexpected parent beacon block root is encountered. - #[display(fmt = "unexpected parent beacon block root")] + #[display("unexpected parent beacon block root")] ParentBeaconBlockRootUnexpected, /// Error when blob gas used exceeds the maximum allowed. - #[display( - fmt = "blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}" - )] + #[display("blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}")] BlobGasUsedExceedsMaxBlobGasPerBlock { /// The actual blob gas used. blob_gas_used: u64, @@ -310,7 +308,7 @@ pub enum ConsensusError { /// Error when blob gas used is not a multiple of blob gas per blob. #[display( - fmt = "blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}" + "blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}" )] BlobGasUsedNotMultipleOfBlobGasPerBlob { /// The actual blob gas used. @@ -321,7 +319,7 @@ pub enum ConsensusError { /// Error when excess blob gas is not a multiple of blob gas per blob. #[display( - fmt = "excess blob gas {excess_blob_gas} is not a multiple of blob gas per blob {blob_gas_per_blob}" + "excess blob gas {excess_blob_gas} is not a multiple of blob gas per blob {blob_gas_per_blob}" )] ExcessBlobGasNotMultipleOfBlobGasPerBlob { /// The actual excess blob gas. @@ -331,20 +329,22 @@ pub enum ConsensusError { }, /// Error when the blob gas used in the header does not match the expected blob gas used. - #[display(fmt = "blob gas used mismatch: {_0}")] + #[display("blob gas used mismatch: {_0}")] BlobGasUsedDiff(GotExpected), /// Error for a transaction that violates consensus. InvalidTransaction(InvalidTransactionError), /// Error when the block's base fee is different from the expected base fee. - #[display(fmt = "block base fee mismatch: {_0}")] + #[display("block base fee mismatch: {_0}")] BaseFeeDiff(GotExpected), /// Error when there is an invalid excess blob gas. - #[display(fmt = "invalid excess blob gas: {diff}; \ + #[display( + "invalid excess blob gas: {diff}; \ parent excess blob gas: {parent_excess_blob_gas}, \ - parent blob gas used: {parent_blob_gas_used}")] + parent blob gas used: {parent_blob_gas_used}" + )] ExcessBlobGasDiff { /// The excess blob gas diff. diff: GotExpected, @@ -355,7 +355,7 @@ pub enum ConsensusError { }, /// Error when the child gas limit exceeds the maximum allowed increase. - #[display(fmt = "child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024")] + #[display("child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024")] GasLimitInvalidIncrease { /// The parent gas limit. parent_gas_limit: u64, @@ -367,7 +367,7 @@ pub enum ConsensusError { /// /// This error occurs when the child gas limit is less than the specified minimum gas limit. #[display( - fmt = "child gas limit {child_gas_limit} is below the minimum allowed limit ({MINIMUM_GAS_LIMIT})" + "child gas limit {child_gas_limit} is below the minimum allowed limit ({MINIMUM_GAS_LIMIT})" )] GasLimitInvalidMinimum { /// The child gas limit. @@ -375,7 +375,7 @@ pub enum ConsensusError { }, /// Error when the child gas limit exceeds the maximum allowed decrease. - #[display(fmt = "child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024")] + #[display("child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024")] GasLimitInvalidDecrease { /// The parent gas limit. parent_gas_limit: u64, @@ -385,7 +385,7 @@ pub enum ConsensusError { /// Error when the block timestamp is in the past compared to the parent timestamp. #[display( - fmt = "block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}" + "block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}" )] TimestampIsInPast { /// The parent block's timestamp. @@ -420,7 +420,7 @@ impl From for ConsensusError { /// `HeaderConsensusError` combines a `ConsensusError` with the `SealedHeader` it relates to. #[derive(derive_more::Display, Debug)] -#[display(fmt = "Consensus error: {_0}, Invalid header: {_1:?}")] +#[display("Consensus error: {_0}, Invalid header: {_1:?}")] pub struct HeaderConsensusError(ConsensusError, SealedHeader); #[cfg(feature = "std")] diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index d5c9d538fe8e7..636e0f7408466 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -177,6 +177,7 @@ mod tests { } #[test] + #[allow(clippy::needless_update)] fn test_evm_configure() { // Create a default `EthEvmConfig` let evm_config = EthEvmConfig::default(); @@ -212,9 +213,13 @@ mod tests { // Ensure that there are no valid authorizations in the EVM context assert!(evm.context.evm.inner.valid_authorizations.is_empty()); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_default_spec() { let evm_config = EthEvmConfig::default(); @@ -229,9 +234,13 @@ mod tests { // Default spec ID assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_custom_cfg() { let evm_config = EthEvmConfig::default(); @@ -256,9 +265,13 @@ mod tests { // Default spec ID assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_custom_block_and_tx() { let evm_config = EthEvmConfig::default(); @@ -286,6 +299,9 @@ mod tests { // Default spec ID assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] @@ -303,9 +319,16 @@ mod tests { // Check that the spec ID is setup properly assert_eq!(evm.handler.spec_id(), SpecId::CONSTANTINOPLE); + + // No Optimism + assert_eq!( + evm.handler.cfg, + HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() } + ); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_inspector() { let evm_config = EthEvmConfig::default(); @@ -344,9 +367,13 @@ mod tests { // Ensure that there are no valid authorizations in the EVM context assert!(evm.context.evm.inner.valid_authorizations.is_empty()); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_and_default_inspector() { let evm_config = EthEvmConfig::default(); let db = CacheDB::>::default(); @@ -360,9 +387,13 @@ mod tests { assert_eq!(evm.context.evm.env, env_with_handler.env); assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_inspector_and_custom_cfg() { let evm_config = EthEvmConfig::default(); let db = CacheDB::>::default(); @@ -381,9 +412,13 @@ mod tests { assert_eq!(evm.context.evm.env.cfg, cfg); assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] + #[allow(clippy::needless_update)] fn test_evm_with_env_inspector_and_custom_block_tx() { let evm_config = EthEvmConfig::default(); let db = CacheDB::>::default(); @@ -409,6 +444,9 @@ mod tests { assert_eq!(evm.context.evm.env.tx, env_with_handler.env.tx); assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // No Optimism + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, ..Default::default() }); } #[test] @@ -427,5 +465,11 @@ mod tests { assert_eq!(evm.handler.spec_id(), SpecId::CONSTANTINOPLE); assert_eq!(evm.context.evm.env, env_with_handler.env); assert_eq!(evm.context.external, NoOpInspector); + + // No Optimism + assert_eq!( + evm.handler.cfg, + HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() } + ); } } diff --git a/crates/evm/execution-errors/src/lib.rs b/crates/evm/execution-errors/src/lib.rs index ba6258e180ddc..2a8cb50bf4012 100644 --- a/crates/evm/execution-errors/src/lib.rs +++ b/crates/evm/execution-errors/src/lib.rs @@ -29,7 +29,7 @@ pub use trie::*; #[derive(Clone, Debug, Display, Eq, PartialEq)] pub enum BlockValidationError { /// EVM error with transaction hash and message - #[display(fmt = "EVM reported invalid transaction ({hash}): {error}")] + #[display("EVM reported invalid transaction ({hash}): {error}")] EVM { /// The hash of the transaction hash: B256, @@ -37,17 +37,17 @@ pub enum BlockValidationError { error: Box>, }, /// Error when recovering the sender for a transaction - #[display(fmt = "failed to recover sender for transaction")] + #[display("failed to recover sender for transaction")] SenderRecoveryError, /// Error when incrementing balance in post execution - #[display(fmt = "incrementing balance in post execution failed")] + #[display("incrementing balance in post execution failed")] IncrementBalanceFailed, /// Error when the state root does not match the expected value. // #[from(ignore)] StateRoot(StateRootError), /// Error when transaction gas limit exceeds available block gas #[display( - fmt = "transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}" + "transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}" )] TransactionGasLimitMoreThanAvailableBlockGas { /// The transaction's gas limit @@ -56,23 +56,23 @@ pub enum BlockValidationError { block_available_gas: u64, }, /// Error for pre-merge block - #[display(fmt = "block {hash} is pre merge")] + #[display("block {hash} is pre merge")] BlockPreMerge { /// The hash of the block hash: B256, }, /// Error for missing total difficulty - #[display(fmt = "missing total difficulty for block {hash}")] + #[display("missing total difficulty for block {hash}")] MissingTotalDifficulty { /// The hash of the block hash: B256, }, /// Error for EIP-4788 when parent beacon block root is missing - #[display(fmt = "EIP-4788 parent beacon block root missing for active Cancun block")] + #[display("EIP-4788 parent beacon block root missing for active Cancun block")] MissingParentBeaconBlockRoot, /// Error for Cancun genesis block when parent beacon block root is not zero #[display( - fmt = "the parent beacon block root is not zero for Cancun genesis block: {parent_beacon_block_root}" + "the parent beacon block root is not zero for Cancun genesis block: {parent_beacon_block_root}" )] CancunGenesisParentBeaconBlockRootNotZero { /// The beacon block root @@ -82,7 +82,7 @@ pub enum BlockValidationError { /// /// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 #[display( - fmt = "failed to apply beacon root contract call at {parent_beacon_block_root}: {message}" + "failed to apply beacon root contract call at {parent_beacon_block_root}: {message}" )] BeaconRootContractCall { /// The beacon block root @@ -97,7 +97,7 @@ pub enum BlockValidationError { /// EVM error during withdrawal requests contract call [EIP-7002] /// /// [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 - #[display(fmt = "failed to apply withdrawal requests contract call: {message}")] + #[display("failed to apply withdrawal requests contract call: {message}")] WithdrawalRequestsContractCall { /// The error message. message: String, @@ -105,7 +105,7 @@ pub enum BlockValidationError { /// EVM error during consolidation requests contract call [EIP-7251] /// /// [EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 - #[display(fmt = "failed to apply consolidation requests contract call: {message}")] + #[display("failed to apply consolidation requests contract call: {message}")] ConsolidationRequestsContractCall { /// The error message. message: String, @@ -113,7 +113,7 @@ pub enum BlockValidationError { /// Error when decoding deposit requests from receipts [EIP-6110] /// /// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 - #[display(fmt = "failed to decode deposit requests from receipts: {_0}")] + #[display("failed to decode deposit requests from receipts: {_0}")] DepositRequestDecode(String), } @@ -219,7 +219,7 @@ pub enum InternalBlockExecutionError { Pruning(PruneSegmentError), /// Error when appending chain on fork is not possible #[display( - fmt = "appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" + "appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" )] AppendChainDoesntConnect { /// The tip of the current chain diff --git a/crates/evm/execution-errors/src/trie.rs b/crates/evm/execution-errors/src/trie.rs index ccf9ea23c29e8..e90022526f9e4 100644 --- a/crates/evm/execution-errors/src/trie.rs +++ b/crates/evm/execution-errors/src/trie.rs @@ -126,13 +126,13 @@ pub enum TrieWitnessError { /// RLP decoding error. Rlp(alloy_rlp::Error), /// Missing storage multiproof. - #[display(fmt = "missing storage multiproof for {_0}")] + #[display("missing storage multiproof for {_0}")] MissingStorageMultiProof(B256), /// Missing account. - #[display(fmt = "missing account {_0}")] + #[display("missing account {_0}")] MissingAccount(B256), /// Missing target node. - #[display(fmt = "target node missing from proof {_0:?}")] + #[display("target node missing from proof {_0:?}")] MissingTargetNode(Nibbles), } diff --git a/crates/net/discv5/src/config.rs b/crates/net/discv5/src/config.rs index 725b5383059eb..9b198e93a54c2 100644 --- a/crates/net/discv5/src/config.rs +++ b/crates/net/discv5/src/config.rs @@ -440,10 +440,10 @@ pub fn discv5_sockets_wrt_rlpx_addr( #[derive(Clone, Debug, PartialEq, Eq, Hash, Display)] pub enum BootNode { /// An unsigned node record. - #[display(fmt = "{_0}")] + #[display("{_0}")] Enode(Multiaddr), /// A signed node record. - #[display(fmt = "{_0:?}")] + #[display("{_0:?}")] Enr(discv5::Enr), } diff --git a/crates/net/eth-wire-types/src/broadcast.rs b/crates/net/eth-wire-types/src/broadcast.rs index 8b5c6872d2b40..bdd657e9d69db 100644 --- a/crates/net/eth-wire-types/src/broadcast.rs +++ b/crates/net/eth-wire-types/src/broadcast.rs @@ -643,7 +643,6 @@ impl PartiallyValidData { /// Partially validated data from an announcement or a /// [`PooledTransactions`](crate::PooledTransactions) response. #[derive(Debug, Deref, DerefMut, IntoIterator, From)] -#[from(PartiallyValidData)] pub struct ValidAnnouncementData { #[deref] #[deref_mut] diff --git a/crates/net/eth-wire-types/src/disconnect_reason.rs b/crates/net/eth-wire-types/src/disconnect_reason.rs index ece289cf075b1..81db4945a130b 100644 --- a/crates/net/eth-wire-types/src/disconnect_reason.rs +++ b/crates/net/eth-wire-types/src/disconnect_reason.rs @@ -14,43 +14,43 @@ use thiserror::Error; pub enum DisconnectReason { /// Disconnect requested by the local node or remote peer. #[default] - #[display(fmt = "disconnect requested")] + #[display("disconnect requested")] DisconnectRequested = 0x00, /// TCP related error - #[display(fmt = "TCP sub-system error")] + #[display("TCP sub-system error")] TcpSubsystemError = 0x01, /// Breach of protocol at the transport or p2p level - #[display(fmt = "breach of protocol, e.g. a malformed message, bad RLP, etc.")] + #[display("breach of protocol, e.g. a malformed message, bad RLP, etc.")] ProtocolBreach = 0x02, /// Node has no matching protocols. - #[display(fmt = "useless peer")] + #[display("useless peer")] UselessPeer = 0x03, /// Either the remote or local node has too many peers. - #[display(fmt = "too many peers")] + #[display("too many peers")] TooManyPeers = 0x04, /// Already connected to the peer. - #[display(fmt = "already connected")] + #[display("already connected")] AlreadyConnected = 0x05, /// `p2p` protocol version is incompatible - #[display(fmt = "incompatible P2P protocol version")] + #[display("incompatible P2P protocol version")] IncompatibleP2PProtocolVersion = 0x06, /// Received a null node identity. - #[display(fmt = "null node identity received - this is automatically invalid")] + #[display("null node identity received - this is automatically invalid")] NullNodeIdentity = 0x07, /// Reason when the client is shutting down. - #[display(fmt = "client quitting")] + #[display("client quitting")] ClientQuitting = 0x08, /// When the received handshake's identify is different from what is expected. - #[display(fmt = "unexpected identity in handshake")] + #[display("unexpected identity in handshake")] UnexpectedHandshakeIdentity = 0x09, /// The node is connected to itself - #[display(fmt = "identity is the same as this node (i.e. connected to itself)")] + #[display("identity is the same as this node (i.e. connected to itself)")] ConnectedToSelf = 0x0a, /// Peer or local node did not respond to a ping in time. - #[display(fmt = "ping timeout")] + #[display("ping timeout")] PingTimeout = 0x0b, /// Peer or local node violated a subprotocol-specific rule. - #[display(fmt = "some other reason specific to a subprotocol")] + #[display("some other reason specific to a subprotocol")] SubprotocolSpecific = 0x10, } diff --git a/crates/net/p2p/src/error.rs b/crates/net/p2p/src/error.rs index 4bd173962be97..fc6040a56f584 100644 --- a/crates/net/p2p/src/error.rs +++ b/crates/net/p2p/src/error.rs @@ -80,23 +80,23 @@ impl EthResponseValidator for RequestResult> { #[derive(Clone, Debug, Eq, PartialEq, Display)] pub enum RequestError { /// Closed channel to the peer. - #[display(fmt = "closed channel to the peer")] + #[display("closed channel to the peer")] /// Indicates the channel to the peer is closed. ChannelClosed, /// Connection to a peer dropped while handling the request. - #[display(fmt = "connection to a peer dropped while handling the request")] + #[display("connection to a peer dropped while handling the request")] /// Represents a dropped connection while handling the request. ConnectionDropped, /// Capability message is not supported by the remote peer. - #[display(fmt = "capability message is not supported by remote peer")] + #[display("capability message is not supported by remote peer")] /// Indicates an unsupported capability message from the remote peer. UnsupportedCapability, /// Request timed out while awaiting response. - #[display(fmt = "request timed out while awaiting response")] + #[display("request timed out while awaiting response")] /// Represents a timeout while waiting for a response. Timeout, /// Received bad response. - #[display(fmt = "received bad response")] + #[display("received bad response")] /// Indicates a bad response was received. BadResponse, } @@ -138,7 +138,7 @@ pub type DownloadResult = Result; pub enum DownloadError { /* ==================== HEADER ERRORS ==================== */ /// Header validation failed. - #[display(fmt = "failed to validate header {hash}, block number {number}: {error}")] + #[display("failed to validate header {hash}, block number {number}: {error}")] HeaderValidation { /// Hash of header failing validation hash: B256, @@ -148,21 +148,21 @@ pub enum DownloadError { error: Box, }, /// Received an invalid tip. - #[display(fmt = "received invalid tip: {_0}")] + #[display("received invalid tip: {_0}")] InvalidTip(GotExpectedBoxed), /// Received a tip with an invalid tip number. - #[display(fmt = "received invalid tip number: {_0}")] + #[display("received invalid tip number: {_0}")] InvalidTipNumber(GotExpected), /// Received a response to a request with unexpected start block - #[display(fmt = "headers response starts at unexpected block: {_0}")] + #[display("headers response starts at unexpected block: {_0}")] HeadersResponseStartBlockMismatch(GotExpected), /// Received headers with less than expected items. - #[display(fmt = "received less headers than expected: {_0}")] + #[display("received less headers than expected: {_0}")] HeadersResponseTooShort(GotExpected), /* ==================== BODIES ERRORS ==================== */ /// Block validation failed - #[display(fmt = "failed to validate body for header {hash}, block number {number}: {error}")] + #[display("failed to validate body for header {hash}, block number {number}: {error}")] BodyValidation { /// Hash of the block failing validation hash: B256, @@ -172,26 +172,26 @@ pub enum DownloadError { error: Box, }, /// Received more bodies than requested. - #[display(fmt = "received more bodies than requested: {_0}")] + #[display("received more bodies than requested: {_0}")] TooManyBodies(GotExpected), /// Headers missing from the database. - #[display(fmt = "header missing from the database: {block_number}")] + #[display("header missing from the database: {block_number}")] MissingHeader { /// Missing header block number. block_number: BlockNumber, }, /// Body range invalid - #[display(fmt = "requested body range is invalid: {range:?}")] + #[display("requested body range is invalid: {range:?}")] InvalidBodyRange { /// Invalid block number range. range: RangeInclusive, }, /* ==================== COMMON ERRORS ==================== */ /// Timed out while waiting for request id response. - #[display(fmt = "timed out while waiting for response")] + #[display("timed out while waiting for response")] Timeout, /// Received empty response while expecting non empty - #[display(fmt = "received empty response")] + #[display("received empty response")] EmptyResponse, /// Error while executing the request. RequestError(RequestError), diff --git a/crates/net/p2p/src/headers/error.rs b/crates/net/p2p/src/headers/error.rs index 3bda79c29c0e7..3112f9d7d456c 100644 --- a/crates/net/p2p/src/headers/error.rs +++ b/crates/net/p2p/src/headers/error.rs @@ -10,7 +10,7 @@ pub type HeadersDownloaderResult = Result; pub enum HeadersDownloaderError { /// The downloaded header cannot be attached to the local head, /// but is valid otherwise. - #[display(fmt = "valid downloaded header cannot be attached to the local head: {error}")] + #[display("valid downloaded header cannot be attached to the local head: {error}")] DetachedHead { /// The local head we attempted to attach to. local_head: Box, diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index ece9bcd56982e..b721a1d492506 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -136,18 +136,46 @@ impl ConfigureEvm for OptimismEvmConfig { #[cfg(test)] mod tests { use super::*; - use reth_primitives::revm_primitives::{BlockEnv, CfgEnv}; - use revm_primitives::SpecId; + use reth_chainspec::{Chain, ChainSpec}; + use reth_evm::execute::ProviderError; + use reth_primitives::{ + revm_primitives::{BlockEnv, CfgEnv, SpecId}, + Genesis, Header, B256, KECCAK_EMPTY, U256, + }; + use reth_revm::{ + db::{CacheDB, EmptyDBTyped}, + inspectors::NoOpInspector, + JournaledState, + }; + use revm_primitives::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; + use std::collections::HashSet; #[test] - #[ignore] fn test_fill_cfg_and_block_env() { + // Create a new configuration environment let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST); + + // Create a default block environment let mut block_env = BlockEnv::default(); + + // Create a default header let header = Header::default(); - let chain_spec = ChainSpec::default(); + + // Build the ChainSpec for Ethereum mainnet, activating London, Paris, and Shanghai + // hardforks + let chain_spec = ChainSpec::builder() + .chain(Chain::mainnet()) + .genesis(Genesis::default()) + .london_activated() + .paris_activated() + .shanghai_activated() + .build(); + + // Define the total difficulty as zero (default) let total_difficulty = U256::ZERO; + // Use the `OptimismEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, + // Header, and total difficulty OptimismEvmConfig::default().fill_cfg_and_block_env( &mut cfg_env, &mut block_env, @@ -156,6 +184,298 @@ mod tests { total_difficulty, ); + // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the + // ChainSpec assert_eq!(cfg_env.chain_id, chain_spec.chain().id()); } + + #[test] + fn test_evm_configure() { + // Create a default `OptimismEvmConfig` + let evm_config = OptimismEvmConfig::default(); + + // Initialize an empty database wrapped in CacheDB + let db = CacheDB::>::default(); + + // Create an EVM instance using the configuration and the database + let evm = evm_config.evm(db); + + // Check that the EVM environment is initialized with default values + assert_eq!(evm.context.evm.inner.env, Box::default()); + + // Latest spec ID and no warm preloaded addresses + assert_eq!( + evm.context.evm.inner.journaled_state, + JournaledState::new(SpecId::LATEST, HashSet::default()) + ); + + // Ensure that the accounts database is empty + assert!(evm.context.evm.inner.db.accounts.is_empty()); + + // Ensure that the block hashes database is empty + assert!(evm.context.evm.inner.db.block_hashes.is_empty()); + + // Verify that there are two default contracts in the contracts database + assert_eq!(evm.context.evm.inner.db.contracts.len(), 2); + assert!(evm.context.evm.inner.db.contracts.contains_key(&KECCAK_EMPTY)); + assert!(evm.context.evm.inner.db.contracts.contains_key(&B256::ZERO)); + + // Ensure that the logs database is empty + assert!(evm.context.evm.inner.db.logs.is_empty()); + + // Ensure that there are no valid authorizations in the EVM context + assert!(evm.context.evm.inner.valid_authorizations.is_empty()); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + + // Default spec ID + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + } + + #[test] + fn test_evm_with_env_default_spec() { + let evm_config = OptimismEvmConfig::default(); + + let db = CacheDB::>::default(); + + let env_with_handler = EnvWithHandlerCfg::default(); + + let evm = evm_config.evm_with_env(db, env_with_handler.clone()); + + // Check that the EVM environment + assert_eq!(evm.context.evm.env, env_with_handler.env); + + // Default spec ID + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_custom_cfg() { + let evm_config = OptimismEvmConfig::default(); + + let db = CacheDB::>::default(); + + // Create a custom configuration environment with a chain ID of 111 + let cfg = CfgEnv::default().with_chain_id(111); + + let env_with_handler = EnvWithHandlerCfg { + env: Box::new(Env { + cfg: cfg.clone(), + block: BlockEnv::default(), + tx: TxEnv::default(), + }), + handler_cfg: Default::default(), + }; + + let evm = evm_config.evm_with_env(db, env_with_handler); + + // Check that the EVM environment is initialized with the custom environment + assert_eq!(evm.context.evm.inner.env.cfg, cfg); + + // Default spec ID + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_custom_block_and_tx() { + let evm_config = OptimismEvmConfig::default(); + + let db = CacheDB::>::default(); + + // Create customs block and tx env + let block = BlockEnv { + basefee: U256::from(1000), + gas_limit: U256::from(10_000_000), + number: U256::from(42), + ..Default::default() + }; + let tx = TxEnv { gas_limit: 5_000_000, gas_price: U256::from(50), ..Default::default() }; + + let env_with_handler = EnvWithHandlerCfg { + env: Box::new(Env { cfg: CfgEnv::default(), block, tx }), + handler_cfg: Default::default(), + }; + + let evm = evm_config.evm_with_env(db, env_with_handler.clone()); + + // Verify that the block and transaction environments are set correctly + assert_eq!(evm.context.evm.env.block, env_with_handler.env.block); + assert_eq!(evm.context.evm.env.tx, env_with_handler.env.tx); + + // Default spec ID + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_spec_id() { + let evm_config = OptimismEvmConfig::default(); + + let db = CacheDB::>::default(); + + let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() }; + + let env_with_handler = EnvWithHandlerCfg { env: Box::new(Env::default()), handler_cfg }; + + let evm = evm_config.evm_with_env(db, env_with_handler); + + // Check that the spec ID is setup properly + assert_eq!(evm.handler.spec_id(), SpecId::ECOTONE); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::ECOTONE, is_optimism: true }); + } + + #[test] + fn test_evm_with_inspector() { + let evm_config = OptimismEvmConfig::default(); + + let db = CacheDB::>::default(); + + // No operation inspector + let noop = NoOpInspector; + + let evm = evm_config.evm_with_inspector(db, noop); + + // Check that the inspector is set correctly + assert_eq!(evm.context.external, noop); + + // Check that the EVM environment is initialized with default values + assert_eq!(evm.context.evm.inner.env, Box::default()); + + // Latest spec ID and no warm preloaded addresses + assert_eq!( + evm.context.evm.inner.journaled_state, + JournaledState::new(SpecId::LATEST, HashSet::default()) + ); + + // Ensure that the accounts database is empty + assert!(evm.context.evm.inner.db.accounts.is_empty()); + + // Ensure that the block hashes database is empty + assert!(evm.context.evm.inner.db.block_hashes.is_empty()); + + // Verify that there are two default contracts in the contracts database + assert_eq!(evm.context.evm.inner.db.contracts.len(), 2); + assert!(evm.context.evm.inner.db.contracts.contains_key(&KECCAK_EMPTY)); + assert!(evm.context.evm.inner.db.contracts.contains_key(&B256::ZERO)); + + // Ensure that the logs database is empty + assert!(evm.context.evm.inner.db.logs.is_empty()); + + // Ensure that there are no valid authorizations in the EVM context + assert!(evm.context.evm.inner.valid_authorizations.is_empty()); + + // Default spec ID + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_and_default_inspector() { + let evm_config = OptimismEvmConfig::default(); + let db = CacheDB::>::default(); + + let env_with_handler = EnvWithHandlerCfg::default(); + + let evm = + evm_config.evm_with_env_and_inspector(db, env_with_handler.clone(), NoOpInspector); + + // Check that the EVM environment is set to default values + assert_eq!(evm.context.evm.env, env_with_handler.env); + assert_eq!(evm.context.external, NoOpInspector); + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_inspector_and_custom_cfg() { + let evm_config = OptimismEvmConfig::default(); + let db = CacheDB::>::default(); + + let cfg = CfgEnv::default().with_chain_id(111); + let block = BlockEnv::default(); + let tx = TxEnv::default(); + let env_with_handler = EnvWithHandlerCfg { + env: Box::new(Env { cfg: cfg.clone(), block, tx }), + handler_cfg: Default::default(), + }; + + let evm = evm_config.evm_with_env_and_inspector(db, env_with_handler, NoOpInspector); + + // Check that the EVM environment is set with custom configuration + assert_eq!(evm.context.evm.env.cfg, cfg); + assert_eq!(evm.context.external, NoOpInspector); + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_inspector_and_custom_block_tx() { + let evm_config = OptimismEvmConfig::default(); + let db = CacheDB::>::default(); + + // Create custom block and tx environment + let block = BlockEnv { + basefee: U256::from(1000), + gas_limit: U256::from(10_000_000), + number: U256::from(42), + ..Default::default() + }; + let tx = TxEnv { gas_limit: 5_000_000, gas_price: U256::from(50), ..Default::default() }; + let env_with_handler = EnvWithHandlerCfg { + env: Box::new(Env { cfg: CfgEnv::default(), block, tx }), + handler_cfg: Default::default(), + }; + + let evm = + evm_config.evm_with_env_and_inspector(db, env_with_handler.clone(), NoOpInspector); + + // Verify that the block and transaction environments are set correctly + assert_eq!(evm.context.evm.env.block, env_with_handler.env.block); + assert_eq!(evm.context.evm.env.tx, env_with_handler.env.tx); + assert_eq!(evm.context.external, NoOpInspector); + assert_eq!(evm.handler.spec_id(), SpecId::LATEST); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }); + } + + #[test] + fn test_evm_with_env_inspector_and_spec_id() { + let evm_config = OptimismEvmConfig::default(); + let db = CacheDB::>::default(); + + let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() }; + let env_with_handler = EnvWithHandlerCfg { env: Box::new(Env::default()), handler_cfg }; + + let evm = + evm_config.evm_with_env_and_inspector(db, env_with_handler.clone(), NoOpInspector); + + // Check that the spec ID is set properly + assert_eq!(evm.handler.spec_id(), SpecId::ECOTONE); + assert_eq!(evm.context.evm.env, env_with_handler.env); + assert_eq!(evm.context.external, NoOpInspector); + + // Check that the spec ID is setup properly + assert_eq!(evm.handler.spec_id(), SpecId::ECOTONE); + + // Optimism in handler + assert_eq!(evm.handler.cfg, HandlerCfg { spec_id: SpecId::ECOTONE, is_optimism: true }); + } } diff --git a/crates/primitives-traits/src/integer_list.rs b/crates/primitives-traits/src/integer_list.rs index d28aee7a6a0d7..df68d612aad6d 100644 --- a/crates/primitives-traits/src/integer_list.rs +++ b/crates/primitives-traits/src/integer_list.rs @@ -143,10 +143,10 @@ impl<'a> Arbitrary<'a> for IntegerList { #[derive(Debug, derive_more::Display)] pub enum RoaringBitmapError { /// The provided input is invalid. - #[display(fmt = "the provided input is invalid")] + #[display("the provided input is invalid")] InvalidInput, /// Failed to deserialize data into type. - #[display(fmt = "failed to deserialize data into type")] + #[display("failed to deserialize data into type")] FailedToDeserialize, } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 3430720e3f389..f3239c72b5d29 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -5,7 +5,7 @@ use alloy_primitives::Log; use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodable}; use bytes::{Buf, BufMut}; use core::{cmp::Ordering, ops::Deref}; -use derive_more::{Deref, DerefMut, From, IntoIterator}; +use derive_more::{DerefMut, From, IntoIterator}; #[cfg(feature = "reth-codec")] use reth_codecs::{Compact, CompactZstd}; use serde::{Deserialize, Serialize}; @@ -74,7 +74,7 @@ impl Receipt { Serialize, Deserialize, From, - Deref, + derive_more::Deref, DerefMut, IntoIterator, )] diff --git a/crates/primitives/src/transaction/error.rs b/crates/primitives/src/transaction/error.rs index 336c396914b44..2f3ffc5f8bad4 100644 --- a/crates/primitives/src/transaction/error.rs +++ b/crates/primitives/src/transaction/error.rs @@ -6,53 +6,53 @@ use crate::{GotExpectedBoxed, U256}; pub enum InvalidTransactionError { /// The sender does not have enough funds to cover the transaction fees #[display( - fmt = "sender does not have enough funds ({}) to cover transaction fees: {}", _0.got, _0.expected + "sender does not have enough funds ({}) to cover transaction fees: {}", _0.got, _0.expected )] InsufficientFunds(GotExpectedBoxed), /// The nonce is lower than the account's nonce, or there is a nonce gap present. /// /// This is a consensus error. - #[display(fmt = "transaction nonce is not consistent")] + #[display("transaction nonce is not consistent")] NonceNotConsistent, /// The transaction is before Spurious Dragon and has a chain ID. - #[display(fmt = "transactions before Spurious Dragon should not have a chain ID")] + #[display("transactions before Spurious Dragon should not have a chain ID")] OldLegacyChainId, /// The chain ID in the transaction does not match the current network configuration. - #[display(fmt = "transaction's chain ID does not match")] + #[display("transaction's chain ID does not match")] ChainIdMismatch, /// The transaction requires EIP-2930 which is not enabled currently. - #[display(fmt = "EIP-2930 transactions are disabled")] + #[display("EIP-2930 transactions are disabled")] Eip2930Disabled, /// The transaction requires EIP-1559 which is not enabled currently. - #[display(fmt = "EIP-1559 transactions are disabled")] + #[display("EIP-1559 transactions are disabled")] Eip1559Disabled, /// The transaction requires EIP-4844 which is not enabled currently. - #[display(fmt = "EIP-4844 transactions are disabled")] + #[display("EIP-4844 transactions are disabled")] Eip4844Disabled, /// The transaction requires EIP-7702 which is not enabled currently. - #[display(fmt = "EIP-7702 transactions are disabled")] + #[display("EIP-7702 transactions are disabled")] Eip7702Disabled, /// Thrown if a transaction is not supported in the current network configuration. - #[display(fmt = "transaction type not supported")] + #[display("transaction type not supported")] TxTypeNotSupported, /// The calculated gas of the transaction exceeds `u64::MAX`. - #[display(fmt = "gas overflow (maximum of u64)")] + #[display("gas overflow (maximum of u64)")] GasUintOverflow, /// The transaction is specified to use less gas than required to start the invocation. - #[display(fmt = "intrinsic gas too low")] + #[display("intrinsic gas too low")] GasTooLow, /// The transaction gas exceeds the limit - #[display(fmt = "intrinsic gas too high")] + #[display("intrinsic gas too high")] GasTooHigh, /// Thrown to ensure no one is able to specify a transaction with a tip higher than the total /// fee cap. - #[display(fmt = "max priority fee per gas higher than max fee per gas")] + #[display("max priority fee per gas higher than max fee per gas")] TipAboveFeeCap, /// Thrown post London if the transaction's fee is less than the base fee of the block. - #[display(fmt = "max fee per gas less than block base fee")] + #[display("max fee per gas less than block base fee")] FeeCapTooLow, /// Thrown if the sender of a transaction is a contract. - #[display(fmt = "transaction signer has bytecode set")] + #[display("transaction signer has bytecode set")] SignerAccountHasBytecode, } @@ -66,7 +66,7 @@ pub enum TransactionConversionError { /// This error variant is used when a transaction cannot be converted into a /// [`PooledTransactionsElement`](crate::PooledTransactionsElement) because it is not supported /// for P2P network. - #[display(fmt = "Transaction is not supported for p2p")] + #[display("Transaction is not supported for p2p")] UnsupportedForP2P, } @@ -78,10 +78,10 @@ impl std::error::Error for TransactionConversionError {} #[derive(Debug, Clone, Eq, PartialEq, derive_more::Display)] pub enum TryFromRecoveredTransactionError { /// Thrown if the transaction type is unsupported. - #[display(fmt = "Unsupported transaction type: {_0}")] + #[display("Unsupported transaction type: {_0}")] UnsupportedTransactionType(u8), /// This error variant is used when a blob sidecar is missing. - #[display(fmt = "Blob sidecar missing for an EIP-4844 transaction")] + #[display("Blob sidecar missing for an EIP-4844 transaction")] BlobSidecarMissing, } diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index fa4ade38ef688..9a858d5a47510 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -175,6 +175,7 @@ where EthApiClient::protocol_version(client).await.unwrap(); EthApiClient::chain_id(client).await.unwrap(); EthApiClient::accounts(client).await.unwrap(); + EthApiClient::get_account(client, address, block_number.into()).await.unwrap(); EthApiClient::block_number(client).await.unwrap(); EthApiClient::get_code(client, address, None).await.unwrap(); EthApiClient::send_raw_transaction(client, tx).await.unwrap(); diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 30c51a9f7e868..1a1e914850f73 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -262,7 +262,7 @@ pub trait EthApi { &self, address: Address, block: BlockId, - ) -> RpcResult; + ) -> RpcResult>; /// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions. #[method(name = "maxPriorityFeePerGas")] @@ -652,7 +652,7 @@ where &self, address: Address, block: BlockId, - ) -> RpcResult { + ) -> RpcResult> { trace!(target: "rpc::eth", "Serving eth_getAccount"); Ok(EthState::get_account(self, address, block).await?) } diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 2d2c159751ac9..1407a661b1b62 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -134,14 +134,13 @@ pub trait EthState: LoadState + SpawnBlocking { &self, address: Address, block_id: BlockId, - ) -> impl Future> + Send { + ) -> impl Future, Self::Error>> + Send { self.spawn_blocking_io(move |this| { let state = this.state_at_block_id(block_id)?; - let account = state - .basic_account(address) - .map_err(Self::Error::from_eth_err)? - .unwrap_or_default(); + let account = state.basic_account(address).map_err(Self::Error::from_eth_err)?; + let Some(account) = account else { return Ok(None) }; + let balance = account.balance; let nonce = account.nonce; let code_hash = account.bytecode_hash.unwrap_or(KECCAK_EMPTY); @@ -152,7 +151,7 @@ pub trait EthState: LoadState + SpawnBlocking { .hashed_storage_root(address, Default::default()) .map_err(Self::Error::from_eth_err)?; - Ok(Account { balance, nonce, code_hash, storage_root }) + Ok(Some(Account { balance, nonce, code_hash, storage_root })) }) } } diff --git a/crates/rpc/rpc/src/eth/helpers/state.rs b/crates/rpc/rpc/src/eth/helpers/state.rs index 7974fc1143233..6b1a24aff097b 100644 --- a/crates/rpc/rpc/src/eth/helpers/state.rs +++ b/crates/rpc/rpc/src/eth/helpers/state.rs @@ -44,7 +44,7 @@ mod tests { use super::*; use reth_evm_ethereum::EthEvmConfig; use reth_primitives::{ - constants::ETHEREUM_BLOCK_GAS_LIMIT, Address, StorageKey, StorageValue, U256, + constants::ETHEREUM_BLOCK_GAS_LIMIT, Address, StorageKey, StorageValue, KECCAK_EMPTY, U256, }; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; use reth_rpc_eth_api::helpers::EthState; @@ -53,19 +53,17 @@ mod tests { }; use reth_rpc_server_types::constants::{DEFAULT_ETH_PROOF_WINDOW, DEFAULT_PROOF_PERMITS}; use reth_tasks::pool::BlockingTaskPool; - use reth_transaction_pool::test_utils::testing_pool; + use reth_transaction_pool::test_utils::{testing_pool, TestPool}; use std::collections::HashMap; - #[tokio::test] - async fn test_storage() { - // === Noop === + fn noop_eth_api() -> EthApi { let pool = testing_pool(); let evm_config = EthEvmConfig::default(); let cache = EthStateCache::spawn(NoopProvider::default(), Default::default(), evm_config); - let eth_api = EthApi::new( + EthApi::new( NoopProvider::default(), - pool.clone(), + pool, (), cache.clone(), GasPriceOracle::new(NoopProvider::default(), Default::default(), cache.clone()), @@ -76,21 +74,20 @@ mod tests { evm_config, None, DEFAULT_PROOF_PERMITS, - ); - let address = Address::random(); - let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap(); - assert_eq!(storage, U256::ZERO.to_be_bytes()); + ) + } + + fn mock_eth_api( + accounts: HashMap, + ) -> EthApi { + let pool = testing_pool(); + let evm_config = EthEvmConfig::default(); - // === Mock === let mock_provider = MockEthProvider::default(); - let storage_value = StorageValue::from(1337); - let storage_key = StorageKey::random(); - let storage = HashMap::from([(storage_key, storage_value)]); - let account = ExtendedAccount::new(0, U256::ZERO).extend_storage(storage); - mock_provider.add_account(address, account); + mock_provider.extend_accounts(accounts); let cache = EthStateCache::spawn(mock_provider.clone(), Default::default(), evm_config); - let eth_api = EthApi::new( + EthApi::new( mock_provider.clone(), pool, (), @@ -103,10 +100,48 @@ mod tests { evm_config, None, DEFAULT_PROOF_PERMITS, - ); + ) + } + + #[tokio::test] + async fn test_storage() { + // === Noop === + let eth_api = noop_eth_api(); + let address = Address::random(); + let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap(); + assert_eq!(storage, U256::ZERO.to_be_bytes()); + + // === Mock === + let storage_value = StorageValue::from(1337); + let storage_key = StorageKey::random(); + let storage = HashMap::from([(storage_key, storage_value)]); + + let accounts = + HashMap::from([(address, ExtendedAccount::new(0, U256::ZERO).extend_storage(storage))]); + let eth_api = mock_eth_api(accounts); let storage_key: U256 = storage_key.into(); let storage = eth_api.storage_at(address, storage_key.into(), None).await.unwrap(); assert_eq!(storage, storage_value.to_be_bytes()); } + + #[tokio::test] + async fn test_get_account_missing() { + let eth_api = noop_eth_api(); + let address = Address::random(); + let account = eth_api.get_account(address, Default::default()).await.unwrap(); + assert!(account.is_none()); + } + + #[tokio::test] + async fn test_get_account_empty() { + let address = Address::random(); + let accounts = HashMap::from([(address, ExtendedAccount::new(0, U256::ZERO))]); + let eth_api = mock_eth_api(accounts); + + let account = eth_api.get_account(address, Default::default()).await.unwrap(); + let expected_account = + reth_rpc_types::Account { code_hash: KECCAK_EMPTY, ..Default::default() }; + assert_eq!(Some(expected_account), account); + } } diff --git a/crates/storage/errors/src/db.rs b/crates/storage/errors/src/db.rs index a2cbcba33ced3..079a7d56fd796 100644 --- a/crates/storage/errors/src/db.rs +++ b/crates/storage/errors/src/db.rs @@ -19,39 +19,39 @@ use core::{ #[derive(Clone, Debug, PartialEq, Eq, derive_more::Display)] pub enum DatabaseError { /// Failed to open the database. - #[display(fmt = "failed to open the database: {_0}")] + #[display("failed to open the database: {_0}")] Open(DatabaseErrorInfo), /// Failed to create a table in the database. - #[display(fmt = "failed to create a table: {_0}")] + #[display("failed to create a table: {_0}")] CreateTable(DatabaseErrorInfo), /// Failed to write a value into a table. Write(Box), /// Failed to read a value from a table. - #[display(fmt = "failed to read a value from a database table: {_0}")] + #[display("failed to read a value from a database table: {_0}")] Read(DatabaseErrorInfo), /// Failed to delete a `(key, value)` pair from a table. - #[display(fmt = "database delete error code: {_0}")] + #[display("database delete error code: {_0}")] Delete(DatabaseErrorInfo), /// Failed to commit transaction changes into the database. - #[display(fmt = "failed to commit transaction changes: {_0}")] + #[display("failed to commit transaction changes: {_0}")] Commit(DatabaseErrorInfo), /// Failed to initiate a transaction. - #[display(fmt = "failed to initialize a transaction: {_0}")] + #[display("failed to initialize a transaction: {_0}")] InitTx(DatabaseErrorInfo), /// Failed to initialize a cursor. - #[display(fmt = "failed to initialize a cursor: {_0}")] + #[display("failed to initialize a cursor: {_0}")] InitCursor(DatabaseErrorInfo), /// Failed to decode a key from a table. - #[display(fmt = "failed to decode a key from a table")] + #[display("failed to decode a key from a table")] Decode, /// Failed to get database stats. - #[display(fmt = "failed to get stats: {_0}")] + #[display("failed to get stats: {_0}")] Stats(DatabaseErrorInfo), /// Failed to use the specified log level, as it's not available. - #[display(fmt = "log level {_0:?} is not available")] + #[display("log level {_0:?} is not available")] LogLevelUnavailable(LogLevel), /// Other unspecified error. - #[display(fmt = "{_0}")] + #[display("{_0}")] Other(String), } @@ -67,7 +67,7 @@ impl std::error::Error for DatabaseError { /// Common error struct to propagate implementation-specific error information. #[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)] -#[display(fmt = "{message} ({code})")] +#[display("{message} ({code})")] pub struct DatabaseErrorInfo { /// Human-readable error message. pub message: String, diff --git a/crates/storage/errors/src/lockfile.rs b/crates/storage/errors/src/lockfile.rs index ede10401a20cb..17687cb69cd2f 100644 --- a/crates/storage/errors/src/lockfile.rs +++ b/crates/storage/errors/src/lockfile.rs @@ -7,12 +7,10 @@ use alloc::string::{String, ToString}; #[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)] pub enum StorageLockError { /// Write lock taken - #[display( - fmt = "storage directory is currently in use as read-write by another process: PID {_0}" - )] + #[display("storage directory is currently in use as read-write by another process: PID {_0}")] Taken(usize), /// Indicates other unspecified errors. - #[display(fmt = "{_0}")] + #[display("{_0}")] Other(String), } diff --git a/crates/storage/errors/src/provider.rs b/crates/storage/errors/src/provider.rs index 980e44c07ec20..16ff50f3340c9 100644 --- a/crates/storage/errors/src/provider.rs +++ b/crates/storage/errors/src/provider.rs @@ -22,27 +22,27 @@ pub enum ProviderError { /// RLP error. Rlp(alloy_rlp::Error), /// Filesystem path error. - #[display(fmt = "{_0}")] + #[display("{_0}")] FsPathError(String), /// Nippy jar error. - #[display(fmt = "nippy jar error: {_0}")] + #[display("nippy jar error: {_0}")] NippyJar(String), /// Trie witness error. - #[display(fmt = "trie witness error: {_0}")] + #[display("trie witness error: {_0}")] TrieWitnessError(String), /// Error when recovering the sender for a transaction - #[display(fmt = "failed to recover sender for transaction")] + #[display("failed to recover sender for transaction")] SenderRecoveryError, /// The header number was not found for the given block hash. - #[display(fmt = "block hash {_0} does not exist in Headers table")] + #[display("block hash {_0} does not exist in Headers table")] BlockHashNotFound(BlockHash), /// A block body is missing. - #[display(fmt = "block meta not found for block #{_0}")] + #[display("block meta not found for block #{_0}")] BlockBodyIndicesNotFound(BlockNumber), /// The transition ID was found for the given address and storage key, but the changeset was /// not found. #[display( - fmt = "storage change set for address {address} and key {storage_key} at block #{block_number} does not exist" + "storage change set for address {address} and key {storage_key} at block #{block_number} does not exist" )] StorageChangesetNotFound { /// The block number found for the address and storage key. @@ -55,9 +55,7 @@ pub enum ProviderError { storage_key: Box, }, /// The block number was found for the given address, but the changeset was not found. - #[display( - fmt = "account change set for address {address} at block #{block_number} does not exist" - )] + #[display("account change set for address {address} at block #{block_number} does not exist")] AccountChangesetNotFound { /// Block number found for the address. block_number: BlockNumber, @@ -65,86 +63,86 @@ pub enum ProviderError { address: Address, }, /// The total difficulty for a block is missing. - #[display(fmt = "total difficulty not found for block #{_0}")] + #[display("total difficulty not found for block #{_0}")] TotalDifficultyNotFound(BlockNumber), /// when required header related data was not found but was required. - #[display(fmt = "no header found for {_0:?}")] + #[display("no header found for {_0:?}")] HeaderNotFound(BlockHashOrNumber), /// The specific transaction is missing. - #[display(fmt = "no transaction found for {_0:?}")] + #[display("no transaction found for {_0:?}")] TransactionNotFound(TxHashOrNumber), /// The specific receipt is missing - #[display(fmt = "no receipt found for {_0:?}")] + #[display("no receipt found for {_0:?}")] ReceiptNotFound(TxHashOrNumber), /// Unable to find the best block. - #[display(fmt = "best block does not exist")] + #[display("best block does not exist")] BestBlockNotFound, /// Unable to find the finalized block. - #[display(fmt = "finalized block does not exist")] + #[display("finalized block does not exist")] FinalizedBlockNotFound, /// Unable to find the safe block. - #[display(fmt = "safe block does not exist")] + #[display("safe block does not exist")] SafeBlockNotFound, /// Mismatch of sender and transaction. - #[display(fmt = "mismatch of sender and transaction id {tx_id}")] + #[display("mismatch of sender and transaction id {tx_id}")] MismatchOfTransactionAndSenderId { /// The transaction ID. tx_id: TxNumber, }, /// Block body wrong transaction count. - #[display(fmt = "stored block indices does not match transaction count")] + #[display("stored block indices does not match transaction count")] BlockBodyTransactionCount, /// Thrown when the cache service task dropped. - #[display(fmt = "cache service task stopped")] + #[display("cache service task stopped")] CacheServiceUnavailable, /// Thrown when we failed to lookup a block for the pending state. - #[display(fmt = "unknown block {_0}")] + #[display("unknown block {_0}")] UnknownBlockHash(B256), /// Thrown when we were unable to find a state for a block hash. - #[display(fmt = "no state found for block {_0}")] + #[display("no state found for block {_0}")] StateForHashNotFound(B256), /// Thrown when we were unable to find a state for a block number. - #[display(fmt = "no state found for block number {_0}")] + #[display("no state found for block number {_0}")] StateForNumberNotFound(u64), /// Unable to find the block number for a given transaction index. - #[display(fmt = "unable to find the block number for a given transaction index")] + #[display("unable to find the block number for a given transaction index")] BlockNumberForTransactionIndexNotFound, /// Root mismatch. - #[display(fmt = "merkle trie {_0}")] + #[display("merkle trie {_0}")] StateRootMismatch(Box), /// Root mismatch during unwind - #[display(fmt = "unwind merkle trie {_0}")] + #[display("unwind merkle trie {_0}")] UnwindStateRootMismatch(Box), /// State is not available for the given block number because it is pruned. - #[display(fmt = "state at block #{_0} is pruned")] + #[display("state at block #{_0} is pruned")] StateAtBlockPruned(BlockNumber), /// Provider does not support this particular request. - #[display(fmt = "this provider does not support this request")] + #[display("this provider does not support this request")] UnsupportedProvider, /// Static File is not found at specified path. #[cfg(feature = "std")] - #[display(fmt = "not able to find {_0} static file at {_1:?}")] + #[display("not able to find {_0} static file at {_1:?}")] MissingStaticFilePath(StaticFileSegment, PathBuf), /// Static File is not found for requested block. - #[display(fmt = "not able to find {_0} static file for block number {_1}")] + #[display("not able to find {_0} static file for block number {_1}")] MissingStaticFileBlock(StaticFileSegment, BlockNumber), /// Static File is not found for requested transaction. - #[display(fmt = "unable to find {_0} static file for transaction id {_1}")] + #[display("unable to find {_0} static file for transaction id {_1}")] MissingStaticFileTx(StaticFileSegment, TxNumber), /// Static File is finalized and cannot be written to. - #[display(fmt = "unable to write block #{_1} to finalized static file {_0}")] + #[display("unable to write block #{_1} to finalized static file {_0}")] FinalizedStaticFile(StaticFileSegment, BlockNumber), /// Trying to insert data from an unexpected block number. - #[display(fmt = "trying to append data to {_0} as block #{_1} but expected block #{_2}")] + #[display("trying to append data to {_0} as block #{_1} but expected block #{_2}")] UnexpectedStaticFileBlockNumber(StaticFileSegment, BlockNumber, BlockNumber), /// Static File Provider was initialized as read-only. - #[display(fmt = "cannot get a writer on a read-only environment.")] + #[display("cannot get a writer on a read-only environment.")] ReadOnlyStaticFileAccess, /// Error encountered when the block number conversion from U256 to u64 causes an overflow. - #[display(fmt = "failed to convert block number U256 to u64: {_0}")] + #[display("failed to convert block number U256 to u64: {_0}")] BlockNumberOverflow(U256), /// Consistent view error. - #[display(fmt = "failed to initialize consistent view: {_0}")] + #[display("failed to initialize consistent view: {_0}")] ConsistentView(Box), /// Storage lock error. StorageLockError(StorageLockError), @@ -191,7 +189,7 @@ impl std::error::Error for ProviderError { /// A root mismatch error at a given block height. #[derive(Clone, Debug, PartialEq, Eq, Display)] -#[display(fmt = "root mismatch at #{block_number} ({block_hash}): {root}")] +#[display("root mismatch at #{block_number} ({block_hash}): {root}")] pub struct RootMismatch { /// The target block root diff. pub root: GotExpected, @@ -205,13 +203,13 @@ pub struct RootMismatch { #[derive(Clone, Debug, PartialEq, Eq, Display)] pub enum ConsistentViewError { /// Error thrown on attempt to initialize provider while node is still syncing. - #[display(fmt = "node is syncing. best block: {best_block:?}")] + #[display("node is syncing. best block: {best_block:?}")] Syncing { /// Best block diff. best_block: GotExpected, }, /// Error thrown on inconsistent database view. - #[display(fmt = "inconsistent database state: {tip:?}")] + #[display("inconsistent database state: {tip:?}")] Inconsistent { /// The tip diff. tip: GotExpected>, diff --git a/crates/storage/errors/src/writer.rs b/crates/storage/errors/src/writer.rs index e5317043c8d4e..71a1c47e2a18a 100644 --- a/crates/storage/errors/src/writer.rs +++ b/crates/storage/errors/src/writer.rs @@ -6,13 +6,13 @@ use reth_primitives::StaticFileSegment; #[derive(Clone, Debug, derive_more::Display, PartialEq, Eq)] pub enum UnifiedStorageWriterError { /// Database writer is missing - #[display(fmt = "Database writer is missing")] + #[display("Database writer is missing")] MissingDatabaseWriter, /// Static file writer is missing - #[display(fmt = "Static file writer is missing")] + #[display("Static file writer is missing")] MissingStaticFileWriter, /// Static file writer is of wrong segment - #[display(fmt = "Static file writer is of wrong segment: got {_0}, expected {_1}")] + #[display("Static file writer is of wrong segment: got {_0}, expected {_1}")] IncorrectStaticFileWriter(StaticFileSegment, StaticFileSegment), /// Database-related errors. Database(DatabaseError), diff --git a/crates/storage/libmdbx-rs/src/codec.rs b/crates/storage/libmdbx-rs/src/codec.rs index 15f20204e20a2..a97ea28ca2ae9 100644 --- a/crates/storage/libmdbx-rs/src/codec.rs +++ b/crates/storage/libmdbx-rs/src/codec.rs @@ -1,5 +1,5 @@ use crate::{Error, TransactionKind}; -use derive_more::*; +use derive_more::{Debug, Deref, DerefMut}; use std::{borrow::Cow, slice}; /// Implement this to be able to decode data values diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 2e1df507c18b4..18688cc1e750c 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -505,7 +505,6 @@ where if let Some(block_state) = self.canonical_in_memory_state.state_by_number(num) { return Ok(Some(block_state.block().block().clone().unseal())); } - self.database.block_by_number(num) } } @@ -635,11 +634,11 @@ where let mut blocks = Vec::with_capacity(capacity); // First, fetch the blocks from the database - let mut db_blocks = self.database.block_range(range.clone())?; - blocks.append(&mut db_blocks); + let mut database_blocks = self.database.block_range(range.clone())?; + blocks.append(&mut database_blocks); // Advance the range iterator by the number of blocks fetched from the database - range.nth(db_blocks.len() - 1); + range.nth(database_blocks.len() - 1); // Fetch the remaining blocks from the in-memory state for num in range { @@ -663,11 +662,11 @@ where let mut blocks = Vec::with_capacity(capacity); // First, fetch the blocks from the database - let mut db_blocks = self.database.block_with_senders_range(range.clone())?; - blocks.append(&mut db_blocks); + let mut database_blocks = self.database.block_with_senders_range(range.clone())?; + blocks.append(&mut database_blocks); // Advance the range iterator by the number of blocks fetched from the database - range.nth(db_blocks.len() - 1); + range.nth(database_blocks.len() - 1); // Fetch the remaining blocks from the in-memory state for num in range { @@ -693,11 +692,11 @@ where let mut blocks = Vec::with_capacity(capacity); // First, fetch the blocks from the database - let mut db_blocks = self.database.sealed_block_with_senders_range(range.clone())?; - blocks.append(&mut db_blocks); + let mut database_blocks = self.database.sealed_block_with_senders_range(range.clone())?; + blocks.append(&mut database_blocks); // Advance the range iterator by the number of blocks fetched from the database - range.nth(db_blocks.len() - 1); + range.nth(database_blocks.len() - 1); // Fetch the remaining blocks from the in-memory state for num in range { @@ -1435,12 +1434,12 @@ impl ForkChoiceSubscriptions for BlockchainProvider2 where DB: Send + Sync, { - fn subscribe_to_safe_block(&self) -> ForkChoiceNotifications { + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_safe_block(); ForkChoiceNotifications(receiver) } - fn subscribe_to_finalized_block(&self) -> ForkChoiceNotifications { + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_finalized_block(); ForkChoiceNotifications(receiver) } @@ -1493,14 +1492,16 @@ mod tests { use itertools::Itertools; use rand::Rng; use reth_chain_state::{ExecutedBlock, NewCanonicalChain}; + use reth_chainspec::ChainSpecProvider; use reth_db::{models::AccountBeforeTx, test_utils::TempDatabase, DatabaseEnv}; use reth_execution_types::ExecutionOutcome; - use reth_primitives::{BlockNumberOrTag, SealedBlock, B256}; + use reth_primitives::{BlockHashOrNumber, BlockNumberOrTag, Header, SealedBlock, B256}; use reth_storage_api::{ - BlockHashReader, BlockNumReader, BlockReaderIdExt, ChangeSetReader, HeaderProvider, + BlockHashReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, + ChangeSetReader, HeaderProvider, }; use reth_testing_utils::generators::{ - self, random_block_range, random_changeset_range, random_eoa_accounts, + self, random_block, random_block_range, random_changeset_range, random_eoa_accounts, }; use revm::{ db::{ @@ -1587,6 +1588,269 @@ mod tests { Ok((provider, database_blocks, in_memory_blocks)) } + #[test] + fn test_block_reader_find_block_by_hash() -> eyre::Result<()> { + // Initialize random number generator and provider factory + let mut rng = generators::rng(); + let factory = create_test_provider_factory(); + + // Generate 10 random blocks and split into database and in-memory blocks + let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1); + let (database_blocks, in_memory_blocks) = blocks.split_at(5); + + // Insert first 5 blocks into the database + let provider_rw = factory.provider_rw()?; + for block in database_blocks { + provider_rw.insert_historical_block( + block.clone().seal_with_senders().expect("failed to seal block with senders"), + )?; + } + provider_rw.commit()?; + + // Create a new provider + let provider = BlockchainProvider2::new(factory)?; + + // Useful blocks + let first_db_block = database_blocks.first().unwrap(); + let first_in_mem_block = in_memory_blocks.first().unwrap(); + let last_in_mem_block = in_memory_blocks.last().unwrap(); + + // No block in memory before setting in memory state + assert_eq!(provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Any)?, None); + assert_eq!( + provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Canonical)?, + None + ); + // No pending block in memory + assert_eq!( + provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Pending)?, + None + ); + + // Insert first block into the in-memory state + let in_memory_block_senders = + first_in_mem_block.senders().expect("failed to recover senders"); + let chain = NewCanonicalChain::Commit { + new: vec![ExecutedBlock::new( + Arc::new(first_in_mem_block.clone()), + Arc::new(in_memory_block_senders), + Default::default(), + Default::default(), + Default::default(), + )], + }; + provider.canonical_in_memory_state.update_chain(chain); + + // Now the block should be found in memory + assert_eq!( + provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Any)?, + Some(first_in_mem_block.clone().into()) + ); + assert_eq!( + provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Canonical)?, + Some(first_in_mem_block.clone().into()) + ); + + // Find the first block in database by hash + assert_eq!( + provider.find_block_by_hash(first_db_block.hash(), BlockSource::Any)?, + Some(first_db_block.clone().into()) + ); + assert_eq!( + provider.find_block_by_hash(first_db_block.hash(), BlockSource::Canonical)?, + Some(first_db_block.clone().into()) + ); + + // No pending block in database + assert_eq!(provider.find_block_by_hash(first_db_block.hash(), BlockSource::Pending)?, None); + + // Insert the last block into the pending state + provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { + block: Arc::new(last_in_mem_block.clone()), + senders: Default::default(), + execution_output: Default::default(), + hashed_state: Default::default(), + trie: Default::default(), + }); + + // Now the last block should be found in memory + assert_eq!( + provider.find_block_by_hash(last_in_mem_block.hash(), BlockSource::Pending)?, + Some(last_in_mem_block.clone().into()) + ); + + Ok(()) + } + + #[test] + fn test_block_reader_block() -> eyre::Result<()> { + // Initialize random number generator and provider factory + let mut rng = generators::rng(); + let factory = create_test_provider_factory(); + + // Generate 10 random blocks and split into database and in-memory blocks + let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1); + let (database_blocks, in_memory_blocks) = blocks.split_at(5); + + // Insert first 5 blocks into the database + let provider_rw = factory.provider_rw()?; + for block in database_blocks { + provider_rw.insert_historical_block( + block.clone().seal_with_senders().expect("failed to seal block with senders"), + )?; + } + provider_rw.commit()?; + + // Create a new provider + let provider = BlockchainProvider2::new(factory)?; + + // First in memory block + let first_in_mem_block = in_memory_blocks.first().unwrap(); + // First database block + let first_db_block = database_blocks.first().unwrap(); + + // First in memory block should not be found yet as not integrated to the in-memory state + assert_eq!(provider.block(BlockHashOrNumber::Hash(first_in_mem_block.hash()))?, None); + assert_eq!(provider.block(BlockHashOrNumber::Number(first_in_mem_block.number))?, None); + + // Insert first block into the in-memory state + let in_memory_block_senders = + first_in_mem_block.senders().expect("failed to recover senders"); + let chain = NewCanonicalChain::Commit { + new: vec![ExecutedBlock::new( + Arc::new(first_in_mem_block.clone()), + Arc::new(in_memory_block_senders), + Default::default(), + Default::default(), + Default::default(), + )], + }; + provider.canonical_in_memory_state.update_chain(chain); + + // First in memory block should be found + assert_eq!( + provider.block(BlockHashOrNumber::Hash(first_in_mem_block.hash()))?, + Some(first_in_mem_block.clone().into()) + ); + assert_eq!( + provider.block(BlockHashOrNumber::Number(first_in_mem_block.number))?, + Some(first_in_mem_block.clone().into()) + ); + + // First database block should be found + assert_eq!( + provider.block(BlockHashOrNumber::Hash(first_db_block.hash()))?, + Some(first_db_block.clone().into()) + ); + assert_eq!( + provider.block(BlockHashOrNumber::Number(first_db_block.number))?, + Some(first_db_block.clone().into()) + ); + + Ok(()) + } + + #[test] + fn test_block_reader_pending_block() -> eyre::Result<()> { + let mut rng = generators::rng(); + let (provider, _, _) = + provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?; + + // Generate a random block + let mut rng = generators::rng(); + let block = random_block(&mut rng, 0, Some(B256::ZERO), None, None); + + // Set the block as pending + provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { + block: Arc::new(block.clone()), + senders: Default::default(), + execution_output: Default::default(), + hashed_state: Default::default(), + trie: Default::default(), + }); + + // Assertions related to the pending block + assert_eq!(provider.pending_block()?, Some(block.clone())); + + assert_eq!( + provider.pending_block_with_senders()?, + Some(reth_primitives::SealedBlockWithSenders { + block: block.clone(), + senders: block.senders().unwrap() + }) + ); + + assert_eq!(provider.pending_block_and_receipts()?, Some((block, vec![]))); + + Ok(()) + } + + #[test] + fn test_block_reader_ommers() -> eyre::Result<()> { + // Initialize random number generator and provider factory + let mut rng = generators::rng(); + let factory = create_test_provider_factory(); + + // Generate 10 random blocks and split into database and in-memory blocks + let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1); + let (database_blocks, in_memory_blocks) = blocks.split_at(5); + + // Take the first in memory block and add 7 ommers to it + let first_in_mem_block = SealedBlock { + ommers: vec![Header::default(); 7], + ..in_memory_blocks.first().unwrap().clone() + }; + + // Insert first 5 blocks into the database + let provider_rw = factory.provider_rw()?; + for block in database_blocks { + provider_rw.insert_historical_block( + block.clone().seal_with_senders().expect("failed to seal block with senders"), + )?; + } + provider_rw.commit()?; + + // Create a new provider + let provider = BlockchainProvider2::new(factory.clone())?; + + // Insert first block into the in-memory state + let in_memory_block_senders = + first_in_mem_block.senders().expect("failed to recover senders"); + let chain = NewCanonicalChain::Commit { + new: vec![ExecutedBlock::new( + Arc::new(first_in_mem_block.clone()), + Arc::new(in_memory_block_senders), + Default::default(), + Default::default(), + Default::default(), + )], + }; + provider.canonical_in_memory_state.update_chain(chain); + + // If the block is after the Merge, we should have an empty ommers list + assert_eq!( + provider.ommers( + (factory.chain_spec().paris_block_and_final_difficulty.unwrap().0 + 2).into() + )?, + Some(vec![]) + ); + + // First in memory block ommers should be found + assert_eq!( + provider.ommers(first_in_mem_block.number.into())?, + Some(first_in_mem_block.ommers.clone()) + ); + assert_eq!( + provider.ommers(first_in_mem_block.hash().into())?, + Some(first_in_mem_block.ommers) + ); + + // A random hash should return None as the block number is not found + assert_eq!(provider.ommers(B256::random().into())?, None); + + Ok(()) + } + #[test] fn test_block_hash_reader() -> eyre::Result<()> { let mut rng = generators::rng(); diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 35fdb3bc9c1ac..cd6fb7732d0ba 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -944,13 +944,13 @@ impl ForkChoiceSubscriptions for BlockchainProvider where DB: Send + Sync, { - fn subscribe_to_safe_block(&self) -> ForkChoiceNotifications { - let receiver = self.chain_info.subscribe_to_safe_block(); + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { + let receiver = self.chain_info.subscribe_safe_block(); ForkChoiceNotifications(receiver) } - fn subscribe_to_finalized_block(&self) -> ForkChoiceNotifications { - let receiver = self.chain_info.subscribe_to_finalized_block(); + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { + let receiver = self.chain_info.subscribe_finalized_block(); ForkChoiceNotifications(receiver) } } diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 8ff774447e779..814b7c121c1f0 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -557,12 +557,12 @@ impl CanonStateSubscriptions for NoopProvider { } impl ForkChoiceSubscriptions for NoopProvider { - fn subscribe_to_safe_block(&self) -> ForkChoiceNotifications { + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let (_, rx) = watch::channel(None); ForkChoiceNotifications(rx) } - fn subscribe_to_finalized_block(&self) -> ForkChoiceNotifications { + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { let (_, rx) = watch::channel(None); ForkChoiceNotifications(rx) } diff --git a/crates/trie/trie/src/trie_cursor/in_memory.rs b/crates/trie/trie/src/trie_cursor/in_memory.rs index fa93d300d7d2e..4159606c4920c 100644 --- a/crates/trie/trie/src/trie_cursor/in_memory.rs +++ b/crates/trie/trie/src/trie_cursor/in_memory.rs @@ -199,7 +199,7 @@ impl<'a, C: TrieCursor> InMemoryStorageTrieCursor<'a, C> { if self.storage_trie_cleared || (exact && in_memory.as_ref().map_or(false, |entry| entry.0 == key)) { - return Ok(in_memory) + return Ok(in_memory.filter(|(nibbles, _)| !exact || nibbles == &key)) } // Reposition the cursor to the first greater or equal node that wasn't removed. @@ -221,6 +221,9 @@ impl<'a, C: TrieCursor> InMemoryStorageTrieCursor<'a, C> { last: Nibbles, ) -> Result, DatabaseError> { let in_memory = self.in_memory_cursor.as_mut().and_then(|c| c.first_after(&last)); + if self.storage_trie_cleared { + return Ok(in_memory) + } // Reposition the cursor to the first greater or equal node that wasn't removed. let mut db_entry = self.cursor.seek(last.clone())?; diff --git a/crates/trie/trie/src/updates.rs b/crates/trie/trie/src/updates.rs index b24eae2bd31da..2b53ddfd7bccf 100644 --- a/crates/trie/trie/src/updates.rs +++ b/crates/trie/trie/src/updates.rs @@ -152,6 +152,10 @@ impl StorageTrieUpdates { /// Extends storage trie updates. pub fn extend(&mut self, other: Self) { + if other.is_deleted { + self.storage_nodes.clear(); + self.removed_nodes.clear(); + } self.is_deleted |= other.is_deleted; self.storage_nodes.extend(ExcludeEmptyFromPair::from_iter(other.storage_nodes)); self.removed_nodes.extend(ExcludeEmpty::from_iter(other.removed_nodes));