Skip to content

Commit 7c834e7

Browse files
palangoclaude
andcommitted
op-batcher: use sync.WaitGroup for fallback-auth watchers
authGroup was an errgroup.Group whose goroutines always returned nil (failures are reported via receiptsCh, not the group error), so the error branch in waitForAuthGroup was unreachable. Switch to a plain sync.WaitGroup, drop the dead error handling, and correct the field comment: watcher creation is back-pressured by, not hard-bounded by, MaxPendingTransactions. Also document the receipts-loop-outlives-authGroup invariant that keeps the final receiptsCh send from blocking. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 740b5ab commit 7c834e7

4 files changed

Lines changed: 23 additions & 24 deletions

File tree

op-batcher/batcher/driver.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,12 @@ type BatchSubmitter struct {
127127

128128
// authGroup tracks the fallback batcher's receipt-watcher goroutines (one
129129
// per auth+batch pair) so the publishing loop can drain them via
130-
// waitForAuthGroup before closing receiptsCh. It is intentionally unbounded:
131-
// pending-tx throttling is enforced by the txmgr Queue (queue.Send blocks at
132-
// MaxPendingTransactions), and the live watcher count is derived from the
133-
// queue's in-flight tx count, so it inherits the same bound.
134-
authGroup errgroup.Group
130+
// waitForAuthGroup before closing receiptsCh. New watchers are back-pressured
131+
// (not hard-bounded) by the txmgr Queue: queue.Send blocks at
132+
// MaxPendingTransactions, so watchers are created no faster than txs drain,
133+
// though a slow receipts loop can briefly leave more than that parked on their
134+
// final receiptsCh send.
135+
authGroup sync.WaitGroup
135136
}
136137

137138
// NewBatchSubmitter initializes the BatchSubmitter driver from a preconfigured DriverSetup

op-batcher/batcher/espresso_driver.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
package batcher
22

33
import (
4-
"context"
5-
"errors"
64
"fmt"
75

86
"github.com/ethereum-optimism/optimism/op-service/txmgr"
97
)
108

11-
// waitForAuthGroup blocks until all in-flight fallback-auth submissions have
12-
// completed. Called from publishingLoop's tail; blocks until killCtx is
13-
// cancelled if any auth retries are still in flight.
9+
// waitForAuthGroup blocks until all in-flight fallback-auth watcher goroutines
10+
// have finished. publishingLoop calls it before closing receiptsCh: each watcher
11+
// is a sender on receiptsCh, so the receipts loop must still be draining
12+
// receiptsCh at this point or a watcher's final send would block forever. Each
13+
// watcher always terminates because the txmgr Queue emits exactly one receipt per
14+
// Send, even on context cancellation.
1415
func (l *BatchSubmitter) waitForAuthGroup() {
15-
if err := l.authGroup.Wait(); err != nil {
16-
if !errors.Is(err, context.Canceled) {
17-
l.Log.Error("error waiting for fallback-auth transactions to complete", "err", err)
18-
}
19-
}
16+
l.authGroup.Wait()
2017
}
2118

2219
// dispatchAuthenticatedSendTx routes sendTx through the fallback-batcher

op-batcher/batcher/fallback_auth.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ func (l *BatchSubmitter) sendTxWithFallbackAuth(txdata txData, isCancel bool, ca
9797
queue.Send(transactionReference, verifyCandidate, authReceiptCh)
9898
queue.Send(transactionReference, *candidate, batchReceiptCh)
9999

100-
l.authGroup.Go(func() error {
100+
l.authGroup.Add(1)
101+
go func() {
102+
defer l.authGroup.Done()
101103
l.watchFallbackAuthReceipts(transactionReference, authReceiptCh, batchReceiptCh, receiptsCh)
102-
return nil
103-
})
104+
}()
104105
}
105106

106107
// watchFallbackAuthReceipts collects the auth and batch receipts for a fallback-auth pair,

op-batcher/batcher/fallback_auth_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func TestFallbackAuth_OrderingAndSuccess(t *testing.T) {
8080
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
8181

8282
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
83-
require.NoError(t, l.authGroup.Wait())
83+
l.authGroup.Wait()
8484

8585
require.Len(t, queue.sends, 2)
8686
// First send must target the BatchAuthenticator (the auth tx), giving it the
@@ -110,7 +110,7 @@ func TestFallbackAuth_AuthFailureRetried(t *testing.T) {
110110
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
111111

112112
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
113-
require.NoError(t, l.authGroup.Wait())
113+
l.authGroup.Wait()
114114

115115
got := <-receiptsCh
116116
require.Error(t, got.Err)
@@ -131,7 +131,7 @@ func TestFallbackAuth_BatchFailureRetried(t *testing.T) {
131131
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
132132

133133
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
134-
require.NoError(t, l.authGroup.Wait())
134+
l.authGroup.Wait()
135135

136136
got := <-receiptsCh
137137
require.Error(t, got.Err)
@@ -155,7 +155,7 @@ func TestFallbackAuth_AuthRevertedRetried(t *testing.T) {
155155
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
156156

157157
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
158-
require.NoError(t, l.authGroup.Wait())
158+
l.authGroup.Wait()
159159

160160
got := <-receiptsCh
161161
require.Error(t, got.Err)
@@ -180,7 +180,7 @@ func TestFallbackAuth_WindowViolationRetried(t *testing.T) {
180180
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
181181

182182
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
183-
require.NoError(t, l.authGroup.Wait())
183+
l.authGroup.Wait()
184184

185185
got := <-receiptsCh
186186
require.Error(t, got.Err)
@@ -207,7 +207,7 @@ func TestFallbackAuth_WindowBoundaryAccepted(t *testing.T) {
207207
receiptsCh := make(chan txmgr.TxReceipt[txRef], 1)
208208

209209
l.sendTxWithFallbackAuth(txdata, false, candidate, queue, receiptsCh)
210-
require.NoError(t, l.authGroup.Wait())
210+
l.authGroup.Wait()
211211

212212
got := <-receiptsCh
213213
require.NoError(t, got.Err)

0 commit comments

Comments
 (0)