From d9681ea7291443163ced04281a874476c8a2542f Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 11 Sep 2024 10:49:08 +0200 Subject: [PATCH] chore(op): define type `reth_optimism_rpc::OpReceiptBuilder` (#10781) --- Cargo.lock | 1 + crates/optimism/rpc/Cargo.toml | 1 + crates/optimism/rpc/src/eth/mod.rs | 4 +- crates/optimism/rpc/src/eth/receipt.rs | 114 +++++++++++++++++++++++- crates/rpc/rpc-eth-types/src/receipt.rs | 4 +- 5 files changed, 118 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 667c282933..6c3ab01751 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7970,6 +7970,7 @@ version = "1.0.6" dependencies = [ "alloy-primitives", "jsonrpsee-types", + "op-alloy-consensus", "op-alloy-network", "op-alloy-rpc-types", "parking_lot 0.12.3", diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 3778b77130..975379f43f 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -33,6 +33,7 @@ reth-chainspec.workspace = true alloy-primitives.workspace = true op-alloy-network.workspace = true op-alloy-rpc-types.workspace = true +op-alloy-consensus.workspace = true revm.workspace = true # async diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index 13078e456b..9f42c50371 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -1,12 +1,14 @@ //! OP-Reth `eth_` endpoint implementation. pub mod receipt; +pub mod rpc; pub mod transaction; mod block; mod call; mod pending_block; -pub mod rpc; + +pub use receipt::{OpReceiptBuilder, OpReceiptFieldsBuilder}; use std::{fmt, sync::Arc}; diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index b68ccd15ab..e7e8770cb7 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -1,17 +1,20 @@ //! Loads and formats OP receipt RPC response. -use op_alloy_rpc_types::{receipt::L1BlockInfo, OptimismTransactionReceiptFields}; +use op_alloy_consensus::{OpDepositReceipt, OpDepositReceiptWithBloom, OpReceiptEnvelope}; +use op_alloy_rpc_types::{ + receipt::L1BlockInfo, OpTransactionReceipt, OptimismTransactionReceiptFields, +}; use reth_chainspec::{ChainSpec, OptimismHardforks}; use reth_evm_optimism::RethL1BlockInfo; use reth_node_api::{FullNodeComponents, NodeTypes}; -use reth_primitives::{Receipt, TransactionMeta, TransactionSigned}; +use reth_primitives::{Receipt, TransactionMeta, TransactionSigned, TxType}; use reth_provider::ChainSpecProvider; use reth_rpc_eth_api::{ helpers::{EthApiSpec, LoadReceipt, LoadTransaction}, FromEthApiError, }; use reth_rpc_eth_types::{EthApiError, EthStateCache, ReceiptBuilder}; -use reth_rpc_types::AnyTransactionReceipt; +use reth_rpc_types::{AnyReceiptEnvelope, AnyTransactionReceipt, Log, TransactionReceipt}; use crate::{OpEthApi, OpEthApiError}; @@ -191,6 +194,111 @@ impl OpReceiptFieldsBuilder { } } +/// Builds an [`OpTransactionReceipt`]. +#[derive(Debug)] +pub struct OpReceiptBuilder { + /// Core receipt, has all the fields of an L1 receipt and is the basis for the OP receipt. + pub core_receipt: TransactionReceipt>, + /// Transaction type. + pub tx_type: TxType, + /// Additional OP receipt fields. + pub op_receipt_fields: OptimismTransactionReceiptFields, +} + +impl OpReceiptBuilder { + /// Returns a new builder. + pub fn new( + chain_spec: &ChainSpec, + transaction: &TransactionSigned, + meta: TransactionMeta, + receipt: &Receipt, + all_receipts: &[Receipt], + l1_block_info: revm::L1BlockInfo, + ) -> Result { + let ReceiptBuilder { base: core_receipt, .. } = + ReceiptBuilder::new(transaction, meta, receipt, all_receipts) + .map_err(OpEthApiError::Eth)?; + + let tx_type = transaction.tx_type(); + + let op_receipt_fields = OpReceiptFieldsBuilder::default() + .l1_block_info(chain_spec, transaction, l1_block_info)? + .deposit_nonce(receipt.deposit_nonce) + .deposit_version(receipt.deposit_receipt_version) + .build(); + + Ok(Self { core_receipt, tx_type, op_receipt_fields }) + } + + /// Builds [`OpTransactionReceipt`] by combing core (l1) receipt fields and additional OP + /// receipt fields. + pub fn build(self) -> OpTransactionReceipt { + let Self { core_receipt, tx_type, op_receipt_fields } = self; + + let OptimismTransactionReceiptFields { + l1_block_info, + deposit_nonce, + deposit_receipt_version, + } = op_receipt_fields; + + let TransactionReceipt { + inner: AnyReceiptEnvelope { inner: receipt_with_bloom, .. }, + transaction_hash, + transaction_index, + block_hash, + block_number, + gas_used, + effective_gas_price, + blob_gas_used, + blob_gas_price, + from, + to, + contract_address, + state_root, + authorization_list, + } = core_receipt; + + let inner = match tx_type { + TxType::Legacy => OpReceiptEnvelope::::Legacy(receipt_with_bloom), + TxType::Eip2930 => OpReceiptEnvelope::::Eip2930(receipt_with_bloom), + TxType::Eip1559 => OpReceiptEnvelope::::Eip1559(receipt_with_bloom), + TxType::Eip4844 => OpReceiptEnvelope::::Eip4844(receipt_with_bloom), + TxType::Eip7702 => { + unimplemented!("not implemented yet for OpReceiptEnvelope") + } + TxType::Deposit => { + OpReceiptEnvelope::::Deposit(OpDepositReceiptWithBloom:: { + receipt: OpDepositReceipt:: { + inner: receipt_with_bloom.receipt, + deposit_nonce, + deposit_receipt_version, + }, + logs_bloom: receipt_with_bloom.logs_bloom, + }) + } + }; + + let inner = TransactionReceipt::> { + inner, + transaction_hash, + transaction_index, + block_hash, + block_number, + gas_used, + effective_gas_price, + blob_gas_used, + blob_gas_price, + from, + to, + contract_address, + state_root, + authorization_list, + }; + + OpTransactionReceipt { inner, l1_block_info } + } +} + #[cfg(test)] mod test { use alloy_primitives::hex; diff --git a/crates/rpc/rpc-eth-types/src/receipt.rs b/crates/rpc/rpc-eth-types/src/receipt.rs index 2d9121e25a..63d148d441 100644 --- a/crates/rpc/rpc-eth-types/src/receipt.rs +++ b/crates/rpc/rpc-eth-types/src/receipt.rs @@ -14,9 +14,9 @@ use super::{EthApiError, EthResult}; #[derive(Debug)] pub struct ReceiptBuilder { /// The base response body, contains L1 fields. - base: TransactionReceipt>, + pub base: TransactionReceipt>, /// Additional L2 fields. - other: OtherFields, + pub other: OtherFields, } impl ReceiptBuilder {