Skip to content
This repository has been archived by the owner on Jun 18, 2024. It is now read-only.

Commit

Permalink
Make response's data field 'optional' (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xDmtri authored Jan 24, 2024
1 parent 1c55c16 commit 8df3eca
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 23 deletions.
14 changes: 11 additions & 3 deletions src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ pub struct Response<T> {
#[serde(untagged)]
pub enum ResponseData<R> {
Error { error: JsonRpcError },
Success { result: R },
Success { result: Option<R> },
}

impl<R> ResponseData<R> {
/// Consume response and return value
pub fn into_result(self) -> Result<R, JsonRpcError> {
pub fn into_result(self) -> Result<Option<R>, JsonRpcError> {
match self {
ResponseData::Success { result } => Ok(result),
ResponseData::Error { error } => Err(error),
Expand All @@ -102,7 +102,15 @@ mod tests {
let response: Response<u64> =
serde_json::from_str(r#"{"jsonrpc": "2.0", "result": 19, "id": 1}"#).unwrap();
assert_eq!(response.id, 1);
assert_eq!(response.data.into_result().unwrap(), 19);
assert_eq!(response.data.into_result().unwrap(), Some(19));
}

#[test]
fn deser_response_without_result() {
let response: Response<u64> =
serde_json::from_str(r#"{"jsonrpc": "2.0", "id": 1, "result": null}"#).unwrap();
assert_eq!(response.id, 1);
assert_eq!(response.data.into_result().unwrap(), None);
}

#[test]
Expand Down
55 changes: 41 additions & 14 deletions src/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ pub enum FlashbotsMiddlewareError<M: Middleware, S: Signer> {
/// An error occured in one of the middlewares.
#[error("{0}")]
MiddlewareError(M::Error),
/// Empty data for bundle simulation request.
#[error("Bundle simulation is not available")]
BundleSimError,
/// Empty data for bundle stats request.
#[error("Bundle stats are not available")]
BundleStatsError,
/// Empty data for user stats request.
#[error("User stats are not available")]
UserStatsError,
}

impl<M: Middleware, S: Signer> MiddlewareError for FlashbotsMiddlewareError<M, S> {
Expand Down Expand Up @@ -170,7 +179,8 @@ impl<M: Middleware, S: Signer> FlashbotsMiddleware<M, S> {
.unwrap_or(&self.relay)
.request("eth_callBundle", [bundle])
.await
.map_err(FlashbotsMiddlewareError::RelayError)
.map_err(FlashbotsMiddlewareError::RelayError)?
.ok_or(FlashbotsMiddlewareError::BundleSimError)
}

/// Send a bundle to the relayer.
Expand All @@ -193,18 +203,26 @@ impl<M: Middleware, S: Signer> FlashbotsMiddleware<M, S> {
return Err(FlashbotsMiddlewareError::MissingParameters);
}

let response: SendBundleResponse = self
let response: Option<SendBundleResponse> = self
.relay
.request("eth_sendBundle", [bundle])
.await
.map_err(FlashbotsMiddlewareError::RelayError)?;

Ok(PendingBundle::new(
response.bundle_hash,
bundle.block().unwrap(),
bundle.transaction_hashes(),
self.provider(),
))
match response {
Some(r) => Ok(PendingBundle::new(
r.bundle_hash,
bundle.block().unwrap(),
bundle.transaction_hashes(),
self.provider(),
)),
None => Ok(PendingBundle::new(
None,
bundle.block().unwrap(),
bundle.transaction_hashes(),
self.provider(),
)),
}
}

/// Get stats for a particular bundle.
Expand All @@ -222,7 +240,8 @@ impl<M: Middleware, S: Signer> FlashbotsMiddleware<M, S> {
}],
)
.await
.map_err(FlashbotsMiddlewareError::RelayError)
.map_err(FlashbotsMiddlewareError::RelayError)?
.ok_or(FlashbotsMiddlewareError::BundleStatsError)
}

/// Get stats for your searcher identity.
Expand All @@ -244,7 +263,8 @@ impl<M: Middleware, S: Signer> FlashbotsMiddleware<M, S> {
}],
)
.await
.map_err(FlashbotsMiddlewareError::RelayError)
.map_err(FlashbotsMiddlewareError::RelayError)?
.ok_or(FlashbotsMiddlewareError::UserStatsError)
}
}

