Skip to content

Commit ec757ac

Browse files
authored
feat: broadcast via multiple providers (#4)
1 parent 432911e commit ec757ac

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/tasks/submit.rs

+52-15
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ use crate::{
33
signer::LocalOrAws,
44
tasks::block::InProgressBlock,
55
};
6-
use alloy::consensus::{constants::GWEI_TO_WEI, SimpleCoder};
7-
use alloy::eips::BlockNumberOrTag;
8-
use alloy::network::{TransactionBuilder, TransactionBuilder4844};
9-
use alloy::providers::{Provider as _, WalletProvider};
10-
use alloy::rpc::types::eth::TransactionRequest;
11-
use alloy::signers::Signer;
12-
use alloy::sol_types::SolCall;
13-
use alloy::transports::TransportError;
6+
use alloy::{
7+
consensus::{constants::GWEI_TO_WEI, SimpleCoder},
8+
eips::BlockNumberOrTag,
9+
network::{TransactionBuilder, TransactionBuilder4844},
10+
providers::SendableTx,
11+
providers::{Provider as _, WalletProvider},
12+
rpc::types::eth::TransactionRequest,
13+
signers::Signer,
14+
sol_types::SolCall,
15+
transports::TransportError,
16+
};
1417
use alloy_primitives::{FixedBytes, U256};
1518
use alloy_sol_types::SolError;
16-
use eyre::eyre;
19+
use eyre::{bail, eyre};
1720
use oauth2::{
1821
basic::BasicClient, basic::BasicTokenType, reqwest::http_client, AuthUrl, ClientId,
1922
ClientSecret, EmptyExtraTokenFields, StandardTokenResponse, TokenResponse, TokenUrl,
@@ -25,6 +28,20 @@ use zenith_types::{
2528
Zenith::{self, IncorrectHostBlock},
2629
};
2730

31+
macro_rules! spawn_provider_send {
32+
($provider:expr, $tx:expr) => {
33+
{
34+
let p = $provider.clone();
35+
let t = $tx.clone();
36+
tokio::spawn(async move {
37+
p.send_tx_envelope(t).await.inspect_err(|e| {
38+
tracing::warn!(%e, "error in transaction broadcast")
39+
})
40+
})
41+
}
42+
};
43+
}
44+
2845
/// OAuth Audience Claim Name, required param by IdP for client credential grant
2946
const OAUTH_AUDIENCE_CLAIM: &str = "audience";
3047

@@ -186,21 +203,41 @@ impl SubmitTask {
186203
return Ok(ControlFlow::Skip);
187204
}
188205

206+
self.send_transaction(resp, tx).await
207+
}
208+
209+
async fn send_transaction(
210+
&self,
211+
resp: &SignResponse,
212+
tx: TransactionRequest,
213+
) -> Result<ControlFlow, eyre::Error> {
189214
tracing::debug!(
190215
host_block_number = %resp.req.host_block_number,
191216
gas_limit = %resp.req.gas_limit,
192217
"sending transaction to network"
193218
);
194219

195-
let _ = match self.provider.send_transaction(tx).await {
196-
Ok(result) => result,
197-
Err(e) => {
198-
error!(error = %e, "error sending transaction");
199-
return Ok(ControlFlow::Skip);
200-
}
220+
let SendableTx::Envelope(tx) = self.provider.fill(tx).await? else {
221+
bail!("failed to fill transaction")
201222
};
202223

224+
// Send the tx via the primary provider
225+
let fut = spawn_provider_send!(&self.provider, &tx);
226+
227+
// Spawn send_tx futures for all additional broadcast providers
228+
for provider in self.config.connect_additional_broadcast().await? {
229+
spawn_provider_send!(&provider, &tx);
230+
}
231+
232+
// question mark unwraps join error, which would be an internal panic
233+
// then if let checks for rpc error
234+
if let Err(e) = fut.await? {
235+
tracing::error!(error = %e, "Primary tx broadcast failed. Skipping transaction.");
236+
return Ok(ControlFlow::Skip);
237+
}
238+
203239
tracing::info!(
240+
tx_hash = %tx.tx_hash(),
204241
ru_chain_id = %resp.req.ru_chain_id,
205242
gas_limit = %resp.req.gas_limit,
206243
"dispatched to network"

0 commit comments

Comments
 (0)