@@ -7,12 +7,13 @@ use eth_types::{
77use eth2_utility:: types:: { ClientMode , InitInput } ;
88use indicatif:: { ProgressBar , ProgressState , ProgressStyle } ;
99use near_crypto:: Signer ;
10- use near_fetch:: ops:: Function ;
10+ use near_fetch:: ops:: { Function , Transaction } ;
1111use near_fetch:: { Client , ops:: MAX_GAS } ;
1212use near_gas:: NearGas ;
1313use near_primitives:: types:: AccountId ;
1414use near_primitives:: views:: FinalExecutionStatus ;
1515use std:: fmt:: Write ;
16+ use tokio:: time:: { Duration , timeout} ;
1617use tracing:: info;
1718
1819use 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
2931impl 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" )
0 commit comments