Expand Down Expand Up @@ -407,7 +427,8 @@ impl<M: Middleware, S: Signer> BroadcasterMiddleware<M, S> {
self.simulation_relay
.request("eth_callBundle", [bundle])
.await
.map_err(FlashbotsMiddlewareError::RelayError)
.map_err(FlashbotsMiddlewareError::RelayError)?
.ok_or(FlashbotsMiddlewareError::BundleSimError)
}

/// Broadcast a bundle to the builders.
Expand Down Expand Up @@ -438,13 +459,19 @@ impl<M: Middleware, S: Signer> BroadcasterMiddleware<M, S> {
.map(|relay| async move {
let response = relay.request("eth_sendBundle", [bundle]).await;
response
.map(|r: SendBundleResponse| {
PendingBundle::new(
.map(|response: Option<SendBundleResponse>| match response {
Some(r) => PendingBundle::new(
r.bundle_hash,
bundle.block().unwrap(),
bundle.transaction_hashes(),
self.provider(),
)
),
None => PendingBundle::new(
None,
bundle.block().unwrap(),
bundle.transaction_hashes(),
self.provider(),
),
})
.map_err(FlashbotsMiddlewareError::RelayError)
})
Expand Down
8 changes: 4 additions & 4 deletions src/pending_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use thiserror::Error;
/// [fb_debug]: https://docs.flashbots.net/flashbots-auction/searchers/faq/#why-didnt-my-transaction-get-included
#[pin_project]
pub struct PendingBundle<'a, P> {
pub bundle_hash: BundleHash,
pub bundle_hash: Option<BundleHash>,
pub block: U64,
pub transactions: Vec<TxHash>,
provider: &'a Provider<P>,
Expand All @@ -38,7 +38,7 @@ pub struct PendingBundle<'a, P> {

impl<'a, P: JsonRpcClient> PendingBundle<'a, P> {
pub fn new(
bundle_hash: BundleHash,
bundle_hash: Option<BundleHash>,
block: U64,
transactions: Vec<TxHash>,
provider: &'a Provider<P>,
Expand All @@ -55,13 +55,13 @@ impl<'a, P: JsonRpcClient> PendingBundle<'a, P> {

/// Get the bundle hash for this pending bundle.
#[deprecated(note = "use the bundle_hash field instead")]
pub fn bundle_hash(&self) -> BundleHash {
pub fn bundle_hash(&self) -> Option<BundleHash> {
self.bundle_hash
}
}

impl<'a, P: JsonRpcClient> Future for PendingBundle<'a, P> {
type Output = Result<BundleHash, PendingBundleError>;
type Output = Result<Option<BundleHash>, PendingBundleError>;

fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
let this = self.project();
Expand Down
4 changes: 2 additions & 2 deletions src/relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl<S: Signer> Relay<S> {
&self,
method: &str,
params: T,
) -> Result<R, RelayError<S>> {
) -> Result<Option<R>, RelayError<S>> {
let next_id = self.id.load(Ordering::SeqCst) + 1;
self.id.store(next_id, Ordering::SeqCst);

Expand Down Expand Up @@ -139,7 +139,7 @@ impl<S: Signer + Clone> Clone for Relay<S> {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct SendBundleResponse {
pub(crate) bundle_hash: BundleHash,
pub(crate) bundle_hash: Option<BundleHash>,
}

#[derive(Serialize)]
Expand Down

0 comments on commit 8df3eca

Please sign in to comment.