From e08223b5a8baf9cceddc1becc1788f2f971fd1b0 Mon Sep 17 00:00:00 2001 From: Nikolay Komarevskiy Date: Mon, 1 Jul 2024 10:15:19 +0000 Subject: [PATCH] feat(BOUN-1091): Add `/api/v3/canister/canister_id/call` in Boundary Node --- rs/boundary_node/ic_boundary/src/core.rs | 10 +++-- rs/boundary_node/ic_boundary/src/routes.rs | 3 ++ .../ic_boundary/src/routes/test.rs | 37 +++++++++++++++++++ rs/boundary_node/ic_boundary/src/snapshot.rs | 3 ++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/rs/boundary_node/ic_boundary/src/core.rs b/rs/boundary_node/ic_boundary/src/core.rs index 1aff521c9f1..1740683dc96 100644 --- a/rs/boundary_node/ic_boundary/src/core.rs +++ b/rs/boundary_node/ic_boundary/src/core.rs @@ -548,9 +548,13 @@ pub fn setup_router( }))); let call_route = { - let mut route = Router::new().route(routes::PATH_CALL, { - post(routes::handle_canister).with_state(proxy.clone()) - }); + let mut route = Router::new() + .route(routes::PATH_CALL, { + post(routes::handle_canister).with_state(proxy.clone()) + }) + .route(routes::PATH_CALL_V3, { + post(routes::handle_canister).with_state(proxy.clone()) + }); // will panic if ip_rate_limit is Some(0) if let Some(rl) = cli.rate_limiting.rate_limit_per_second_per_ip { diff --git a/rs/boundary_node/ic_boundary/src/routes.rs b/rs/boundary_node/ic_boundary/src/routes.rs index b6d2e6895de..db891f85925 100644 --- a/rs/boundary_node/ic_boundary/src/routes.rs +++ b/rs/boundary_node/ic_boundary/src/routes.rs @@ -93,6 +93,7 @@ const HEADERS_HIDE_HTTP_REQUEST: [&str; 4] = pub const PATH_STATUS: &str = "/api/v2/status"; pub const PATH_QUERY: &str = "/api/v2/canister/:canister_id/query"; pub const PATH_CALL: &str = "/api/v2/canister/:canister_id/call"; +pub const PATH_CALL_V3: &str = "/api/v3/canister/:canister_id/call"; pub const PATH_READ_STATE: &str = "/api/v2/canister/:canister_id/read_state"; pub const PATH_SUBNET_READ_STATE: &str = "/api/v2/subnet/:subnet_id/read_state"; pub const PATH_HEALTH: &str = "/health"; @@ -112,6 +113,7 @@ pub enum RequestType { Status, Query, Call, + CallV3, ReadState, ReadStateSubnet, } @@ -520,6 +522,7 @@ pub async fn validate_canister_request( let request_type = match matched_path.as_str() { PATH_QUERY => RequestType::Query, PATH_CALL => RequestType::Call, + PATH_CALL_V3 => RequestType::CallV3, PATH_READ_STATE => RequestType::ReadState, _ => panic!("unknown path, should never happen"), }; diff --git a/rs/boundary_node/ic_boundary/src/routes/test.rs b/rs/boundary_node/ic_boundary/src/routes/test.rs index e4332db558c..224904f2328 100644 --- a/rs/boundary_node/ic_boundary/src/routes/test.rs +++ b/rs/boundary_node/ic_boundary/src/routes/test.rs @@ -546,6 +546,43 @@ async fn test_all_call_types() -> Result<(), Error> { let body = String::from_utf8_lossy(&body); assert_eq!(body, "a".repeat(1024)); + // Test call v3 + let content = HttpCallContent::Call { + update: HttpCanisterUpdate { + canister_id: Blob(canister_id.get().as_slice().to_vec()), + method_name: "foobar".to_string(), + arg: Blob(vec![]), + sender: Blob(sender.as_slice().to_vec()), + nonce: None, + ingress_expiry: 1234, + }, + }; + + let envelope = HttpRequestEnvelope:: { + content, + sender_delegation: None, + sender_pubkey: None, + sender_sig: None, + }; + + let body = serde_cbor::to_vec(&envelope).unwrap(); + + let request = Request::builder() + .method("POST") + .uri(format!( + "http://localhost/api/v3/canister/{canister_id}/call" + )) + .body(Body::from(body)) + .unwrap(); + + let resp = app.call(request).await.unwrap(); + assert_eq!(resp.status(), StatusCode::ACCEPTED); + + let (_parts, body) = resp.into_parts(); + let body = hyper::body::to_bytes(body).await.unwrap().to_vec(); + let body = String::from_utf8_lossy(&body); + assert_eq!(body, "a".repeat(1024)); + // Test canister read_state let content = HttpReadStateContent::ReadState { read_state: HttpReadState { diff --git a/rs/boundary_node/ic_boundary/src/snapshot.rs b/rs/boundary_node/ic_boundary/src/snapshot.rs index 9ddc0f890af..7a98c5deedc 100644 --- a/rs/boundary_node/ic_boundary/src/snapshot.rs +++ b/rs/boundary_node/ic_boundary/src/snapshot.rs @@ -72,6 +72,9 @@ impl Node { RequestType::Unknown => { panic!("can't construct url for unknown request type") } + RequestType::CallV3 => Url::from_str(&format!( + "https://{node_id}:{node_port}/api/v3/canister/{principal}/call", + )), RequestType::ReadStateSubnet => Url::from_str(&format!( "https://{node_id}:{node_port}/api/v2/subnet/{principal}/read_state", )),