From ed8d4df72bbd5eda7f5796a4b6fc1787e548c849 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:21:46 -0700 Subject: [PATCH 1/4] Add GET get_mapping_values --- node/rest/src/lib.rs | 1 + node/rest/src/routes.rs | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/node/rest/src/lib.rs b/node/rest/src/lib.rs index 202dbcca0f..5b5b652ad7 100644 --- a/node/rest/src/lib.rs +++ b/node/rest/src/lib.rs @@ -133,6 +133,7 @@ impl, R: Routing> Rest { // All the endpoints before the call to `route_layer` are protected with JWT auth. .route(&format!("/{network}/node/address"), get(Self::get_node_address)) + .route(&format!("/{network}/program/:id/mapping/:name"), get(Self::get_mapping_values)) .route_layer(middleware::from_fn(auth_middleware)) // ----------------- DEPRECATED ROUTES ----------------- diff --git a/node/rest/src/routes.rs b/node/rest/src/routes.rs index 500cbf9b96..67c0dcb9eb 100644 --- a/node/rest/src/routes.rs +++ b/node/rest/src/routes.rs @@ -33,10 +33,11 @@ pub(crate) struct BlockRange { end: u32, } -/// The `get_mapping_value` query object. -#[derive(Deserialize, Serialize)] +/// The query object for `get_mapping_value` and `get_mapping_values`. +#[derive(Copy, Clone, Deserialize, Serialize)] pub(crate) struct Metadata { - metadata: bool, + metadata: Option, + all: Option, } impl, R: Routing> Rest { @@ -230,13 +231,13 @@ impl, R: Routing> Rest { pub(crate) async fn get_mapping_value( State(rest): State, Path((id, name, key)): Path<(ProgramID, Identifier, Plaintext)>, - metadata: Option>, + metadata: Query, ) -> Result { // Retrieve the mapping value. let mapping_value = rest.ledger.vm().finalize_store().get_value_confirmed(id, name, &key)?; // Check if metadata is requested and return the value with metadata if so. - if metadata.map(|q| q.metadata).unwrap_or(false) { + if metadata.metadata.unwrap_or(false) { return Ok(ErasedJson::pretty(json!({ "data": mapping_value, "height": rest.ledger.latest_height(), @@ -247,6 +248,33 @@ impl, R: Routing> Rest { Ok(ErasedJson::pretty(mapping_value)) } + // GET //program/{programID}/mapping/{mappingName}?all={true}&metadata={true} + pub(crate) async fn get_mapping_values( + State(rest): State, + Path((id, name)): Path<(ProgramID, Identifier)>, + metadata: Query, + ) -> Result { + // If the `all` query parameter is set, return the full mapping. + if metadata.all.unwrap_or(false) { + // Retrieve all the mapping values from the mapping. + let mapping_values = rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name)?; + + // Check if metadata is requested and return the mapping with metadata if so. + if metadata.metadata.unwrap_or(false) { + return Ok(ErasedJson::pretty(json!({ + "data": mapping_values, + "height": rest.ledger.latest_height(), + }))); + } + + // Return the full mapping without metadata. + return Ok(ErasedJson::pretty(mapping_values)); + } + + // Return an error if the `all` query parameter is not set to `true`. + Err(RestError("Invalid query parameter. At this time, 'all=true' must be included".to_string())) + } + // GET //statePath/{commitment} pub(crate) async fn get_state_path_for_commitment( State(rest): State, From a83a69e16b4f0138c351f4b378c355bfc2b61a73 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:27:00 -0700 Subject: [PATCH 2/4] Wrap call around blocking task --- node/rest/src/routes.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/node/rest/src/routes.rs b/node/rest/src/routes.rs index 67c0dcb9eb..a33e51a371 100644 --- a/node/rest/src/routes.rs +++ b/node/rest/src/routes.rs @@ -256,14 +256,25 @@ impl, R: Routing> Rest { ) -> Result { // If the `all` query parameter is set, return the full mapping. if metadata.all.unwrap_or(false) { + // Retrieve the latest height. + let height = rest.ledger.latest_height(); + // Retrieve all the mapping values from the mapping. - let mapping_values = rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name)?; + let mapping_values = match tokio::task::spawn_blocking(move || { + rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name) + }) + .await + { + Ok(Ok(mapping_values)) => mapping_values, + Ok(Err(err)) => return Err(RestError(format!("Unable to read mapping - {err}"))), + Err(err) => return Err(RestError(format!("Unable to read mapping - {err}"))), + }; // Check if metadata is requested and return the mapping with metadata if so. if metadata.metadata.unwrap_or(false) { return Ok(ErasedJson::pretty(json!({ "data": mapping_values, - "height": rest.ledger.latest_height(), + "height": height, }))); } From 87f3bbd57ef4540b9ce0f99bcac7e0ccfbb703b1 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:21:13 -0700 Subject: [PATCH 3/4] nit --- node/rest/src/routes.rs | 53 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/node/rest/src/routes.rs b/node/rest/src/routes.rs index a33e51a371..cdc74d0801 100644 --- a/node/rest/src/routes.rs +++ b/node/rest/src/routes.rs @@ -254,36 +254,35 @@ impl, R: Routing> Rest { Path((id, name)): Path<(ProgramID, Identifier)>, metadata: Query, ) -> Result { - // If the `all` query parameter is set, return the full mapping. - if metadata.all.unwrap_or(false) { - // Retrieve the latest height. - let height = rest.ledger.latest_height(); - - // Retrieve all the mapping values from the mapping. - let mapping_values = match tokio::task::spawn_blocking(move || { - rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name) - }) - .await - { - Ok(Ok(mapping_values)) => mapping_values, - Ok(Err(err)) => return Err(RestError(format!("Unable to read mapping - {err}"))), - Err(err) => return Err(RestError(format!("Unable to read mapping - {err}"))), - }; - - // Check if metadata is requested and return the mapping with metadata if so. - if metadata.metadata.unwrap_or(false) { - return Ok(ErasedJson::pretty(json!({ - "data": mapping_values, - "height": height, - }))); - } + // Return an error if the `all` query parameter is not set to `true`. + if metadata.all != Some(true) { + return Err(RestError("Invalid query parameter. At this time, 'all=true' must be included".to_string())); + } + + // Retrieve the latest height. + let height = rest.ledger.latest_height(); + + // Retrieve all the mapping values from the mapping. + let mapping_values = match tokio::task::spawn_blocking(move || { + rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name) + }) + .await + { + Ok(Ok(mapping_values)) => mapping_values, + Ok(Err(err)) => return Err(RestError(format!("Unable to read mapping - {err}"))), + Err(err) => return Err(RestError(format!("Unable to read mapping - {err}"))), + }; - // Return the full mapping without metadata. - return Ok(ErasedJson::pretty(mapping_values)); + // Check if metadata is requested and return the mapping with metadata if so. + if metadata.metadata.unwrap_or(false) { + return Ok(ErasedJson::pretty(json!({ + "data": mapping_values, + "height": height, + }))); } - // Return an error if the `all` query parameter is not set to `true`. - Err(RestError("Invalid query parameter. At this time, 'all=true' must be included".to_string())) + // Return the full mapping without metadata. + Ok(ErasedJson::pretty(mapping_values)) } // GET //statePath/{commitment} From 0388e682a519c75c717121b04e802033fdf35b20 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:29:26 -0700 Subject: [PATCH 4/4] Add Json serialization into blocking task --- node/rest/src/routes.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/node/rest/src/routes.rs b/node/rest/src/routes.rs index cdc74d0801..23b8072878 100644 --- a/node/rest/src/routes.rs +++ b/node/rest/src/routes.rs @@ -263,26 +263,24 @@ impl, R: Routing> Rest { let height = rest.ledger.latest_height(); // Retrieve all the mapping values from the mapping. - let mapping_values = match tokio::task::spawn_blocking(move || { - rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name) - }) - .await + match tokio::task::spawn_blocking(move || rest.ledger.vm().finalize_store().get_mapping_confirmed(id, name)) + .await { - Ok(Ok(mapping_values)) => mapping_values, - Ok(Err(err)) => return Err(RestError(format!("Unable to read mapping - {err}"))), - Err(err) => return Err(RestError(format!("Unable to read mapping - {err}"))), - }; + Ok(Ok(mapping_values)) => { + // Check if metadata is requested and return the mapping with metadata if so. + if metadata.metadata.unwrap_or(false) { + return Ok(ErasedJson::pretty(json!({ + "data": mapping_values, + "height": height, + }))); + } - // Check if metadata is requested and return the mapping with metadata if so. - if metadata.metadata.unwrap_or(false) { - return Ok(ErasedJson::pretty(json!({ - "data": mapping_values, - "height": height, - }))); + // Return the full mapping without metadata. + Ok(ErasedJson::pretty(mapping_values)) + } + Ok(Err(err)) => Err(RestError(format!("Unable to read mapping - {err}"))), + Err(err) => Err(RestError(format!("Unable to read mapping - {err}"))), } - - // Return the full mapping without metadata. - Ok(ErasedJson::pretty(mapping_values)) } // GET //statePath/{commitment}