Skip to content

Commit 2a732cf

Browse files
fix: Handle shutdown RPC errors gracefully (#2329)
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. NOTE: PR titles should follow semantic commits: https://www.conventionalcommits.org/en/v1.0.0/ --> ## Overview Closes #2328 <!-- Please provide an explanation of the PR, including the appropriate context, background, goal, and rationale. If there is an issue with this information, please provide a tl;dr and link the issue. Ex: Closes #<issue number> --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved handling of submission cancellations, providing clearer feedback when operations are canceled due to context termination. - Added new status and error codes to better represent and communicate context cancellation events during data availability operations. - **Bug Fixes** - Submission processes now exit promptly and log informative messages when canceled, ensuring cleaner and more predictable behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 8c90d88 commit 2a732cf

6 files changed

Lines changed: 43 additions & 10 deletions

File tree

block/submitter.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ func (m *Manager) submitHeadersToDA(ctx context.Context) error {
5656
gasPrice := m.gasPrice
5757
initialGasPrice := gasPrice
5858

59-
daSubmitRetryLoop:
6059
for !submittedAllHeaders && attempt < maxSubmitAttempts {
6160
select {
6261
case <-ctx.Done():
63-
break daSubmitRetryLoop
62+
m.logger.Info("context done, stopping header submission loop")
63+
return nil
6464
case <-time.After(backoff):
6565
}
6666

@@ -78,9 +78,9 @@ daSubmitRetryLoop:
7878
}
7979
}
8080

81-
ctx, cancel := context.WithTimeout(ctx, 60*time.Second) // TODO: make this configurable
82-
res := types.SubmitWithHelpers(ctx, m.da, m.logger, headersBz, gasPrice, nil)
83-
cancel()
81+
submitctx, submitCtxCancel := context.WithTimeout(ctx, 60*time.Second) // TODO: make this configurable
82+
res := types.SubmitWithHelpers(submitctx, m.da, m.logger, headersBz, gasPrice, nil)
83+
submitCtxCancel()
8484

8585
switch res.Code {
8686
case coreda.StatusSuccess:
@@ -115,6 +115,9 @@ daSubmitRetryLoop:
115115
gasPrice = gasPrice * m.gasMultiplier
116116
}
117117
m.logger.Info("retrying DA layer submission with", "backoff", backoff, "gasPrice", gasPrice)
118+
case coreda.StatusContextCanceled:
119+
m.logger.Info("DA layer submission canceled", "attempt", attempt)
120+
return nil
118121
default:
119122
m.logger.Error("DA layer submission failed", "error", res.Message, "attempt", attempt)
120123
backoff = m.exponentialBackoff(backoff)
@@ -175,12 +178,12 @@ func (m *Manager) submitBatchToDA(ctx context.Context, batch coresequencer.Batch
175178
initialGasPrice := m.gasPrice
176179
gasPrice := initialGasPrice
177180

178-
daSubmitRetryLoop:
179-
for !submittedAllTxs && attempt < maxSubmitAttempts {
181+
for attempt < maxSubmitAttempts {
180182
// Wait for backoff duration or exit if context is done
181183
select {
182184
case <-ctx.Done():
183-
break daSubmitRetryLoop
185+
m.logger.Info("context done, stopping batch submission loop")
186+
return nil
184187
case <-time.After(backoff):
185188
}
186189

@@ -251,12 +254,13 @@ daSubmitRetryLoop:
251254
gasPrice = gasPrice * gasMultiplier
252255
}
253256
m.logger.Info("retrying DA layer submission with", "backoff", backoff, "gasPrice", gasPrice)
254-
257+
case coreda.StatusContextCanceled:
258+
m.logger.Info("DA layer submission canceled due to context cancellation", "attempt", attempt)
259+
return nil
255260
case coreda.StatusTooBig:
256261
// Blob size adjustment is handled within DA impl or SubmitWithOptions call
257262
// fallthrough to default exponential backoff
258263
fallthrough
259-
260264
default:
261265
m.logger.Error("DA layer submission failed", "error", res.Message, "attempt", attempt)
262266
backoff = m.exponentialBackoff(backoff)

core/da/da.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const (
9191
StatusContextDeadline
9292
StatusError
9393
StatusIncorrectAccountSequence
94+
StatusContextCanceled
9495
)
9596

9697
// BaseResult contains basic information returned by DA layer.

core/da/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ var (
1212
ErrTxIncorrectAccountSequence = errors.New("incorrect account sequence")
1313
ErrContextDeadline = errors.New("context deadline")
1414
ErrHeightFromFuture = errors.New("given height is from the future")
15+
ErrContextCanceled = errors.New("context canceled")
1516
)

da/jsonrpc/client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ func (api *API) Get(ctx context.Context, ids []da.ID, _ []byte) ([]da.Blob, erro
4242
api.Logger.Debug("Making RPC call", "method", "Get", "num_ids", len(ids), "namespace", string(api.Namespace))
4343
res, err := api.Internal.Get(ctx, ids, api.Namespace)
4444
if err != nil {
45+
if errors.Is(err, context.Canceled) {
46+
api.Logger.Debug("RPC call canceled due to context cancellation", "method", "Get")
47+
return res, context.Canceled
48+
}
4549
api.Logger.Error("RPC call failed", "method", "Get", "error", err)
4650
// Wrap error for context, potentially using the translated error from the RPC library
4751
return nil, fmt.Errorf("failed to get blobs: %w", err)
@@ -64,6 +68,10 @@ func (api *API) GetIDs(ctx context.Context, height uint64, _ []byte) (*da.GetIDs
6468
api.Logger.Debug("RPC call indicates height from future", "method", "GetIDs", "height", height)
6569
return nil, err // Return the specific ErrHeightFromFuture
6670
}
71+
if errors.Is(err, context.Canceled) {
72+
api.Logger.Debug("RPC call canceled due to context cancellation", "method", "GetIDs")
73+
return res, context.Canceled
74+
}
6775
api.Logger.Error("RPC call failed", "method", "GetIDs", "error", err)
6876
return nil, err
6977
}
@@ -119,6 +127,10 @@ func (api *API) Submit(ctx context.Context, blobs []da.Blob, gasPrice float64, _
119127
api.Logger.Debug("Making RPC call", "method", "Submit", "num_blobs", len(blobs), "gas_price", gasPrice, "namespace", string(api.Namespace))
120128
res, err := api.Internal.Submit(ctx, blobs, gasPrice, api.Namespace)
121129
if err != nil {
130+
if errors.Is(err, context.Canceled) {
131+
api.Logger.Debug("RPC call canceled due to context cancellation", "method", "Submit")
132+
return res, context.Canceled
133+
}
122134
api.Logger.Error("RPC call failed", "method", "Submit", "error", err)
123135
} else {
124136
api.Logger.Debug("RPC call successful", "method", "Submit", "num_ids_returned", len(res))
@@ -168,6 +180,10 @@ func (api *API) SubmitWithOptions(ctx context.Context, inputBlobs []da.Blob, gas
168180
api.Logger.Debug("Making RPC call", "method", "SubmitWithOptions", "num_blobs_original", len(inputBlobs), "num_blobs_to_submit", len(blobsToSubmit), "gas_price", gasPrice, "namespace", string(api.Namespace))
169181
res, err := api.Internal.SubmitWithOptions(ctx, blobsToSubmit, gasPrice, api.Namespace, options)
170182
if err != nil {
183+
if errors.Is(err, context.Canceled) {
184+
api.Logger.Debug("RPC call canceled due to context cancellation", "method", "SubmitWithOptions")
185+
return res, context.Canceled
186+
}
171187
api.Logger.Error("RPC call failed", "method", "SubmitWithOptions", "error", err)
172188
} else {
173189
api.Logger.Debug("RPC call successful", "method", "SubmitWithOptions", "num_ids_returned", len(res))

da/jsonrpc/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ func getKnownErrorsMapping() jsonrpc.Errors {
1515
errs.Register(jsonrpc.ErrorCode(coreda.StatusAlreadyInMempool), &coreda.ErrTxAlreadyInMempool)
1616
errs.Register(jsonrpc.ErrorCode(coreda.StatusIncorrectAccountSequence), &coreda.ErrTxIncorrectAccountSequence)
1717
errs.Register(jsonrpc.ErrorCode(coreda.StatusContextDeadline), &coreda.ErrContextDeadline)
18+
errs.Register(jsonrpc.ErrorCode(coreda.StatusContextCanceled), &coreda.ErrContextCanceled)
1819
return errs
1920
}

types/da.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ func SubmitWithHelpers(
2929

3030
// Handle errors returned by SubmitWithOptions
3131
if err != nil {
32+
if errors.Is(err, context.Canceled) {
33+
logger.Debug("DA submission canceled via helper due to context cancellation")
34+
return coreda.ResultSubmit{
35+
BaseResult: coreda.BaseResult{
36+
Code: coreda.StatusContextCanceled,
37+
Message: "submission canceled",
38+
IDs: ids,
39+
},
40+
}
41+
}
3242
status := coreda.StatusError
3343
switch {
3444
case errors.Is(err, coreda.ErrTxTimedOut):

0 commit comments

Comments
 (0)