From 183d58b02738a6e68b5ec8d860a4fbdf1cb87bee Mon Sep 17 00:00:00 2001 From: Nathan F Yospe Date: Tue, 27 Feb 2024 14:44:34 -0500 Subject: [PATCH] Updates for the API --- api/builder.toml | 32 +++++++++++++++++++----- api/submit.toml | 33 +++++++++++++++++++++++++ src/block_info.rs | 9 +++++++ src/builder.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++-- src/data_source.rs | 16 ++++++++++-- 5 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 api/submit.toml diff --git a/api/builder.toml b/api/builder.toml index 7db1070..d5bd8ae 100644 --- a/api/builder.toml +++ b/api/builder.toml @@ -1,10 +1,28 @@ # Copyright (c) 2024 Espresso Systems (espressosys.com) # This file is part of the HotShot Builder Protocol. # -# TODO: License +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. [meta] -NAME = "hs-builder" +NAME = "hs-builder-get" DESCRIPTION = "" FORMAT_VERSION = "0.1.0" @@ -36,10 +54,12 @@ Get the specified block candidate. Returns application-specific encoded transactions type """ -[route.submit_txn] -PATH = ["submittxn/:txn"] -":txn" = "TaggedBase64" +[route.claim_header] +PATH = ["claimheader/:block_hash/:signature"] +":block_hash" = "TaggedBase64" +":signature" = "TaggedBase64" DOC = """ +Get the specified block candidate. -Returns --- +Returns application-specific block header type """ diff --git a/api/submit.toml b/api/submit.toml new file mode 100644 index 0000000..a9d1db4 --- /dev/null +++ b/api/submit.toml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Espresso Systems (espressosys.com) +# This file is part of the HotShot Builder Protocol. +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +[meta] +NAME = "hs-builder-submit" +DESCRIPTION = "" +FORMAT_VERSION = "0.1.0" + +[route.submit_txn] +PATH = ["/submit"] +METHOD = "POST" +DOC = "Submit a transaction to builder's private mempool." diff --git a/src/block_info.rs b/src/block_info.rs index 3d40411..2649527 100644 --- a/src/block_info.rs +++ b/src/block_info.rs @@ -25,3 +25,12 @@ pub struct AvailableBlockData { pub sender: ::SignatureKey, pub _phantom: PhantomData, } + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] +#[serde(bound = "")] +pub struct AvailableBlockHeader { + pub block_header: ::BlockHeader, + pub signature: <::SignatureKey as SignatureKey>::PureAssembledSignatureType, + pub sender: ::SignatureKey, + pub _phantom: PhantomData, +} diff --git a/src/builder.rs b/src/builder.rs index 7291e14..4d04a8d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -10,9 +10,16 @@ use hotshot_types::{ use serde::{Deserialize, Serialize}; use snafu::{ResultExt, Snafu}; use tagged_base64::TaggedBase64; -use tide_disco::{api::ApiError, method::ReadState, Api, RequestError, StatusCode}; +use tide_disco::{ + api::ApiError, + method::{ReadState, WriteState}, + Api, RequestError, StatusCode, +}; -use crate::{api::load_api, data_source::BuilderDataSource}; +use crate::{ + api::load_api, + data_source::{AcceptsTxnSubmits, BuilderDataSource}, +}; #[derive(Args, Default)] pub struct Options { @@ -61,6 +68,16 @@ pub enum Error { source: BuildError, resource: String, }, + #[snafu(display("error unpacking transaction: {source}"))] + #[from(ignore)] + TxnUnpack { + source: RequestError, + }, + #[snafu(display("error submitting transaction: {source}"))] + #[from(ignore)] + TxnSubmit { + source: BuildError, + }, Custom { message: String, status: StatusCode, @@ -84,6 +101,8 @@ impl tide_disco::error::Error for Error { BuildError::Missing => StatusCode::NotFound, BuildError::Error { .. } => StatusCode::InternalServerError, }, + Error::TxnUnpack { .. } => StatusCode::BadRequest, + Error::TxnSubmit { .. } => StatusCode::InternalServerError, Error::Custom { .. } => StatusCode::InternalServerError, } } @@ -130,6 +149,44 @@ where }) } .boxed() + })? + .get("claim_header", |req, state| { + async move { + let hash: BuilderCommitment = req.blob_param("block_hash")?; + let signature = req.blob_param("signature")?; + state + .claim_block_header(&hash, &signature) + .await + .context(BlockClaimSnafu { + resource: hash.to_string(), + }) + } + .boxed() + })?; + Ok(api) +} + +pub fn submit_api(options: &Options) -> Result, ApiError> +where + State: 'static + Send + Sync + WriteState, + ::State: Send + Sync + AcceptsTxnSubmits, + Types: NodeType, +{ + let mut api = load_api::( + options.api_path.as_ref(), + include_str!("../api/submit.toml"), + options.extensions.clone(), + )?; + api.with_version("0.0.1".parse().unwrap()) + .post("submit_txn", |req, state| { + async move { + let tx = req + .body_auto::<::Transaction>() + .context(TxnUnpackSnafu)?; + state.submit_txn(tx).await.context(TxnSubmitSnafu)?; + Ok(()) + } + .boxed() })?; Ok(api) } diff --git a/src/data_source.rs b/src/data_source.rs index 2623e21..d969979 100644 --- a/src/data_source.rs +++ b/src/data_source.rs @@ -7,7 +7,7 @@ use hotshot_types::{ use tagged_base64::TaggedBase64; use crate::{ - block_info::{AvailableBlockData, AvailableBlockInfo}, + block_info::{AvailableBlockData, AvailableBlockHeader, AvailableBlockInfo}, builder::BuildError, }; @@ -27,5 +27,17 @@ where block_hash: &BuilderCommitment, signature: &<::SignatureKey as SignatureKey>::PureAssembledSignatureType, ) -> Result, BuildError>; - async fn submit_txn(&self, txn: ::Transaction) -> Result<(), BuildError>; + async fn claim_block_header( + &self, + block_hash: &BuilderCommitment, + signature: &<::SignatureKey as SignatureKey>::PureAssembledSignatureType, + ) -> Result, BuildError>; +} + +#[async_trait] +pub trait AcceptsTxnSubmits +where + I: NodeType, +{ + async fn submit_txn(&mut self, txn: ::Transaction) -> Result<(), BuildError>; }