@@ -63,7 +63,7 @@ type FeeData struct {
6363	gasLimit  uint64 
6464}
6565
66- // Sender Transaction sender to send transaction to l1/l2 geth  
66+ // Sender Transaction sender to send transaction to l1/l2 
6767type  Sender  struct  {
6868	config             * config.SenderConfig 
6969	gethClient         * gethclient.Client 
@@ -105,30 +105,7 @@ func NewSender(ctx context.Context, config *config.SenderConfig, signerConfig *c
105105		return  nil , fmt .Errorf ("failed to create transaction signer, err: %w" , err )
106106	}
107107
108- 	// Get maximum nonce from database 
109- 	dbNonce , err  :=  orm .NewPendingTransaction (db ).GetMaxNonceBySenderAddress (ctx , transactionSigner .GetAddr ().Hex ())
110- 	if  err  !=  nil  {
111- 		return  nil , fmt .Errorf ("failed to get max nonce from database for address %s, err: %w" , transactionSigner .GetAddr ().Hex (), err )
112- 	}
113- 
114- 	// Get pending nonce from the client 
115- 	pendingNonce , err  :=  client .PendingNonceAt (ctx , transactionSigner .GetAddr ())
116- 	if  err  !=  nil  {
117- 		return  nil , fmt .Errorf ("failed to get pending nonce for address %s, err: %w" , transactionSigner .GetAddr ().Hex (), err )
118- 	}
119- 
120- 	// Take the maximum of both values 
121- 	var  finalNonce  uint64 
122- 	if  pendingNonce  >  dbNonce  {
123- 		finalNonce  =  pendingNonce 
124- 	} else  {
125- 		finalNonce  =  dbNonce 
126- 	}
127- 
128- 	log .Info ("nonce initialization" , "address" , transactionSigner .GetAddr ().Hex (), "pendingNonce" , pendingNonce , "dbNonce" , dbNonce , "finalNonce" , finalNonce )
129- 
130- 	transactionSigner .SetNonce (finalNonce )
131- 
108+ 	// Create sender instance first and then initialize nonce 
132109	sender  :=  & Sender {
133110		ctx :                   ctx ,
134111		config :                config ,
@@ -144,8 +121,13 @@ func NewSender(ctx context.Context, config *config.SenderConfig, signerConfig *c
144121		service :               service ,
145122		senderType :            senderType ,
146123	}
147- 	sender .metrics  =  initSenderMetrics (reg )
148124
125+ 	// Initialize nonce using the new method 
126+ 	if  err  :=  sender .resetNonce (); err  !=  nil  {
127+ 		return  nil , fmt .Errorf ("failed to reset nonce: %w" , err )
128+ 	}
129+ 
130+ 	sender .metrics  =  initSenderMetrics (reg )
149131	go  sender .loop (ctx )
150132
151133	return  sender , nil 
@@ -259,7 +241,10 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data
259241		// Check if contain nonce, and reset nonce 
260242		// only reset nonce when it is not from resubmit 
261243		if  strings .Contains (err .Error (), "nonce too low" ) {
262- 			s .resetNonce (context .Background ())
244+ 			if  err  :=  s .resetNonce (); err  !=  nil  {
245+ 				log .Warn ("failed to reset nonce after failed send transaction" , "address" , s .transactionSigner .GetAddr ().String (), "err" , err )
246+ 				return  common.Hash {}, 0 , fmt .Errorf ("failed to reset nonce after failed send transaction, err: %w" , err )
247+ 			}
263248		}
264249		return  common.Hash {}, 0 , fmt .Errorf ("failed to send transaction, err: %w" , err )
265250	}
@@ -344,14 +329,46 @@ func (s *Sender) createTx(feeData *FeeData, target *common.Address, data []byte,
344329	return  signedTx , nil 
345330}
346331
332+ // initializeNonce initializes the nonce by taking the maximum of database nonce and pending nonce. 
333+ func  (s  * Sender ) initializeNonce () (uint64 , error ) {
334+ 	// Get maximum nonce from database 
335+ 	dbNonce , err  :=  s .pendingTransactionOrm .GetMaxNonceBySenderAddress (s .ctx , s .transactionSigner .GetAddr ().Hex ())
336+ 	if  err  !=  nil  {
337+ 		return  0 , fmt .Errorf ("failed to get max nonce from database for address %s, err: %w" , s .transactionSigner .GetAddr ().Hex (), err )
338+ 	}
339+ 
340+ 	// Get pending nonce from the client 
341+ 	pendingNonce , err  :=  s .client .PendingNonceAt (s .ctx , s .transactionSigner .GetAddr ())
342+ 	if  err  !=  nil  {
343+ 		return  0 , fmt .Errorf ("failed to get pending nonce for address %s, err: %w" , s .transactionSigner .GetAddr ().Hex (), err )
344+ 	}
345+ 
346+ 	// Take the maximum of pending nonce and (db nonce + 1) 
347+ 	// Database stores the used nonce, so the next available nonce should be dbNonce + 1 
348+ 	// When dbNonce is -1 (no records), dbNonce + 1 = 0, which is correct 
349+ 	nextDbNonce  :=  uint64 (dbNonce  +  1 )
350+ 	var  finalNonce  uint64 
351+ 	if  pendingNonce  >  nextDbNonce  {
352+ 		finalNonce  =  pendingNonce 
353+ 	} else  {
354+ 		finalNonce  =  nextDbNonce 
355+ 	}
356+ 
357+ 	log .Info ("nonce initialization" , "address" , s .transactionSigner .GetAddr ().Hex (), "maxDbNonce" , dbNonce , "nextDbNonce" , nextDbNonce , "pendingNonce" , pendingNonce , "finalNonce" , finalNonce )
358+ 
359+ 	return  finalNonce , nil 
360+ }
361+ 
347362// resetNonce reset nonce if send signed tx failed. 
348- func  (s  * Sender ) resetNonce (ctx  context. Context )  {
349- 	nonce , err  :=  s .client . PendingNonceAt ( ctx ,  s . transactionSigner . GetAddr () )
363+ func  (s  * Sender ) resetNonce ()  error  {
364+ 	nonce , err  :=  s .initializeNonce ( )
350365	if  err  !=  nil  {
351- 		log .Warn ("failed to reset nonce" , "address" , s .transactionSigner .GetAddr ().String (), "err" , err )
352- 		return 
366+ 		log .Error ("failed to reset nonce" , "address" , s .transactionSigner .GetAddr ().String (), "err" , err )
367+ 		return   fmt . Errorf ( "failed to reset nonce, err: %w" ,  err ) 
353368	}
369+ 	log .Info ("reset nonce" , "address" , s .transactionSigner .GetAddr ().String (), "nonce" , nonce )
354370	s .transactionSigner .SetNonce (nonce )
371+ 	return  nil 
355372}
356373
357374func  (s  * Sender ) createReplacingTransaction (tx  * gethTypes.Transaction , baseFee , blobBaseFee  uint64 ) (* gethTypes.Transaction , error ) {
0 commit comments