Skip to content
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

backport: #217 - shouldn't wait SubmissionRetryInterval at the first iteration #227

Merged
merged 3 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* [#216](https://github.com/babylonlabs-io/finality-provider/pull/216) Add multiple fpd connecting to one eotsd in e2e tests
* [#218](https://github.com/babylonlabs-io/finality-provider/pull/218) Prune used merkle proof
* [#221](https://github.com/babylonlabs-io/finality-provider/pull/221) Cleanup TODOs
* [#227](https://github.com/babylonlabs-io/finality-provider/pull/227) Fix FP submission loop

## v0.13.1

Expand Down
92 changes: 47 additions & 45 deletions finality-provider/service/fp_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,58 +339,60 @@ func (fp *FinalityProviderInstance) retrySubmitSigsUntilFinalized(targetBlocks [
var failedCycles uint32
targetHeight := targetBlocks[len(targetBlocks)-1].Height

// we break the for loop if the block is finalized or the signature is successfully submitted
// error will be returned if maximum retries have been reached or the query to the consumer chain fails
// First iteration happens before the loop
for {
select {
case <-time.After(fp.cfg.SubmissionRetryInterval):
// error will be returned if max retries have been reached
var res *types.TxResponse
var err error
res, err = fp.SubmitBatchFinalitySignatures(targetBlocks)
if err != nil {
fp.logger.Debug(
"failed to submit finality signature to the consumer chain",
zap.String("pk", fp.GetBtcPkHex()),
zap.Uint32("current_failures", failedCycles),
zap.Uint64("target_start_height", targetBlocks[0].Height),
zap.Uint64("target_end_height", targetHeight),
zap.Error(err),
)

if clientcontroller.IsUnrecoverable(err) {
return nil, err
}

if clientcontroller.IsExpected(err) {
return nil, nil
}
// Attempt submission immediately
// error will be returned if max retries have been reached
var res *types.TxResponse
var err error
res, err = fp.SubmitBatchFinalitySignatures(targetBlocks)
if err != nil {
fp.logger.Debug(
"failed to submit finality signature to the consumer chain",
zap.String("pk", fp.GetBtcPkHex()),
zap.Uint32("current_failures", failedCycles),
zap.Uint64("target_start_height", targetBlocks[0].Height),
zap.Uint64("target_end_height", targetHeight),
zap.Error(err),
)

failedCycles++
if failedCycles > fp.cfg.MaxSubmissionRetries {
return nil, fmt.Errorf("reached max failed cycles with err: %w", err)
}
} else {
// the signature has been successfully submitted
return res, nil
if clientcontroller.IsUnrecoverable(err) {
return nil, err
}

// periodically query the index block to be later checked whether it is Finalized
finalized, err := fp.checkBlockFinalization(targetHeight)
if err != nil {
return nil, fmt.Errorf("failed to query block finalization at height %v: %w", targetHeight, err)
}
if finalized {
fp.logger.Debug(
"the block is already finalized, skip submission",
zap.String("pk", fp.GetBtcPkHex()),
zap.Uint64("target_height", targetHeight),
)
// returning nil here is to safely break the loop
// the error still exists
if clientcontroller.IsExpected(err) {
return nil, nil
}

failedCycles++
if failedCycles > fp.cfg.MaxSubmissionRetries {
return nil, fmt.Errorf("reached max failed cycles with err: %w", err)
}
} else {
// the signature has been successfully submitted
return res, nil
}

// periodically query the index block to be later checked whether it is Finalized
finalized, err := fp.checkBlockFinalization(targetHeight)
if err != nil {
return nil, fmt.Errorf("failed to query block finalization at height %v: %w", targetHeight, err)
}
if finalized {
fp.logger.Debug(
"the block is already finalized, skip submission",
zap.String("pk", fp.GetBtcPkHex()),
zap.Uint64("target_height", targetHeight),
)
// TODO: returning nil here is to safely break the loop
// the error still exists
return nil, nil
}

// Wait for the retry interval
select {
case <-time.After(fp.cfg.SubmissionRetryInterval):
// Continue to next retry iteration
case <-fp.quit:
fp.logger.Debug("the finality-provider instance is closing", zap.String("pk", fp.GetBtcPkHex()))
return nil, ErrFinalityProviderShutDown
Expand Down
Loading