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

chore(rpc): decouple op receipt response #8353

Merged
merged 48 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c34b31e
chore(trie): `PrefixSet::iter` (#8343)
rkrasiuk May 22, 2024
ea2c313
dep: bump `alloy-trie` to 0.4.1 (#8344)
rkrasiuk May 22, 2024
e2a5857
docs: add panic comments in from_compact() (#8346)
fgimenez May 22, 2024
9071330
docs: add warning notes about using NippyJar and Compact encoding for…
fgimenez May 22, 2024
f45ca74
refactor(consensus, evm): move post-execution validation to consensus…
shekhirin May 22, 2024
d0386b8
feat: use broadcast channel for event listeners (#8193)
fgimenez May 22, 2024
7653e81
perf(primitives): avoid cloning receipts when calculating the root (#…
DaniPopes May 22, 2024
dbc65ad
style: small refactor for `txpool_inspect` (#8348)
tcoratger May 22, 2024
bc914a6
fix: check for files in is_database_empty (#8351)
fgimenez May 22, 2024
50b479f
Remove 'optimism' feature from receipt response building
emhane May 22, 2024
3eddaf3
feat: implement table range checksums for reth db checksum (#7623)
AbnerZheng May 22, 2024
8158c28
doc: remove missing link (#8363)
fgimenez May 23, 2024
c5bc960
fix(storage): use u8 for NippiJar's DataReader::offset_size (#8360)
fgimenez May 23, 2024
155876d
chore: improve HaveNotReceivedUpdatesForAWhile warning (#8356)
Rjected May 23, 2024
4250c33
chore: clippy happy (#8362)
mattsse May 23, 2024
f447db1
feat: add static-file-types (#8361)
mattsse May 23, 2024
3312dc2
chore: make unknown block error lowercase (#8355)
Rjected May 23, 2024
b8eebbd
chore: add docs for using personal tag in kurtosis (#8354)
Rjected May 23, 2024
bc4dd37
chore(editor): set indent size=2 for the yaml files (#8366)
jsvisa May 23, 2024
c73af62
chore: remove network setup from config (#8364)
mattsse May 23, 2024
a4933e7
chore: remove peer types dep (#8368)
mattsse May 23, 2024
39d24b4
feat: return parent beacon block root in payload conversion (#8349)
Rjected May 23, 2024
62e05b5
fix: disable timeout on DbTool level (#8357)
wlawt May 23, 2024
0e87ff4
chore: sort workspace members (#8374)
mattsse May 23, 2024
8263480
chore(github): run update-book-cli in the lint workflow (#8335)
jsvisa May 23, 2024
1287bbc
chore: extract provider types (#8372)
mattsse May 23, 2024
d7172b6
chore(deps): shrink some deps (#8376)
mattsse May 23, 2024
df7c9ee
chore: extract p2p types from interfaces (#8382)
mattsse May 24, 2024
05fddd3
chore: replace interfaces dep with storage-errors (#8384)
mattsse May 24, 2024
76d7f4e
chore: import codecs directly (#8385)
mattsse May 24, 2024
6df2b1c
fix(book): rethdb usage with op-node (#8375)
bsh98 May 24, 2024
9f61d18
chore: extract block execution errors (#8386)
mattsse May 24, 2024
e0a9319
chore(deps): rm reth-interfaces dep from reth-revm (#8387)
mattsse May 24, 2024
91f288d
chore: remove wire-types optimism feature (#8383)
mattsse May 24, 2024
4ee75d5
chore: move sync to p2p crate (#8389)
mattsse May 24, 2024
7892604
chore: simplify tree result types (#8390)
mattsse May 24, 2024
b06433c
chore(trie): account specific hashed storage cursor (#8377)
rkrasiuk May 24, 2024
59622db
chore: add 0BSD to deny.toml (#8391)
Rjected May 24, 2024
a8e5eb6
feat: implement clientVersionV1 in engine API (#8016)
guha-rahul May 24, 2024
46fd454
chore: reorder struct account hashing struct defs (#8392)
mattsse May 25, 2024
0056f2f
chore(deps): use error imports directly (#8388)
mattsse May 25, 2024
7dd7877
refactor: extract init from node-core (#8373)
wlawt May 25, 2024
df83bef
chore: replace reth-interface usage (#8394)
mattsse May 25, 2024
a6cfa2c
chore: remove rpc-layer dep (#8395)
mattsse May 25, 2024
72f2f1b
chore: rm unused functions (#8396)
mattsse May 25, 2024
d1fb731
Make module for optimism tx rpc response
emhane May 25, 2024
33efb99
Merge branch 'main' into emhane/rpc-build-receipts
emhane May 25, 2024
44beab5
Add module header
emhane May 25, 2024
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
26 changes: 22 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ members = [
"crates/optimism/evm/",
"crates/optimism/node/",
"crates/optimism/payload/",
"crates/optimism/rpc",
"crates/node-core/",
"crates/node/api/",
"crates/stages/",
Expand Down Expand Up @@ -278,6 +279,7 @@ reth-transaction-pool = { path = "crates/transaction-pool" }
reth-trie = { path = "crates/trie" }
reth-trie-parallel = { path = "crates/trie-parallel" }
reth-optimism-consensus = { path = "crates/optimism/consensus" }
reth-optimism-rpc = { path = "crates/optimism/rpc" }
reth-node-events = { path = "crates/node/events" }
reth-testing-utils = { path = "testing/testing-utils" }

Expand All @@ -297,7 +299,7 @@ alloy-primitives = "0.7.2"
alloy-dyn-abi = "0.7.2"
alloy-sol-types = "0.7.2"
alloy-rlp = "0.3.4"
alloy-trie = "0.4.0"
alloy-trie = "0.4"
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "64feb9b" }
alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "64feb9b" }
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "64feb9b" }
Expand Down
31 changes: 31 additions & 0 deletions crates/optimism/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "reth-optimism-rpc"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
description = "An extension of ethereum RPC for optimism."

[lints]
workspace = true

[dependencies]
# reth
reth-evm.workspace = true
reth-evm-optimism = { workspace = true, features = ["optimism"] }
revm.workspace = true
reth-network-api.workspace = true
reth-rpc = { workspace = true, features = ["optimism"] }
reth-rpc-api.workspace = true
reth-rpc-types.workspace = true
reth-primitives = { workspace = true, features = ["optimism"] }
reth-provider.workspace = true
reth-transaction-pool.workspace = true

# rpc
jsonrpsee.workspace = true

# misc
thiserror.workspace = true
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//! Optimism specific types.
//! RPC errors specific to OP.

use jsonrpsee::types::ErrorObject;
use reth_rpc::{eth::error::EthApiError, result::internal_rpc_err};
use reth_rpc_types::ToRpcError;

use crate::{eth::error::EthApiError, result::internal_rpc_err};

/// Eth Optimism Api Error
#[cfg(feature = "optimism")]
#[derive(Debug, thiserror::Error)]
pub enum OptimismEthApiError {
/// Thrown when calculating L1 gas fee
Expand Down
4 changes: 4 additions & 0 deletions crates/optimism/rpc/src/lib.rs
emhane marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//! Optimism RPC extension.

pub mod error;
pub mod receipts;
192 changes: 192 additions & 0 deletions crates/optimism/rpc/src/receipts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
//! Formats OP receipt RPC responses.

use reth_evm::ConfigureEvm;
use reth_evm_optimism::RethL1BlockInfo;
use reth_network_api::NetworkInfo;
use reth_primitives::{BlockId, Receipt, TransactionMeta, TransactionSigned};
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
use reth_rpc::{
eth::{
api::transactions::ReceiptResponseBuilder,
error::{EthApiError, EthResult},
},
EthApi,
};
use reth_rpc_types::{AnyTransactionReceipt, OptimismTransactionReceiptFields};
use reth_transaction_pool::TransactionPool;
use revm::L1BlockInfo;

use crate::error::OptimismEthApiError;

/// Helper function for `eth_getBlockReceipts`. Returns all transaction receipts in the block.
///
/// Returns `None` if the block wasn't found.
pub async fn block_receipts<Provider, Pool, Network, EvmConfig>(
eth_api: &EthApi<Provider, Pool, Network, EvmConfig>,
block_id: BlockId,
) -> EthResult<Option<Vec<AnyTransactionReceipt>>>
where
Provider:
BlockReaderIdExt + ChainSpecProvider + EvmEnvProvider + StateProviderFactory + 'static,
Pool: TransactionPool + 'static,
Network: NetworkInfo + 'static,
EvmConfig: ConfigureEvm + 'static,
{
if let Some((block, receipts)) = eth_api.load_block_and_receipts(block_id).await? {
let block_number = block.number;
let base_fee = block.base_fee_per_gas;
let block_hash = block.hash();
let excess_blob_gas = block.excess_blob_gas;
let timestamp = block.timestamp;
let block = block.unseal();

let l1_block_info = reth_evm_optimism::extract_l1_info(&block).ok();

let receipts = block
.body
.into_iter()
.zip(receipts.iter())
.enumerate()
.map(|(idx, (ref tx, receipt))| {
let meta = TransactionMeta {
tx_hash: tx.hash,
index: idx as u64,
block_hash,
block_number,
base_fee,
excess_blob_gas,
timestamp,
};

let optimism_tx_meta =
build_op_tx_meta(eth_api, tx, l1_block_info.clone(), timestamp)?;

ReceiptResponseBuilder::new(tx, meta, receipt, &receipts)
.map(|builder| op_fields(builder, tx, receipt, optimism_tx_meta).build())
})
.collect::<EthResult<Vec<_>>>();
return receipts.map(Some)
}

Ok(None)
}

/// Helper function for `eth_getTransactionReceipt`
///
/// Returns the receipt
pub async fn build_transaction_receipt<Provider, Pool, Network, EvmConfig>(
eth_api: &EthApi<Provider, Pool, Network, EvmConfig>,
tx: TransactionSigned,
meta: TransactionMeta,
receipt: Receipt,
) -> EthResult<AnyTransactionReceipt>
where
Provider: BlockReaderIdExt + ChainSpecProvider,
{
let (block, receipts) = eth_api
.cache()
.get_block_and_receipts(meta.block_hash)
.await?
.ok_or(EthApiError::UnknownBlockNumber)?;

let block = block.unseal();
let l1_block_info = reth_evm_optimism::extract_l1_info(&block).ok();
let optimism_tx_meta = build_op_tx_meta(eth_api, &tx, l1_block_info, block.timestamp)?;

let resp_builder = ReceiptResponseBuilder::new(&tx, meta, &receipt, &receipts)?;
let resp_builder = op_fields(resp_builder, &tx, &receipt, optimism_tx_meta);

Ok(resp_builder.build())
}

/// Builds op metadata object using the provided [TransactionSigned], L1 block info and
/// `block_timestamp`. The L1BlockInfo is used to calculate the l1 fee and l1 data gas for the
/// transaction. If the L1BlockInfo is not provided, the meta info will be empty.
pub fn build_op_tx_meta<Provider, Pool, Network, EvmConfig>(
eth_api: &EthApi<Provider, Pool, Network, EvmConfig>,
tx: &TransactionSigned,
l1_block_info: Option<revm::L1BlockInfo>,
block_timestamp: u64,
) -> EthResult<OptimismTxMeta>
where
Provider: BlockReaderIdExt + ChainSpecProvider,
{
let Some(l1_block_info) = l1_block_info else { return Ok(OptimismTxMeta::default()) };

let (l1_fee, l1_data_gas) = if !tx.is_deposit() {
let envelope_buf = tx.envelope_encoded();

let inner_l1_fee = l1_block_info
.l1_tx_data_fee(
&eth_api.provider().chain_spec(),
block_timestamp,
&envelope_buf,
tx.is_deposit(),
)
.map_err(|_| OptimismEthApiError::L1BlockFeeError)?;
let inner_l1_data_gas = l1_block_info
.l1_data_gas(&eth_api.provider().chain_spec(), block_timestamp, &envelope_buf)
.map_err(|_| OptimismEthApiError::L1BlockGasError)?;
(
Some(inner_l1_fee.saturating_to::<u128>()),
Some(inner_l1_data_gas.saturating_to::<u128>()),
)
} else {
(None, None)
};

Ok(OptimismTxMeta::new(Some(l1_block_info), l1_fee, l1_data_gas))
}

/// Applies OP specific fields to a receipts response.
pub fn op_fields(
resp_builder: ReceiptResponseBuilder,
tx: &TransactionSigned,
receipt: &Receipt,
optimism_tx_meta: OptimismTxMeta,
) -> ReceiptResponseBuilder {
let mut op_fields = OptimismTransactionReceiptFields::default();

if tx.is_deposit() {
op_fields.deposit_nonce = receipt.deposit_nonce.map(reth_primitives::U64::from);
op_fields.deposit_receipt_version =
receipt.deposit_receipt_version.map(reth_primitives::U64::from);
} else if let Some(l1_block_info) = optimism_tx_meta.l1_block_info {
op_fields.l1_fee = optimism_tx_meta.l1_fee;
op_fields.l1_gas_used = optimism_tx_meta.l1_data_gas.map(|dg| {
dg + l1_block_info.l1_fee_overhead.unwrap_or_default().saturating_to::<u128>()
});
op_fields.l1_fee_scalar = Some(f64::from(l1_block_info.l1_base_fee_scalar) / 1_000_000.0);
op_fields.l1_gas_price = Some(l1_block_info.l1_base_fee.saturating_to());
}

resp_builder.add_other_fields(op_fields.into())
}

/// Optimism Transaction Metadata
///
/// Includes the L1 fee and data gas for the tx along with the L1
/// block info. In order to pass the [OptimismTxMeta] into the
/// async colored [ReceiptResponseBuilder], a reference counter
/// for the L1 block info is used so the L1 block info can be
/// shared between receipts.
#[derive(Debug, Default, Clone)]
pub struct OptimismTxMeta {
emhane marked this conversation as resolved.
Show resolved Hide resolved
/// The L1 block info.
pub l1_block_info: Option<L1BlockInfo>,
/// The L1 fee for the block.
pub l1_fee: Option<u128>,
/// The L1 data gas for the block.
pub l1_data_gas: Option<u128>,
}

impl OptimismTxMeta {
/// Creates a new [OptimismTxMeta].
pub fn new(
l1_block_info: Option<L1BlockInfo>,
l1_fee: Option<u128>,
l1_data_gas: Option<u128>,
) -> Self {
Self { l1_block_info, l1_fee, l1_data_gas }
}
}
4 changes: 0 additions & 4 deletions crates/rpc/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ revm-inspectors = { workspace = true, features = ["js-tracer"] }
reth-evm.workspace = true
reth-network-types.workspace = true

reth-evm-optimism = { workspace = true, optional = true }

# eth
alloy-rlp.workspace = true
alloy-dyn-abi = { workspace = true, features = ["eip712"] }
Expand Down Expand Up @@ -91,6 +89,4 @@ optimism = [
"reth-primitives/optimism",
"reth-rpc-types-compat/optimism",
"reth-provider/optimism",
"dep:reth-evm-optimism",
"reth-evm-optimism/optimism",
]
Loading
Loading