parent
c6f042b94f
commit
ad47dcf228
|
@ -12,6 +12,7 @@ nomos-storage = { path = "../../nomos-services/storage", features = ["sled"] }
|
|||
nomos-api = { path = "../../nomos-services/api" }
|
||||
nomos-node = { path = "../nomos-node" }
|
||||
nomos-core = { path = "../../nomos-core" }
|
||||
full-replication = { path = "../../nomos-da/full-replication" }
|
||||
serde = "1.0"
|
||||
tracing = "0.1"
|
||||
async-trait = "0.1.73"
|
||||
|
@ -19,8 +20,9 @@ axum = "0.6"
|
|||
hyper = "0.14.27"
|
||||
tower-http = "0.4"
|
||||
utoipa = "4.0"
|
||||
utoipa-swagger-ui = "4.0"
|
||||
utoipa-swagger-ui = "6.0"
|
||||
futures = "0.3"
|
||||
serde_yaml = "0.9.25"
|
||||
clap = { version = "4.4.6", features = ["derive"] }
|
||||
eyre = "0.6"
|
||||
eyre = "0.6"
|
||||
|
||||
|
|
|
@ -84,7 +84,12 @@ where
|
|||
)
|
||||
.layer(TraceLayer::new_for_http())
|
||||
// .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
|
||||
.route("/blocks", routing::get(store::store_blocks::<T, S>))
|
||||
.route("/store/blocks", routing::get(store::store_blocks::<T, S>))
|
||||
.route("/explorer/blocks", routing::get(store::blocks::<T, S>))
|
||||
.route(
|
||||
"/explorer/blocks/depth",
|
||||
routing::get(store::block_depth::<T, S>),
|
||||
)
|
||||
.with_state(handle);
|
||||
|
||||
Server::bind(&self.settings.address)
|
||||
|
|
|
@ -4,12 +4,14 @@ use std::hash::Hash;
|
|||
|
||||
// crates
|
||||
use axum::extract::{Query, State};
|
||||
use axum::response::Response;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use hyper::StatusCode;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
// internal
|
||||
use full_replication::Certificate;
|
||||
use nomos_api::http::storage;
|
||||
use nomos_core::block::BlockId;
|
||||
use nomos_core::block::{Block, BlockId};
|
||||
use nomos_core::tx::Transaction;
|
||||
use nomos_node::make_request_and_return_response;
|
||||
use nomos_storage::backends::StorageSerde;
|
||||
|
@ -44,3 +46,182 @@ where
|
|||
.collect();
|
||||
make_request_and_return_response!(futures::future::try_join_all(results))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct BlocksByIdQueryParams {
|
||||
from: BlockId,
|
||||
to: Option<BlockId>,
|
||||
}
|
||||
|
||||
pub(crate) async fn blocks<Tx, S>(
|
||||
State(store): State<OverwatchHandle>,
|
||||
Query(query): Query<BlocksByIdQueryParams>,
|
||||
) -> Response
|
||||
where
|
||||
Tx: Transaction
|
||||
+ Clone
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Hash
|
||||
+ Serialize
|
||||
+ DeserializeOwned
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
<Tx as Transaction>::Hash: std::cmp::Ord + Debug + Send + Sync + 'static,
|
||||
S: StorageSerde + Send + Sync + 'static,
|
||||
{
|
||||
let BlocksByIdQueryParams { from, to } = query;
|
||||
// get the from block
|
||||
let from = match storage::block_req::<S, Tx>(&store, from).await {
|
||||
Ok(from) => match from {
|
||||
Some(from) => from,
|
||||
None => {
|
||||
return IntoResponse::into_response((StatusCode::NOT_FOUND, "from block not found"))
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
return IntoResponse::into_response((StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
|
||||
}
|
||||
};
|
||||
|
||||
// check if to is valid
|
||||
match to {
|
||||
Some(to) => match storage::block_req::<S, Tx>(&store, to).await {
|
||||
Ok(to) => match to {
|
||||
Some(to) => handle_to::<S, Tx>(store, from, Some(to)).await,
|
||||
None => IntoResponse::into_response((StatusCode::NOT_FOUND, "to block not found")),
|
||||
},
|
||||
Err(e) => {
|
||||
IntoResponse::into_response((StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
|
||||
}
|
||||
},
|
||||
None => handle_to::<S, Tx>(store, from, None).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_to<S, Tx>(
|
||||
store: OverwatchHandle,
|
||||
from: Block<Tx, Certificate>,
|
||||
to: Option<Block<Tx, Certificate>>,
|
||||
) -> Response
|
||||
where
|
||||
Tx: Transaction
|
||||
+ Clone
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Hash
|
||||
+ Serialize
|
||||
+ DeserializeOwned
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
<Tx as Transaction>::Hash: std::cmp::Ord + Debug + Send + Sync + 'static,
|
||||
S: StorageSerde + Send + Sync + 'static,
|
||||
{
|
||||
let mut current = Some(from.header().parent());
|
||||
let mut blocks = Vec::new();
|
||||
while let Some(id) = current {
|
||||
if let Some(to) = &to {
|
||||
if id == to.header().id {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let block = match storage::block_req::<S, Tx>(&store, id).await {
|
||||
Ok(block) => block,
|
||||
Err(e) => {
|
||||
return IntoResponse::into_response((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
e.to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
match block {
|
||||
Some(block) => {
|
||||
current = Some(block.header().parent());
|
||||
blocks.push(block);
|
||||
}
|
||||
None => {
|
||||
current = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntoResponse::into_response((StatusCode::OK, ::axum::Json(blocks)))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct BlocksByDepthQueryParams {
|
||||
from: BlockId,
|
||||
#[serde(default = "default_depth")]
|
||||
depth: usize,
|
||||
}
|
||||
|
||||
fn default_depth() -> usize {
|
||||
500
|
||||
}
|
||||
|
||||
pub(crate) async fn block_depth<Tx, S>(
|
||||
State(store): State<OverwatchHandle>,
|
||||
Query(query): Query<BlocksByDepthQueryParams>,
|
||||
) -> Response
|
||||
where
|
||||
Tx: Transaction
|
||||
+ Clone
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Hash
|
||||
+ Serialize
|
||||
+ DeserializeOwned
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
<Tx as Transaction>::Hash: std::cmp::Ord + Debug + Send + Sync + 'static,
|
||||
S: StorageSerde + Send + Sync + 'static,
|
||||
{
|
||||
let BlocksByDepthQueryParams { from, depth } = query;
|
||||
// get the from block
|
||||
let from = match storage::block_req::<S, Tx>(&store, from).await {
|
||||
Ok(from) => match from {
|
||||
Some(from) => from,
|
||||
None => {
|
||||
return IntoResponse::into_response((StatusCode::NOT_FOUND, "from block not found"))
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
return IntoResponse::into_response((StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
|
||||
}
|
||||
};
|
||||
|
||||
let mut current = Some(from.header().parent());
|
||||
let mut blocks = Vec::new();
|
||||
while blocks.len() < depth {
|
||||
if let Some(id) = current {
|
||||
let block = match storage::block_req::<S, Tx>(&store, id).await {
|
||||
Ok(block) => block,
|
||||
Err(e) => {
|
||||
return IntoResponse::into_response((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
e.to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
match block {
|
||||
Some(block) => {
|
||||
current = Some(block.header().parent());
|
||||
blocks.push(block);
|
||||
}
|
||||
None => {
|
||||
current = None;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IntoResponse::into_response((StatusCode::OK, ::axum::Json(blocks)))
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ impl StorageTransaction for SledTransaction {
|
|||
}
|
||||
|
||||
/// Sled storage backend
|
||||
|
||||
pub struct SledBackend<SerdeOp> {
|
||||
sled: sled::Db,
|
||||
_serde_op: PhantomData<SerdeOp>,
|
||||
|
|
|
@ -136,16 +136,16 @@ impl<Backend: StorageBackend> StorageMsg<Backend> {
|
|||
impl<Backend: StorageBackend> Debug for StorageMsg<Backend> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
StorageMsg::Load { key, .. } => {
|
||||
Self::Load { key, .. } => {
|
||||
write!(f, "Load {{ {key:?} }}")
|
||||
}
|
||||
StorageMsg::Store { key, value } => {
|
||||
Self::Store { key, value } => {
|
||||
write!(f, "Store {{ {key:?}, {value:?}}}")
|
||||
}
|
||||
StorageMsg::Remove { key, .. } => {
|
||||
Self::Remove { key, .. } => {
|
||||
write!(f, "Remove {{ {key:?} }}")
|
||||
}
|
||||
StorageMsg::Execute { .. } => write!(f, "Execute transaction"),
|
||||
Self::Execute { .. } => write!(f, "Execute transaction"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue