Skip to content

Commit 364863d

Browse files
committed
add timeout
1 parent 3003f20 commit 364863d

6 files changed

Lines changed: 116 additions & 55 deletions

File tree

relayer/relayer.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ max_headers_per_period = 1000
2121
sync_sleep_secs = 60
2222
submission_sleep_secs = 12
2323
dry_run = false
24+
fast_mode = false
2425

2526
[logging]
2627
level = "info"

relayer/src/clients/near.rs

Lines changed: 105 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ use eth_types::{
77
use eth2_utility::types::{ClientMode, InitInput};
88
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
99
use near_crypto::Signer;
10-
use near_fetch::ops::Function;
10+
use near_fetch::ops::{Function, Transaction};
1111
use near_fetch::{Client, ops::MAX_GAS};
1212
use near_gas::NearGas;
1313
use near_primitives::types::AccountId;
1414
use near_primitives::views::FinalExecutionStatus;
1515
use std::fmt::Write;
16+
use tokio::time::{Duration, timeout};
1617
use tracing::info;
1718

1819
use crate::config::RelayerConfig;
@@ -24,6 +25,7 @@ pub struct ContractClient {
2425
signer: Signer,
2526
client: Client,
2627
relayer_config: RelayerConfig,
28+
timeout_secs: u64,
2729
}
2830

2931
impl ContractClient {
@@ -33,12 +35,14 @@ impl ContractClient {
3335
signer: Signer,
3436
client: Client,
3537
relayer_config: RelayerConfig,
38+
timeout_secs: u64,
3639
) -> Self {
3740
Self {
3841
eth_light_client_account_id,
3942
signer,
4043
client,
4144
relayer_config,
45+
timeout_secs,
4246
}
4347
}
4448

@@ -47,16 +51,18 @@ impl ContractClient {
4751
where
4852
T: BorshDeserialize,
4953
{
50-
let result = self
51-
.client
52-
.view(&self.eth_light_client_account_id, method_name)
53-
.await
54-
.wrap_err(format!("Failed to call view method '{}'", method_name))?
55-
.borsh::<T>()
56-
.wrap_err(format!(
57-
"Failed to deserialize result from '{}'",
58-
method_name
59-
))?;
54+
let response = timeout(
55+
Duration::from_secs(self.timeout_secs),
56+
self.client
57+
.view(&self.eth_light_client_account_id, method_name),
58+
)
59+
.await
60+
.wrap_err("Near view time out")?
61+
.wrap_err(format!("Failed to call view method '{}'", method_name))?;
62+
let result = response.borsh::<T>().wrap_err(format!(
63+
"Failed to deserialize result from '{}'",
64+
method_name
65+
))?;
6066
Ok(result)
6167
}
6268

@@ -93,38 +99,45 @@ impl ContractClient {
9399

94100
/// Get block hash safely by block number
95101
pub async fn get_block_hash(&self, block_number: u64) -> Result<Option<H256>> {
96-
let result = self
97-
.client
98-
.view(&self.eth_light_client_account_id, "block_hash_safe")
99-
.args_borsh(block_number)
100-
.await
101-
.wrap_err(format!(
102-
"Failed to call view method 'block_hash_safe' with block number {}",
103-
block_number
104-
))?
105-
.borsh::<Option<H256>>()
106-
.wrap_err(format!(
107-
"Failed to get block hash result for block number {}",
108-
block_number
109-
))?;
102+
let response = timeout(
103+
Duration::from_secs(self.timeout_secs),
104+
self.client
105+
.view(&self.eth_light_client_account_id, "block_hash_safe")
106+
.args_borsh(block_number),
107+
)
108+
.await
109+
.wrap_err("Near view time out")?
110+
.wrap_err(format!(
111+
"Failed to call view method 'block_hash_safe' with block number {}",
112+
block_number
113+
))?;
114+
115+
let result = response.borsh::<Option<H256>>().wrap_err(format!(
116+
"Failed to get block hash result for block number {}",
117+
block_number
118+
))?;
110119
Ok(result)
111120
}
112121

113122
pub async fn submit_light_client_update(&self, update: LightClientUpdate) -> Result<()> {
114-
self.client
115-
.call(
116-
&self.signer,
117-
&self.eth_light_client_account_id,
118-
"submit_beacon_chain_light_client_update",
119-
)
120-
.args_borsh(update)
121-
.gas(NearGas::from_tgas(100))
122-
.retry_exponential(1000, 3)
123-
.transact()
124-
.await
125-
.wrap_err("Failed to send light client update transaction")?
126-
.into_result()
127-
.wrap_err("Failed to submit light client update")?;
123+
timeout(
124+
Duration::from_secs(self.timeout_secs),
125+
self.client
126+
.call(
127+
&self.signer,
128+
&self.eth_light_client_account_id,
129+
"submit_beacon_chain_light_client_update",
130+
)
131+
.args_borsh(update)
132+
.gas(NearGas::from_tgas(100))
133+
.retry_exponential(1000, 3)
134+
.transact(),
135+
)
136+
.await
137+
.wrap_err("Near call time out")?
138+
.wrap_err("Failed to send light client update transaction")?
139+
.into_result()
140+
.wrap_err("Failed to submit light client update")?;
128141

129142
info!("Light client update submitted successfully");
130143
Ok(())
@@ -174,21 +187,11 @@ impl ContractClient {
174187
batch = batch.call(function);
175188
}
176189

177-
let status = batch
178-
.retry_exponential(1000, 3)
179-
.transact()
180-
.await
181-
.wrap_err(format!(
182-
"Failed to submit execution headers batch {} of {}",
183-
batch_index + 1,
184-
total_batches
185-
))?
186-
.status;
187-
188-
if let FinalExecutionStatus::Failure(err) = status {
189-
return Err(eyre::Report::msg(
190-
format!("Fail on batch submission: {err}").to_string(),
191-
));
190+
if self.relayer_config.fast_mode {
191+
self.submit_batch_async(batch, batch_index, total_batches)
192+
.await?;
193+
} else {
194+
self.submit_batch(batch, batch_index, total_batches).await?;
192195
}
193196

194197
// Update progress bar
@@ -210,6 +213,54 @@ impl ContractClient {
210213
Ok(())
211214
}
212215

216+
pub async fn submit_batch_async(
217+
&self,
218+
batch: Transaction<'_>,
219+
batch_index: usize,
220+
total_batches: usize,
221+
) -> Result<()> {
222+
let _ = timeout(
223+
Duration::from_secs(self.timeout_secs),
224+
batch.retry_exponential(1000, 3).transact_async(),
225+
)
226+
.await
227+
.wrap_err("Near call time out")
228+
.wrap_err(format!(
229+
"Failed to submit execution headers batch {} of {}",
230+
batch_index + 1,
231+
total_batches
232+
))?;
233+
234+
Ok(())
235+
}
236+
pub async fn submit_batch(
237+
&self,
238+
batch: Transaction<'_>,
239+
batch_index: usize,
240+
total_batches: usize,
241+
) -> Result<()> {
242+
let status = timeout(
243+
Duration::from_secs(self.timeout_secs),
244+
batch.retry_exponential(1000, 3).transact(),
245+
)
246+
.await
247+
.wrap_err("Near call time out")?
248+
.wrap_err(format!(
249+
"Failed to submit execution headers batch {} of {}",
250+
batch_index + 1,
251+
total_batches
252+
))?
253+
.status;
254+
255+
if let FinalExecutionStatus::Failure(err) = status {
256+
return Err(eyre::Report::msg(
257+
format!("Fail on batch submission: {err}").to_string(),
258+
));
259+
}
260+
261+
Ok(())
262+
}
263+
213264
pub async fn init_contract(&self, init_input: InitInput) -> Result<()> {
214265
self.client
215266
.call(&self.signer, &self.eth_light_client_account_id, "init")

relayer/src/config.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ pub struct RelayerConfig {
106106
/// Enable dry run mode (don't actually submit transactions)
107107
#[serde(default)]
108108
pub dry_run: bool,
109+
110+
/// Fast mode: send headers asynchronously without waiting for the result
111+
#[serde(default)]
112+
pub fast_mode: bool,
109113
}
110114

111115
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -163,6 +167,7 @@ impl Default for RelayerConfig {
163167
submission_sleep_secs: defaults::SUBMISSION_SLEEP_SECS,
164168
max_iterations: None,
165169
dry_run: false,
170+
fast_mode: false,
166171
}
167172
}
168173
}

relayer/src/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub mod defaults {
2323
pub const TIMEOUT_SECS: u64 = 30;
2424

2525
// Execution client settings
26-
pub const EXECUTION_BATCH_SIZE: usize = 1000;
26+
pub const EXECUTION_BATCH_SIZE: usize = 500;
2727

2828
// Relayer operation settings
2929
pub const UPDATE_INTERVAL_EPOCHS: u64 = 1;

relayer/src/relay.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ impl EthRelayer {
6464
signer,
6565
client,
6666
config.relayer.clone(),
67+
config.near.timeout_secs,
6768
))
6869
}
6970

relayer/tests/common/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use eth2_utility::types::InitInput;
99
use near_crypto::{InMemorySigner, SecretKey};
1010
use near_workspaces::network::Sandbox;
1111
use near_workspaces::{Contract, Worker, cargo_near_build};
12+
use relayer::config::NearConfig;
1213
use relayer::{ContractClient, config::RelayerConfig};
1314

1415
/// Test fixture that sets up the sandbox environment and deploys the contract
@@ -57,11 +58,13 @@ impl TestFixture {
5758

5859
// Create our NearContract wrapper with default config for tests
5960
let relayer_config = RelayerConfig::default();
61+
let near_config = NearConfig::default();
6062
let near_client = ContractClient::new(
6163
contract.id().clone(),
6264
signer,
6365
near_fetch_client,
6466
relayer_config,
67+
near_config.timeout_secs,
6568
);
6669

6770
Ok(Self {

0 commit comments

Comments
 (0)