diff --git a/crates/networking/rpc/authentication.rs b/crates/networking/rpc/authentication.rs index 1aee37178..40bcbac30 100644 --- a/crates/networking/rpc/authentication.rs +++ b/crates/networking/rpc/authentication.rs @@ -16,7 +16,7 @@ pub enum AuthenticationError { } pub fn authenticate( - secret: Bytes, + secret: &Bytes, auth_header: Option>>, ) -> Result<(), RpcErr> { match auth_header { @@ -39,8 +39,8 @@ struct Claims { } /// Authenticates bearer jwt to check that authrpc calls are sent by the consensus layer -pub fn validate_jwt_authentication(token: &str, secret: Bytes) -> Result<(), AuthenticationError> { - let decoding_key = DecodingKey::from_secret(&secret); +pub fn validate_jwt_authentication(token: &str, secret: &Bytes) -> Result<(), AuthenticationError> { + let decoding_key = DecodingKey::from_secret(secret); let mut validation = Validation::new(Algorithm::HS256); validation.validate_exp = false; validation.set_required_spec_claims(&["iat"]); diff --git a/crates/networking/rpc/engine/exchange_transition_config.rs b/crates/networking/rpc/engine/exchange_transition_config.rs index 84ff9438a..7d0faa2f1 100644 --- a/crates/networking/rpc/engine/exchange_transition_config.rs +++ b/crates/networking/rpc/engine/exchange_transition_config.rs @@ -1,10 +1,9 @@ use ethereum_rust_core::{serde_utils, H256}; -use ethereum_rust_storage::Store; use serde::{Deserialize, Serialize}; use serde_json::Value; use tracing::{info, warn}; -use crate::{utils::RpcErr, RpcHandler}; +use crate::{utils::RpcErr, RpcApiContext, RpcHandler}; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -45,11 +44,11 @@ impl RpcHandler for ExchangeTransitionConfigV1Req { Ok(ExchangeTransitionConfigV1Req { payload }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Received new engine request: {self}"); let payload = &self.payload; - let chain_config = storage.get_chain_config()?; + let chain_config = context.storage.get_chain_config()?; let terminal_total_difficulty = chain_config.terminal_total_difficulty; if terminal_total_difficulty.unwrap_or_default() != payload.terminal_total_difficulty { @@ -59,7 +58,9 @@ impl RpcHandler for ExchangeTransitionConfigV1Req { ); }; - let block = storage.get_block_header(payload.terminal_block_number)?; + let block = context + .storage + .get_block_header(payload.terminal_block_number)?; let terminal_block_hash = block.map_or(H256::zero(), |block| block.compute_block_hash()); serde_json::to_value(ExchangeTransitionConfigPayload { diff --git a/crates/networking/rpc/engine/fork_choice.rs b/crates/networking/rpc/engine/fork_choice.rs index 7824a6486..78b7f7e89 100644 --- a/crates/networking/rpc/engine/fork_choice.rs +++ b/crates/networking/rpc/engine/fork_choice.rs @@ -4,7 +4,6 @@ use ethereum_rust_blockchain::{ latest_canonical_block_hash, payload::{create_payload, BuildPayloadArgs}, }; -use ethereum_rust_storage::Store; use serde_json::Value; use tracing::{info, warn}; @@ -14,7 +13,7 @@ use crate::{ payload::PayloadStatus, }, utils::RpcRequest, - RpcErr, RpcHandler, + RpcApiContext, RpcErr, RpcHandler, }; #[derive(Debug)] @@ -58,7 +57,8 @@ impl RpcHandler for ForkChoiceUpdatedV3 { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!( "New fork choice request with head: {}, safe: {}, finalized: {}.", self.fork_choice_state.head_block_hash, @@ -68,7 +68,7 @@ impl RpcHandler for ForkChoiceUpdatedV3 { let fork_choice_error_to_response = |error| { let response = match error { InvalidForkChoice::NewHeadAlreadyCanonical => ForkChoiceResponse::from( - PayloadStatus::valid_with_hash(latest_canonical_block_hash(&storage).unwrap()), + PayloadStatus::valid_with_hash(latest_canonical_block_hash(storage).unwrap()), ), InvalidForkChoice::Syncing => ForkChoiceResponse::from(PayloadStatus::syncing()), reason => { @@ -83,7 +83,7 @@ impl RpcHandler for ForkChoiceUpdatedV3 { }; let head_block = match apply_fork_choice( - &storage, + storage, self.fork_choice_state.head_block_hash, self.fork_choice_state.safe_block_hash, self.fork_choice_state.finalized_block_hash, @@ -125,7 +125,7 @@ impl RpcHandler for ForkChoiceUpdatedV3 { }; let payload_id = args.id(); response.set_id(payload_id); - let payload = match create_payload(&args, &storage) { + let payload = match create_payload(&args, storage) { Ok(payload) => payload, Err(ChainError::EvmError(error)) => return Err(error.into()), // Parent block is guaranteed to be present at this point, diff --git a/crates/networking/rpc/engine/mod.rs b/crates/networking/rpc/engine/mod.rs index 59e855a49..cd57a46ee 100644 --- a/crates/networking/rpc/engine/mod.rs +++ b/crates/networking/rpc/engine/mod.rs @@ -2,7 +2,7 @@ pub mod exchange_transition_config; pub mod fork_choice; pub mod payload; -use crate::{utils::RpcRequest, RpcErr, RpcHandler, Store}; +use crate::{utils::RpcRequest, RpcApiContext, RpcErr, RpcHandler}; use serde_json::{json, Value}; pub type ExchangeCapabilitiesRequest = Vec; @@ -30,7 +30,7 @@ impl RpcHandler for ExchangeCapabilitiesRequest { }) } - fn handle(&self, _storage: Store) -> Result { + fn handle(&self, _context: RpcApiContext) -> Result { Ok(json!(*self)) } } diff --git a/crates/networking/rpc/engine/payload.rs b/crates/networking/rpc/engine/payload.rs index 59e6e2ed5..b85188b7d 100644 --- a/crates/networking/rpc/engine/payload.rs +++ b/crates/networking/rpc/engine/payload.rs @@ -3,12 +3,12 @@ use ethereum_rust_blockchain::error::ChainError; use ethereum_rust_blockchain::payload::build_payload; use ethereum_rust_core::types::Fork; use ethereum_rust_core::{H256, U256}; -use ethereum_rust_storage::Store; use serde_json::Value; use tracing::{error, info, warn}; use crate::types::payload::ExecutionPayloadResponse; use crate::utils::RpcRequest; +use crate::RpcApiContext; use crate::{ types::payload::{ExecutionPayloadV3, PayloadStatus}, RpcErr, RpcHandler, @@ -56,7 +56,8 @@ impl RpcHandler for NewPayloadV3Request { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; let block_hash = self.payload.block_hash; info!("Received new payload with block hash: {block_hash:#x}"); @@ -114,7 +115,7 @@ impl RpcHandler for NewPayloadV3Request { // Execute and store the block info!("Executing payload with block hash: {block_hash:#x}"); - let payload_status = match add_block(&block, &storage) { + let payload_status = match add_block(&block, storage) { Err(ChainError::ParentNotFound) => Ok(PayloadStatus::syncing()), // Under the current implementation this is not possible: we always calculate the state // transition of any new payload as long as the parent is present. If we received the @@ -185,15 +186,15 @@ impl RpcHandler for GetPayloadV3Request { Ok(GetPayloadV3Request { payload_id }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Requested payload with id: {:#018x}", self.payload_id); - let Some(mut payload) = storage.get_payload(self.payload_id)? else { + let Some(mut payload) = context.storage.get_payload(self.payload_id)? else { return Err(RpcErr::UnknownPayload(format!( "Payload with id {:#018x} not found", self.payload_id ))); }; - let (blobs_bundle, block_value) = build_payload(&mut payload, &storage) + let (blobs_bundle, block_value) = build_payload(&mut payload, &context.storage) .map_err(|err| RpcErr::Internal(err.to_string()))?; serde_json::to_value(ExecutionPayloadResponse { execution_payload: ExecutionPayloadV3::from_block(payload), diff --git a/crates/networking/rpc/eth/account.rs b/crates/networking/rpc/eth/account.rs index 953999daa..060ec8278 100644 --- a/crates/networking/rpc/eth/account.rs +++ b/crates/networking/rpc/eth/account.rs @@ -1,9 +1,9 @@ -use ethereum_rust_storage::Store; use serde_json::Value; use tracing::info; use crate::types::account_proof::{AccountProof, StorageProof}; use crate::types::block_identifier::BlockIdentifierOrHash; +use crate::RpcApiContext; use crate::{utils::RpcErr, RpcHandler}; use ethereum_rust_core::{Address, BigEndianHash, H256, U256}; @@ -47,19 +47,21 @@ impl RpcHandler for GetBalanceRequest { block: BlockIdentifierOrHash::parse(params[1].clone(), 1)?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested balance of account {} at block {}", self.address, self.block ); - let Some(block_number) = self.block.resolve_block_number(&storage)? else { + let Some(block_number) = self.block.resolve_block_number(&context.storage)? else { return Err(RpcErr::Internal( "Could not resolve block number".to_owned(), )); // Should we return Null here? }; - let account = storage.get_account_info(block_number, self.address)?; + let account = context + .storage + .get_account_info(block_number, self.address)?; let balance = account.map(|acc| acc.balance).unwrap_or_default(); serde_json::to_value(format!("{:#x}", balance)) @@ -80,19 +82,20 @@ impl RpcHandler for GetCodeRequest { block: BlockIdentifierOrHash::parse(params[1].clone(), 1)?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested code of account {} at block {}", self.address, self.block ); - let Some(block_number) = self.block.resolve_block_number(&storage)? else { + let Some(block_number) = self.block.resolve_block_number(&context.storage)? else { return Err(RpcErr::Internal( "Could not resolve block number".to_owned(), )); // Should we return Null here? }; - let code = storage + let code = context + .storage .get_code_by_account_address(block_number, self.address)? .unwrap_or_default(); @@ -115,19 +118,20 @@ impl RpcHandler for GetStorageAtRequest { block: BlockIdentifierOrHash::parse(params[2].clone(), 2)?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested storage sot {} of account {} at block {}", self.storage_slot, self.address, self.block ); - let Some(block_number) = self.block.resolve_block_number(&storage)? else { + let Some(block_number) = self.block.resolve_block_number(&context.storage)? else { return Err(RpcErr::Internal( "Could not resolve block number".to_owned(), )); // Should we return Null here? }; - let storage_value = storage + let storage_value = context + .storage .get_storage_at(block_number, self.address, self.storage_slot)? .unwrap_or_default(); let storage_value = H256::from_uint(&storage_value); @@ -149,18 +153,19 @@ impl RpcHandler for GetTransactionCountRequest { block: BlockIdentifierOrHash::parse(params[1].clone(), 1)?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested nonce of account {} at block {}", self.address, self.block ); - let Some(block_number) = self.block.resolve_block_number(&storage)? else { + let Some(block_number) = self.block.resolve_block_number(&context.storage)? else { return serde_json::to_value("0x0") .map_err(|error| RpcErr::Internal(error.to_string())); }; - let nonce = storage + let nonce = context + .storage .get_nonce_by_account_address(block_number, self.address)? .unwrap_or_default(); @@ -186,12 +191,13 @@ impl RpcHandler for GetProofRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!( "Requested proof for account {} at block {} with storage keys: {:?}", self.address, self.block, self.storage_keys ); - let Some(block_number) = self.block.resolve_block_number(&storage)? else { + let Some(block_number) = self.block.resolve_block_number(storage)? else { return Ok(Value::Null); }; // Create account proof diff --git a/crates/networking/rpc/eth/block.rs b/crates/networking/rpc/eth/block.rs index fea369977..74295d090 100644 --- a/crates/networking/rpc/eth/block.rs +++ b/crates/networking/rpc/eth/block.rs @@ -10,7 +10,7 @@ use crate::{ receipt::{RpcReceipt, RpcReceiptBlockInfo, RpcReceiptTxInfo}, }, utils::RpcErr, - RpcHandler, + RpcApiContext, RpcHandler, }; use ethereum_rust_core::{ types::{ @@ -68,9 +68,10 @@ impl RpcHandler for GetBlockByNumberRequest { hydrated: serde_json::from_value(params[1].clone())?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!("Requested block with number: {}", self.block); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; @@ -109,7 +110,8 @@ impl RpcHandler for GetBlockByHashRequest { hydrated: serde_json::from_value(params[1].clone())?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!("Requested block with hash: {:#x}", self.block); let block_number = match storage.get_block_number(self.block)? { Some(number) => number, @@ -149,16 +151,16 @@ impl RpcHandler for GetBlockTransactionCountRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested transaction count for block with number: {}", self.block ); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(&context.storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; - let block_body = match storage.get_block_body(block_number)? { + let block_body = match context.storage.get_block_body(block_number)? { Some(block_body) => block_body, _ => return Ok(Value::Null), }; @@ -182,9 +184,10 @@ impl RpcHandler for GetBlockReceiptsRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!("Requested receipts for block with number: {}", self.block); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; @@ -195,7 +198,7 @@ impl RpcHandler for GetBlockReceiptsRequest { // Block not found _ => return Ok(Value::Null), }; - let receipts = get_all_block_rpc_receipts(block_number, header, body, &storage)?; + let receipts = get_all_block_rpc_receipts(block_number, header, body, storage)?; serde_json::to_value(&receipts).map_err(|error| RpcErr::Internal(error.to_string())) } @@ -214,16 +217,17 @@ impl RpcHandler for GetRawHeaderRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested raw header for block with identifier: {}", self.block ); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(&context.storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; - let header = storage + let header = context + .storage .get_block_header(block_number)? .ok_or(RpcErr::BadParams("Header not found".to_owned()))?; @@ -246,14 +250,14 @@ impl RpcHandler for GetRawBlockRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Requested raw block: {}", self.block); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(&context.storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; - let header = storage.get_block_header(block_number)?; - let body = storage.get_block_body(block_number)?; + let header = context.storage.get_block_header(block_number)?; + let body = context.storage.get_block_body(block_number)?; let (header, body) = match (header, body) { (Some(header), Some(body)) => (header, body), _ => return Ok(Value::Null), @@ -279,8 +283,9 @@ impl RpcHandler for GetRawReceipts { }) } - fn handle(&self, storage: Store) -> Result { - let block_number = match self.block.resolve_block_number(&storage)? { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; + let block_number = match self.block.resolve_block_number(storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; @@ -290,7 +295,7 @@ impl RpcHandler for GetRawReceipts { (Some(header), Some(body)) => (header, body), _ => return Ok(Value::Null), }; - let receipts: Vec = get_all_block_receipts(block_number, header, body, &storage)? + let receipts: Vec = get_all_block_receipts(block_number, header, body, storage)? .iter() .map(|receipt| format!("0x{}", hex::encode(receipt.encode_to_vec()))) .collect(); @@ -303,9 +308,9 @@ impl RpcHandler for BlockNumberRequest { Ok(Self {}) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Requested latest block number"); - match storage.get_latest_block_number() { + match context.storage.get_latest_block_number() { Ok(Some(block_number)) => serde_json::to_value(format!("{:#x}", block_number)) .map_err(|error| RpcErr::Internal(error.to_string())), Ok(None) => Err(RpcErr::Internal("No blocks found".to_owned())), @@ -319,15 +324,15 @@ impl RpcHandler for GetBlobBaseFee { Ok(Self {}) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Requested blob gas price"); - match storage.get_latest_block_number() { + match context.storage.get_latest_block_number() { Ok(Some(block_number)) => { - let header = match storage.get_block_header(block_number)? { + let header = match context.storage.get_block_header(block_number)? { Some(header) => header, _ => return Err(RpcErr::Internal("Could not get block header".to_owned())), }; - let parent_header = match find_parent_header(&header, &storage) { + let parent_header = match find_parent_header(&header, &context.storage) { Ok(header) => header, Err(error) => return Err(RpcErr::Internal(error.to_string())), }; diff --git a/crates/networking/rpc/eth/client.rs b/crates/networking/rpc/eth/client.rs index a52eece66..f090b0c70 100644 --- a/crates/networking/rpc/eth/client.rs +++ b/crates/networking/rpc/eth/client.rs @@ -1,9 +1,7 @@ -use tracing::info; - -use ethereum_rust_storage::Store; use serde_json::Value; +use tracing::info; -use crate::{utils::RpcErr, RpcHandler}; +use crate::{utils::RpcErr, RpcApiContext, RpcHandler}; pub struct ChainId; impl RpcHandler for ChainId { @@ -11,9 +9,10 @@ impl RpcHandler for ChainId { Ok(Self {}) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!("Requested chain id"); - let chain_spec = storage + let chain_spec = context + .storage .get_chain_config() .map_err(|error| RpcErr::Internal(error.to_string()))?; serde_json::to_value(format!("{:#x}", chain_spec.chain_id)) @@ -27,7 +26,7 @@ impl RpcHandler for Syncing { Ok(Self {}) } - fn handle(&self, _storage: Store) -> Result { + fn handle(&self, _context: RpcApiContext) -> Result { Ok(Value::Bool(false)) } } diff --git a/crates/networking/rpc/eth/fee_market.rs b/crates/networking/rpc/eth/fee_market.rs index cc83a1f73..e1b8cf663 100644 --- a/crates/networking/rpc/eth/fee_market.rs +++ b/crates/networking/rpc/eth/fee_market.rs @@ -4,7 +4,7 @@ use serde::Serialize; use serde_json::Value; use tracing::info; -use crate::{types::block_identifier::BlockIdentifier, utils::RpcErr, RpcHandler}; +use crate::{types::block_identifier::BlockIdentifier, utils::RpcErr, RpcApiContext, RpcHandler}; use ethereum_rust_core::types::calculate_base_fee_per_blob_gas; use ethereum_rust_storage::Store; @@ -67,7 +67,8 @@ impl RpcHandler for FeeHistoryRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!( "Requested fee history for {} blocks starting from {}", self.block_count, self.newest_block @@ -79,7 +80,7 @@ impl RpcHandler for FeeHistoryRequest { } let (start_block, end_block) = - Self::get_range(&storage, self.block_count, &self.newest_block)?; + Self::get_range(storage, self.block_count, &self.newest_block)?; let oldest_block = start_block; let block_count = (end_block - start_block) as usize; let mut base_fee_per_gas = Vec::::with_capacity(block_count + 1); diff --git a/crates/networking/rpc/eth/filter.rs b/crates/networking/rpc/eth/filter.rs index a5e8c8f13..c0e6018fd 100644 --- a/crates/networking/rpc/eth/filter.rs +++ b/crates/networking/rpc/eth/filter.rs @@ -266,7 +266,7 @@ mod tests { }, map_http_requests, utils::test_utils::{self, start_test_api}, - FILTER_DURATION, + RpcApiContext, FILTER_DURATION, }; use crate::{ types::block_identifier::BlockIdentifier, @@ -436,18 +436,22 @@ mod tests { json_req: serde_json::Value, filters_pointer: ActiveFilters, ) -> u64 { - let node = example_p2p_node(); + let context = RpcApiContext { + storage: Store::new("in-mem", EngineType::InMemory) + .expect("Fatal: could not create in memory test db"), + jwt_secret: Default::default(), + local_p2p_node: example_p2p_node(), + active_filters: filters_pointer.clone(), + }; let request: RpcRequest = serde_json::from_value(json_req).expect("Test json is incorrect"); let genesis_config: Genesis = serde_json::from_str(TEST_GENESIS).expect("Fatal: non-valid genesis test config"); - let store = Store::new("in-mem", EngineType::InMemory) - .expect("Fatal: could not create in memory test db"); - store + + context + .storage .add_initial_state(genesis_config) .expect("Fatal: could not add test genesis in test"); - let response = map_http_requests(&request, store, node, filters_pointer.clone()) - .unwrap() - .to_string(); + let response = map_http_requests(&request, context).unwrap().to_string(); let trimmed_id = response.trim().trim_matches('"'); assert!(trimmed_id.starts_with("0x")); let hex = trimmed_id.trim_start_matches("0x"); @@ -485,13 +489,15 @@ mod tests { ), ); let active_filters = Arc::new(Mutex::new(HashMap::from([filter]))); - map_http_requests( - &uninstall_filter_req, - Store::new("in-mem", EngineType::InMemory).unwrap(), - example_p2p_node(), - active_filters.clone(), - ) - .unwrap(); + let context = RpcApiContext { + storage: Store::new("in-mem", EngineType::InMemory).unwrap(), + local_p2p_node: example_p2p_node(), + jwt_secret: Default::default(), + active_filters: active_filters.clone(), + }; + + map_http_requests(&uninstall_filter_req, context).unwrap(); + assert!( active_filters.clone().lock().unwrap().len() == 0, "Expected filter map to be empty after request" @@ -500,6 +506,14 @@ mod tests { #[test] fn removing_non_existing_filter_returns_false() { + let active_filters = Arc::new(Mutex::new(HashMap::new())); + + let context = RpcApiContext { + storage: Store::new("in-mem", EngineType::InMemory).unwrap(), + local_p2p_node: example_p2p_node(), + active_filters: active_filters.clone(), + jwt_secret: Default::default(), + }; let uninstall_filter_req: RpcRequest = serde_json::from_value(json!( { "jsonrpc":"2.0", @@ -511,14 +525,7 @@ mod tests { ,"id":1 })) .expect("Json for test is not a valid request"); - let active_filters = Arc::new(Mutex::new(HashMap::new())); - let res = map_http_requests( - &uninstall_filter_req, - Store::new("in-mem", EngineType::InMemory).unwrap(), - example_p2p_node(), - active_filters.clone(), - ) - .unwrap(); + let res = map_http_requests(&uninstall_filter_req, context).unwrap(); assert!(matches!(res, serde_json::Value::Bool(false))); } diff --git a/crates/networking/rpc/eth/gas_price.rs b/crates/networking/rpc/eth/gas_price.rs index 8fc995146..fe3f18417 100644 --- a/crates/networking/rpc/eth/gas_price.rs +++ b/crates/networking/rpc/eth/gas_price.rs @@ -1,9 +1,8 @@ use ethereum_rust_blockchain::constants::MIN_GAS_LIMIT; -use ethereum_rust_storage::Store; use tracing::error; use crate::utils::RpcErr; -use crate::RpcHandler; +use crate::{RpcApiContext, RpcHandler}; use serde_json::Value; // TODO: This does not need a struct, @@ -41,8 +40,8 @@ impl RpcHandler for GasPrice { // we can look into more sophisticated estimation methods, if needed. /// Estimate Gas Price based on already accepted transactions, /// as per the spec, this will be returned in wei. - fn handle(&self, storage: Store) -> Result { - let Some(latest_block_number) = storage.get_latest_block_number()? else { + fn handle(&self, context: RpcApiContext) -> Result { + let Some(latest_block_number) = context.storage.get_latest_block_number()? else { error!("FATAL: LATEST BLOCK NUMBER IS MISSING"); return Err(RpcErr::Internal("Error calculating gas price".to_string())); }; @@ -64,7 +63,7 @@ impl RpcHandler for GasPrice { // caching this result, also we can have a specific DB method // that returns a block range to not query them one-by-one. for block_num in block_range { - let Some(block_body) = storage.get_block_body(block_num)? else { + let Some(block_body) = context.storage.get_block_body(block_num)? else { error!("Block body for block number {block_num} is missing but is below the latest known block!"); return Err(RpcErr::Internal( "Error calculating gas price: missing data".to_string(), @@ -93,7 +92,7 @@ mod tests { use crate::{ map_http_requests, utils::{parse_json_hex, test_utils::example_p2p_node, RpcRequest}, - RpcHandler, + RpcApiContext, RpcHandler, }; use bytes::Bytes; use ethereum_rust_blockchain::constants::MIN_GAS_LIMIT; @@ -104,10 +103,11 @@ mod tests { }, Address, Bloom, H256, U256, }; + use ethereum_rust_net::types::Node; use ethereum_rust_storage::{EngineType, Store}; use hex_literal::hex; use serde_json::json; - use std::str::FromStr; + use std::{net::Ipv4Addr, str::FromStr}; // Base price for each test transaction. const BASE_PRICE_IN_WEI: u64 = 10_u64.pow(9); fn test_header(block_num: u64) -> BlockHeader { @@ -198,7 +198,7 @@ mod tests { } #[test] fn test_for_legacy_txs() { - let store = setup_store(); + let context = default_context(); for block_num in 1..100 { let mut txs = vec![]; for nonce in 1..=3 { @@ -212,21 +212,25 @@ mod tests { }; let block_header = test_header(block_num); let block = Block::new(block_header.clone(), block_body); - store.add_block(block).unwrap(); - store + context.storage.add_block(block).unwrap(); + context + .storage .set_canonical_block(block_num, block_header.compute_block_hash()) .unwrap(); - store.update_latest_block_number(block_num).unwrap(); + context + .storage + .update_latest_block_number(block_num) + .unwrap(); } let gas_price = GasPrice {}; - let response = gas_price.handle(store).unwrap(); + let response = gas_price.handle(context).unwrap(); let parsed_result = parse_json_hex(&response).unwrap(); assert_eq!(parsed_result, 2000000000); } #[test] fn test_for_eip_1559_txs() { - let store = setup_store(); + let context = default_context(); for block_num in 1..100 { let mut txs = vec![]; for nonce in 1..=3 { @@ -239,20 +243,24 @@ mod tests { }; let block_header = test_header(block_num); let block = Block::new(block_header.clone(), block_body); - store.add_block(block).unwrap(); - store + context.storage.add_block(block).unwrap(); + context + .storage .set_canonical_block(block_num, block_header.compute_block_hash()) .unwrap(); - store.update_latest_block_number(block_num).unwrap(); + context + .storage + .update_latest_block_number(block_num) + .unwrap(); } let gas_price = GasPrice {}; - let response = gas_price.handle(store).unwrap(); + let response = gas_price.handle(context).unwrap(); let parsed_result = parse_json_hex(&response).unwrap(); assert_eq!(parsed_result, 2000000000); } #[test] fn test_with_mixed_transactions() { - let store = setup_store(); + let context = default_context(); for block_num in 1..100 { let txs = vec![ legacy_tx_for_test(1), @@ -267,20 +275,24 @@ mod tests { }; let block_header = test_header(block_num); let block = Block::new(block_header.clone(), block_body); - store.add_block(block).unwrap(); - store + context.storage.add_block(block).unwrap(); + context + .storage .set_canonical_block(block_num, block_header.compute_block_hash()) .unwrap(); - store.update_latest_block_number(block_num).unwrap(); + context + .storage + .update_latest_block_number(block_num) + .unwrap(); } let gas_price = GasPrice {}; - let response = gas_price.handle(store).unwrap(); + let response = gas_price.handle(context).unwrap(); let parsed_result = parse_json_hex(&response).unwrap(); assert_eq!(parsed_result, 2000000000); } #[test] fn test_with_not_enough_blocks_or_transactions() { - let store = setup_store(); + let context = default_context(); for block_num in 1..10 { let txs = vec![legacy_tx_for_test(1)]; let block_body = BlockBody { @@ -290,23 +302,27 @@ mod tests { }; let block_header = test_header(block_num); let block = Block::new(block_header.clone(), block_body); - store.add_block(block).unwrap(); - store + context.storage.add_block(block).unwrap(); + context + .storage .set_canonical_block(block_num, block_header.compute_block_hash()) .unwrap(); - store.update_latest_block_number(block_num).unwrap(); + context + .storage + .update_latest_block_number(block_num) + .unwrap(); } let gas_price = GasPrice {}; - let response = gas_price.handle(store).unwrap(); + let response = gas_price.handle(context).unwrap(); let parsed_result = parse_json_hex(&response).unwrap(); assert_eq!(parsed_result, 1000000000); } #[test] fn test_with_no_blocks_but_genesis() { - let store = setup_store(); + let context = default_context(); let gas_price = GasPrice {}; let expected_gas_price = MIN_GAS_LIMIT; - let response = gas_price.handle(store).unwrap(); + let response = gas_price.handle(context).unwrap(); let parsed_result = parse_json_hex(&response).unwrap(); assert_eq!(parsed_result, expected_gas_price); } @@ -320,7 +336,8 @@ mod tests { }); let expected_response = json!("0x3b9aca00"); let request: RpcRequest = serde_json::from_value(raw_json).expect("Test json is not valid"); - let storage = setup_store(); + let mut context = default_context(); + context.local_p2p_node = example_p2p_node(); for block_num in 1..100 { let txs = vec![legacy_tx_for_test(1)]; @@ -331,14 +348,31 @@ mod tests { }; let block_header = test_header(block_num); let block = Block::new(block_header.clone(), block_body); - storage.add_block(block).unwrap(); - storage + context.storage.add_block(block).unwrap(); + context + .storage .set_canonical_block(block_num, block_header.compute_block_hash()) .unwrap(); - storage.update_latest_block_number(block_num).unwrap(); + context + .storage + .update_latest_block_number(block_num) + .unwrap(); } - let response = - map_http_requests(&request, storage, example_p2p_node(), Default::default()).unwrap(); + let response = map_http_requests(&request, context).unwrap(); assert_eq!(response, expected_response) } + + fn default_context() -> RpcApiContext { + RpcApiContext { + storage: setup_store(), + jwt_secret: Default::default(), + local_p2p_node: Node { + ip: std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + udp_port: Default::default(), + tcp_port: Default::default(), + node_id: Default::default(), + }, + active_filters: Default::default(), + } + } } diff --git a/crates/networking/rpc/eth/logs.rs b/crates/networking/rpc/eth/logs.rs index cefeb83d6..b45034e70 100644 --- a/crates/networking/rpc/eth/logs.rs +++ b/crates/networking/rpc/eth/logs.rs @@ -4,7 +4,7 @@ // - Ethereum's reference: https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newfilter use crate::{ types::{block_identifier::BlockIdentifier, receipt::RpcLog}, - RpcErr, RpcHandler, + RpcApiContext, RpcErr, RpcHandler, }; use ethereum_rust_core::{H160, H256}; use ethereum_rust_storage::Store; @@ -84,8 +84,8 @@ impl RpcHandler for LogsFilter { )), } } - fn handle(&self, storage: Store) -> Result { - let filtered_logs = fetch_logs_with_filter(self, storage)?; + fn handle(&self, context: RpcApiContext) -> Result { + let filtered_logs = fetch_logs_with_filter(self, context.storage)?; serde_json::to_value(filtered_logs).map_err(|error| { tracing::error!("Log filtering request failed with: {error}"); RpcErr::Internal("Failed to filter logs".to_string()) diff --git a/crates/networking/rpc/eth/transaction.rs b/crates/networking/rpc/eth/transaction.rs index d0cbcca82..a88dd9832 100644 --- a/crates/networking/rpc/eth/transaction.rs +++ b/crates/networking/rpc/eth/transaction.rs @@ -5,7 +5,7 @@ use crate::{ transaction::{RpcTransaction, SendRawTransactionRequest}, }, utils::RpcErr, - RpcHandler, + RpcApiContext, RpcHandler, }; use ethereum_rust_core::{ types::{AccessListEntry, BlockHash, BlockHeader, BlockNumber, GenericTransaction, TxKind}, @@ -96,16 +96,16 @@ impl RpcHandler for CallRequest { block, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { let block = self.block.clone().unwrap_or_default(); info!("Requested call on block: {}", block); - let header = match block.resolve_block_header(&storage)? { + let header = match block.resolve_block_header(&context.storage)? { Some(header) => header, // Block not found _ => return Ok(Value::Null), }; // Run transaction - let result = simulate_tx(&self.transaction, &header, storage, SpecId::CANCUN)?; + let result = simulate_tx(&self.transaction, &header, context.storage, SpecId::CANCUN)?; serde_json::to_value(format!("0x{:#x}", result.output())) .map_err(|error| RpcErr::Internal(error.to_string())) } @@ -132,20 +132,20 @@ impl RpcHandler for GetTransactionByBlockNumberAndIndexRequest { }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested transaction at index: {} of block with number: {}", self.transaction_index, self.block, ); - let block_number = match self.block.resolve_block_number(&storage)? { + let block_number = match self.block.resolve_block_number(&context.storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; - let block_body = match storage.get_block_body(block_number)? { + let block_body = match context.storage.get_block_body(block_number)? { Some(block_body) => block_body, _ => return Ok(Value::Null), }; - let block_header = match storage.get_block_header(block_number)? { + let block_header = match context.storage.get_block_header(block_number)? { Some(block_body) => block_body, _ => return Ok(Value::Null), }; @@ -183,16 +183,16 @@ impl RpcHandler for GetTransactionByBlockHashAndIndexRequest { .map_err(|error| RpcErr::BadParams(error.to_string()))?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { info!( "Requested transaction at index: {} of block with hash: {:#x}", self.transaction_index, self.block, ); - let block_number = match storage.get_block_number(self.block)? { + let block_number = match context.storage.get_block_number(self.block)? { Some(number) => number, _ => return Ok(Value::Null), }; - let block_body = match storage.get_block_body(block_number)? { + let block_body = match context.storage.get_block_body(block_number)? { Some(block_body) => block_body, _ => return Ok(Value::Null), }; @@ -221,7 +221,8 @@ impl RpcHandler for GetTransactionByHashRequest { transaction_hash: serde_json::from_value(params[0].clone())?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!( "Requested transaction with hash: {:#x}", self.transaction_hash, @@ -259,7 +260,8 @@ impl RpcHandler for GetTransactionReceiptRequest { transaction_hash: serde_json::from_value(params[0].clone())?, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; info!( "Requested receipt for transaction {:#x}", self.transaction_hash, @@ -274,7 +276,7 @@ impl RpcHandler for GetTransactionReceiptRequest { None => return Ok(Value::Null), }; let receipts = - block::get_all_block_rpc_receipts(block_number, block.header, block.body, &storage)?; + block::get_all_block_rpc_receipts(block_number, block.header, block.body, storage)?; serde_json::to_value(receipts.get(index as usize)) .map_err(|error| RpcErr::Internal(error.to_string())) } @@ -304,14 +306,14 @@ impl RpcHandler for CreateAccessListRequest { block, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { let block = self.block.clone().unwrap_or_default(); info!("Requested access list creation for tx on block: {}", block); - let block_number = match block.resolve_block_number(&storage)? { + let block_number = match block.resolve_block_number(&context.storage)? { Some(block_number) => block_number, _ => return Ok(Value::Null), }; - let header = match storage.get_block_header(block_number)? { + let header = match context.storage.get_block_header(block_number)? { Some(header) => header, // Block not found _ => return Ok(Value::Null), @@ -320,7 +322,7 @@ impl RpcHandler for CreateAccessListRequest { let (gas_used, access_list, error) = match ethereum_rust_vm::create_access_list( &self.transaction, &header, - &mut evm_state(storage, header.compute_block_hash()), + &mut evm_state(context.storage, header.compute_block_hash()), SpecId::CANCUN, )? { ( @@ -386,8 +388,10 @@ impl RpcHandler for GetRawTransaction { }) } - fn handle(&self, storage: Store) -> Result { - let tx = storage.get_transaction_by_hash(self.transaction_hash)?; + fn handle(&self, context: RpcApiContext) -> Result { + let tx = context + .storage + .get_transaction_by_hash(self.transaction_hash)?; let tx = match tx { Some(tx) => tx, @@ -423,10 +427,11 @@ impl RpcHandler for EstimateGasRequest { block, }) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { + let storage = &context.storage; let block = self.block.clone().unwrap_or_default(); info!("Requested estimate on block: {}", block); - let block_header = match block.resolve_block_header(&storage)? { + let block_header = match block.resolve_block_header(storage)? { Some(header) => header, // Block not found _ => return Ok(Value::Null), @@ -464,7 +469,7 @@ impl RpcHandler for EstimateGasRequest { highest_gas_limit = recap_with_account_balances( highest_gas_limit, &self.transaction, - &storage, + storage, block_header.number, )?; } @@ -570,15 +575,15 @@ impl RpcHandler for SendRawTransactionRequest { Ok(transaction) } - fn handle(&self, storage: Store) -> Result { + fn handle(&self, context: RpcApiContext) -> Result { let hash = if let SendRawTransactionRequest::EIP4844(wrapped_blob_tx) = self { mempool::add_blob_transaction( wrapped_blob_tx.tx.clone(), wrapped_blob_tx.blobs_bundle.clone(), - storage, + context.storage, ) } else { - mempool::add_transaction(self.to_transaction(), storage) + mempool::add_transaction(self.to_transaction(), context.storage) }?; serde_json::to_value(format!("{:#x}", hash)) .map_err(|error| RpcErr::Internal(error.to_string())) diff --git a/crates/networking/rpc/rpc.rs b/crates/networking/rpc/rpc.rs index 71d14787d..645386c29 100644 --- a/crates/networking/rpc/rpc.rs +++ b/crates/networking/rpc/rpc.rs @@ -70,12 +70,12 @@ pub struct RpcApiContext { trait RpcHandler: Sized { fn parse(params: &Option>) -> Result; - fn call(req: &RpcRequest, storage: Store) -> Result { + fn call(req: &RpcRequest, context: RpcApiContext) -> Result { let request = Self::parse(&req.params)?; - request.handle(storage) + request.handle(context) } - fn handle(&self, storage: Store) -> Result; + fn handle(&self, context: RpcApiContext) -> Result; } const FILTER_DURATION: Duration = { @@ -149,15 +149,8 @@ pub async fn handle_http_request( State(service_context): State, body: String, ) -> Json { - let storage = service_context.storage; - let local_p2p_node = service_context.local_p2p_node; let req: RpcRequest = serde_json::from_str(&body).unwrap(); - let res = map_http_requests( - &req, - storage, - local_p2p_node, - service_context.active_filters, - ); + let res = map_http_requests(&req, service_context); rpc_response(req.id, res) } @@ -166,129 +159,116 @@ pub async fn handle_authrpc_request( auth_header: Option>>, body: String, ) -> Json { - let storage = service_context.storage; - let secret = service_context.jwt_secret; let req: RpcRequest = serde_json::from_str(&body).unwrap(); - match authenticate(secret, auth_header) { + match authenticate(&service_context.jwt_secret, auth_header) { Err(error) => rpc_response(req.id, Err(error)), Ok(()) => { // Proceed with the request - let res = map_authrpc_requests(&req, storage, service_context.active_filters); + let res = map_authrpc_requests(&req, service_context); rpc_response(req.id, res) } } } /// Handle requests that can come from either clients or other users -pub fn map_http_requests( - req: &RpcRequest, - storage: Store, - local_p2p_node: Node, - filters: ActiveFilters, -) -> Result { +pub fn map_http_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.namespace() { - Ok(RpcNamespace::Eth) => map_eth_requests(req, storage, filters), - Ok(RpcNamespace::Admin) => map_admin_requests(req, storage, local_p2p_node), - Ok(RpcNamespace::Debug) => map_debug_requests(req, storage), - Ok(RpcNamespace::Web3) => map_web3_requests(req, storage), + Ok(RpcNamespace::Eth) => map_eth_requests(req, context), + Ok(RpcNamespace::Admin) => map_admin_requests(req, context), + Ok(RpcNamespace::Debug) => map_debug_requests(req, context), + Ok(RpcNamespace::Web3) => map_web3_requests(req, context), _ => Err(RpcErr::MethodNotFound(req.method.clone())), } } /// Handle requests from consensus client -pub fn map_authrpc_requests( - req: &RpcRequest, - storage: Store, - active_filters: ActiveFilters, -) -> Result { +pub fn map_authrpc_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.namespace() { - Ok(RpcNamespace::Engine) => map_engine_requests(req, storage), - Ok(RpcNamespace::Eth) => map_eth_requests(req, storage, active_filters), + Ok(RpcNamespace::Engine) => map_engine_requests(req, context), + Ok(RpcNamespace::Eth) => map_eth_requests(req, context), _ => Err(RpcErr::MethodNotFound(req.method.clone())), } } -pub fn map_eth_requests( - req: &RpcRequest, - storage: Store, - filters: ActiveFilters, -) -> Result { +pub fn map_eth_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.method.as_str() { - "eth_chainId" => ChainId::call(req, storage), - "eth_syncing" => Syncing::call(req, storage), - "eth_getBlockByNumber" => GetBlockByNumberRequest::call(req, storage), - "eth_getBlockByHash" => GetBlockByHashRequest::call(req, storage), - "eth_getBalance" => GetBalanceRequest::call(req, storage), - "eth_getCode" => GetCodeRequest::call(req, storage), - "eth_getStorageAt" => GetStorageAtRequest::call(req, storage), + "eth_chainId" => ChainId::call(req, context), + "eth_syncing" => Syncing::call(req, context), + "eth_getBlockByNumber" => GetBlockByNumberRequest::call(req, context), + "eth_getBlockByHash" => GetBlockByHashRequest::call(req, context), + "eth_getBalance" => GetBalanceRequest::call(req, context), + "eth_getCode" => GetCodeRequest::call(req, context), + "eth_getStorageAt" => GetStorageAtRequest::call(req, context), "eth_getBlockTransactionCountByNumber" => { - GetBlockTransactionCountRequest::call(req, storage) + GetBlockTransactionCountRequest::call(req, context) } - "eth_getBlockTransactionCountByHash" => GetBlockTransactionCountRequest::call(req, storage), + "eth_getBlockTransactionCountByHash" => GetBlockTransactionCountRequest::call(req, context), "eth_getTransactionByBlockNumberAndIndex" => { - GetTransactionByBlockNumberAndIndexRequest::call(req, storage) + GetTransactionByBlockNumberAndIndexRequest::call(req, context) } "eth_getTransactionByBlockHashAndIndex" => { - GetTransactionByBlockHashAndIndexRequest::call(req, storage) + GetTransactionByBlockHashAndIndexRequest::call(req, context) } - "eth_getBlockReceipts" => GetBlockReceiptsRequest::call(req, storage), - "eth_getTransactionByHash" => GetTransactionByHashRequest::call(req, storage), - "eth_getTransactionReceipt" => GetTransactionReceiptRequest::call(req, storage), - "eth_createAccessList" => CreateAccessListRequest::call(req, storage), - "eth_blockNumber" => BlockNumberRequest::call(req, storage), - "eth_call" => CallRequest::call(req, storage), - "eth_blobBaseFee" => GetBlobBaseFee::call(req, storage), - "eth_getTransactionCount" => GetTransactionCountRequest::call(req, storage), - "eth_feeHistory" => FeeHistoryRequest::call(req, storage), - "eth_estimateGas" => EstimateGasRequest::call(req, storage), - "eth_getLogs" => LogsFilter::call(req, storage), - "eth_newFilter" => NewFilterRequest::stateful_call(req, storage, filters), - "eth_uninstallFilter" => DeleteFilterRequest::stateful_call(req, storage, filters), - "eth_getFilterChanges" => FilterChangesRequest::stateful_call(req, storage, filters), - "eth_sendRawTransaction" => SendRawTransactionRequest::call(req, storage), - "eth_getProof" => GetProofRequest::call(req, storage), - "eth_gasPrice" => GasPrice::call(req, storage), + "eth_getBlockReceipts" => GetBlockReceiptsRequest::call(req, context), + "eth_getTransactionByHash" => GetTransactionByHashRequest::call(req, context), + "eth_getTransactionReceipt" => GetTransactionReceiptRequest::call(req, context), + "eth_createAccessList" => CreateAccessListRequest::call(req, context), + "eth_blockNumber" => BlockNumberRequest::call(req, context), + "eth_call" => CallRequest::call(req, context), + "eth_blobBaseFee" => GetBlobBaseFee::call(req, context), + "eth_getTransactionCount" => GetTransactionCountRequest::call(req, context), + "eth_feeHistory" => FeeHistoryRequest::call(req, context), + "eth_estimateGas" => EstimateGasRequest::call(req, context), + "eth_getLogs" => LogsFilter::call(req, context), + "eth_newFilter" => { + NewFilterRequest::stateful_call(req, context.storage, context.active_filters) + } + "eth_uninstallFilter" => { + DeleteFilterRequest::stateful_call(req, context.storage, context.active_filters) + } + "eth_getFilterChanges" => { + FilterChangesRequest::stateful_call(req, context.storage, context.active_filters) + } + "eth_sendRawTransaction" => SendRawTransactionRequest::call(req, context), + "eth_getProof" => GetProofRequest::call(req, context), + "eth_gasPrice" => GasPrice::call(req, context), unknown_eth_method => Err(RpcErr::MethodNotFound(unknown_eth_method.to_owned())), } } -pub fn map_debug_requests(req: &RpcRequest, storage: Store) -> Result { +pub fn map_debug_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.method.as_str() { - "debug_getRawHeader" => GetRawHeaderRequest::call(req, storage), - "debug_getRawBlock" => GetRawBlockRequest::call(req, storage), - "debug_getRawTransaction" => GetRawTransaction::call(req, storage), - "debug_getRawReceipts" => GetRawReceipts::call(req, storage), + "debug_getRawHeader" => GetRawHeaderRequest::call(req, context), + "debug_getRawBlock" => GetRawBlockRequest::call(req, context), + "debug_getRawTransaction" => GetRawTransaction::call(req, context), + "debug_getRawReceipts" => GetRawReceipts::call(req, context), unknown_debug_method => Err(RpcErr::MethodNotFound(unknown_debug_method.to_owned())), } } -pub fn map_engine_requests(req: &RpcRequest, storage: Store) -> Result { +pub fn map_engine_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.method.as_str() { - "engine_exchangeCapabilities" => ExchangeCapabilitiesRequest::call(req, storage), - "engine_forkchoiceUpdatedV3" => ForkChoiceUpdatedV3::call(req, storage), - "engine_newPayloadV3" => NewPayloadV3Request::call(req, storage), + "engine_exchangeCapabilities" => ExchangeCapabilitiesRequest::call(req, context), + "engine_forkchoiceUpdatedV3" => ForkChoiceUpdatedV3::call(req, context), + "engine_newPayloadV3" => NewPayloadV3Request::call(req, context), "engine_exchangeTransitionConfigurationV1" => { - ExchangeTransitionConfigV1Req::call(req, storage) + ExchangeTransitionConfigV1Req::call(req, context) } - "engine_getPayloadV3" => GetPayloadV3Request::call(req, storage), + "engine_getPayloadV3" => GetPayloadV3Request::call(req, context), unknown_engine_method => Err(RpcErr::MethodNotFound(unknown_engine_method.to_owned())), } } -pub fn map_admin_requests( - req: &RpcRequest, - storage: Store, - local_p2p_node: Node, -) -> Result { +pub fn map_admin_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.method.as_str() { - "admin_nodeInfo" => admin::node_info(storage, local_p2p_node), + "admin_nodeInfo" => admin::node_info(context.storage, context.local_p2p_node), unknown_admin_method => Err(RpcErr::MethodNotFound(unknown_admin_method.to_owned())), } } -pub fn map_web3_requests(req: &RpcRequest, storage: Store) -> Result { +pub fn map_web3_requests(req: &RpcRequest, context: RpcApiContext) -> Result { match req.method.as_str() { - "web3_clientVersion" => web3::client_version(req, storage), + "web3_clientVersion" => web3::client_version(req, context.storage), unknown_web3_method => Err(RpcErr::MethodNotFound(unknown_web3_method.to_owned())), } } @@ -340,7 +320,13 @@ mod tests { let storage = Store::new("temp.db", EngineType::InMemory).expect("Failed to create test DB"); storage.set_chain_config(&example_chain_config()).unwrap(); - let result = map_http_requests(&request, storage, local_p2p_node, Default::default()); + let context = RpcApiContext { + local_p2p_node, + storage, + jwt_secret: Default::default(), + active_filters: Default::default(), + }; + let result = map_http_requests(&request, context); let rpc_response = rpc_response(request.id, result); let expected_response = to_rpc_response_success_value( r#"{"jsonrpc":"2.0","id":1,"result":{"enode":"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@127.0.0.1:30303","id":"d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666","ip":"127.0.0.1","name":"ethereum_rust/0.1.0/rust1.80","ports":{"discovery":30303,"listener":30303},"protocols":{"eth":{"chainId":3151908,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":false,"eip150Block":0,"eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":null,"berlinBlock":0,"londonBlock":0,"arrowGlacierBlock":null,"grayGlacierBlock":null,"mergeNetsplitBlock":0,"shanghaiTime":0,"cancunTime":0,"pragueTime":1718232101,"verkleTime":null,"terminalTotalDifficulty":0,"terminalTotalDifficultyPassed":true}}}}"#, @@ -371,7 +357,13 @@ mod tests { .expect("Failed to add genesis block to DB"); let local_p2p_node = example_p2p_node(); // Process request - let result = map_http_requests(&request, storage, local_p2p_node, Default::default()); + let context = RpcApiContext { + local_p2p_node, + storage, + jwt_secret: Default::default(), + active_filters: Default::default(), + }; + let result = map_http_requests(&request, context); let response = rpc_response(request.id, result); let expected_response = to_rpc_response_success_value( r#"{"jsonrpc":"2.0","id":1,"result":{"accessList":[],"gasUsed":"0x5208"}}"#, @@ -394,7 +386,13 @@ mod tests { .expect("Failed to add genesis block to DB"); let local_p2p_node = example_p2p_node(); // Process request - let result = map_http_requests(&request, storage, local_p2p_node, Default::default()); + let context = RpcApiContext { + local_p2p_node, + storage, + jwt_secret: Default::default(), + active_filters: Default::default(), + }; + let result = map_http_requests(&request, context); let response = serde_json::from_value::(rpc_response(request.id, result).0) .expect("Request failed");