diff --git a/src/integration/integration_test.rs b/src/integration/integration_test.rs index c5f8957..49f2d06 100644 --- a/src/integration/integration_test.rs +++ b/src/integration/integration_test.rs @@ -6,7 +6,7 @@ mod tests { use std::time::Duration; use crate::debug_api::SetDryRunRequestAction; - use crate::integration::RollupBoostTestHarnessBuilder; + use crate::integration::{ChaosTestHarness, RollupBoostTestHarnessBuilder}; use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; #[tokio::test] @@ -159,7 +159,7 @@ mod tests { let delay = Arc::new(Mutex::new(Duration::from_secs(0))); let delay_for_handler = delay.clone(); - let handler = Box::new(move |_method: &str, _params: Value, _result: Value| { + let handler = Box::new(move |method: &str, _params: Value, _result: Value| { let delay = delay_for_handler.lock().unwrap(); // sleep the amount of time specified in the delay std::thread::sleep(*delay); @@ -203,6 +203,7 @@ mod tests { // Test that the builder returns a block with an incorrect state root and that rollup-boost // does not process it. let handler = Box::new(move |method: &str, _params: Value, _result: Value| { + println!("Method: {}", method); if method != "engine_getPayloadV3" { return None; } @@ -246,4 +247,18 @@ mod tests { Ok(()) } + + #[tokio::test] + async fn test_integration_chaos() -> eyre::Result<()> { + let handler = Box::new(move |method: &str, _params: Value, _result: Value| { + println!("Method: {}", method); + None + }); + let harness = ChaosTestHarness::new("test_integration_chaos", handler).await; + + // sleep for 10000 seconds + tokio::time::sleep(tokio::time::Duration::from_secs(10000)).await; + + Ok(()) + } } diff --git a/src/integration/mod.rs b/src/integration/mod.rs index d73efaf..5b4a934 100644 --- a/src/integration/mod.rs +++ b/src/integration/mod.rs @@ -800,3 +800,39 @@ impl BlockBuilderCreatorValidator { Ok(None) } } + +pub struct ChaosTestHarness { + _framework: IntegrationFramework, +} + +impl ChaosTestHarness { + async fn new(test_name: &str, proxy_handler: DynHandlerFn) -> Self { + let mut framework = IntegrationFramework::new(test_name).unwrap(); + + let genesis_path = PathBuf::from( + "/Users/ferranbt/go/src/github.com/ethereum-optimism/optimism/.devnet/genesis-l2.json", + ); + let jwt_path = framework.write_file("jwt.hex", DEFAULT_JWT_TOKEN).unwrap(); + + let builder_reth_config = service_reth::RethConfig::new() + .jwt_secret_path(jwt_path.clone()) + .chain_config_path(genesis_path); + + // start the reth node + let service = framework + .start("reth", Box::new(builder_reth_config)) + .await + .unwrap(); + + let reth_authrpc_port = service.get_port("authrpc"); + + // add the proxy on known port 4444, we have to use a known port here because the setup is static + let _ = start_proxy_server(proxy_handler, 4444, reth_authrpc_port) + .await + .unwrap(); + + Self { + _framework: framework, + } + } +} diff --git a/src/integration/proxy.rs b/src/integration/proxy.rs index d97de9a..4e55490 100644 --- a/src/integration/proxy.rs +++ b/src/integration/proxy.rs @@ -16,7 +16,7 @@ use tokio::net::{TcpListener, TcpStream}; struct JsonRpcRequest { jsonrpc: String, method: String, - params: Value, + params: Option, id: Value, } @@ -53,6 +53,8 @@ async fn proxy( let (parts, body) = req.into_parts(); let bytes = body.collect().await?.to_bytes(); + println!("Proxy request bytes: {:?}", bytes); + let json_rpc_request = serde_json::from_slice::(&bytes).unwrap(); let req = Request::from_parts(parts, Full::new(bytes)); @@ -78,14 +80,19 @@ async fn proxy( let json_rpc_response = serde_json::from_slice::(&bytes).unwrap(); let bytes = if let Some(result) = json_rpc_response.clone().result { - let value = (config.handler)(&json_rpc_request.method, json_rpc_request.params, result); - if let Some(value) = value { - // If the handler returns a value, we replace the result with the new value - // The callback only returns the result of the jsonrpc request so we have to wrap it up - // again in a JsonRpcResponse - let mut new_json_rpc_resp = json_rpc_response; - new_json_rpc_resp.result = Some(value); - Bytes::from(serde_json::to_vec(&new_json_rpc_resp).unwrap()) + if let Some(params) = json_rpc_request.params { + let value = (config.handler)(&json_rpc_request.method, params, result); + if let Some(value) = value { + // If the handler returns a value, we replace the result with the new value + // The callback only returns the result of the jsonrpc request so we have to wrap it up + // again in a JsonRpcResponse + let mut new_json_rpc_resp = json_rpc_response; + new_json_rpc_resp.result = Some(value); + Bytes::from(serde_json::to_vec(&new_json_rpc_resp).unwrap()) + } else { + // If the handler returns None, we return the original response + bytes + } } else { // If the handler returns None, we return the original response bytes