diff --git a/crates/builder-api/api/v0_1/submit.toml b/crates/builder-api/api/v0_1/submit.toml index 929ec45854..a3c56b8491 100644 --- a/crates/builder-api/api/v0_1/submit.toml +++ b/crates/builder-api/api/v0_1/submit.toml @@ -44,3 +44,13 @@ Submit a list of transactions to builder's private mempool." Returns the corresponding list of transaction hashes """ + +[route.get_txn_stat] +PATH = ["get_txn_stat/:transaction_hash"] +METHOD = "GET" +":transaction_hash" = "TaggedBase64" +DOC = """ +Get the transactions's status. + +Returns "pending", "sequenced" or "rejected" with error. +""" \ No newline at end of file diff --git a/crates/builder-api/src/v0_1/builder.rs b/crates/builder-api/src/v0_1/builder.rs index 0e1066a8ba..7e31a27335 100644 --- a/crates/builder-api/src/v0_1/builder.rs +++ b/crates/builder-api/src/v0_1/builder.rs @@ -50,6 +50,15 @@ pub enum BuildError { Error(String), } +/// Enum to keep track on status of a transactions +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum TransactionStatus { + Pending, + Sequenced { block: u64, offset: u64 }, + Rejected { reason: String }, // Rejection reason is in the String format + Unknown, +} + #[derive(Clone, Debug, Error, Deserialize, Serialize)] pub enum Error { #[error("Error processing request: {0}")] @@ -70,6 +79,8 @@ pub enum Error { TxnSubmit(BuildError), #[error("Error getting builder address: {0}")] BuilderAddress(#[from] BuildError), + #[error("Error getting transaction status: {0}")] + TxnStatGet(BuildError), #[error("Custom error {status}: {message}")] Custom { message: String, status: StatusCode }, } @@ -95,6 +106,7 @@ impl tide_disco::error::Error for Error { Error::TxnSubmit { .. } => StatusCode::INTERNAL_SERVER_ERROR, Error::Custom { .. } => StatusCode::INTERNAL_SERVER_ERROR, Error::BuilderAddress { .. } => StatusCode::INTERNAL_SERVER_ERROR, + Error::TxnStatGet { .. } => StatusCode::BAD_REQUEST, } } } @@ -177,6 +189,12 @@ where .get("builder_address", |_req, state| { async move { state.builder_address().await.map_err(|e| e.into()) }.boxed() })?; + // .get("transaction_status", |req, state| { + // async move { + // let tx_hash = req.blob_param("transaction_hash")?; + // state.claim_tx_status(tx_hash).await.map_err(|e| e.into()) + // }.boxed() + // })? Ok(api) } @@ -216,6 +234,20 @@ where Ok(hashes) } .boxed() + })? + .at("get_txn_stat", |req: RequestParams, state| { + async move { + let tx = req + .body_auto::<::Transaction, Ver>(Ver::instance()) + .map_err(Error::TxnUnpack)?; + let hash = tx.commit(); + state + .claim_tx_status(hash) + .await + .map_err(Error::TxnStatGet)?; + Ok(hash) + } + .boxed() })?; Ok(api) } diff --git a/crates/builder-api/src/v0_1/data_source.rs b/crates/builder-api/src/v0_1/data_source.rs index c36b457623..e0e293a94f 100644 --- a/crates/builder-api/src/v0_1/data_source.rs +++ b/crates/builder-api/src/v0_1/data_source.rs @@ -14,7 +14,7 @@ use hotshot_types::{ use super::{ block_info::{AvailableBlockData, AvailableBlockHeaderInput, AvailableBlockInfo}, - builder::BuildError, + builder::{BuildError, TransactionStatus}, }; #[async_trait] @@ -48,6 +48,9 @@ pub trait BuilderDataSource { /// To get the builder's address async fn builder_address(&self) -> Result; + + // To get the status of submitted transaction + // async fn claim_tx_status(&self, txn_hash: Commitment) -> Result; } #[async_trait] @@ -59,4 +62,9 @@ where &self, txns: Vec<::Transaction>, ) -> Result::Transaction>>, BuildError>; + + async fn claim_tx_status( + &self, + txn_hash: Commitment<::Transaction>, + ) -> Result; } diff --git a/crates/task-impls/src/builder.rs b/crates/task-impls/src/builder.rs index fba215217b..b7dfd3bd7d 100644 --- a/crates/task-impls/src/builder.rs +++ b/crates/task-impls/src/builder.rs @@ -54,6 +54,7 @@ impl From for BuilderClientError { BuildError::Missing => Self::BlockMissing, BuildError::Error(message) => Self::Api(message), }, + BuilderApiError::TxnStatGet(source) => Self::Api(source.to_string()), } } } diff --git a/crates/testing/src/block_builder/random.rs b/crates/testing/src/block_builder/random.rs index cea9e40328..0b73112692 100644 --- a/crates/testing/src/block_builder/random.rs +++ b/crates/testing/src/block_builder/random.rs @@ -19,12 +19,16 @@ use async_broadcast::{broadcast, Sender}; use async_compatibility_layer::art::{async_sleep, async_spawn}; use async_lock::RwLock; use async_trait::async_trait; +use committable::Commitment; use futures::{future::BoxFuture, Stream, StreamExt}; use hotshot::types::{Event, EventType, SignatureKey}; -use hotshot_builder_api::v0_1::{ - block_info::{AvailableBlockData, AvailableBlockHeaderInput, AvailableBlockInfo}, - builder::BuildError, - data_source::BuilderDataSource, +use hotshot_builder_api::{ + v0_1::{ + block_info::{AvailableBlockData, AvailableBlockHeaderInput, AvailableBlockInfo}, + builder::BuildError, + data_source::BuilderDataSource, + }, + v0_2::builder::TransactionStatus, }; use hotshot_example_types::block_types::TestTransaction; use hotshot_types::{ @@ -328,4 +332,8 @@ impl BuilderDataSource for RandomBuilderSource { async fn builder_address(&self) -> Result { Ok(self.pub_key.clone()) } + + // async fn claim_tx_status(&self, _txn_hash: Commitment) -> Result { + // Ok(TransactionStatus::Unknown) // Sishan: place holder + // } } diff --git a/crates/testing/src/block_builder/simple.rs b/crates/testing/src/block_builder/simple.rs index e1207a4fc2..0f0b99469b 100644 --- a/crates/testing/src/block_builder/simple.rs +++ b/crates/testing/src/block_builder/simple.rs @@ -25,8 +25,8 @@ use hotshot::{ types::{Event, EventType, SignatureKey}, }; use hotshot_builder_api::{ - v0_1, v0_1::{ + self, block_info::{AvailableBlockData, AvailableBlockHeaderInput, AvailableBlockInfo}, builder::{BuildError, Error, Options}, }, @@ -316,6 +316,10 @@ where async fn builder_address(&self) -> Result { Ok(self.pub_key.clone()) } + + // async fn claim_tx_status(&self, _txn_hash: Commitment) -> Result { + // Ok(TransactionStatus::Unknown) // Sishan: place holder + // } } impl SimpleBuilderSource {