Skip to content

Commit bf247bd

Browse files
LeanSerrafkrause98
authored andcommitted
fix(l1): support multiple rpc requests in a single request (#2006)
**Motivation** The hive tests from `engine-withdrawals` were failing with a panic because we were asuming only a single RLPRequest could be received but the test sent an array of requets **Description** Introduce a wrapper struct that contains a `Single` type for single `RPCRequest` and `Multiple` for an array of requests, so serde can deserialize into the correct one. If we have an array of request we execute them sequentially. Then return a json encoded array of responses. The function `rpc_response` was also changed to return `serde_json::Value` because it was returning an incorrect value when using it to create the array of responses. This PR fixes the following tests from `engine-withdrawals`: - "Withdrawals Fork on Block 1 - 1 Block Re-Org" - "Withdrawals Fork on Block 1 - 8 Block Re-Org NewPayload" - "Withdrawals Fork on Block 8 - 10 Block Re-Org NewPayload" - "Withdrawals Fork on Canonical Block 8 / Side Block 7 - 10 Block Re-Org" - "Withdrawals Fork on Canonical Block 8 / Side Block 9 - 10 Block Re-Org" Advances #1586
1 parent 1497f81 commit bf247bd

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

.github/workflows/ci_l1.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ jobs:
181181
ethrex_flags: ""
182182
- name: "Engine withdrawal tests"
183183
simulation: ethereum/engine
184-
test_pattern: "engine-withdrawals/engine-withdrawals test loader|GetPayloadV2 Block Value|Sync after 2 blocks - Withdrawals on Genesis|Max Initcode Size|Pre-Merge Fork Number > 0|Empty Withdrawals|Corrupted Block Hash Payload|Withdrawals Fork on Block 2|Withdrawals Fork on Block 3|GetPayloadBodies"
184+
test_pattern: "engine-withdrawals/engine-withdrawals test loader|GetPayloadV2 Block Value|Sync after 2 blocks - Withdrawals on Genesis|Max Initcode Size|Pre-Merge Fork Number > 0|Empty Withdrawals|Corrupted Block Hash Payload|Withdrawals Fork on Block 2|Withdrawals Fork on Block 3|GetPayloadBodies|Withdrawals Fork on Block 1 - 1 Block Re-Org|Withdrawals Fork on Block 1 - 8 Block Re-Org NewPayload|Withdrawals Fork on Block 8 - 10 Block Re-Org NewPayload|Withdrawals Fork on Canonical Block 8 / Side Block 7 - 10 Block Re-Org [^S]|Withdrawals Fork on Canonical Block 8 / Side Block 9 - 10 Block Re-Org [^S]"
185185
ethrex_flags: ""
186186
- name: "Sync full"
187187
simulation: ethereum/sync

crates/networking/rpc/rpc.rs

+39-23
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use eth::{
3737
},
3838
};
3939
use ethrex_p2p::{sync::SyncManager, types::NodeRecord};
40+
use serde::Deserialize;
4041
use serde_json::Value;
4142
use std::{
4243
collections::HashMap,
@@ -68,6 +69,13 @@ use axum::extract::State;
6869
use ethrex_p2p::types::Node;
6970
use ethrex_storage::{error::StoreError, Store};
7071

72+
#[derive(Deserialize)]
73+
#[serde(untagged)]
74+
enum RpcRequestWrapper {
75+
Single(RpcRequest),
76+
Multiple(Vec<RpcRequest>),
77+
}
78+
7179
#[derive(Debug, Clone)]
7280
pub struct RpcApiContext {
7381
storage: Store,
@@ -214,9 +222,22 @@ pub async fn handle_http_request(
214222
State(service_context): State<RpcApiContext>,
215223
body: String,
216224
) -> Json<Value> {
217-
let req: RpcRequest = serde_json::from_str(&body).unwrap();
218-
let res = map_http_requests(&req, service_context).await;
219-
rpc_response(req.id, res)
225+
let req = serde_json::from_str::<RpcRequestWrapper>(&body).unwrap();
226+
let res = match req {
227+
RpcRequestWrapper::Single(request) => {
228+
let res = map_http_requests(&request, service_context).await;
229+
rpc_response(request.id, res)
230+
}
231+
RpcRequestWrapper::Multiple(requests) => {
232+
let mut responses = Vec::new();
233+
for req in requests {
234+
let res = map_http_requests(&req, service_context.clone()).await;
235+
responses.push(rpc_response(req.id, res));
236+
}
237+
serde_json::to_value(responses).unwrap()
238+
}
239+
};
240+
Json(res)
220241
}
221242

222243
pub async fn handle_authrpc_request(
@@ -226,11 +247,11 @@ pub async fn handle_authrpc_request(
226247
) -> Json<Value> {
227248
let req: RpcRequest = serde_json::from_str(&body).unwrap();
228249
match authenticate(&service_context.jwt_secret, auth_header) {
229-
Err(error) => rpc_response(req.id, Err(error)),
250+
Err(error) => Json(rpc_response(req.id, Err(error))),
230251
Ok(()) => {
231252
// Proceed with the request
232253
let res = map_authrpc_requests(&req, service_context).await;
233-
rpc_response(req.id, res)
254+
Json(rpc_response(req.id, res))
234255
}
235256
}
236257
}
@@ -398,28 +419,23 @@ pub fn map_net_requests(req: &RpcRequest, contex: RpcApiContext) -> Result<Value
398419
}
399420
}
400421

401-
fn rpc_response<E>(id: RpcRequestId, res: Result<Value, E>) -> Json<Value>
422+
fn rpc_response<E>(id: RpcRequestId, res: Result<Value, E>) -> Value
402423
where
403424
E: Into<RpcErrorMetadata>,
404425
{
405426
match res {
406-
Ok(result) => Json(
407-
serde_json::to_value(RpcSuccessResponse {
408-
id,
409-
jsonrpc: "2.0".to_string(),
410-
result,
411-
})
412-
.unwrap(),
413-
),
414-
Err(error) => Json(
415-
serde_json::to_value(RpcErrorResponse {
416-
id,
417-
jsonrpc: "2.0".to_string(),
418-
error: error.into(),
419-
})
420-
.unwrap(),
421-
),
427+
Ok(result) => serde_json::to_value(RpcSuccessResponse {
428+
id,
429+
jsonrpc: "2.0".to_string(),
430+
result,
431+
}),
432+
Err(error) => serde_json::to_value(RpcErrorResponse {
433+
id,
434+
jsonrpc: "2.0".to_string(),
435+
error: error.into(),
436+
}),
422437
}
438+
.unwrap()
423439
}
424440

425441
#[cfg(test)]
@@ -593,7 +609,7 @@ mod tests {
593609
};
594610
let result = map_http_requests(&request, context).await;
595611
let response =
596-
serde_json::from_value::<RpcSuccessResponse>(rpc_response(request.id, result).0)
612+
serde_json::from_value::<RpcSuccessResponse>(rpc_response(request.id, result))
597613
.expect("Request failed");
598614
let expected_response_string = r#"{"jsonrpc":"2.0","id":1,"result":{"accessList":[{"address":"0x7dcd17433742f4c0ca53122ab541d0ba67fc27df","storageKeys":["0x0000000000000000000000000000000000000000000000000000000000000000","0x13a08e3cd39a1bc7bf9103f63f83273cced2beada9f723945176d6b983c65bd2"]}],"gasUsed":"0xca3c"}}"#;
599615
let expected_response =

0 commit comments

Comments
 (0)