From 36cfe502376946c5da94f36a5cfd9c3f51fabb53 Mon Sep 17 00:00:00 2001 From: Himanshu Goyal Date: Tue, 12 Mar 2024 11:44:53 -0400 Subject: [PATCH 1/5] refere hotshot-types --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5ed0812..68a0d21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "hs-builder-api" +name = "hotshot-events-service" version = "0.1.1" edition = "2021" @@ -10,7 +10,7 @@ async-trait = "0.1" clap = { version = "4.4", features = ["derive", "env"] } derive_more = "0.99" futures = "0.3" -hotshot-types = { git = "https://github.com/EspressoSystems/HotShot.git", tag = "0.5.21" } +hotshot-types = { git = "https://github.com/EspressoSystems/hotshot-types.git", tag = "v0.1.0" } serde = { version = "1.0", features = ["derive"] } snafu = { version = "0.7", features = ["backtraces"] } tagged-base64 = { git = "https://github.com/EspressoSystems/tagged-base64", tag = "0.3.4" } From 669da8e66860db26d4349d833fb4cbde183424c1 Mon Sep 17 00:00:00 2001 From: Himanshu Goyal Date: Tue, 12 Mar 2024 11:47:21 -0400 Subject: [PATCH 2/5] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f955e4..ccf6abe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # hotshot-events-service -Minimal dependencies shared API definitions for Internal HotShot Events +Minimal dependencies shared API definitions to serve Internal HotShot Events # HotShot Consensus Module From 34cbb2cf2ca603015380feeeedb090327075f233 Mon Sep 17 00:00:00 2001 From: Himanshu Goyal Date: Tue, 12 Mar 2024 12:46:08 -0400 Subject: [PATCH 3/5] Add api specs --- src/events_info.rs | 26 ++++++++++++++++++++++++++ src/events_source.rs | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/events_info.rs create mode 100644 src/events_source.rs diff --git a/src/events_info.rs b/src/events_info.rs new file mode 100644 index 0000000..dd6254b --- /dev/null +++ b/src/events_info.rs @@ -0,0 +1,26 @@ +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 { + pub event: Event, + pub signature: <::SignatureKey as SignatureKey>::PureAssembledSignatureType, + pub sender: ::SignatureKey, + pub _phantom: PhantomData, +} + +#[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 }, +} diff --git a/src/events_source.rs b/src/events_source.rs new file mode 100644 index 0000000..6819641 --- /dev/null +++ b/src/events_source.rs @@ -0,0 +1,18 @@ +use std::{hash::Hash, marker::PhantomData}; + +use hotshot_types::event::Event; +use serde::{Deserialize, Serialize}; + +use crate::{events_info::{EventInfo, EventError}}; + +#[async_trait] +pub trait EventsSource +where + I: NodeType, + <::SignatureKey as SignatureKey>::PureAssembledSignatureType: + for<'a> TryFrom<&'a TaggedBase64> + Into, +{ + async fn get_available_hotshot_events( + &self, + ) -> Result>, EventError>; +} \ No newline at end of file From 351da4db5a62433a726766a2f8b060e7a7ca7a03 Mon Sep 17 00:00:00 2001 From: Himanshu Goyal Date: Tue, 12 Mar 2024 13:09:08 -0400 Subject: [PATCH 4/5] define api --- src/events.rs | 123 +++++++++++++++++++++++++++++++++++++++++++ src/events_info.rs | 15 +----- src/events_source.rs | 1 + 3 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 src/events.rs diff --git a/src/events.rs b/src/events.rs new file mode 100644 index 0000000..1e851f6 --- /dev/null +++ b/src/events.rs @@ -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, + + /// 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, +} + +#[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(options: &Options) -> Result, ApiError> +where + State: 'static + Send + Sync + ReadState, + ::State: Send + Sync + BuilderDataSource, + Types: NodeType, + <::SignatureKey as SignatureKey>::PureAssembledSignatureType: + for<'a> TryFrom<&'a TaggedBase64> + Into + Display, + for<'a> <<::SignatureKey as SignatureKey>::PureAssembledSignatureType as TryFrom< + &'a TaggedBase64, + >>::Error: Display, +{ + let mut api = load_api::( + 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) +} \ No newline at end of file diff --git a/src/events_info.rs b/src/events_info.rs index dd6254b..4506e08 100644 --- a/src/events_info.rs +++ b/src/events_info.rs @@ -3,7 +3,6 @@ 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 { @@ -11,16 +10,4 @@ pub struct EventInfo { pub signature: <::SignatureKey as SignatureKey>::PureAssembledSignatureType, pub sender: ::SignatureKey, pub _phantom: PhantomData, -} - -#[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 }, -} +} \ No newline at end of file diff --git a/src/events_source.rs b/src/events_source.rs index 6819641..0142d84 100644 --- a/src/events_source.rs +++ b/src/events_source.rs @@ -14,5 +14,6 @@ where { async fn get_available_hotshot_events( &self, + view_number: I::Time, ) -> Result>, EventError>; } \ No newline at end of file From c3ab5936dd352c002cf49063e409f58c7cc2db3f Mon Sep 17 00:00:00 2001 From: Himanshu Goyal Date: Tue, 12 Mar 2024 13:42:00 -0400 Subject: [PATCH 5/5] error serialise --- src/events.rs | 8 ++++---- src/events_info.rs | 13 ++++++++----- src/events_source.rs | 14 ++++++++++---- src/lib.rs | 3 +++ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/events.rs b/src/events.rs index 1e851f6..f19119d 100644 --- a/src/events.rs +++ b/src/events.rs @@ -93,7 +93,7 @@ impl tide_disco::error::Error for Error { pub fn define_api(options: &Options) -> Result, ApiError> where State: 'static + Send + Sync + ReadState, - ::State: Send + Sync + BuilderDataSource, + ::State: Send + Sync + EventsSource, Types: NodeType, <::SignatureKey as SignatureKey>::PureAssembledSignatureType: for<'a> TryFrom<&'a TaggedBase64> + Into + Display, @@ -109,11 +109,11 @@ where api.with_version("0.0.1".parse().unwrap()) .get("available_hotshot_events", |req, state| { async move { - let view_number = req.blob_param("view_number")?; + let view_number= req.blob_param("view_number")?; state - .get_available_hotshot_events(&view_number) + .get_available_hotshot_events(view_number) .await - .context(AvailableEventSnafu { + .context(EventAvailableSnafu { resource: view_number.to_string(), }) } diff --git a/src/events_info.rs b/src/events_info.rs index 4506e08..e8f549d 100644 --- a/src/events_info.rs +++ b/src/events_info.rs @@ -1,13 +1,16 @@ -use std::{hash::Hash, marker::PhantomData}; - use hotshot_types::event::Event; +use hotshot_types::{ + traits::{node_implementation::NodeType, signature_key::SignatureKey}, + utils::BuilderCommitment, + vid::VidCommitment, +}; use serde::{Deserialize, Serialize}; use snafu::{ResultExt, Snafu}; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] -#[serde(bound = "")] +use std::{hash::Hash, marker::PhantomData}; +#[derive(Clone, Debug)] pub struct EventInfo { pub event: Event, pub signature: <::SignatureKey as SignatureKey>::PureAssembledSignatureType, pub sender: ::SignatureKey, pub _phantom: PhantomData, -} \ No newline at end of file +} diff --git a/src/events_source.rs b/src/events_source.rs index 0142d84..c95e98d 100644 --- a/src/events_source.rs +++ b/src/events_source.rs @@ -1,9 +1,15 @@ +use async_trait::async_trait; use std::{hash::Hash, marker::PhantomData}; - use hotshot_types::event::Event; use serde::{Deserialize, Serialize}; - -use crate::{events_info::{EventInfo, EventError}}; +use hotshot_types::{ + traits::{node_implementation::NodeType, signature_key::SignatureKey}, + utils::BuilderCommitment, + vid::VidCommitment, + data::ViewNumber +}; +use tagged_base64::TaggedBase64; +use crate::{events_info::{EventInfo}, events::EventError}; #[async_trait] pub trait EventsSource @@ -14,6 +20,6 @@ where { async fn get_available_hotshot_events( &self, - view_number: I::Time, + view_number: ViewNumber, ) -> Result>, EventError>; } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index b32f9e2..f815fc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,4 @@ mod api; +pub mod events; +pub mod events_info; +pub mod events_source;