mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore: remove op-flagged arguments from receipt root calc (#6517)
This commit is contained in:
@ -1243,10 +1243,14 @@ mod tests {
|
||||
use reth_db::{tables, test_utils::TempDatabase, transaction::DbTxMut, DatabaseEnv};
|
||||
use reth_interfaces::test_utils::TestConsensus;
|
||||
use reth_node_ethereum::EthEvmConfig;
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use reth_primitives::proofs::calculate_receipt_root;
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_primitives::proofs::calculate_receipt_root_optimism;
|
||||
use reth_primitives::{
|
||||
constants::{EIP1559_INITIAL_BASE_FEE, EMPTY_ROOT_HASH, ETHEREUM_BLOCK_GAS_LIMIT},
|
||||
keccak256,
|
||||
proofs::{calculate_receipt_root, calculate_transaction_root, state_root_unhashed},
|
||||
proofs::{calculate_transaction_root, state_root_unhashed},
|
||||
revm_primitives::AccountInfo,
|
||||
stage::StageCheckpoint,
|
||||
Account, Address, ChainSpecBuilder, Genesis, GenesisAccount, Header, Signature,
|
||||
@ -1466,7 +1470,7 @@ mod tests {
|
||||
let receipts_root = calculate_receipt_root(&receipts);
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
let receipts_root = calculate_receipt_root(&receipts, &chain_spec, 0);
|
||||
let receipts_root = calculate_receipt_root_optimism(&receipts, &chain_spec, 0);
|
||||
|
||||
SealedBlockWithSenders::new(
|
||||
SealedBlock {
|
||||
|
||||
@ -345,13 +345,17 @@ impl StorageInner {
|
||||
|
||||
/// Fills in the post-execution header fields based on the given BundleState and gas used.
|
||||
/// In doing this, the state root is calculated and the final header is returned.
|
||||
///
|
||||
/// This is optimism-specific and contains the `ChainSpec` so the proper state root can be
|
||||
/// calculated.
|
||||
#[cfg(feature = "optimism")]
|
||||
pub(crate) fn complete_header<S: StateProviderFactory>(
|
||||
&self,
|
||||
mut header: Header,
|
||||
bundle_state: &BundleStateWithReceipts,
|
||||
client: &S,
|
||||
gas_used: u64,
|
||||
#[cfg(feature = "optimism")] chain_spec: &ChainSpec,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Header, BlockExecutionError> {
|
||||
let receipts = bundle_state.receipts_by_block(header.number);
|
||||
header.receipts_root = if receipts.is_empty() {
|
||||
@ -363,11 +367,9 @@ impl StorageInner {
|
||||
.collect::<Vec<ReceiptWithBloom>>();
|
||||
header.logs_bloom =
|
||||
receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
proofs::calculate_receipt_root(
|
||||
proofs::calculate_receipt_root_optimism(
|
||||
&receipts_with_bloom,
|
||||
#[cfg(feature = "optimism")]
|
||||
chain_spec,
|
||||
#[cfg(feature = "optimism")]
|
||||
header.timestamp,
|
||||
)
|
||||
};
|
||||
@ -384,6 +386,41 @@ impl StorageInner {
|
||||
Ok(header)
|
||||
}
|
||||
|
||||
/// Fills in the post-execution header fields based on the given BundleState and gas used.
|
||||
/// In doing this, the state root is calculated and the final header is returned.
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
pub(crate) fn complete_header<S: StateProviderFactory>(
|
||||
&self,
|
||||
mut header: Header,
|
||||
bundle_state: &BundleStateWithReceipts,
|
||||
client: &S,
|
||||
gas_used: u64,
|
||||
) -> Result<Header, BlockExecutionError> {
|
||||
let receipts = bundle_state.receipts_by_block(header.number);
|
||||
header.receipts_root = if receipts.is_empty() {
|
||||
EMPTY_RECEIPTS
|
||||
} else {
|
||||
let receipts_with_bloom = receipts
|
||||
.iter()
|
||||
.map(|r| (*r).clone().expect("receipts have not been pruned").into())
|
||||
.collect::<Vec<ReceiptWithBloom>>();
|
||||
header.logs_bloom =
|
||||
receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
proofs::calculate_receipt_root(&receipts_with_bloom)
|
||||
};
|
||||
|
||||
header.gas_used = gas_used;
|
||||
|
||||
// calculate the state root
|
||||
let state_root = client
|
||||
.latest()
|
||||
.map_err(|_| BlockExecutionError::ProviderError)?
|
||||
.state_root(bundle_state)
|
||||
.unwrap();
|
||||
header.state_root = state_root;
|
||||
Ok(header)
|
||||
}
|
||||
|
||||
/// Builds and executes a new block with the given transactions, on the provided [EVMProcessor].
|
||||
///
|
||||
/// This returns the header of the executed block, as well as the poststate from execution.
|
||||
|
||||
@ -69,14 +69,13 @@ pub fn calculate_withdrawals_root(withdrawals: &[Withdrawal]) -> B256 {
|
||||
}
|
||||
|
||||
/// Calculates the receipt root for a header.
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 {
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false))
|
||||
}
|
||||
|
||||
/// Calculates the receipt root for a header.
|
||||
#[cfg(feature = "optimism")]
|
||||
pub fn calculate_receipt_root(
|
||||
pub fn calculate_receipt_root_optimism(
|
||||
receipts: &[ReceiptWithBloom],
|
||||
chain_spec: &crate::ChainSpec,
|
||||
timestamp: u64,
|
||||
@ -109,7 +108,6 @@ pub fn calculate_receipt_root(
|
||||
/// Calculates the receipt root for a header for the reference type of [Receipt].
|
||||
///
|
||||
/// NOTE: Prefer [calculate_receipt_root] if you have log blooms memoized.
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 {
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| {
|
||||
ReceiptWithBloomRef::from(*r).encode_inner(buf, false)
|
||||
@ -120,7 +118,7 @@ pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 {
|
||||
///
|
||||
/// NOTE: Prefer [calculate_receipt_root] if you have log blooms memoized.
|
||||
#[cfg(feature = "optimism")]
|
||||
pub fn calculate_receipt_root_ref(
|
||||
pub fn calculate_receipt_root_ref_optimism(
|
||||
receipts: &[&Receipt],
|
||||
chain_spec: &crate::ChainSpec,
|
||||
timestamp: u64,
|
||||
@ -263,11 +261,10 @@ pub mod triehash {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use crate::proofs::calculate_receipt_root;
|
||||
use crate::{
|
||||
bloom,
|
||||
constants::EMPTY_ROOT_HASH,
|
||||
hex_literal::hex,
|
||||
proofs::{calculate_receipt_root, calculate_transaction_root},
|
||||
bloom, constants::EMPTY_ROOT_HASH, hex_literal::hex, proofs::calculate_transaction_root,
|
||||
Address, Block, GenesisAccount, Log, Receipt, ReceiptWithBloom, TxType, B256, GOERLI,
|
||||
HOLESKY, MAINNET, SEPOLIA, U256,
|
||||
};
|
||||
@ -543,13 +540,14 @@ mod tests {
|
||||
bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()),
|
||||
},
|
||||
];
|
||||
let root = calculate_receipt_root(&receipts, OP_GOERLI.as_ref(), case.1);
|
||||
let root = calculate_receipt_root_optimism(&receipts, OP_GOERLI.as_ref(), case.1);
|
||||
assert_eq!(root, case.2);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn check_receipt_root() {
|
||||
fn check_receipt_root_optimism() {
|
||||
let logs = vec![Log { address: Address::ZERO, topics: vec![], data: Default::default() }];
|
||||
let bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
let receipt = ReceiptWithBloom {
|
||||
@ -558,21 +556,32 @@ mod tests {
|
||||
success: true,
|
||||
cumulative_gas_used: 102068,
|
||||
logs,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce: None,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom,
|
||||
};
|
||||
let receipt = vec![receipt];
|
||||
let root = calculate_receipt_root(
|
||||
&receipt,
|
||||
#[cfg(feature = "optimism")]
|
||||
crate::OP_GOERLI.as_ref(),
|
||||
#[cfg(feature = "optimism")]
|
||||
0,
|
||||
);
|
||||
let root = calculate_receipt_root_optimism(&receipt, crate::OP_GOERLI.as_ref(), 0);
|
||||
assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0"));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
#[test]
|
||||
fn check_receipt_root_optimism() {
|
||||
let logs = vec![Log { address: Address::ZERO, topics: vec![], data: Default::default() }];
|
||||
let bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
let receipt = ReceiptWithBloom {
|
||||
receipt: Receipt {
|
||||
tx_type: TxType::EIP2930,
|
||||
success: true,
|
||||
cumulative_gas_used: 102068,
|
||||
logs,
|
||||
},
|
||||
bloom,
|
||||
};
|
||||
let receipt = vec![receipt];
|
||||
let root = calculate_receipt_root(&receipt);
|
||||
assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0"));
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use crate::proofs::calculate_receipt_root_ref;
|
||||
#[cfg(feature = "optimism")]
|
||||
use crate::proofs::calculate_receipt_root_ref_optimism;
|
||||
use crate::{
|
||||
compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR},
|
||||
logs_bloom,
|
||||
proofs::calculate_receipt_root_ref,
|
||||
Bloom, Log, PruneSegmentError, TxType, B256,
|
||||
logs_bloom, Bloom, Log, PruneSegmentError, TxType, B256,
|
||||
};
|
||||
use alloy_rlp::{length_of_length, Decodable, Encodable};
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
@ -110,7 +112,7 @@ impl Receipts {
|
||||
chain_spec: &crate::ChainSpec,
|
||||
timestamp: u64,
|
||||
) -> Option<B256> {
|
||||
Some(calculate_receipt_root_ref(
|
||||
Some(calculate_receipt_root_ref_optimism(
|
||||
&self.receipt_vec[index].iter().map(Option::as_ref).collect::<Option<Vec<_>>>()?,
|
||||
chain_spec,
|
||||
timestamp,
|
||||
|
||||
@ -1,16 +1,43 @@
|
||||
use crate::processor::{verify_receipt, EVMProcessor};
|
||||
use crate::processor::{compare_receipts_root_and_logs_bloom, EVMProcessor};
|
||||
use reth_interfaces::executor::{
|
||||
BlockExecutionError, BlockValidationError, OptimismBlockExecutionError,
|
||||
};
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
revm_primitives::ResultAndState, BlockWithSenders, Hardfork, Receipt, TxType, U256,
|
||||
proofs::calculate_receipt_root_optimism, revm_primitives::ResultAndState, BlockWithSenders,
|
||||
Bloom, ChainSpec, Hardfork, Receipt, ReceiptWithBloom, TxType, B256, U256,
|
||||
};
|
||||
use reth_provider::{BlockExecutor, BlockExecutorStats, BundleStateWithReceipts};
|
||||
use revm::DatabaseCommit;
|
||||
use std::time::Instant;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
/// Verify the calculated receipts root against the expected receipts root.
|
||||
pub fn verify_receipt_optimism<'a>(
|
||||
expected_receipts_root: B256,
|
||||
expected_logs_bloom: Bloom,
|
||||
receipts: impl Iterator<Item = &'a Receipt> + Clone,
|
||||
chain_spec: &ChainSpec,
|
||||
timestamp: u64,
|
||||
) -> Result<(), BlockExecutionError> {
|
||||
// Calculate receipts root.
|
||||
let receipts_with_bloom = receipts.map(|r| r.clone().into()).collect::<Vec<ReceiptWithBloom>>();
|
||||
let receipts_root =
|
||||
calculate_receipt_root_optimism(&receipts_with_bloom, chain_spec, timestamp);
|
||||
|
||||
// Create header log bloom.
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
|
||||
compare_receipts_root_and_logs_bloom(
|
||||
receipts_root,
|
||||
logs_bloom,
|
||||
expected_receipts_root,
|
||||
expected_logs_bloom,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<'a, EvmConfig> BlockExecutor for EVMProcessor<'a, EvmConfig>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv,
|
||||
@ -38,7 +65,7 @@ where
|
||||
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
|
||||
if self.chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) {
|
||||
let time = Instant::now();
|
||||
if let Err(error) = verify_receipt(
|
||||
if let Err(error) = verify_receipt_optimism(
|
||||
block.header.receipts_root,
|
||||
block.header.logs_bloom,
|
||||
receipts.iter(),
|
||||
|
||||
@ -530,35 +530,48 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify receipts
|
||||
/// Calculate the receipts root, and copmare it against against the expected receipts root and logs
|
||||
/// bloom.
|
||||
pub fn verify_receipt<'a>(
|
||||
expected_receipts_root: B256,
|
||||
expected_logs_bloom: Bloom,
|
||||
receipts: impl Iterator<Item = &'a Receipt> + Clone,
|
||||
#[cfg(feature = "optimism")] chain_spec: &ChainSpec,
|
||||
#[cfg(feature = "optimism")] timestamp: u64,
|
||||
) -> Result<(), BlockExecutionError> {
|
||||
// Check receipts root.
|
||||
// Calculate receipts root.
|
||||
let receipts_with_bloom = receipts.map(|r| r.clone().into()).collect::<Vec<ReceiptWithBloom>>();
|
||||
let receipts_root = reth_primitives::proofs::calculate_receipt_root(
|
||||
&receipts_with_bloom,
|
||||
#[cfg(feature = "optimism")]
|
||||
chain_spec,
|
||||
#[cfg(feature = "optimism")]
|
||||
timestamp,
|
||||
);
|
||||
if receipts_root != expected_receipts_root {
|
||||
let receipts_root = reth_primitives::proofs::calculate_receipt_root(&receipts_with_bloom);
|
||||
|
||||
// Create header log bloom.
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
|
||||
compare_receipts_root_and_logs_bloom(
|
||||
receipts_root,
|
||||
logs_bloom,
|
||||
expected_receipts_root,
|
||||
expected_logs_bloom,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compare the calculated receipts root with the expected receipts root, also copmare
|
||||
/// the calculated logs bloom with the expected logs bloom.
|
||||
pub fn compare_receipts_root_and_logs_bloom(
|
||||
calculated_receipts_root: B256,
|
||||
calculated_logs_bloom: Bloom,
|
||||
expected_receipts_root: B256,
|
||||
expected_logs_bloom: Bloom,
|
||||
) -> Result<(), BlockExecutionError> {
|
||||
if calculated_receipts_root != expected_receipts_root {
|
||||
return Err(BlockValidationError::ReceiptRootDiff(
|
||||
GotExpected { got: receipts_root, expected: expected_receipts_root }.into(),
|
||||
GotExpected { got: calculated_receipts_root, expected: expected_receipts_root }.into(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
||||
// Create header log bloom.
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
if logs_bloom != expected_logs_bloom {
|
||||
if calculated_logs_bloom != expected_logs_bloom {
|
||||
return Err(BlockValidationError::BloomLogDiff(
|
||||
GotExpected { got: logs_bloom, expected: expected_logs_bloom }.into(),
|
||||
GotExpected { got: calculated_logs_bloom, expected: expected_logs_bloom }.into(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user