diff --git a/Cargo.lock b/Cargo.lock index 1861325277..7f8825a2e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3025,8 +3025,10 @@ dependencies = [ "sha2 0.10.8", "snafu 0.8.4", "static_assertions", + "surf-disco", "tagged-base64", "thiserror", + "tide-disco", "time 0.3.36", "tracing", "trait-set", diff --git a/types/Cargo.toml b/types/Cargo.toml index c1a9acb53a..b6e982d8ef 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -57,3 +57,5 @@ tracing = { workspace = true } trait-set = { workspace = true } url = { workspace = true } vbs = { workspace = true } +surf-disco = { workspace = true } +tide-disco = { workspace = true } diff --git a/types/src/v0/impls/auction.rs b/types/src/v0/impls/auction.rs index ac4e03a35b..7400da9301 100644 --- a/types/src/v0/impls/auction.rs +++ b/types/src/v0/impls/auction.rs @@ -1,21 +1,26 @@ use crate::{ eth_signature_key::{EthKeyPair, SigningError}, v0_1::ValidatedState, - v0_3::{BidTx, BidTxBody, FullNetworkTx}, + v0_3::{ + AuctionResults, AuctionResultsProvider, BidTx, BidTxBody, FullNetworkTx, HasUrls, + SolverClient, + }, FeeAccount, FeeAmount, FeeError, FeeInfo, NamespaceId, }; +use async_trait::async_trait; use committable::{Commitment, Committable}; use ethers::types::Signature; use hotshot_types::{ data::ViewNumber, traits::{ - auction_results_provider::HasUrl, node_implementation::ConsensusTime, + node_implementation::{ConsensusTime, NodeType}, signature_key::BuilderSignatureKey, }, }; use std::str::FromStr; use thiserror::Error; use url::Url; +use vbs::version::StaticVersion; impl FullNetworkTx { /// Proxy for `execute` method of each transaction variant. @@ -98,6 +103,11 @@ impl BidTxBody { pub fn with_url(self, url: Url) -> Self { Self { url, ..self } } + + /// Get the cloned `url` field. + fn url(&self) -> Url { + self.url.clone() + } } impl Default for BidTxBody { @@ -213,19 +223,49 @@ impl BidTx { pub fn account(&self) -> FeeAccount { self.body.account } -} - -impl HasUrl for BidTx { /// Get the `url` field from the body. fn url(&self) -> Url { self.body.url() } } -impl HasUrl for BidTxBody { - /// Get the cloned `url` field. - fn url(&self) -> Url { - self.url.clone() +impl AuctionResults { + pub fn winning_bids(&self) -> &[BidTx] { + &self.winning_bids + } + pub fn reserve_bids(&self) -> &[(NamespaceId, Url)] { + &self.reserve_bids + } +} + +impl HasUrls for AuctionResults { + fn urls(&self) -> Vec { + self.winning_bids() + .iter() + .map(|bid| bid.url()) + .chain(self.reserve_bids().iter().map(|bid| bid.1.clone())) + .collect() + } +} + +const SOLVER_URL: &str = "https://solver:1234"; +type Ver = StaticVersion<0, 3>; + +#[async_trait] +impl AuctionResultsProvider for AuctionResults { + type AuctionResult = AuctionResults; + + /// Fetch the auction results. + async fn fetch_auction_result( + &self, + view_number: TYPES::Time, + ) -> anyhow::Result { + let resp = SolverClient::::new(Url::from_str(SOLVER_URL).unwrap()) + .get::(&format!("/v0/api/auction_results/{}", *view_number)) + .send() + .await + .unwrap(); + Ok(resp) } } diff --git a/types/src/v0/v0_3/auction.rs b/types/src/v0/v0_3/auction.rs index a44e368006..1850181ef7 100644 --- a/types/src/v0/v0_3/auction.rs +++ b/types/src/v0/v0_3/auction.rs @@ -1,8 +1,13 @@ use crate::{FeeAccount, FeeAmount, NamespaceId}; +use anyhow::Result; +use async_trait::async_trait; use ethers::types::Signature; -use hotshot_types::data::ViewNumber; -use serde::{Deserialize, Serialize}; +use hotshot_types::{data::ViewNumber, traits::node_implementation::NodeType}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use surf_disco::Request; +use tide_disco::error::ServerError; use url::Url; +use vbs::version::StaticVersionType; #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)] /// Wrapper enum for Full Network Transactions. Each transaction type @@ -40,7 +45,24 @@ pub struct BidTxBody { pub(crate) namespaces: Vec, } -/// The results of an Auction +// TODO this will be in HotShot +pub trait HasUrls { + /// Returns the builer url associated with the datatype + fn urls(&self) -> Vec; +} + +// TODO this will be in HotShot +#[async_trait] +pub trait AuctionResultsProvider: Send + Sync + Clone { + /// The AuctionSolverResult is a type that holds the data associated with a particular solver + /// run, for a particular view. + type AuctionResult: HasUrls; + + /// Fetches the auction result for a view. Does not cache the result, + /// subsequent calls will invoke additional wasted calls. + async fn fetch_auction_result(&self, view_number: TYPES::Time) -> Result; +} + #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)] pub struct AuctionResults { /// view number the results are for @@ -50,3 +72,24 @@ pub struct AuctionResults { /// A list of reserve sequencers being used pub(crate) reserve_bids: Vec<(NamespaceId, Url)>, } + +type SurfClient = surf_disco::Client; + +#[derive(Debug, Clone)] +pub struct SolverClient { + agent: SurfClient, + _url: Url, +} + +impl SolverClient { + pub fn new(url: Url) -> Self { + Self { + agent: SurfClient::new(url.clone()), + _url: url, + } + } + + pub fn get(&self, route: &str) -> Request { + self.agent.get(route) + } +} diff --git a/types/src/v0/v0_3/mod.rs b/types/src/v0/v0_3/mod.rs index f8a6ef1b6a..43c70f4f18 100644 --- a/types/src/v0/v0_3/mod.rs +++ b/types/src/v0/v0_3/mod.rs @@ -20,5 +20,7 @@ pub const VERSION: Version = Version { major: 0, minor: 3 }; mod auction; mod header; -pub use auction::{AuctionResults, BidTx, BidTxBody, FullNetworkTx}; +pub use auction::{ + AuctionResults, AuctionResultsProvider, BidTx, BidTxBody, FullNetworkTx, HasUrls, SolverClient, +}; pub use header::Header;