feat: integrate OpPrimitives (#13556)

This commit is contained in:
Arsenii Kulikov
2024-12-27 18:11:11 +03:00
committed by GitHub
parent c35fe4ac54
commit 4994cdf0b0
44 changed files with 524 additions and 506 deletions

View File

@ -35,6 +35,7 @@ tracing.workspace = true
[dev-dependencies]
alloy-primitives.workspace = true
op-alloy-consensus.workspace = true
reth-optimism-chainspec.workspace = true
[features]

View File

@ -23,8 +23,8 @@ use reth_consensus_common::validation::{
};
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_forks::OpHardforks;
use reth_optimism_primitives::OpPrimitives;
use reth_primitives::{BlockBody, BlockWithSenders, GotExpected, SealedBlock, SealedHeader};
use reth_optimism_primitives::{OpBlock, OpBlockBody, OpPrimitives, OpReceipt};
use reth_primitives::{BlockWithSenders, GotExpected, SealedBlockFor, SealedHeader};
use std::{sync::Arc, time::SystemTime};
mod proof;
@ -52,23 +52,26 @@ impl OpBeaconConsensus {
impl FullConsensus<OpPrimitives> for OpBeaconConsensus {
fn validate_block_post_execution(
&self,
block: &BlockWithSenders,
input: PostExecutionInput<'_>,
block: &BlockWithSenders<OpBlock>,
input: PostExecutionInput<'_, OpReceipt>,
) -> Result<(), ConsensusError> {
validate_block_post_execution(block, &self.chain_spec, input.receipts)
}
}
impl Consensus for OpBeaconConsensus {
impl Consensus<Header, OpBlockBody> for OpBeaconConsensus {
fn validate_body_against_header(
&self,
body: &BlockBody,
body: &OpBlockBody,
header: &SealedHeader,
) -> Result<(), ConsensusError> {
validate_body_against_header(body, header.header())
}
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
fn validate_block_pre_execution(
&self,
block: &SealedBlockFor<OpBlock>,
) -> Result<(), ConsensusError> {
// Check ommers hash
let ommers_hash = reth_primitives::proofs::calculate_ommers_root(&block.body.ommers);
if block.header.ommers_hash != ommers_hash {

View File

@ -1,15 +1,17 @@
//! Helper function for Receipt root calculation for Optimism hardforks.
use alloy_consensus::TxReceipt;
use alloy_eips::eip2718::Encodable2718;
use alloy_primitives::B256;
use alloy_trie::root::ordered_trie_root_with_encoder;
use reth_chainspec::ChainSpec;
use reth_optimism_forks::OpHardfork;
use reth_primitives::{Receipt, ReceiptWithBloom};
use reth_optimism_primitives::OpReceipt;
use reth_primitives::ReceiptWithBloom;
/// Calculates the receipt root for a header.
pub(crate) fn calculate_receipt_root_optimism(
receipts: &[ReceiptWithBloom<Receipt>],
receipts: &[ReceiptWithBloom<OpReceipt>],
chain_spec: &ChainSpec,
timestamp: u64,
) -> B256 {
@ -25,7 +27,9 @@ pub(crate) fn calculate_receipt_root_optimism(
.iter()
.cloned()
.map(|mut r| {
r.receipt.deposit_nonce = None;
if let OpReceipt::Deposit(receipt) = &mut r.receipt {
receipt.deposit_nonce = None;
}
r
})
.collect::<Vec<_>>();
@ -36,11 +40,11 @@ pub(crate) fn calculate_receipt_root_optimism(
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_2718(buf))
}
/// Calculates the receipt root for a header for the reference type of [Receipt].
/// Calculates the receipt root for a header for the reference type of [`OpReceipt`].
///
/// NOTE: Prefer calculate receipt root optimism if you have log blooms memoized.
pub fn calculate_receipt_root_no_memo_optimism(
receipts: &[&Receipt],
receipts: &[&OpReceipt],
chain_spec: impl reth_chainspec::Hardforks,
timestamp: u64,
) -> B256 {
@ -56,7 +60,9 @@ pub fn calculate_receipt_root_no_memo_optimism(
.iter()
.map(|r| {
let mut r = (*r).clone();
r.deposit_nonce = None;
if let OpReceipt::Deposit(r) = &mut r {
r.deposit_nonce = None;
}
r
})
.collect::<Vec<_>>();
@ -74,9 +80,11 @@ pub fn calculate_receipt_root_no_memo_optimism(
#[cfg(test)]
mod tests {
use super::*;
use alloy_consensus::Receipt;
use alloy_primitives::{b256, bloom, hex, Address, Bloom, Bytes, Log, LogData};
use op_alloy_consensus::OpDepositReceipt;
use reth_optimism_chainspec::BASE_SEPOLIA;
use reth_primitives::{Receipt, ReceiptWithBloom, TxType};
use reth_primitives::ReceiptWithBloom;
/// Tests that the receipt root is computed correctly for the regolith block.
/// This was implemented due to a minor bug in op-geth and op-erigon where in
@ -114,21 +122,21 @@ mod tests {
let receipts = vec![
// 0xb0d6ee650637911394396d81172bd1c637d568ed1fbddab0daddfca399c58b53
ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Deposit,
success: true,
cumulative_gas_used: 46913,
logs: vec![],
receipt: OpReceipt::Deposit(OpDepositReceipt {
inner: Receipt {
status: true.into(),
cumulative_gas_used: 46913,
logs: vec![],
},
deposit_nonce: Some(4012991u64),
deposit_receipt_version: None,
},
}),
logs_bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
},
// 0x2f433586bae30573c393adfa02bc81d2a1888a3d6c9869f473fb57245166bd9a
ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Eip1559,
success: true,
receipt: OpReceipt::Eip1559(Receipt {
status: true.into(),
cumulative_gas_used: 118083,
logs: vec![
Log {
@ -164,17 +172,13 @@ mod tests {
b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"),
], Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")))
},
],
deposit_nonce: None,
deposit_receipt_version: None,
},
]}),
logs_bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()),
},
// 0x6c33676e8f6077f46a62eabab70bc6d1b1b18a624b0739086d77093a1ecf8266
ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Eip1559,
success: true,
receipt: OpReceipt::Eip1559(Receipt {
status: true.into(),
cumulative_gas_used: 189253,
logs: vec![
Log {
@ -207,16 +211,13 @@ mod tests {
Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")))
},
],
deposit_nonce: None,
deposit_receipt_version: None,
},
}),
logs_bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()),
},
// 0x4d3ecbef04ba7ce7f5ab55be0c61978ca97c117d7da448ed9771d4ff0c720a3f
ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Eip1559,
success: true,
receipt: OpReceipt::Eip1559(Receipt {
status: true.into(),
cumulative_gas_used: 346969,
logs: vec![
Log {
@ -279,16 +280,13 @@ mod tests {
Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d24d8e9ac1aa79e200000000000000000000000000000000000000000000000014bc73062aea80930000000000000000000000000000000000000000000000000000000000000000")))
},
],
deposit_nonce: None,
deposit_receipt_version: None,
},
}),
logs_bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()),
},
// 0xf738af5eb00ba23dbc1be2dbce41dbc0180f0085b7fb46646e90bf737af90351
ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Eip1559,
success: true,
receipt: OpReceipt::Eip1559(Receipt {
status: true.into(),
cumulative_gas_used: 623249,
logs: vec![
Log {
@ -321,9 +319,7 @@ mod tests {
Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007717500762343034303661353035646234633961386163316433306335633332303265370000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d515141646b33736538396b47716577395256567a316b68643548375562476d4d4a485a62566f386a6d346f4a2f30000000000000000000")))
},
],
deposit_nonce: None,
deposit_receipt_version: None,
},
}),
logs_bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()),
},
];
@ -340,14 +336,11 @@ mod tests {
}];
let logs_bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
let receipt = ReceiptWithBloom {
receipt: Receipt {
tx_type: TxType::Eip2930,
success: true,
receipt: OpReceipt::Eip2930(Receipt {
status: true.into(),
cumulative_gas_used: 102068,
logs,
deposit_nonce: None,
deposit_receipt_version: None,
},
}),
logs_bloom,
};
let receipt = vec![receipt];

