From 3dbeeb0e85f9d18967634df96074e1276f7b33d0 Mon Sep 17 00:00:00 2001 From: Ape Dev Date: Thu, 29 Jun 2023 18:45:10 +0200 Subject: [PATCH 1/5] End simulation endpoint --- src/lib.rs | 11 +++++++++++ src/simulation.rs | 19 +++++++++++++++++++ tests/api.rs | 20 +++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b8ec2cb..b6d421b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ pub fn simulate_routes( simulate(config.clone()) .or(simulate_bundle(config.clone())) .or(simulate_stateful_new(config, state.clone())) + .or(simulate_stateful_end(state.clone())) .or(simulate_stateful(state)) } @@ -62,6 +63,16 @@ pub fn simulate_stateful_new( .and_then(simulation::simulate_stateful_new) } +/// POST /simulate-stateful/{statefulSimulationId} +pub fn simulate_stateful_end( + state: Arc, +) -> impl Filter + Clone { + warp::path!("simulate-stateful" / Uuid) + .and(warp::delete()) + .and(with_state(state)) + .and_then(simulation::simulate_stateful_end) +} + /// POST /simulate-stateful/{statefulSimulationId} pub fn simulate_stateful( state: Arc, diff --git a/src/simulation.rs b/src/simulation.rs index d74906c..24286db 100644 --- a/src/simulation.rs +++ b/src/simulation.rs @@ -74,6 +74,11 @@ pub struct StatefulSimulationResponse { pub stateful_simulation_id: Uuid, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct StatefulSimulationEndResponse { + pub success: bool, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CallTrace { #[serde(rename = "callType")] @@ -266,6 +271,20 @@ pub async fn simulate_stateful_new( Ok(warp::reply::json(&response)) } +pub async fn simulate_stateful_end( + param: Uuid, + state: Arc, +) -> Result { + if state.evms.contains_key(¶m) { + state.evms.remove(¶m); + let response = StatefulSimulationEndResponse { success: true }; + Ok(warp::reply::json(&response)) + } else { + let response = StatefulSimulationEndResponse { success: false }; + Ok(warp::reply::json(&response)) + } +} + pub async fn simulate_stateful( param: Uuid, transactions: Vec, diff --git a/tests/api.rs b/tests/api.rs index 72986ba..6269b1d 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -6,7 +6,10 @@ use transaction_simulator::{ config::config, errors::{handle_rejection, ErrorMessage}, simulate_routes, - simulation::{SimulationRequest, SimulationResponse, StatefulSimulationResponse}, + simulation::{ + SimulationRequest, SimulationResponse, StatefulSimulationEndResponse, + StatefulSimulationResponse, + }, SharedSimulationState, }; use warp::Filter; @@ -648,4 +651,19 @@ async fn post_simulate_stateful() { U256::from(body[1].return_data.0.to_vec().as_slice()), U256::from(1680526127 + 12) ); + + let res = warp::test::request() + .method("DELETE") + .path( + format!( + "/simulate-stateful/{}", + simulation_response_body.stateful_simulation_id + ) + .as_str(), + ) + .reply(&filter) + .await; + assert_eq!(res.status(), 200); + let body: StatefulSimulationEndResponse = serde_json::from_slice(&res.body()).unwrap(); + assert_eq!(body.success, true); } From 112f7ab78cdb9a9d63712db8a71f7f3977c98fc9 Mon Sep 17 00:00:00 2001 From: Ape Dev Date: Thu, 29 Jun 2023 18:46:27 +0200 Subject: [PATCH 2/5] Update comment --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b6d421b..ffc37b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ pub fn simulate_stateful_new( .and_then(simulation::simulate_stateful_new) } -/// POST /simulate-stateful/{statefulSimulationId} +/// DELETE /simulate-stateful/{statefulSimulationId} pub fn simulate_stateful_end( state: Arc, ) -> impl Filter + Clone { From 82bbc4223faae97da4fe88b69a322535413ad822 Mon Sep 17 00:00:00 2001 From: Ape Dev Date: Sat, 15 Jul 2023 12:53:09 +0200 Subject: [PATCH 3/5] Warp doesn't like 404s --- README.md | 17 ++++++++++++++++- src/errors.rs | 2 +- src/simulation.rs | 4 ++-- tests/api.rs | 7 +++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dcd2fe9..5eb4aa5 100644 --- a/README.md +++ b/README.md @@ -146,13 +146,28 @@ Example response: "exitReason": "Return" }] ``` - Notes: - `chainId` must be the same in all transactions. - `blockNumber` can be included and incremented when a multi-block simulation is required, or omitted in all transactions to use latest. +### DELETE /api/v1/simulate-stateful/{statefulSimulationId} + +Ends a current stateful simulation, freeing associated memory. + +[See the full request and response types below.](#types) + +Example response: + +```json +{ + "success": true +} +``` + + + ### Authentication If you set an `API_KEY` environment variable then all calls to the API must be accompanied by a `X-API-KEY` header which contains this API Key. diff --git a/src/errors.rs b/src/errors.rs index 116c48c..24cbb89 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -53,7 +53,7 @@ impl Reject for EvmError {} pub async fn handle_rejection(err: Rejection) -> Result { let code; let message: String; - + println!("Handling rejection: {:?}", err); if err.is_not_found() { code = StatusCode::NOT_FOUND; message = "NOT_FOUND".to_string(); diff --git a/src/simulation.rs b/src/simulation.rs index 24286db..c823708 100644 --- a/src/simulation.rs +++ b/src/simulation.rs @@ -280,8 +280,8 @@ pub async fn simulate_stateful_end( let response = StatefulSimulationEndResponse { success: true }; Ok(warp::reply::json(&response)) } else { - let response = StatefulSimulationEndResponse { success: false }; - Ok(warp::reply::json(&response)) + println!("Rejecting as not found!"); + return Err(warp::reject::not_found()); } } diff --git a/tests/api.rs b/tests/api.rs index 6269b1d..f14cfa7 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -666,4 +666,11 @@ async fn post_simulate_stateful() { assert_eq!(res.status(), 200); let body: StatefulSimulationEndResponse = serde_json::from_slice(&res.body()).unwrap(); assert_eq!(body.success, true); + + let res: warp::hyper::Response = warp::test::request() + .method("DELETE") + .path("/simulate-stateful/6f676bc7-3416-4647-99ee-e1be90fb6d2e") + .reply(&filter) + .await; + assert_eq!(res.status(), 404); } From f9e4bcde11758ea296dfba552831d04fa8fd26f6 Mon Sep 17 00:00:00 2001 From: Devan Non Date: Sat, 15 Jul 2023 22:53:41 +0200 Subject: [PATCH 4/5] return 404 if simulation state not found --- src/errors.rs | 8 ++++++++ src/simulation.rs | 5 ++--- tests/api.rs | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 24cbb89..2265674 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -45,6 +45,11 @@ pub struct InvalidBlockNumbersError(); impl Reject for InvalidBlockNumbersError {} +#[derive(Debug)] +pub struct StateNotFound(); + +impl Reject for StateNotFound {} + #[derive(Debug)] pub struct EvmError(pub Report); @@ -57,6 +62,9 @@ pub async fn handle_rejection(err: Rejection) -> Result if err.is_not_found() { code = StatusCode::NOT_FOUND; message = "NOT_FOUND".to_string(); + } else if let Some(_e) = err.find::() { + code = StatusCode::NOT_FOUND; + message = "STATE_NOT_FOUND".to_string(); } else if let Some(FromHexError) = err.find() { code = StatusCode::BAD_REQUEST; message = "FROM_HEX_ERROR".to_string(); diff --git a/src/simulation.rs b/src/simulation.rs index c823708..989b214 100644 --- a/src/simulation.rs +++ b/src/simulation.rs @@ -16,7 +16,7 @@ use warp::Rejection; use crate::errors::{ FromDecStrError, FromHexError, IncorrectChainIdError, InvalidBlockNumbersError, - MultipleChainIdsError, NoURLForChainIdError, + MultipleChainIdsError, NoURLForChainIdError, StateNotFound, }; use crate::SharedSimulationState; @@ -280,8 +280,7 @@ pub async fn simulate_stateful_end( let response = StatefulSimulationEndResponse { success: true }; Ok(warp::reply::json(&response)) } else { - println!("Rejecting as not found!"); - return Err(warp::reject::not_found()); + Err(warp::reject::custom(StateNotFound())) } } diff --git a/tests/api.rs b/tests/api.rs index f14cfa7..4f5dc29 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -667,7 +667,7 @@ async fn post_simulate_stateful() { let body: StatefulSimulationEndResponse = serde_json::from_slice(&res.body()).unwrap(); assert_eq!(body.success, true); - let res: warp::hyper::Response = warp::test::request() + let res = warp::test::request() .method("DELETE") .path("/simulate-stateful/6f676bc7-3416-4647-99ee-e1be90fb6d2e") .reply(&filter) From fc9ce1f61c9366054b68d4fb5d3b8fce8b8b92bd Mon Sep 17 00:00:00 2001 From: Devan Non Date: Sat, 15 Jul 2023 22:57:02 +0200 Subject: [PATCH 5/5] chore: clippy --- tests/api.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/api.rs b/tests/api.rs index 4f5dc29..2c1ba6c 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -477,13 +477,13 @@ async fn post_simulate_bundle_multiple_block_numbers() { assert_eq!(res.status(), 200); - let body: Vec = serde_json::from_slice(&res.body()).unwrap(); + let body: Vec = serde_json::from_slice(res.body()).unwrap(); assert_eq!(body.len(), 4); - assert_eq!(body[0].success, true); - assert_eq!(body[1].success, false); - assert_eq!(body[2].success, true); - assert_eq!(body[3].success, true); + assert!(body[0].success); + assert!(!body[1].success); + assert!(body[2].success); + assert!(body[3].success); assert_eq!(body[0].block_number, 16968595); assert_eq!(body[1].block_number, 16968596); @@ -554,7 +554,7 @@ async fn post_simulate_stateful() { assert_eq!(res.status(), 200); let simulation_response_body: StatefulSimulationResponse = - serde_json::from_slice(&res.body()).unwrap(); + serde_json::from_slice(res.body()).unwrap(); assert_eq!( simulation_response_body .stateful_simulation_id @@ -594,11 +594,11 @@ async fn post_simulate_stateful() { assert_eq!(res.status(), 200); - let body: Vec = serde_json::from_slice(&res.body()).unwrap(); + let body: Vec = serde_json::from_slice(res.body()).unwrap(); assert_eq!(body.len(), 2); - assert_eq!(body[0].success, true); - assert_eq!(body[1].success, false); + assert!(body[0].success); + assert!(!body[1].success); assert_eq!(body[0].block_number, 16968595); assert_eq!(body[1].block_number, 16968596); @@ -635,11 +635,11 @@ async fn post_simulate_stateful() { assert_eq!(res.status(), 200); - let body: Vec = serde_json::from_slice(&res.body()).unwrap(); + let body: Vec = serde_json::from_slice(res.body()).unwrap(); assert_eq!(body.len(), 2); - assert_eq!(body[0].success, true); - assert_eq!(body[1].success, true); + assert!(body[0].success); + assert!(body[1].success); assert_eq!(body[0].block_number, 16968597); assert_eq!(body[1].block_number, 16968598); @@ -664,8 +664,8 @@ async fn post_simulate_stateful() { .reply(&filter) .await; assert_eq!(res.status(), 200); - let body: StatefulSimulationEndResponse = serde_json::from_slice(&res.body()).unwrap(); - assert_eq!(body.success, true); + let body: StatefulSimulationEndResponse = serde_json::from_slice(res.body()).unwrap(); + assert!(body.success); let res = warp::test::request() .method("DELETE")