Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chain-specific Block, LocalBlock, and BlockReceipt types #741

Merged
merged 25 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 190 additions & 26 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"crates/edr_rpc_eth",
"crates/edr_solidity",
"crates/edr_test_utils",
"crates/edr_utils",
"crates/tools",
]
resolver = "2"
Expand Down
1 change: 1 addition & 0 deletions crates/edr_eth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
anyhow = "1.0.89"
alloy-eips = { version = "0.3", default-features = false }
alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] }
auto_impl = { version = "1.2", default-features = false }
c-kzg = { version = "1.0.3", default-features = false }
derive-where = { version = "1.2.7", default-features = false }
hash-db = { version = "0.15.2", default-features = false }
Expand Down
8 changes: 5 additions & 3 deletions crates/edr_eth/src/eips/eip2718.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloy_rlp::Buf as _;

use crate::{
receipt::{self, MapReceiptLogs, Receipt},
receipt::{self, ExecutionReceipt, MapReceiptLogs},
transaction::{self, TransactionType},
Bloom,
};
Expand Down Expand Up @@ -111,7 +111,9 @@ where
}
}

impl<DataT: Receipt<LogT>, LogT> Receipt<LogT> for TypedEnvelope<DataT> {
impl<DataT: ExecutionReceipt> ExecutionReceipt for TypedEnvelope<DataT> {
type Log = DataT::Log;

fn cumulative_gas_used(&self) -> u64 {
self.data().cumulative_gas_used()
}
Expand All @@ -120,7 +122,7 @@ impl<DataT: Receipt<LogT>, LogT> Receipt<LogT> for TypedEnvelope<DataT> {
self.data().logs_bloom()
}

fn transaction_logs(&self) -> &[LogT] {
fn transaction_logs(&self) -> &[Self::Log] {
self.data().transaction_logs()
}

Expand Down
2 changes: 1 addition & 1 deletion crates/edr_eth/src/l1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
pub struct L1ChainSpec;

impl ChainSpec for L1ChainSpec {
type Block = BlockEnv;
type BlockEnv = BlockEnv;
type Context = ();
type HaltReason = HaltReason;
type Hardfork = SpecId;
Expand Down
45 changes: 41 additions & 4 deletions crates/edr_eth/src/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
mod block;
/// Types for execution receipts.
pub mod execution;
mod factory;
mod transaction;

pub use self::{block::BlockReceipt, transaction::TransactionReceipt};
use crate::{Bloom, B256};
use auto_impl::auto_impl;

pub use self::{block::BlockReceipt, factory::ReceiptFactory, transaction::TransactionReceipt};
use crate::{Address, Bloom, B256, U256};

/// Log generated after execution of a transaction.
#[derive(Clone, Debug, PartialEq, Eq)]
Expand All @@ -34,15 +37,27 @@ pub enum RootOrStatus<'root> {
Status(bool),
}

/// Trait for a receipt that internally contains an execution receipt.
pub trait AsExecutionReceipt {
/// The type of the inner execution receipt.
type ExecutionReceipt: ExecutionReceipt;

/// Returns a reference to the inner execution receipt.
fn as_execution_receipt(&self) -> &Self::ExecutionReceipt;
}

/// Trait for a receipt that's generated after execution of a transaction.
pub trait Receipt<LogT> {
#[auto_impl(Box, Arc)]
pub trait ExecutionReceipt {
type Log;

/// Returns the cumulative gas used in the block after this transaction was
/// executed.
fn cumulative_gas_used(&self) -> u64;
/// Returns the bloom filter of the logs generated within this transaction.
fn logs_bloom(&self) -> &Bloom;
/// Returns the logs generated within this transaction.
fn transaction_logs(&self) -> &[LogT];
fn transaction_logs(&self) -> &[Self::Log];
/// Returns the state root (pre-EIP-658) or status (post-EIP-658) of the
/// receipt.
fn root_or_status(&self) -> RootOrStatus<'_>;
Expand All @@ -52,3 +67,25 @@ pub trait MapReceiptLogs<OldLogT, NewLogT, OutputT> {
/// Maps the logs of the receipt to a new type.
fn map_logs(self, map_fn: impl FnMut(OldLogT) -> NewLogT) -> OutputT;
}

#[auto_impl(Box, Arc)]
pub trait ReceiptTrait {
fn block_number(&self) -> u64;

fn block_hash(&self) -> &B256;

fn contract_address(&self) -> Option<&Address>;

fn effective_gas_price(&self) -> Option<&U256>;

fn from(&self) -> &Address;

fn gas_used(&self) -> u64;

fn to(&self) -> Option<&Address>;

/// Returns the transaction hash.
fn transaction_hash(&self) -> &B256;

fn transaction_index(&self) -> u64;
}
89 changes: 82 additions & 7 deletions crates/edr_eth/src/receipt/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@ use std::ops::Deref;

use alloy_rlp::BufMut;

use super::{Receipt, TransactionReceipt};
use crate::{log::FilterLog, B256};
use super::{AsExecutionReceipt, ExecutionReceipt, ReceiptTrait, RootOrStatus, TransactionReceipt};
use crate::{log::FilterLog, Address, Bloom, B256, U256};

/// Type for a receipt that's included in a block.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BlockReceipt<ExecutionReceiptT: Receipt<FilterLog>> {
pub inner: TransactionReceipt<ExecutionReceiptT, FilterLog>,
pub struct BlockReceipt<ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>> {
pub inner: TransactionReceipt<ExecutionReceiptT>,
/// Hash of the block that this is part of
pub block_hash: B256,
/// Number of the block that this is part of
pub block_number: u64,
}

impl<ExecutionReceiptT: Receipt<FilterLog>> Deref for BlockReceipt<ExecutionReceiptT> {
type Target = TransactionReceipt<ExecutionReceiptT, FilterLog>;
impl<ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>> AsExecutionReceipt
for BlockReceipt<ExecutionReceiptT>
{
type ExecutionReceipt = ExecutionReceiptT;

fn as_execution_receipt(&self) -> &ExecutionReceiptT {
self.inner.as_execution_receipt()
}
}

impl<ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>> Deref
for BlockReceipt<ExecutionReceiptT>
{
type Target = TransactionReceipt<ExecutionReceiptT>;

fn deref(&self) -> &Self::Target {
&self.inner
Expand All @@ -25,7 +37,7 @@ impl<ExecutionReceiptT: Receipt<FilterLog>> Deref for BlockReceipt<ExecutionRece

impl<ExecutionReceiptT> alloy_rlp::Encodable for BlockReceipt<ExecutionReceiptT>
where
ExecutionReceiptT: Receipt<FilterLog> + alloy_rlp::Encodable,
ExecutionReceiptT: ExecutionReceipt<Log = FilterLog> + alloy_rlp::Encodable,
{
fn encode(&self, out: &mut dyn BufMut) {
self.inner.encode(out);
Expand All @@ -35,3 +47,66 @@ where
self.inner.length()
}
}

impl<ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>> ExecutionReceipt
for BlockReceipt<ExecutionReceiptT>
{
type Log = ExecutionReceiptT::Log;

fn cumulative_gas_used(&self) -> u64 {
self.inner.cumulative_gas_used()
}

fn logs_bloom(&self) -> &Bloom {
self.inner.logs_bloom()
}

fn transaction_logs(&self) -> &[Self::Log] {
self.inner.transaction_logs()
}

fn root_or_status(&self) -> RootOrStatus<'_> {
self.inner.root_or_status()
}
}

impl<ExecutionReceiptT> ReceiptTrait for BlockReceipt<ExecutionReceiptT>
where
ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>,
{
fn block_number(&self) -> u64 {
self.block_number
}

fn block_hash(&self) -> &B256 {
&self.block_hash
}

fn contract_address(&self) -> Option<&Address> {
self.inner.contract_address.as_ref()
}

fn effective_gas_price(&self) -> Option<&U256> {
self.inner.effective_gas_price.as_ref()
}

fn from(&self) -> &Address {
&self.inner.from
}

fn gas_used(&self) -> u64 {
self.inner.gas_used
}

fn to(&self) -> Option<&Address> {
self.inner.to.as_ref()
}

fn transaction_hash(&self) -> &B256 {
&self.inner.transaction_hash
}

fn transaction_index(&self) -> u64 {
self.inner.transaction_index
}
}
6 changes: 4 additions & 2 deletions crates/edr_eth/src/receipt/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod legacy;

use alloy_rlp::{RlpDecodable, RlpEncodable};

use super::{Execution, MapReceiptLogs, Receipt};
use super::{Execution, ExecutionReceipt, MapReceiptLogs};
use crate::{Bloom, B256};

#[derive(Clone, Debug, PartialEq, Eq, RlpDecodable, RlpEncodable)]
Expand Down Expand Up @@ -109,7 +109,9 @@ where
}
}

impl<LogT> Receipt<LogT> for Execution<LogT> {
impl<LogT> ExecutionReceipt for Execution<LogT> {
type Log = LogT;

fn cumulative_gas_used(&self) -> u64 {
match self {
Execution::Legacy(receipt) => receipt.cumulative_gas_used,
Expand Down
31 changes: 31 additions & 0 deletions crates/edr_eth/src/receipt/factory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use auto_impl::auto_impl;
use revm_wiring::evm_wiring::HardforkTrait;

use crate::{
log::FilterLog,
receipt::{ExecutionReceipt, ReceiptTrait, TransactionReceipt},
B256,
};

/// Trait for constructing a receipt from a transaction receipt and the block it
/// was executed in.
#[auto_impl(&, Box, Arc)]
pub trait ReceiptFactory<ExecutionReceiptT, HardforkT, SignedTransactionT>
where
ExecutionReceiptT: ExecutionReceipt<Log = FilterLog>,
HardforkT: HardforkTrait,
{
/// Type of the receipt that the factory constructs.
type Output: ExecutionReceipt<Log = FilterLog> + ReceiptTrait;

/// Constructs a new instance from a transaction receipt and the block it
/// was executed in.
fn create_receipt(
&self,
hardfork: HardforkT,
transaction: &SignedTransactionT,
transaction_receipt: TransactionReceipt<ExecutionReceiptT>,
block_hash: &B256,
block_number: u64,
) -> Self::Output;
}
Loading
Loading