Skip to content

Commit

Permalink
define api
Browse files Browse the repository at this point in the history
  • Loading branch information
move47 committed Mar 12, 2024
1 parent 34cbb2c commit 351da4d
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 14 deletions.
123 changes: 123 additions & 0 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
use std::{fmt::Display, path::PathBuf};

use clap::Args;
use derive_more::From;
use futures::FutureExt;
use hotshot_types::{
traits::{node_implementation::NodeType, signature_key::SignatureKey},
utils::BuilderCommitment,
};
use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};
use tagged_base64::TaggedBase64;
use tide_disco::{
api::ApiError,
method::{ReadState, WriteState},
Api, RequestError, StatusCode,
};

use crate::{
api::load_api,
events_source::{EventsSource},
};

#[derive(Args, Default)]
pub struct Options {
#[arg(long = "hotshot-events-service-api-path", env = "HOTSHOT_EVENTS_SERVICE_API_PATH")]
pub api_path: Option<PathBuf>,

/// Additional API specification files to merge with `hotshot-events-service-api-path`.
///
/// These optional files may contain route definitions for application-specific routes that have
/// been added as extensions to the basic hotshot-events-service API.
#[arg(
long = "hotshot-events-extension",
env = "HOTSHOT_EVENTS_SERVICE_EXTENSIONS",
value_delimiter = ','
)]
pub extensions: Vec<toml::Value>,
}

#[derive(Clone, Debug, Snafu, Deserialize, Serialize)]
#[snafu(visibility(pub))]
pub enum EventError {
/// The requested resource does not exist or is not known to this hotshot node.
NotFound,
/// The requested resource exists but is not currently available.
Missing,
/// There was an error while trying to fetch the requested resource.
#[snafu(display("Failed to fetch requested resource: {message}"))]
Error { message: String },
}


#[derive(Clone, Debug, From, Snafu, Deserialize, Serialize)]
#[snafu(visibility(pub))]
pub enum Error {
Request {
source: RequestError,
},
#[snafu(display("error receiving events {resource}: {source}"))]
#[from(ignore)]
EventAvailable {
source: EventError,
resource: String,
},
Custom {
message: String,
status: StatusCode,
},
}

impl tide_disco::error::Error for Error {
fn catch_all(status: StatusCode, msg: String) -> Self {
Error::Custom {
message: msg,
status,
}
}

fn status(&self) -> StatusCode {
match self {
Error::Request { .. } => StatusCode::BadRequest,
Error::EventAvailable { source, .. } => match source
{
EventError::NotFound => StatusCode::NotFound,
EventError::Missing => StatusCode::NotFound,
EventError::Error { .. } => StatusCode::InternalServerError,
},
}
}
}

pub fn define_api<State, Types: NodeType>(options: &Options) -> Result<Api<State, Error>, ApiError>
where
State: 'static + Send + Sync + ReadState,
<State as ReadState>::State: Send + Sync + BuilderDataSource<Types>,
Types: NodeType,
<<Types as NodeType>::SignatureKey as SignatureKey>::PureAssembledSignatureType:
for<'a> TryFrom<&'a TaggedBase64> + Into<TaggedBase64> + Display,
for<'a> <<<Types as NodeType>::SignatureKey as SignatureKey>::PureAssembledSignatureType as TryFrom<
&'a TaggedBase64,
>>::Error: Display,
{
let mut api = load_api::<State, Error>(
options.api_path.as_ref(),
include_str!("../api/hotshot_events.toml"),
options.extensions.clone(),
)?;
api.with_version("0.0.1".parse().unwrap())
.get("available_hotshot_events", |req, state| {
async move {
let view_number = req.blob_param("view_number")?;
state
.get_available_hotshot_events(&view_number)
.await
.context(AvailableEventSnafu {
resource: view_number.to_string(),
})
}
.boxed()
})?;
Ok(api)
}
15 changes: 1 addition & 14 deletions src/events_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,11 @@ use std::{hash::Hash, marker::PhantomData};
use hotshot_types::event::Event;
use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]
#[serde(bound = "")]
pub struct EventInfo<I: NodeType> {
pub event: Event<I>,
pub signature: <<I as NodeType>::SignatureKey as SignatureKey>::PureAssembledSignatureType,
pub sender: <I as NodeType>::SignatureKey,
pub _phantom: PhantomData<I>,
}

#[derive(Clone, Debug, Snafu, Deserialize, Serialize)]
#[snafu(visibility(pub))]
pub enum EventError {
/// The requested resource does not exist or is not known to this hotshot node.
NotFound,
/// The requested resource exists but is not currently available.
Missing,
/// There was an error while trying to fetch the requested resource.
#[snafu(display("Failed to fetch requested resource: {message}"))]
Error { message: String },
}
}
1 change: 1 addition & 0 deletions src/events_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ where
{
async fn get_available_hotshot_events(
&self,
view_number: I::Time,
) -> Result<Vec<EventInfo<I>>, EventError>;
}

0 comments on commit 351da4d

Please sign in to comment.