Skip to content
Open
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
1 change: 1 addition & 0 deletions crates/networking/rpc/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod block_access_list;
pub mod chain_config;
pub mod execution_witness;
pub mod execution_witness_by_hash;
pub mod preimage;
70 changes: 70 additions & 0 deletions crates/networking/rpc/debug/preimage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use ethrex_common::H256;
use serde_json::Value;

use crate::{RpcApiContext, RpcErr, RpcHandler};

pub struct PreimageRequest {
_hash: H256,
}

impl RpcHandler for PreimageRequest {
fn parse(params: &Option<Vec<Value>>) -> Result<Self, RpcErr> {
let params = params
.as_ref()
.ok_or(RpcErr::BadParams("No params provided".to_owned()))?;
if params.len() != 1 {
return Err(RpcErr::BadParams(format!(
"Expected 1 param, got {}",
params.len()
)));
}
let hash: H256 = serde_json::from_value(params[0].clone())?;
Ok(PreimageRequest { _hash: hash })
}

async fn handle(&self, _context: RpcApiContext) -> Result<Value, RpcErr> {
// ethrex does not maintain a keccak preimage store.
// Geth returns {"code": -32000, "message": "unknown preimage"} in this case.
Err(RpcErr::BadParams("unknown preimage".to_owned()))
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::RpcHandler;
use serde_json::json;

#[test]
fn parse_valid_hash() {
let params = Some(vec![json!(
"0x0000000000000000000000000000000000000000000000000000000000000001"
)]);
let req = PreimageRequest::parse(&params).unwrap();
assert_eq!(req._hash, H256::from_low_u64_be(1));
}

#[test]
fn parse_no_params() {
assert!(PreimageRequest::parse(&None).is_err());
}

#[test]
fn parse_too_many_params() {
let params = Some(vec![json!("0x01"), json!("0x02")]);
assert!(PreimageRequest::parse(&params).is_err());
}

#[tokio::test]
async fn handle_returns_unknown_preimage_error() {
let req = PreimageRequest {
_hash: H256::zero(),
};
let storage = crate::test_utils::setup_store().await;
let context = crate::test_utils::default_context_with_storage(storage).await;
let result = req.handle(context).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(matches!(err, RpcErr::BadParams(ref msg) if msg == "unknown preimage"));
}
}
2 changes: 2 additions & 0 deletions crates/networking/rpc/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::debug::block_access_list::BlockAccessListRequest;
use crate::debug::chain_config::ChainConfigRequest;
use crate::debug::execution_witness::ExecutionWitnessRequest;
use crate::debug::execution_witness_by_hash::ExecutionWitnessByBlockHashRequest;
use crate::debug::preimage::PreimageRequest;
use crate::engine::blobs::{BlobsV2Request, BlobsV3Request};
use crate::engine::client_version::GetClientVersionV1Request;
use crate::engine::payload::{GetPayloadV5Request, GetPayloadV6Request, NewPayloadV5Request};
Expand Down Expand Up @@ -1155,6 +1156,7 @@ pub async fn map_debug_requests(req: &RpcRequest, context: RpcApiContext) -> Res
"debug_getBlockAccessList" => BlockAccessListRequest::call(req, context).await,
"debug_traceTransaction" => TraceTransactionRequest::call(req, context).await,
"debug_traceBlockByNumber" => TraceBlockByNumberRequest::call(req, context).await,
"debug_preimage" => PreimageRequest::call(req, context).await,
unknown_debug_method => Err(RpcErr::MethodNotFound(unknown_debug_method.to_owned())),
}
}
Expand Down
78 changes: 78 additions & 0 deletions test/tests/rpc/debug_preimage_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::{fs::File, io::BufReader, path::PathBuf};

use bytes::Bytes;
use ethrex_common::{
Address, H256, U256,
types::{GenesisAccount},
};
use ethrex_l2_rpc::signer::{LocalSigner, Signer};
use ethrex_rpc::rpc::map_http_requests;
use ethrex_rpc::test_utils::default_context_with_storage;
use ethrex_rpc::utils::RpcRequest;
use ethrex_storage::{EngineType, Store};
use secp256k1::SecretKey;
use serde_json::json;

const TEST_PRIVATE_KEY: &str = "850643a0224065ecce3882673c21f56bcf6eef86274cc21cadff15930b59fc8c";

fn test_secret_key() -> SecretKey {
SecretKey::from_slice(&hex::decode(TEST_PRIVATE_KEY).unwrap()).unwrap()
}

fn workspace_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}

fn sender_from_key(sk: &SecretKey) -> Address {
LocalSigner::new(*sk).address
}

async fn setup_store(sender: Address) -> Store {
let file = File::open(workspace_root().join("fixtures/genesis/execution-api.json"))
.expect("Failed to open genesis file");
let reader = BufReader::new(file);
let mut genesis: ethrex_common::types::Genesis =
serde_json::from_reader(reader).expect("Failed to deserialize genesis file");
genesis.alloc.insert(
sender,
GenesisAccount {
balance: U256::from(10).pow(U256::from(20)),
code: Bytes::new(),
storage: Default::default(),
nonce: 0,
},
);
let mut store =
Store::new("store.db", EngineType::InMemory).expect("Failed to build DB for testing");
store
.add_initial_state(genesis)
.await
.expect("Failed to add genesis state");
store
}

#[tokio::test]
async fn preimage_returns_unknown_preimage_error() {
let sk = test_secret_key();
let sender = sender_from_key(&sk);
let store = setup_store(sender).await;

let body = json!({
"jsonrpc": "2.0",
"method": "debug_preimage",
"params": [format!("{:#x}", H256::zero())],
"id": 1
});
let request: RpcRequest = serde_json::from_value(body).expect("valid RPC request");
let context = default_context_with_storage(store.clone()).await;
let result = map_http_requests(&request, context).await;

// Geth returns {"code": -32000, "message": "unknown preimage"} when
// the preimage is not available. ethrex does not maintain a preimage
// store, so this should always be an error.
let err = result.expect_err("should return an error, not null");
assert!(
matches!(err, ethrex_rpc::utils::RpcErr::BadParams(ref msg) if msg == "unknown preimage"),
"expected BadParams(\"unknown preimage\"), got {err:?}"
);
}
1 change: 1 addition & 0 deletions test/tests/rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod authrpc_batch_tests;
mod client_version_tests;
mod debug_preimage_tests;
mod http_batch_tests;
mod subscription_manager_tests;
Loading