Skip to content

Commit

Permalink
return empty responses if data is unavailable in db
Browse files Browse the repository at this point in the history
  • Loading branch information
sug0 committed Nov 25, 2024
1 parent 5d4d679 commit 01d6e8a
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 25 deletions.
13 changes: 13 additions & 0 deletions shared/src/commitment_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::sync::LazyLock;

use namada_sdk::borsh::BorshSerializeExt;
use namada_sdk::masp_primitives::merkle_tree::CommitmentTree;
use namada_sdk::masp_primitives::sapling::Node;

/// Return an empty serialized [`CommitmentTree`].
#[inline]
pub fn empty() -> Vec<u8> {
static EMPTY_TREE: LazyLock<Vec<u8>> =
LazyLock::new(|| CommitmentTree::<Node>::empty().serialize_to_vec());
EMPTY_TREE.clone()
}
1 change: 1 addition & 0 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod block;
pub mod block_results;
pub mod commitment_tree;
pub mod error;
pub mod extracted_masp_tx;
pub mod header;
Expand Down
3 changes: 0 additions & 3 deletions webserver/src/error/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ use crate::response::api::ApiErrorResponse;

#[derive(Error, Debug)]
pub enum TreeError {
#[error("Commitment Tree not found")]
NotFound,
#[error("Database error: {0}")]
Database(String),
}

impl IntoResponse for TreeError {
fn into_response(self) -> Response {
let status_code = match self {
TreeError::NotFound => StatusCode::NOT_FOUND,
TreeError::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
};

Expand Down
3 changes: 0 additions & 3 deletions webserver/src/error/witness_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ use crate::response::api::ApiErrorResponse;

#[derive(Error, Debug)]
pub enum WitnessMapError {
#[error("WitnessMap not found")]
NotFound,
#[error("Database error: {0}")]
Database(String),
}

impl IntoResponse for WitnessMapError {
fn into_response(self) -> Response {
let status_code = match self {
WitnessMapError::NotFound => StatusCode::NOT_FOUND,
WitnessMapError::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
};

Expand Down
16 changes: 8 additions & 8 deletions webserver/src/handler/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use axum::extract::{Query, State};
use axum::Json;
use axum_macros::debug_handler;
use axum_trace_id::TraceId;
use shared::commitment_tree::empty as empty_tree;
use shared::error::InspectWrap;

use crate::dto::tree::TreeQueryParams;
Expand All @@ -23,12 +24,11 @@ pub async fn get_commitment_tree(
TreeError::Database(err.to_string())
})?;

if let Some((commitment_tree, block_height)) = maybe_commitment_tree {
Ok(Json(TreeResponse {
commitment_tree,
block_height,
}))
} else {
Err(TreeError::NotFound)
}
let (commitment_tree, block_height) = maybe_commitment_tree
.unwrap_or_else(|| (empty_tree(), query_params.height));

Ok(Json(TreeResponse {
commitment_tree,
block_height,
}))
}
15 changes: 7 additions & 8 deletions webserver/src/handler/witness_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ pub async fn get_witness_map(
WitnessMapError::Database(err.to_string())
})?;

if let Some((witnesses, block_height)) = witnesses_and_height {
Ok(Json(WitnessMapResponse::new(
BlockHeight(block_height),
witnesses,
)))
} else {
Err(WitnessMapError::NotFound)
}
let (witnesses, block_height) =
witnesses_and_height.unwrap_or((Vec::new(), query_params.height));

Ok(Json(WitnessMapResponse::new(
BlockHeight(block_height),
witnesses,
)))
}
13 changes: 10 additions & 3 deletions webserver/src/repository/witness_map.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use anyhow::Context;
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper};
use diesel::{
ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl,
SelectableHelper,
};
use orm::schema::witness;
use orm::witness::WitnessDb;
use shared::error::ContextDbInteractError;
Expand Down Expand Up @@ -35,17 +38,21 @@ impl WitnessMapRepositoryTrait for WitnessMapRepository {
)?;

conn.interact(move |conn| {
let closest_height = witness::table
let Some(closest_height) = witness::table
.order(abs(witness::dsl::block_height - block_height).asc())
.filter(witness::dsl::block_height.le(block_height))
.select(witness::dsl::block_height)
.first(conn)
.optional()
.with_context(|| {
format!(
"Failed to fetch height from the db closest to the \
provided height {block_height}"
)
})?;
})?
else {
return anyhow::Ok((vec![], block_height));
};

let witnesses = witness::table
.filter(witness::dsl::block_height.eq(closest_height))
Expand Down

0 comments on commit 01d6e8a

Please sign in to comment.