Skip to content

Commit

Permalink
override ethgetproof
Browse files Browse the repository at this point in the history
  • Loading branch information
joshieDo committed Nov 26, 2024
1 parent 552ca9a commit 7daee24
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 1 deletion.
9 changes: 9 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ alloy-eips = "0.6.4"
alloy-network = "0.6.4"
alloy-primitives = "0.8.11"
alloy-rpc-types = "0.6.4"
alloy-rpc-types-eth = "0.6.4"
alloy-signer-local = { version = "0.6.4", features = ["mnemonic"] }

# tokio
Expand All @@ -158,6 +159,7 @@ tokio = { version = "1.21", default-features = false }
reth-chainspec = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-cli = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-cli-util = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-errors = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-evm = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-rpc-eth-api = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-node-api = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
Expand Down Expand Up @@ -185,9 +187,12 @@ reth-provider = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aa
"optimism",
] }
reth-revm = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-rpc-types-compat = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-rpc-eth-types = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-storage-api = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-tracing = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-trie-common = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-trie-db = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-network = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
reth-network-types = { git = "https://github.com/paradigmxyz/reth.git", rev = "f211aac" }
Expand Down
11 changes: 10 additions & 1 deletion bin/odyssey/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ use alloy_primitives::Address;
use alloy_signer_local::PrivateKeySigner;
use clap::Parser;
use eyre::Context;
use odyssey_node::{chainspec::OdysseyChainSpecParser, node::OdysseyNode};
use odyssey_node::{
chainspec::OdysseyChainSpecParser,
node::OdysseyNode,
rpc::{EthApiExt, EthApiOverrideServer},
};
use odyssey_wallet::{OdysseyWallet, OdysseyWalletApiServer};
use odyssey_walltime::{OdysseyWallTime, OdysseyWallTimeRpcApiServer};
use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher};
Expand Down Expand Up @@ -56,6 +60,11 @@ fn main() {
.with_components(OdysseyNode::components(&rollup_args))
.with_add_ons(OpAddOns::new(rollup_args.sequencer_http))
.extend_rpc_modules(move |ctx| {
// override eth namespace
ctx.modules.replace_configured(
EthApiExt::new(ctx.registry.eth_api().clone()).into_rpc(),
)?;

// register odyssey wallet namespace
if let Ok(sk) = std::env::var("EXP1_SK") {
let signer: PrivateKeySigner =
Expand Down
10 changes: 10 additions & 0 deletions crates/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ revm-precompile.workspace = true
revm-primitives.workspace = true

reth-cli.workspace = true
reth-errors.workspace = true
reth-node-api.workspace = true
reth-node-builder.workspace = true
reth-optimism-node.workspace = true
Expand All @@ -25,18 +26,27 @@ reth-payload-builder.workspace = true
reth-primitives.workspace = true
reth-evm.workspace = true
reth-revm.workspace = true
reth-rpc-eth-api.workspace = true
reth-rpc-eth-types.workspace = true
reth-rpc-types-compat.workspace = true
reth-storage-api.workspace = true
reth-transaction-pool.workspace = true
reth-trie-common.workspace = true
reth-trie-db.workspace = true
reth-network.workspace = true
reth-network-types.workspace = true

alloy-consensus.workspace = true
alloy-eips.workspace = true
alloy-primitives.workspace = true
alloy-rpc-types.workspace = true
alloy-rpc-types-eth.workspace = true


serde_json.workspace = true
tracing.workspace = true
eyre.workspace = true
jsonrpsee.workspace = true

[lints]
workspace = true
1 change: 1 addition & 0 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
pub mod chainspec;
pub mod evm;
pub mod node;
pub mod rpc;
111 changes: 111 additions & 0 deletions crates/node/src/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//! Odyssey rpc logic.
//!
//! `eth_` namespace overrides:
//!
//! - `eth_getProof` will _ONLY_ return the storage proofs _WITHOUT_ an account proof _IF_ targeting
//! the withdrawal contract. Otherwise, it fallbacks to default behaviour.
use alloy_eips::BlockId;
use alloy_primitives::Address;
use alloy_rpc_types::serde_helpers::JsonStorageKey;
use alloy_rpc_types_eth::EIP1186AccountProofResponse;
use jsonrpsee::{
core::{async_trait, RpcResult},
proc_macros::rpc,
};
use reth_errors::RethError;
use reth_rpc_eth_api::{
helpers::{EthState, FullEthApi},
FromEthApiError,
};
use reth_rpc_eth_types::EthApiError;
use reth_rpc_types_compat::proof::from_primitive_account_proof;
use reth_storage_api::BlockIdReader;
use reth_trie_common::AccountProof;
use tracing::trace;

const WITHDRAWAL_CONTRACT: alloy_primitives::Address =
alloy_primitives::address!("4200000000000000000000000000000000000011");

/// Odyssey `eth_` RPC namespace overrides.
#[cfg_attr(not(test), rpc(server, namespace = "eth"))]
#[cfg_attr(test, rpc(server, client, namespace = "eth"))]
pub trait EthApiOverride {
/// Returns the account and storage values of the specified account including the Merkle-proof.
/// This call can be used to verify that the data you are pulling from is not tampered with.
#[method(name = "getProof")]
async fn get_proof(
&self,
address: Address,
keys: Vec<JsonStorageKey>,
block_number: Option<BlockId>,
) -> RpcResult<EIP1186AccountProofResponse>;
}

/// Implementation of the `eth_` namespace override
#[derive(Debug)]
pub struct EthApiExt<Eth> {
eth_api: Eth,
}

impl<E> EthApiExt<E> {
/// Create a new `EthApiExt` module.
pub const fn new(eth_api: E) -> Self {
Self { eth_api }
}
}

#[async_trait]
impl<Eth> EthApiOverrideServer for EthApiExt<Eth>
where
Eth: FullEthApi + Send + Sync + 'static,
{
async fn get_proof(
&self,
address: Address,
keys: Vec<JsonStorageKey>,
block_number: Option<BlockId>,
) -> RpcResult<EIP1186AccountProofResponse> {
trace!(target: "rpc::eth", ?address, ?keys, ?block_number, "Serving eth_getProof");

// If we are targeting the withdrawal contract, then we only need to provide the storage
// proofs for withdrawal.
if address == WITHDRAWAL_CONTRACT {
let _permit = self
.eth_api
.acquire_owned()
.await
.map_err(RethError::other)
.map_err(EthApiError::Internal)?;

return self
.eth_api
.spawn_blocking_io(move |this| {
let state = this.state_at_block_id(block_number.unwrap_or_default())?;
let storage_root = state
.storage_root(WITHDRAWAL_CONTRACT, Default::default())
.map_err(EthApiError::from_eth_err)?;
let storage_proofs = keys
.iter()
.map(|key| {
state.storage_proof(
WITHDRAWAL_CONTRACT,
key.as_b256(),
Default::default(),
)
})
.collect::<Result<Vec<_>, _>>()
.map_err(EthApiError::from_eth_err)?;
let proof = AccountProof { storage_root, storage_proofs, ..Default::default() };
Ok(from_primitive_account_proof(proof, keys))
})
.await
.map_err(Into::into);
}

EthState::get_proof(&self.eth_api, address, keys, block_number)
.map_err(Into::into)?
.await
.map_err(Into::into)
}
}

0 comments on commit 7daee24

Please sign in to comment.