@@ -51,6 +51,12 @@ const (
5151 // Max number of retries to perform on submission errors, such as
5252 // networking issues etc.
5353 maxSubmissionRetries = 5
54+
55+ // The possible reasons returned by `fastPathAvailable()`
56+ fastPathNoAvailability = "fast-path: conditions not satisfied"
57+ fastPathNoSpacing = "fast-path: not enough spacing elapsed"
58+ fastPathStateNonce = "fast-path: next unindexed nonce"
59+ fastPathInFlightNonce = "fast-path: next unsubmitted nonce"
5460)
5561
5662// BatchTxPool is a TxPool implementation that collects and groups transactions
@@ -145,25 +151,37 @@ func (t *txQueue) staleEntry(now time.Time, spacing time.Duration) bool {
145151 return len (t .txs ) == 0 && now .Sub (t .lastSubmittedAt ) >= (spacing * stalenessFactor )
146152}
147153
148- // validNonce compares the transaction nonce with the nonce from the local
149- // state index and the last submission activity (if any), and returns whether
150- // the transaction nonce is valid for submission.
151- func (t * txQueue ) validNonce (
154+ // fastPathAvailable checks whether there is a fast-path strategy, based on
155+ // the EOA's last activity and the given transaction nonce. If enough spacing
156+ // has elapsed since the EOA's last activity, for the given current time and
157+ // spacing duration, and the transaction nonce matches the nonce from the
158+ // local staate index or the last submission activity (if any), fast-path is
159+ // available.
160+ //
161+ // Returns the matching fast-path strategy, if any, and a boolean value which
162+ // denotes its availability.
163+ func (t * txQueue ) fastPathAvailable (
164+ now time.Time ,
165+ spacing time.Duration ,
152166 txNonce uint64 ,
153167 stateNonce uint64 ,
154- ) bool {
168+ ) (string , bool ) {
169+ if ! t .spacingElapsed (now , spacing ) {
170+ return fastPathNoSpacing , false
171+ }
172+
155173 if txNonce == stateNonce {
156- return true
174+ return fastPathStateNonce , true
157175 }
158176
159177 // a value of 0 for `lastSubmittedNonce` is legit, if this is the EOA's
160178 // first transaction ever, so we use `lastSubmittedAt` to differentiate
161179 // between Go's zero-value.
162180 if txNonce == t .lastSubmittedNonce + 1 && ! t .lastSubmittedAt .IsZero () {
163- return true
181+ return fastPathInFlightNonce , true
164182 }
165183
166- return false
184+ return fastPathNoAvailability , false
167185}
168186
169187// pruneTxs drops pooled transactions that can never be submitted from this
@@ -370,7 +388,8 @@ func (t *BatchTxPool) Add(
370388 // has elapsed and the tx nonce is the next expected, we submit right
371389 // away and update the `lastSubmittedAt` & `lastSubmittedNonce` fields,
372390 // for classifying future submissions, that might arrive shortly.
373- if eoaQueue .spacingElapsed (time .Now (), t .config .TxBatchInterval ) && eoaQueue .validNonce (tx .Nonce (), nonce ) {
391+ reason , ok := eoaQueue .fastPathAvailable (time .Now (), t .config .TxBatchInterval , tx .Nonce (), nonce )
392+ if ok {
374393 // Bound the submit so a hung call cannot pin `txQueuesMux`
375394 // indefinitely (see `fastPathSubmitTimeout`).
376395 submitCtx , cancel := context .WithTimeout (ctx , fastPathSubmitTimeout )
@@ -387,7 +406,7 @@ func (t *BatchTxPool) Add(
387406 )
388407 return err
389408 }
390- t .logSubmission (from , []pooledEvmTx {userTx }, flushReasonFastPath , flowTxID )
409+ t .logSubmission (from , []pooledEvmTx {userTx }, reason , flowTxID )
391410
392411 eoaQueue .lastSubmittedAt = time .Now ()
393412 eoaQueue .lastSubmittedNonce = tx .Nonce ()
0 commit comments