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

chore(*): use proper retry #29

Merged
merged 7 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
30 changes: 21 additions & 9 deletions btcclient/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package btcclient
import (
"fmt"

"github.com/babylonlabs-io/babylon/types/retry"
"github.com/avast/retry-go/v4"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
Expand Down Expand Up @@ -66,13 +66,16 @@ func (c *Client) getBestBlockHashWithRetry() (*chainhash.Hash, error) {
err error
)

if err := retry.Do(c.retrySleepTime, c.maxRetrySleepTime, func() error {
if err := retry.Do(func() error {
blockHash, err = c.GetBestBlockHash()
if err != nil {
return err
}
return nil
}); err != nil {
},
retry.Delay(c.retrySleepTime),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are those those options ever set in btclient ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in f7c96e3

retry.MaxDelay(c.maxRetrySleepTime),
); err != nil {
c.logger.Debug(
"failed to query the best block hash", zap.Error(err))
}
Expand All @@ -86,13 +89,16 @@ func (c *Client) getBlockHashWithRetry(height uint64) (*chainhash.Hash, error) {
err error
)

if err := retry.Do(c.retrySleepTime, c.maxRetrySleepTime, func() error {
if err := retry.Do(func() error {
blockHash, err = c.GetBlockHash(int64(height))
if err != nil {
return err
}
return nil
}); err != nil {
},
retry.Delay(c.retrySleepTime),
retry.MaxDelay(c.maxRetrySleepTime),
); err != nil {
c.logger.Debug(
"failed to query the block hash", zap.Uint64("height", height), zap.Error(err))
}
Expand All @@ -106,13 +112,16 @@ func (c *Client) getBlockWithRetry(hash *chainhash.Hash) (*wire.MsgBlock, error)
err error
)

if err := retry.Do(c.retrySleepTime, c.maxRetrySleepTime, func() error {
if err := retry.Do(func() error {
block, err = c.GetBlock(hash)
if err != nil {
return err
}
return nil
}); err != nil {
},
retry.Delay(c.retrySleepTime),
retry.MaxDelay(c.maxRetrySleepTime),
); err != nil {
c.logger.Debug(
"failed to query the block", zap.String("hash", hash.String()), zap.Error(err))
}
Expand All @@ -126,13 +135,16 @@ func (c *Client) getBlockVerboseWithRetry(hash *chainhash.Hash) (*btcjson.GetBlo
err error
)

if err := retry.Do(c.retrySleepTime, c.maxRetrySleepTime, func() error {
if err := retry.Do(func() error {
blockVerbose, err = c.GetBlockVerbose(hash)
if err != nil {
return err
}
return nil
}); err != nil {
},
retry.Delay(c.retrySleepTime),
retry.MaxDelay(c.maxRetrySleepTime),
); err != nil {
c.logger.Debug(
"failed to query the block verbose", zap.String("hash", hash.String()), zap.Error(err))
}
Expand Down
4 changes: 4 additions & 0 deletions config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
const (
defaultRetrySleepTime = 5 * time.Second
defaultMaxRetrySleepTime = 5 * time.Minute
defaultMaxRetryTimes = 5
)

// CommonConfig defines the server's basic configuration
Expand All @@ -23,6 +24,8 @@ type CommonConfig struct {
// Maximum backoff interval between retries. Exponential backoff leads to interval increase.
// This value is the cap of the interval, when exceeded the retries stop.
MaxRetrySleepTime time.Duration `mapstructure:"max-retry-sleep-time"`
// The max number of retries in case of a failure
MaxRetryTimes uint `mapstructure:"max-retry-times"`
}

func isOneOf(v string, list []string) bool {
Expand Down Expand Up @@ -60,5 +63,6 @@ func DefaultCommonConfig() CommonConfig {
LogLevel: "debug",
RetrySleepTime: defaultRetrySleepTime,
MaxRetrySleepTime: defaultMaxRetrySleepTime,
MaxRetryTimes: defaultMaxRetryTimes,
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/log v1.3.1
cosmossdk.io/math v1.3.0
github.com/avast/retry-go/v4 v4.5.1
github.com/avast/retry-go/v4 v4.6.0
github.com/babylonlabs-io/babylon v0.9.1
github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d
github.com/btcsuite/btcd v0.24.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o=
github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc=
github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA=
github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
Expand Down
11 changes: 5 additions & 6 deletions monitor/liveness_checker_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package monitor_test

import (
"math/rand"
"testing"

bbndatagen "github.com/babylonlabs-io/babylon/testutil/datagen"
bbntypes "github.com/babylonlabs-io/babylon/types"
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
monitortypes "github.com/babylonlabs-io/babylon/x/monitor/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

"github.com/babylonlabs-io/vigilante/config"
"github.com/babylonlabs-io/vigilante/monitor"
"github.com/babylonlabs-io/vigilante/testutil/datagen"
"github.com/babylonlabs-io/vigilante/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"math/rand"
"testing"
)

func FuzzLivenessChecker(f *testing.F) {
Expand All @@ -33,6 +31,7 @@ func FuzzLivenessChecker(f *testing.F) {
ComCfg: &config.CommonConfig{
RetrySleepTime: 1,
MaxRetrySleepTime: 0,
MaxRetryTimes: 1,
},
BBNQuerier: mockBabylonClient,
}
Expand Down
52 changes: 37 additions & 15 deletions monitor/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package monitor
import (
"fmt"

"github.com/babylonlabs-io/babylon/types/retry"
"github.com/avast/retry-go/v4"
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types"
Expand Down Expand Up @@ -61,15 +61,18 @@ func (m *Monitor) FindTipConfirmedEpoch() (uint64, error) {
func (m *Monitor) queryCurrentEpochWithRetry() (*epochingtypes.QueryCurrentEpochResponse, error) {
var currentEpochRes epochingtypes.QueryCurrentEpochResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.CurrentEpoch()
if err != nil {
return err
}

currentEpochRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
); err != nil {
m.logger.Debug(
"failed to query the current epoch", zap.Error(err))

Expand All @@ -82,15 +85,18 @@ func (m *Monitor) queryCurrentEpochWithRetry() (*epochingtypes.QueryCurrentEpoch
func (m *Monitor) queryRawCheckpointWithRetry(epoch uint64) (*ckpttypes.QueryRawCheckpointResponse, error) {
var rawCheckpointRes ckpttypes.QueryRawCheckpointResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.RawCheckpoint(epoch)
if err != nil {
return err
}

rawCheckpointRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
); err != nil {
m.logger.Debug(
"failed to query the raw checkpoint", zap.Error(err))

Expand All @@ -103,15 +109,18 @@ func (m *Monitor) queryRawCheckpointWithRetry(epoch uint64) (*ckpttypes.QueryRaw
func (m *Monitor) queryBlsPublicKeyListWithRetry(epoch uint64) (*ckpttypes.QueryBlsPublicKeyListResponse, error) {
var blsPublicKeyListRes ckpttypes.QueryBlsPublicKeyListResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.BlsPublicKeyList(epoch, nil)
if err != nil {
return err
}

blsPublicKeyListRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
); err != nil {
m.logger.Debug(
"failed to query the BLS public key list", zap.Error(err))

Expand All @@ -124,15 +133,18 @@ func (m *Monitor) queryBlsPublicKeyListWithRetry(epoch uint64) (*ckpttypes.Query
func (m *Monitor) queryEndedEpochBTCHeightWithRetry(epoch uint64) (*monitortypes.QueryEndedEpochBtcHeightResponse, error) {
var endedEpochBTCHeightRes monitortypes.QueryEndedEpochBtcHeightResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.EndedEpochBTCHeight(epoch)
if err != nil {
return err
}

endedEpochBTCHeightRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
); err != nil {
m.logger.Debug(
"failed to query the ended epoch BTC height", zap.Error(err))

Expand All @@ -145,15 +157,19 @@ func (m *Monitor) queryEndedEpochBTCHeightWithRetry(epoch uint64) (*monitortypes
func (m *Monitor) queryReportedCheckpointBTCHeightWithRetry(hashStr string) (*monitortypes.QueryReportedCheckpointBtcHeightResponse, error) {
var reportedCheckpointBtcHeightRes monitortypes.QueryReportedCheckpointBtcHeightResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.ReportedCheckpointBTCHeight(hashStr)
if err != nil {
return err
}

reportedCheckpointBtcHeightRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
retry.Attempts(m.ComCfg.MaxRetryTimes),
); err != nil {
m.logger.Debug(
"failed to query the reported checkpoint BTC height", zap.Error(err))

Expand All @@ -166,15 +182,18 @@ func (m *Monitor) queryReportedCheckpointBTCHeightWithRetry(hashStr string) (*mo
func (m *Monitor) queryBTCHeaderChainTipWithRetry() (*btclctypes.QueryTipResponse, error) {
var btcHeaderChainTipRes btclctypes.QueryTipResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.BTCHeaderChainTip()
if err != nil {
return err
}

btcHeaderChainTipRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say we need to pass attempts config to every method, it would pretty wierd that some methods do not respect config value.

); err != nil {
m.logger.Debug(
"failed to query the BTC header chain tip", zap.Error(err))

Expand All @@ -187,15 +206,18 @@ func (m *Monitor) queryBTCHeaderChainTipWithRetry() (*btclctypes.QueryTipRespons
func (m *Monitor) queryContainsBTCBlockWithRetry(blockHash *chainhash.Hash) (*btclctypes.QueryContainsBytesResponse, error) {
var containsBTCBlockRes btclctypes.QueryContainsBytesResponse

if err := retry.Do(m.ComCfg.RetrySleepTime, m.ComCfg.MaxRetrySleepTime, func() error {
if err := retry.Do(func() error {
res, err := m.BBNQuerier.ContainsBTCBlock(blockHash)
if err != nil {
return err
}

containsBTCBlockRes = *res
return nil
}); err != nil {
},
retry.Delay(m.ComCfg.RetrySleepTime),
retry.MaxDelay(m.ComCfg.MaxRetrySleepTime),
); err != nil {
m.logger.Debug(
"failed to query the contains BTC block", zap.Error(err))

Expand Down
9 changes: 6 additions & 3 deletions reporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"sync"
"time"

"github.com/avast/retry-go/v4"
"github.com/babylonlabs-io/babylon/btctxformatter"
"github.com/babylonlabs-io/babylon/types/retry"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
"github.com/babylonlabs-io/vigilante/btcclient"
"github.com/babylonlabs-io/vigilante/config"
Expand Down Expand Up @@ -57,10 +57,13 @@ func New(
btccParamsRes *btcctypes.QueryParamsResponse
err error
)
err = retry.Do(retrySleepTime, maxRetrySleepTime, func() error {
err = retry.Do(func() error {
btccParamsRes, err = babylonClient.BTCCheckpointParams()
return err
})
},
retry.Delay(retrySleepTime),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say that, given max-attempts is in common potion of the config it should probably set in every program, otherwise we risk seeing some wierd behaviour only to learn some toold respect this config option and some does not

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed added it in f7c96e3

retry.MaxDelay(maxRetrySleepTime),
)
if err != nil {
return nil, fmt.Errorf("failed to get BTC Checkpoint parameters: %w", err)
}
Expand Down
18 changes: 12 additions & 6 deletions reporter/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

pv "github.com/cosmos/relayer/v2/relayer/provider"

"github.com/babylonlabs-io/babylon/types/retry"
"github.com/avast/retry-go/v4"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
"github.com/babylonlabs-io/vigilante/types"
Expand All @@ -33,10 +33,13 @@ func (r *Reporter) getHeaderMsgsToSubmit(signer string, ibs []*types.IndexedBloc
for i, header := range ibs {
blockHash := header.BlockHash()
var res *btclctypes.QueryContainsBytesResponse
err = retry.Do(r.retrySleepTime, r.maxRetrySleepTime, func() error {
err = retry.Do(func() error {
res, err = r.babylonClient.ContainsBTCBlock(&blockHash)
return err
})
},
retry.Delay(r.retrySleepTime),
retry.MaxDelay(r.maxRetrySleepTime),
)
if err != nil {
return nil, err
}
Expand All @@ -57,7 +60,7 @@ func (r *Reporter) getHeaderMsgsToSubmit(signer string, ibs []*types.IndexedBloc

blockChunks := chunkBy(ibsToSubmit, int(r.Cfg.MaxHeadersInMsg))

headerMsgsToSubmit := []*btclctypes.MsgInsertHeaders{}
headerMsgsToSubmit := make([]*btclctypes.MsgInsertHeaders, 0, len(blockChunks))

for _, ibChunk := range blockChunks {
msgInsertHeaders := types.NewMsgInsertHeaders(signer, ibChunk)
Expand All @@ -69,14 +72,17 @@ func (r *Reporter) getHeaderMsgsToSubmit(signer string, ibs []*types.IndexedBloc

func (r *Reporter) submitHeaderMsgs(msg *btclctypes.MsgInsertHeaders) error {
// submit the headers
err := retry.Do(r.retrySleepTime, r.maxRetrySleepTime, func() error {
err := retry.Do(func() error {
res, err := r.babylonClient.InsertHeaders(context.Background(), msg)
if err != nil {
return err
}
r.logger.Infof("Successfully submitted %d headers to Babylon with response code %v", len(msg.Headers), res.Code)
return nil
})
},
retry.Delay(r.retrySleepTime),
retry.MaxDelay(r.maxRetrySleepTime),
)
if err != nil {
r.metrics.FailedHeadersCounter.Add(float64(len(msg.Headers)))
return fmt.Errorf("failed to submit headers: %w", err)
Expand Down
Loading
Loading