@@ -196,7 +196,7 @@ pub async fn submit_tx_with_backoff<T: Middleware + NonceManaged + 'static>(
196
196
197
197
#[ allow( clippy:: large_enum_variant) ]
198
198
pub enum SubmitTxError < T : Middleware + NonceManaged + ' static > {
199
- GasUsageEstimateError ( ContractError < T > ) ,
199
+ GasUsageEstimateError ( TypedTransaction , ContractError < T > ) ,
200
200
GasLimitExceeded { estimate : U256 , limit : U256 } ,
201
201
GasPriceEstimateError ( <T as Middleware >:: Error ) ,
202
202
SubmissionError ( TypedTransaction , <T as Middleware >:: Error ) ,
@@ -211,8 +211,8 @@ where
211
211
{
212
212
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
213
213
match self {
214
- SubmitTxError :: GasUsageEstimateError ( e) => {
215
- write ! ( f, "Error estimating gas for reveal: {e:?}" )
214
+ SubmitTxError :: GasUsageEstimateError ( tx , e) => {
215
+ write ! ( f, "Error estimating gas for reveal: Tx:{tx:?}, Error: {e:?}" )
216
216
}
217
217
SubmitTxError :: GasLimitExceeded { estimate, limit } => write ! (
218
218
f,
@@ -247,7 +247,16 @@ pub async fn submit_tx<T: Middleware + NonceManaged + 'static>(
247
247
// A value of 100 submits the tx with the same fee as the estimate.
248
248
fee_estimate_multiplier_pct : u64 ,
249
249
) -> Result < TransactionReceipt , backoff:: Error < SubmitTxError < T > > > {
250
+ // Estimate the gas *before* filling the transaction. Filling the transaction increments the nonce of the
251
+ // provider. If we can't send the transaction (because the gas estimation fails), then the nonce will be
252
+ // out of sync with the one on-chain, causing subsequent transactions to fail.
253
+ let gas: U256 = call. estimate_gas ( ) . await . map_err ( |e| {
254
+ backoff:: Error :: transient ( SubmitTxError :: GasUsageEstimateError ( call. tx . clone ( ) , e) )
255
+ } ) ?;
256
+
250
257
let mut transaction = call. tx . clone ( ) ;
258
+ // Setting the gas here avoids a redundant call to estimate_gas within the Provider's fill_transaction method.
259
+ transaction. set_gas ( gas) ;
251
260
252
261
// manually fill the tx with the gas price info, so we can log the details in case of error
253
262
client
@@ -258,6 +267,7 @@ pub async fn submit_tx<T: Middleware + NonceManaged + 'static>(
258
267
if let Some ( e) = e. as_error_response ( ) {
259
268
if let Some ( e) = e. as_revert_data ( ) {
260
269
return backoff:: Error :: transient ( SubmitTxError :: GasUsageEstimateError (
270
+ transaction. clone ( ) ,
261
271
ContractError :: Revert ( e. clone ( ) ) ,
262
272
) ) ;
263
273
}
0 commit comments