-
Notifications
You must be signed in to change notification settings - Fork 12
Send Fallback Batch tx only after Auth tx Confirms (m3)
#467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: espresso/batcher-fallback
Are you sure you want to change the base?
Changes from all commits
3a629d9
5dbf252
af73e32
9fe36d8
47cb2a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,13 @@ func computeCommitment(candidate *txmgr.TxCandidate) ([32]byte, error) { | |
| // separate signature is needed — the L1 transaction is already signed by the TxManager's key. | ||
| func (l *BatchSubmitter) sendTxWithFallbackAuth(txdata txData, isCancel bool, candidate *txmgr.TxCandidate, queue TxSender[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) { | ||
| transactionReference := newTxRef(txdata, isCancel) | ||
| // The auth tx shares the batch txdata's identity (so a failure requeues the right frames) | ||
| // but is always a calldata tx. Auth failures must carry its real type: an ErrAlreadyReserved | ||
| // receipt labeled with the batch's blob type would make cancelBlockingTx cancel the wrong | ||
| // pool, leaving the reserving tx stuck. | ||
| authReference := transactionReference | ||
| authReference.isBlob = false | ||
| authReference.daType = DaTypeCalldata | ||
| l.Log.Debug("Sending fallback-authenticated L1 transaction", "txRef", transactionReference) | ||
|
|
||
| commitment, err := computeCommitment(candidate) | ||
|
|
@@ -79,43 +86,22 @@ func (l *BatchSubmitter) sendTxWithFallbackAuth(txdata txData, isCancel bool, ca | |
| To: &l.RollupConfig.BatchAuthenticatorAddress, | ||
| } | ||
|
|
||
| // Private buffered channels: queue.Send forwards exactly one receipt to each, so the watcher | ||
| // reads exactly once per channel (even on context cancellation, the queue still emits a | ||
| // ctx-error receipt). These never reach handleReceipt; only the synthetic receipt below does. | ||
| authReceiptCh := make(chan txmgr.TxReceipt[txRef], 1) | ||
| batchReceiptCh := make(chan txmgr.TxReceipt[txRef], 1) | ||
|
|
||
| l.Log.Debug( | ||
| "Sending fallback authenticateBatchInfo transaction", | ||
| "txRef", transactionReference, | ||
| "commitment", hexutil.Encode(commitment[:]), | ||
| "address", l.RollupConfig.BatchAuthenticatorAddress.String(), | ||
| ) | ||
| // Submit the auth tx then the batch tx, in order, on the publishing-loop goroutine so their | ||
| // nonces are assigned in submission order. Each Send blocks here when the queue is at its | ||
| // MaxPendingTransactions limit. | ||
| queue.Send(transactionReference, verifyCandidate, authReceiptCh) | ||
| queue.Send(transactionReference, *candidate, batchReceiptCh) | ||
|
|
||
| l.authGroup.Add(1) | ||
| go func() { | ||
| defer l.authGroup.Done() | ||
| l.watchFallbackAuthReceipts(transactionReference, authReceiptCh, batchReceiptCh, receiptsCh) | ||
| }() | ||
| } | ||
|
|
||
| // watchFallbackAuthReceipts collects the auth and batch receipts for a fallback-auth pair, | ||
| // validates that the batch tx landed within the lookback window of the auth tx, and forwards a | ||
| // single synthetic receipt keyed to the batch txData onto receiptsCh. Any failure produces an | ||
| // error receipt so the channel manager rewinds and resubmits the frame set. | ||
| func (l *BatchSubmitter) watchFallbackAuthReceipts(transactionReference txRef, authReceiptCh, batchReceiptCh chan txmgr.TxReceipt[txRef], receiptsCh chan txmgr.TxReceipt[txRef]) { | ||
| // Submit the auth tx and wait for its receipt, then send the batch tx. Each Send | ||
| // blocks here when the queue is at its MaxPendingTransactions limit. | ||
| authReceiptCh := make(chan txmgr.TxReceipt[txRef], 1) | ||
| queue.Send(authReference, verifyCandidate, authReceiptCh) | ||
| authResult := <-authReceiptCh | ||
| batchResult := <-batchReceiptCh | ||
|
|
||
| if authResult.Err != nil { | ||
| l.Log.Error("Failed to send fallback authenticateBatchInfo transaction", "txRef", transactionReference, "err", authResult.Err) | ||
| receiptsCh <- txmgr.TxReceipt[txRef]{ | ||
| ID: transactionReference, | ||
| ID: authReference, | ||
| Err: fmt.Errorf("failed to send fallback authenticateBatchInfo transaction: %w", authResult.Err), | ||
| } | ||
| return | ||
|
|
@@ -129,12 +115,17 @@ func (l *BatchSubmitter) watchFallbackAuthReceipts(transactionReference txRef, a | |
| if authResult.Receipt.Status != types.ReceiptStatusSuccessful { | ||
| l.Log.Error("Fallback authenticateBatchInfo transaction reverted", "txRef", transactionReference, "txHash", authResult.Receipt.TxHash) | ||
| receiptsCh <- txmgr.TxReceipt[txRef]{ | ||
| ID: transactionReference, | ||
| ID: authReference, | ||
| Err: fmt.Errorf("fallback authenticateBatchInfo transaction reverted: %s", authResult.Receipt.TxHash), | ||
| } | ||
| return | ||
| } | ||
|
|
||
| // The auth tx is confirmed on L1. Now send the batch tx | ||
| batchReceiptCh := make(chan txmgr.TxReceipt[txRef], 1) | ||
| queue.Send(transactionReference, *candidate, batchReceiptCh) | ||
| batchResult := <-batchReceiptCh | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In post-Espresso fallback-auth mode, Useful? React with 👍 / 👎.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is now the intended design after addressing |
||
|
|
||
| if batchResult.Err != nil { | ||
| l.Log.Error("Failed to send batch inbox transaction", "txRef", transactionReference, "err", batchResult.Err) | ||
| receiptsCh <- txmgr.TxReceipt[txRef]{ | ||
|
|
@@ -147,6 +138,7 @@ func (l *BatchSubmitter) watchFallbackAuthReceipts(transactionReference txRef, a | |
| distance := new(big.Int).Sub(batchResult.Receipt.BlockNumber, authResult.Receipt.BlockNumber) | ||
| lookbackWindow := new(big.Int).SetUint64(derive.BatchAuthLookbackWindow) | ||
| if distance.Sign() < 0 || distance.Cmp(lookbackWindow) > 0 { | ||
| l.Metr.RecordFallbackAuthWindowExceeded() | ||
| l.Log.Error("authenticateBatchInfo transaction too far from batch inbox transaction", "txRef", transactionReference, "distance", distance) | ||
| receiptsCh <- txmgr.TxReceipt[txRef]{ | ||
| ID: transactionReference, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When any deployment sets
--num-confirmationsabove 25, this new check rejects the CLI config before the batcher has loaded the rollup config, so it also blocks chains that have noBatchAuthenticatorAddressor Espresso fallback-auth path at all. The lookback bound only matters forsendTxWithFallbackAuth; non-Espresso or pre-Espresso batchers can still safely wait for more confirmations, so this should be applied only when fallback auth is actually configured/active, or after rollup config is available.Useful? React with 👍 / 👎.