View File

@ -3,16 +3,17 @@ use alloy_consensus::TxReceipt;
use alloy_primitives::{Bloom, B256};
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_consensus::ConsensusError;
use reth_primitives::{gas_spent_by_transactions, BlockWithSenders, GotExpected, Receipt};
use reth_optimism_primitives::{OpBlock, OpReceipt};
use reth_primitives::{gas_spent_by_transactions, BlockWithSenders, GotExpected};
/// Validate a block with regard to execution results:
///
/// - Compares the receipts root in the block header to the block body
/// - Compares the gas used in the block header to the actual gas usage after execution
pub fn validate_block_post_execution(
block: &BlockWithSenders,
block: &BlockWithSenders<OpBlock>,
chain_spec: &ChainSpec,
receipts: &[Receipt],
receipts: &[OpReceipt],
) -> Result<(), ConsensusError> {
// Before Byzantium, receipts contained state root that would mean that expensive
// operation as hashing that is required for state root got calculated in every
@ -33,10 +34,10 @@ pub fn validate_block_post_execution(
// Check if gas used matches the value set in header.
let cumulative_gas_used =
receipts.last().map(|receipt| receipt.cumulative_gas_used).unwrap_or(0);
if block.gas_used != cumulative_gas_used {
receipts.last().map(|receipt| receipt.cumulative_gas_used()).unwrap_or(0);
if block.gas_used as u128 != cumulative_gas_used {
return Err(ConsensusError::BlockGasUsed {
gas: GotExpected { got: cumulative_gas_used, expected: block.gas_used },
gas: GotExpected { got: cumulative_gas_used as u64, expected: block.gas_used },
gas_spent_by_tx: gas_spent_by_transactions(receipts),
})
}
@ -48,12 +49,12 @@ pub fn validate_block_post_execution(
fn verify_receipts(
expected_receipts_root: B256,
expected_logs_bloom: Bloom,
receipts: &[Receipt],
receipts: &[OpReceipt],
chain_spec: &ChainSpec,
timestamp: u64,
) -> Result<(), ConsensusError> {
// Calculate receipts root.
let receipts_with_bloom = receipts.iter().cloned().map(Receipt::with_bloom).collect::<Vec<_>>();
let receipts_with_bloom = receipts.iter().cloned().map(Into::into).collect::<Vec<_>>();
let receipts_root =
calculate_receipt_root_optimism(&receipts_with_bloom, chain_spec, timestamp);