diff --git a/.golangci.yml b/.golangci.yml index 891b3fd6..219c7680 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,7 @@ run: timeout: 5m + +linters: disable-all: true enable: - asasalint @@ -8,96 +10,69 @@ run: - bodyclose - containedctx - contextcheck - - cyclop - decorder - - depguard - dogsled - - dupl - durationcheck - errcheck - errchkjson - errname - errorlint - - execinquery - exhaustive - - exhaustivestruct - - exhaustruct - - exportloopref - forbidigo - forcetypeassert - - funlen - - gci - - gochecknoglobals - - gochecknoinits - - gocognit - goconst - gocritic - gocyclo - - godot - - godox - - goerr113 - - gofumpt - goheader - - golint - - gomnd - - gomoddirectives - gomodguard - goprintffuncname - - gosec - gosimple - govet - grouper - - ifshort - importas - ineffassign - - interfacebloat - - interfacer - - ireturn - - lll - loggercheck - maintidx - makezero - - maligned - misspell - nakedret - - nestif - nilerr - - nilnil - - nlreturn +# - nlreturn # Style wise I personally like this one, todo(lazar): unlax at somepoint, good practice - noctx - - nolintlint - nonamedreturns - - nosnakecase - nosprintfhostport - paralleltest - - prealloc - - predeclared - - promlinter - reassign - revive - rowserrcheck - - scopelint - sqlclosecheck - staticcheck - - structcheck - stylecheck - - tagliatelle - tenv - testableexamples - - testpackage - - thelper - tparallel - typecheck - unconvert - unparam - - unused - usestdlibvars - - varcheck - - varnamelen + - unused - wastedassign - whitespace - - wrapcheck - - wsl +# - wrapcheck # we really should be using this, lax for now todo(lazar): unlax at somepoint, good practice issues: max-same-issues: 0 + # Default: https://golangci-lint.run/usage/false-positives/#default-exclusions + exclude-dirs: + - e2etest + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gocyclo + - errcheck + - dupl + - gosec + - path-except: _test\.go + linters: + - forbidigo \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 24faed89..fd032b01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * [#94](https://github.com/babylonlabs-io/vigilante/pull/94) adds gosec and fixes gosec issues * [#96](https://github.com/babylonlabs-io/vigilante/pull/96) fixes potential stale data read +* [#98](https://github.com/babylonlabs-io/vigilante/pull/98) fixes golangci configuration ## v0.15.0 diff --git a/btcclient/client_wallet.go b/btcclient/client_wallet.go index 4fa3c1e8..0645b439 100644 --- a/btcclient/client_wallet.go +++ b/btcclient/client_wallet.go @@ -174,5 +174,4 @@ func (c *Client) TxDetails(txHash *chainhash.Hash, pkScript []byte) (*notifier.T } return c.getTxDetails(req, txNotFoundErrMsgBitcoind) - } diff --git a/btcclient/notifier.go b/btcclient/notifier.go index 79f328b0..d5077d63 100644 --- a/btcclient/notifier.go +++ b/btcclient/notifier.go @@ -31,14 +31,14 @@ type Bitcoind struct { func DefaultBitcoindConfig() Bitcoind { return Bitcoind{ - RPCHost: config.DefaultRpcBtcNodeHost, - RPCUser: config.DefaultBtcNodeRpcUser, - RPCPass: config.DefaultBtcNodeRpcPass, + RPCHost: config.DefaultRPCBtcNodeHost, + RPCUser: config.DefaultBtcNodeRPCUser, + RPCPass: config.DefaultBtcNodeRPCPass, RPCPolling: true, BlockPollingInterval: 30 * time.Second, TxPollingInterval: 30 * time.Second, EstimateMode: config.DefaultBtcNodeEstimateMode, - BlockCacheSize: config.DefaultBtcblockCacheSize, + BlockCacheSize: config.DefaultBtcBlockCacheSize, ZMQPubRawBlock: config.DefaultZmqBlockEndpoint, ZMQPubRawTx: config.DefaultZmqTxEndpoint, ZMQReadDeadline: 30 * time.Second, @@ -71,23 +71,23 @@ type EmptyHintCache struct{} var _ HintCache = (*EmptyHintCache)(nil) -func (c *EmptyHintCache) CommitSpendHint(height uint32, spendRequests ...chainntnfs.SpendRequest) error { +func (c *EmptyHintCache) CommitSpendHint(_ uint32, _ ...chainntnfs.SpendRequest) error { return nil } -func (c *EmptyHintCache) QuerySpendHint(spendRequest chainntnfs.SpendRequest) (uint32, error) { +func (c *EmptyHintCache) QuerySpendHint(_ chainntnfs.SpendRequest) (uint32, error) { return 0, nil } -func (c *EmptyHintCache) PurgeSpendHint(spendRequests ...chainntnfs.SpendRequest) error { +func (c *EmptyHintCache) PurgeSpendHint(_ ...chainntnfs.SpendRequest) error { return nil } -func (c *EmptyHintCache) CommitConfirmHint(height uint32, confRequests ...chainntnfs.ConfRequest) error { +func (c *EmptyHintCache) CommitConfirmHint(_ uint32, _ ...chainntnfs.ConfRequest) error { return nil } -func (c *EmptyHintCache) QueryConfirmHint(confRequest chainntnfs.ConfRequest) (uint32, error) { +func (c *EmptyHintCache) QueryConfirmHint(_ chainntnfs.ConfRequest) (uint32, error) { return 0, nil } -func (c *EmptyHintCache) PurgeConfirmHint(confRequests ...chainntnfs.ConfRequest) error { +func (c *EmptyHintCache) PurgeConfirmHint(_ ...chainntnfs.ConfRequest) error { return nil } @@ -96,7 +96,7 @@ func (c *EmptyHintCache) PurgeConfirmHint(confRequests ...chainntnfs.ConfRequest // // According to chain.BitcoindConfig docs it should also support tor if node backend // // works over tor. func BuildDialer(rpcHost string) func(string) (net.Conn, error) { - return func(addr string) (net.Conn, error) { + return func(_ string) (net.Conn, error) { return net.Dial("tcp", rpcHost) } } diff --git a/btcclient/query.go b/btcclient/query.go index 5cfa99ee..237bf11b 100644 --- a/btcclient/query.go +++ b/btcclient/query.go @@ -21,7 +21,7 @@ func (c *Client) GetBestBlock() (uint32, error) { } if height < 0 || height > int64(math.MaxUint32) { - panic(fmt.Errorf("height (%d) is out of uint32 range", height)) //software bug, panic + panic(fmt.Errorf("height (%d) is out of uint32 range", height)) // software bug, panic } return uint32(height), nil @@ -41,7 +41,7 @@ func (c *Client) GetBlockByHash(blockHash *chainhash.Hash) (*types.IndexedBlock, btcTxs := types.GetWrappedTxs(mBlock) height := blockInfo.Height if height < 0 || height > int64(math.MaxUint32) { - panic(fmt.Errorf("height (%d) is out of uint32 range", height)) //software bug, panic + panic(fmt.Errorf("height (%d) is out of uint32 range", height)) // software bug, panic } return types.NewIndexedBlock(uint32(height), &mBlock.Header, btcTxs), mBlock, nil } @@ -82,6 +82,7 @@ func (c *Client) getBestBlockHashWithRetry() (*chainhash.Hash, error) { ); err != nil { c.logger.Debug( "failed to query the best block hash", zap.Error(err)) + return nil, err } return blockHash, nil @@ -106,6 +107,7 @@ func (c *Client) getBlockHashWithRetry(height uint32) (*chainhash.Hash, error) { ); err != nil { c.logger.Debug( "failed to query the block hash", zap.Uint32("height", height), zap.Error(err)) + return nil, err } return blockHash, nil @@ -130,6 +132,7 @@ func (c *Client) getBlockWithRetry(hash *chainhash.Hash) (*wire.MsgBlock, error) ); err != nil { c.logger.Debug( "failed to query the block", zap.String("hash", hash.String()), zap.Error(err)) + return nil, err } return block, nil @@ -154,6 +157,7 @@ func (c *Client) getBlockVerboseWithRetry(hash *chainhash.Hash) (*btcjson.GetBlo ); err != nil { c.logger.Debug( "failed to query the block verbose", zap.String("hash", hash.String()), zap.Error(err)) + return nil, err } return blockVerbose, nil @@ -235,6 +239,7 @@ func (c *Client) getBlockCountWithRetry() (int64, error) { retry.Attempts(c.maxRetryTimes), ); err != nil { c.logger.Debug("failed to query get block count", zap.Error(err)) + return 0, err } return height, nil diff --git a/btcstaking-tracker/atomicslasher/babylon_adapter.go b/btcstaking-tracker/atomicslasher/babylon_adapter.go index 0365c408..be3a73ce 100644 --- a/btcstaking-tracker/atomicslasher/babylon_adapter.go +++ b/btcstaking-tracker/atomicslasher/babylon_adapter.go @@ -108,7 +108,7 @@ func (ba *BabylonAdapter) HandleAllBTCDelegations(handleFunc func(btcDel *bstype } func (ba *BabylonAdapter) IsFPSlashed( - ctx context.Context, + _ context.Context, fpBTCPK *bbn.BIP340PubKey, ) (bool, error) { fpResp, err := ba.bbnClient.FinalityProvider(fpBTCPK.MarshalHex()) diff --git a/btcstaking-tracker/atomicslasher/routines.go b/btcstaking-tracker/atomicslasher/routines.go index 22a73d06..0f676e50 100644 --- a/btcstaking-tracker/atomicslasher/routines.go +++ b/btcstaking-tracker/atomicslasher/routines.go @@ -124,7 +124,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() { cancel() if err != nil { as.logger.Error( - "failed to get BTC staking paramter at version", + "failed to get BTC staking parameter at version", zap.Uint32("version", paramsVersion), zap.Error(err), ) diff --git a/btcstaking-tracker/atomicslasher/types.go b/btcstaking-tracker/atomicslasher/types.go index 50e9629a..5b3167f6 100644 --- a/btcstaking-tracker/atomicslasher/types.go +++ b/btcstaking-tracker/atomicslasher/types.go @@ -12,20 +12,20 @@ import ( "github.com/btcsuite/btcd/wire" ) -type slashingPath int +type SlashingPath int const ( - slashStakingTx slashingPath = iota + slashStakingTx SlashingPath = iota slashUnbondingTx ) type SlashingTxInfo struct { - path slashingPath + path SlashingPath StakingTxHash chainhash.Hash SlashingMsgTx *wire.MsgTx } -func NewSlashingTxInfo(path slashingPath, stakingTxHash chainhash.Hash, slashingMsgTx *wire.MsgTx) *SlashingTxInfo { +func NewSlashingTxInfo(path SlashingPath, stakingTxHash chainhash.Hash, slashingMsgTx *wire.MsgTx) *SlashingTxInfo { return &SlashingTxInfo{ path: path, StakingTxHash: stakingTxHash, @@ -139,7 +139,7 @@ func (bdi *BTCDelegationIndex) Remove(stakingTxHash chainhash.Hash) { delete(bdi.unbondingSlashingTxMap, del.UnbondingSlashingTxHash) } -func (bdi *BTCDelegationIndex) FindSlashedBTCDelegation(txHash chainhash.Hash) (*TrackedDelegation, slashingPath) { +func (bdi *BTCDelegationIndex) FindSlashedBTCDelegation(txHash chainhash.Hash) (*TrackedDelegation, SlashingPath) { bdi.Lock() defer bdi.Unlock() diff --git a/btcstaking-tracker/btcslasher/btc_utils.go b/btcstaking-tracker/btcslasher/btc_utils.go index 917962a9..676346fc 100644 --- a/btcstaking-tracker/btcslasher/btc_utils.go +++ b/btcstaking-tracker/btcslasher/btc_utils.go @@ -21,7 +21,7 @@ func (bs *BTCSlasher) isTaprootOutputSpendable(txBytes []byte, outIdx uint32) (b stakingMsgTx, err := bbn.NewBTCTxFromBytes(txBytes) if err != nil { return false, fmt.Errorf( - "failed to convert staking tx to MsgTx: %v", + "failed to convert staking tx to MsgTx: %w", err, ) } @@ -33,7 +33,7 @@ func (bs *BTCSlasher) isTaprootOutputSpendable(txBytes []byte, outIdx uint32) (b txOut, err := bs.BTCClient.GetTxOut(&stakingMsgTxHash, outIdx, true) if err != nil { return false, fmt.Errorf( - "failed to get the output of tx %s: %v", + "failed to get the output of tx %s: %w", stakingMsgTxHash.String(), err, ) diff --git a/btcstaking-tracker/btcslasher/slasher.go b/btcstaking-tracker/btcslasher/slasher.go index 39e4afa2..51418586 100644 --- a/btcstaking-tracker/btcslasher/slasher.go +++ b/btcstaking-tracker/btcslasher/slasher.go @@ -194,7 +194,7 @@ func (bs *BTCSlasher) slashingEnforcer() { ) // record the metrics of the slashed delegation - bs.metrics.RecordSlashedDelegation(slashRes.Del, slashRes.SlashingTxHash.String()) + bs.metrics.RecordSlashedDelegation(slashRes.Del) } } } @@ -259,7 +259,8 @@ func (bs *BTCSlasher) SlashFinalityProvider(extractedFpBTCSK *btcec.PrivateKey) // Initialize a semaphore to control the number of concurrent operations sem := semaphore.NewWeighted(bs.maxSlashingConcurrency) - delegations := append(activeBTCDels, unbondedBTCDels...) + activeBTCDels = append(activeBTCDels, unbondedBTCDels...) + delegations := activeBTCDels // try to slash both staking and unbonding txs for each BTC delegation // sign and submit slashing tx for each active and unbonded delegation diff --git a/btcstaking-tracker/btcslasher/slasher_test.go b/btcstaking-tracker/btcslasher/slasher_test.go index 5e68a5cb..f555fed6 100644 --- a/btcstaking-tracker/btcslasher/slasher_test.go +++ b/btcstaking-tracker/btcslasher/slasher_test.go @@ -29,6 +29,7 @@ import ( "github.com/babylonlabs-io/vigilante/testutil/mocks" ) +//nolint:maintidx // Ignoring high maintainability index for this fuzz test func FuzzSlasher(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) diff --git a/btcstaking-tracker/btcslasher/slasher_utils.go b/btcstaking-tracker/btcslasher/slasher_utils.go index d3734c06..2538a40b 100644 --- a/btcstaking-tracker/btcslasher/slasher_utils.go +++ b/btcstaking-tracker/btcslasher/slasher_utils.go @@ -50,14 +50,15 @@ func (bs *BTCSlasher) slashBTCDelegation( txHash1, err1 := bs.sendSlashingTx(fpBTCPK, extractedfpBTCSK, del, false) txHash2, err2 := bs.sendSlashingTx(fpBTCPK, extractedfpBTCSK, del, true) - if err1 != nil && err2 != nil { + switch { + case err1 != nil && err2 != nil: // both attempts fail accumulatedErrs = multierror.Append(accumulatedErrs, err1, err2) txHash = nil - } else if err1 == nil { + case err1 == nil: // slashing tx is submitted successfully txHash = txHash1 - } else if err2 == nil { + case err2 == nil: // unbonding slashing tx is submitted successfully txHash = txHash2 } @@ -126,7 +127,7 @@ func (bs *BTCSlasher) sendSlashingTx( if err != nil { // Warning: this can only be an error in Bitcoin side return nil, fmt.Errorf( - "failed to check if BTC delegation %s under finality provider %s is slashable: %v", + "failed to check if BTC delegation %s under finality provider %s is slashable: %w", del.BtcPk.MarshalHex(), fpBTCPK.MarshalHex(), err, @@ -158,7 +159,7 @@ func (bs *BTCSlasher) sendSlashingTx( if err != nil { // Warning: this can only be a programming error in Babylon side return nil, fmt.Errorf( - "failed to build witness for BTC delegation %s under finality provider %s: %v", + "failed to build witness for BTC delegation %s under finality provider %s: %w", del.BtcPk.MarshalHex(), fpBTCPK.MarshalHex(), err, @@ -174,7 +175,7 @@ func (bs *BTCSlasher) sendSlashingTx( txHash, err = bs.BTCClient.SendRawTransaction(slashingMsgTxWithWitness, true) if err != nil { return nil, fmt.Errorf( - "failed to submit slashing tx of BTC delegation %s under finality provider %s to Bitcoin: %v", + "failed to submit slashing tx of BTC delegation %s under finality provider %s to Bitcoin: %w", del.BtcPk.MarshalHex(), fpBTCPK.MarshalHex(), err, @@ -206,12 +207,12 @@ func BuildUnbondingSlashingTxWithWitness( fpBtcPkList, err := bbn.NewBTCPKsFromBIP340PKs(d.FpBtcPkList) if err != nil { - return nil, fmt.Errorf("failed to convert finality provider pks to BTC pks: %v", err) + return nil, fmt.Errorf("failed to convert finality provider pks to BTC pks: %w", err) } covenantBtcPkList, err := bbn.NewBTCPKsFromBIP340PKs(bsParams.CovenantPks) if err != nil { - return nil, fmt.Errorf("failed to convert covenant pks to BTC pks: %v", err) + return nil, fmt.Errorf("failed to convert covenant pks to BTC pks: %w", err) } if d.UnbondingTime > uint32(^uint16(0)) { @@ -229,11 +230,11 @@ func BuildUnbondingSlashingTxWithWitness( btcNet, ) if err != nil { - return nil, fmt.Errorf("could not create BTC unbonding info: %v", err) + return nil, fmt.Errorf("could not create BTC unbonding info: %w", err) } slashingSpendInfo, err := unbondingInfo.SlashingPathSpendInfo() if err != nil { - return nil, fmt.Errorf("could not get unbonding slashing spend info: %v", err) + return nil, fmt.Errorf("could not get unbonding slashing spend info: %w", err) } // get the list of covenant signatures encrypted by the given finality provider's PK @@ -272,7 +273,7 @@ func BuildUnbondingSlashingTxWithWitness( ) if err != nil { return nil, fmt.Errorf( - "failed to build witness for unbonding BTC delegation %s under finality provider %s: %v", + "failed to build witness for unbonding BTC delegation %s under finality provider %s: %w", d.BtcPk.MarshalHex(), bbn.NewBIP340PubKeyFromBTCPK(fpSK.PubKey()).MarshalHex(), err, @@ -313,12 +314,12 @@ func BuildSlashingTxWithWitness( fpBtcPkList, err := bbn.NewBTCPKsFromBIP340PKs(d.FpBtcPkList) if err != nil { - return nil, fmt.Errorf("failed to convert finality provider pks to BTC pks: %v", err) + return nil, fmt.Errorf("failed to convert finality provider pks to BTC pks: %w", err) } covenantBtcPkList, err := bbn.NewBTCPKsFromBIP340PKs(bsParams.CovenantPks) if err != nil { - return nil, fmt.Errorf("failed to convert covenant pks to BTC pks: %v", err) + return nil, fmt.Errorf("failed to convert covenant pks to BTC pks: %w", err) } if d.TotalSat > math.MaxInt64 { @@ -337,11 +338,11 @@ func BuildSlashingTxWithWitness( btcNet, ) if err != nil { - return nil, fmt.Errorf("could not create BTC staking info: %v", err) + return nil, fmt.Errorf("could not create BTC staking info: %w", err) } slashingSpendInfo, err := stakingInfo.SlashingPathSpendInfo() if err != nil { - return nil, fmt.Errorf("could not get slashing spend info: %v", err) + return nil, fmt.Errorf("could not get slashing spend info: %w", err) } // get the list of covenant signatures encrypted by the given finality provider's PK @@ -380,7 +381,7 @@ func BuildSlashingTxWithWitness( ) if err != nil { return nil, fmt.Errorf( - "failed to build witness for BTC delegation of %s under finality provider %s: %v", + "failed to build witness for BTC delegation of %s under finality provider %s: %w", d.BtcPk.MarshalHex(), bbn.NewBIP340PubKeyFromBTCPK(fpSK.PubKey()).MarshalHex(), err, diff --git a/btcstaking-tracker/expected_routines.go b/btcstaking-tracker/expected_routines.go index 9106e8be..54ebcb08 100644 --- a/btcstaking-tracker/expected_routines.go +++ b/btcstaking-tracker/expected_routines.go @@ -1,4 +1,4 @@ -package btcstaking_tracker +package btcstakingtracker type IBTCSlasher interface { // common functions diff --git a/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go b/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go index 95c131be..b33fb81b 100644 --- a/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go +++ b/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go @@ -180,7 +180,7 @@ func (sew *StakingEventWatcher) checkBabylonDelegations(status btcstakingtypes.B delegations, err := sew.babylonNodeAdapter.DelegationsByStatus(status, i, sew.cfg.NewDelegationsBatchSize) if err != nil { - return fmt.Errorf("error fetching active delegations from babylon: %v", err) + return fmt.Errorf("error fetching active delegations from babylon: %w", err) } sew.logger.Debugf("fetched %d delegations from babylon by status %s", len(delegations), status) @@ -324,13 +324,13 @@ func tryParseStakerSignatureFromSpentTx(tx *wire.MsgTx, td *TrackedDelegation) ( } if tx.TxOut[0].Value != td.UnbondingOutput.Value || !bytes.Equal(tx.TxOut[0].PkScript, td.UnbondingOutput.PkScript) { - return nil, fmt.Errorf("unbonding tx must have ouput which matches unbonding output of retrieved from Babylon") + return nil, fmt.Errorf("unbonding tx must have output which matches unbonding output of retrieved from Babylon") } stakingTxInputIdx, err := getStakingTxInputIdx(tx, td) if err != nil { - return nil, fmt.Errorf("unbonding tx does not spend staking output: %v", err) + return nil, fmt.Errorf("unbonding tx does not spend staking output: %w", err) } stakingTxInput := tx.TxIn[stakingTxInputIdx] @@ -358,13 +358,13 @@ func (sew *StakingEventWatcher) reportUnbondingToBabylon( active, err := sew.babylonNodeAdapter.IsDelegationActive(stakingTxHash) if err != nil { - return fmt.Errorf("error checking if delegation is active: %v", err) + return fmt.Errorf("error checking if delegation is active: %w", err) } verified, err := sew.babylonNodeAdapter.IsDelegationVerified(stakingTxHash) if err != nil { - return fmt.Errorf("error checking if delegation is verified: %v", err) + return fmt.Errorf("error checking if delegation is verified: %w", err) } if !active && !verified { @@ -374,7 +374,7 @@ func (sew *StakingEventWatcher) reportUnbondingToBabylon( if err = sew.babylonNodeAdapter.ReportUnbonding(ctx, stakingTxHash, stakeSpendingTx, proof); err != nil { sew.metrics.FailedReportedUnbondingTransactions.Inc() - return fmt.Errorf("error reporting unbonding tx %s to babylon: %v", stakingTxHash, err) + return fmt.Errorf("error reporting unbonding tx %s to babylon: %w", stakingTxHash, err) } sew.metrics.ReportedUnbondingTransactionsCounter.Inc() @@ -396,7 +396,7 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t quitCtx, cancel := sew.quitContext() defer cancel() - var spendingTx *wire.MsgTx = nil + var spendingTx *wire.MsgTx select { case spendDetail := <-spendEvent.Spend: spendingTx = spendDetail.SpendingTx @@ -405,7 +405,7 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t } _, err := tryParseStakerSignatureFromSpentTx(spendingTx, td) - delegationId := td.StakingTx.TxHash() + delegationID := td.StakingTx.TxHash() spendingTxHash := spendingTx.TxHash() if err != nil { @@ -414,30 +414,30 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t // either withdrawal transaction or slashing transaction spending staking staking output. // As we only care about unbonding transactions, we do not need to take additional actions. // We start polling babylon for delegation to stop being active, and then delete it from unbondingTracker. - sew.logger.Debugf("Spending tx %s for staking tx %s is not unbonding tx. Info: %v", spendingTxHash, delegationId, err) - proof, err := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) - if err != nil { - sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationId) + sew.logger.Debugf("Spending tx %s for staking tx %s is not unbonding tx. Info: %v", spendingTxHash, delegationID, err) + proof := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) + if proof == nil { + sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationID) return } - sew.reportUnbondingToBabylon(quitCtx, delegationId, spendingTx, proof) + sew.reportUnbondingToBabylon(quitCtx, delegationID, spendingTx, proof) } else { sew.metrics.DetectedUnbondingTransactionsCounter.Inc() // We found valid unbonding tx. We need to try to report it to babylon. // We stop reporting if delegation is no longer active or we succeed. - proof, err := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) - if err != nil { - sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationId) + proof := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) + if proof == nil { + sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationID) return } - sew.logger.Debugf("found unbonding tx %s for staking tx %s", spendingTxHash, delegationId) - sew.reportUnbondingToBabylon(quitCtx, delegationId, spendingTx, proof) - sew.logger.Debugf("unbonding tx %s for staking tx %s reported to babylon", spendingTxHash, delegationId) + sew.logger.Debugf("found unbonding tx %s for staking tx %s", spendingTxHash, delegationID) + sew.reportUnbondingToBabylon(quitCtx, delegationID, spendingTx, proof) + sew.logger.Debugf("unbonding tx %s for staking tx %s reported to babylon", spendingTxHash, delegationID) } utils.PushOrQuit[*delegationInactive]( sew.unbondingRemovalChan, - &delegationInactive{stakingTxHash: delegationId}, + &delegationInactive{stakingTxHash: delegationID}, sew.quit, ) } @@ -471,7 +471,7 @@ func (sew *StakingEventWatcher) buildSpendingTxProof(spendingTx *wire.MsgTx) (*b func (sew *StakingEventWatcher) waitForStakeSpendInclusionProof( ctx context.Context, spendingTx *wire.MsgTx, -) (*btcstakingtypes.InclusionProof, error) { +) *btcstakingtypes.InclusionProof { var ( proof *btcstakingtypes.InclusionProof err error @@ -498,7 +498,7 @@ func (sew *StakingEventWatcher) waitForStakeSpendInclusionProof( }), ) - return proof, nil + return proof } func (sew *StakingEventWatcher) handleUnbondedDelegations() { @@ -564,12 +564,7 @@ func (sew *StakingEventWatcher) handlerVerifiedDelegations() { select { case <-ticker.C: sew.logger.Debug("Checking for new staking txs") - - if err := sew.checkBtcForStakingTx(); err != nil { - sew.logger.Errorf("error checking verified delegations: %v", err) - continue - } - + sew.checkBtcForStakingTx() case <-sew.quit: sew.logger.Debug("verified delegations loop quit") return @@ -579,7 +574,7 @@ func (sew *StakingEventWatcher) handlerVerifiedDelegations() { // checkBtcForStakingTx gets a snapshot of current Delegations in cache // checks if staking tx is in BTC, generates a proof and invokes sending of MsgAddBTCDelegationInclusionProof -func (sew *StakingEventWatcher) checkBtcForStakingTx() error { +func (sew *StakingEventWatcher) checkBtcForStakingTx() { for del := range sew.pendingTracker.DelegationsIter() { if del.ActivationInProgress { continue @@ -607,8 +602,6 @@ func (sew *StakingEventWatcher) checkBtcForStakingTx() error { go sew.activateBtcDelegation(txHash, proof) } - - return nil } // activateBtcDelegation invokes bbn client and send MsgAddBTCDelegationInclusionProof @@ -624,7 +617,7 @@ func (sew *StakingEventWatcher) activateBtcDelegation( _ = retry.Do(func() error { verified, err := sew.babylonNodeAdapter.IsDelegationVerified(stakingTxHash) if err != nil { - return fmt.Errorf("error checking if delegation is active: %v", err) + return fmt.Errorf("error checking if delegation is active: %w", err) } if !verified { @@ -634,7 +627,7 @@ func (sew *StakingEventWatcher) activateBtcDelegation( if err := sew.babylonNodeAdapter.ActivateDelegation(ctx, stakingTxHash, proof); err != nil { sew.metrics.FailedReportedActivateDelegations.Inc() - return fmt.Errorf("error reporting activate delegation tx %s to babylon: %v", stakingTxHash, err) + return fmt.Errorf("error reporting activate delegation tx %s to babylon: %w", stakingTxHash, err) } sew.metrics.ReportedActivateDelegationsCounter.Inc() diff --git a/btcstaking-tracker/stakingeventwatcher/tracked_delegations.go b/btcstaking-tracker/stakingeventwatcher/tracked_delegations.go index 5d2ddce6..aad1f094 100644 --- a/btcstaking-tracker/stakingeventwatcher/tracked_delegations.go +++ b/btcstaking-tracker/stakingeventwatcher/tracked_delegations.go @@ -74,20 +74,20 @@ func (td *TrackedDelegations) DelegationsIter() iter.Seq[*TrackedDelegation] { } func (td *TrackedDelegations) AddDelegation( - StakingTx *wire.MsgTx, - StakingOutputIdx uint32, - UnbondingOutput *wire.TxOut, + stakingTx *wire.MsgTx, + stakingOutputIdx uint32, + unbondingOutput *wire.TxOut, delegationStartHeight uint32, shouldUpdate bool, ) (*TrackedDelegation, error) { delegation := &TrackedDelegation{ - StakingTx: StakingTx, - StakingOutputIdx: StakingOutputIdx, - UnbondingOutput: UnbondingOutput, + StakingTx: stakingTx, + StakingOutputIdx: stakingOutputIdx, + UnbondingOutput: unbondingOutput, DelegationStartHeight: delegationStartHeight, } - stakingTxHash := StakingTx.TxHash() + stakingTxHash := stakingTx.TxHash() td.mu.Lock() defer td.mu.Unlock() @@ -115,7 +115,7 @@ func (td *TrackedDelegations) RemoveDelegation(stakingTxHash chainhash.Hash) { func (td *TrackedDelegations) HasDelegationChanged( stakingTxHash chainhash.Hash, newDelegation *newDelegation, -) (exists bool, changed bool) { +) (bool, bool) { td.mu.Lock() defer td.mu.Unlock() diff --git a/btcstaking-tracker/tracker.go b/btcstaking-tracker/tracker.go index 3137f80a..85152ba5 100644 --- a/btcstaking-tracker/tracker.go +++ b/btcstaking-tracker/tracker.go @@ -1,4 +1,4 @@ -package btcstaking_tracker +package btcstakingtracker import ( "fmt" diff --git a/cmd/vigilante/cmd/btcstaking_tracker.go b/cmd/vigilante/cmd/btcstaking_tracker.go index c1d78b7d..dd8e6678 100644 --- a/cmd/vigilante/cmd/btcstaking_tracker.go +++ b/cmd/vigilante/cmd/btcstaking_tracker.go @@ -15,7 +15,7 @@ import ( func GetBTCStakingTracker() *cobra.Command { var babylonKeyDir string var cfgFile = "" - var startHeight uint64 = 0 + var startHeight uint64 cmd := &cobra.Command{ Use: "bstracker", @@ -143,7 +143,6 @@ func GetBTCStakingTracker() *cobra.Command { <-interruptHandlersDone rootLogger.Info("Shutdown complete") - }, } cmd.Flags().StringVar(&babylonKeyDir, "babylon-key", "", "Directory of the Babylon key") diff --git a/cmd/vigilante/cmd/monitor.go b/cmd/vigilante/cmd/monitor.go index 35da53d4..11f376c3 100644 --- a/cmd/vigilante/cmd/monitor.go +++ b/cmd/vigilante/cmd/monitor.go @@ -79,7 +79,7 @@ func GetMonitorCmd() *cobra.Command { panic(err) } - dbBackend, err := cfg.Monitor.DatabaseConfig.GetDbBackend() + dbBackend, err := cfg.Monitor.DatabaseConfig.GetDBBackend() if err != nil { panic(err) } diff --git a/cmd/vigilante/cmd/reporter.go b/cmd/vigilante/cmd/reporter.go index ec4b1596..02d21ed0 100644 --- a/cmd/vigilante/cmd/reporter.go +++ b/cmd/vigilante/cmd/reporter.go @@ -118,7 +118,6 @@ func GetReporterCmd() *cobra.Command { <-interruptHandlersDone rootLogger.Info("Shutdown complete") - }, } cmd.Flags().StringVar(&babylonKeyDir, "babylon-key-dir", "", "Directory of the Babylon key") diff --git a/cmd/vigilante/cmd/submitter.go b/cmd/vigilante/cmd/submitter.go index a734578d..3c6d7986 100644 --- a/cmd/vigilante/cmd/submitter.go +++ b/cmd/vigilante/cmd/submitter.go @@ -62,7 +62,7 @@ func GetSubmitterCmd() *cobra.Command { // register submitter metrics submitterMetrics := metrics.NewSubmitterMetrics() - dbBackend, err := cfg.Submitter.DatabaseConfig.GetDbBackend() + dbBackend, err := cfg.Submitter.DatabaseConfig.GetDBBackend() if err != nil { panic(err) } diff --git a/cmd/vigilante/main.go b/cmd/vigilante/main.go index cdca8091..4b313ca5 100644 --- a/cmd/vigilante/main.go +++ b/cmd/vigilante/main.go @@ -15,11 +15,7 @@ func main() { rootCmd := cmd.NewRootCmd() if err := rootCmd.Execute(); err != nil { - switch e := err.(type) { - // TODO: dedicated error codes for vigilantes - default: - fmt.Print(e.Error()) - os.Exit(1) - } + fmt.Print(err.Error()) + os.Exit(1) } } diff --git a/config/bitcoin.go b/config/bitcoin.go index 0b89ea07..561c4cd2 100644 --- a/config/bitcoin.go +++ b/config/bitcoin.go @@ -81,14 +81,14 @@ func (cfg *BTCConfig) Validate() error { return nil } +// Config for polling jitter in bitcoind client, with polling enabled const ( - // Config for polling jittner in bitcoind client, with polling enabled DefaultTxPollingJitter = 0.5 - DefaultRpcBtcNodeHost = "127.0.01:18556" - DefaultBtcNodeRpcUser = "rpcuser" - DefaultBtcNodeRpcPass = "rpcpass" + DefaultRPCBtcNodeHost = "127.0.01:18556" + DefaultBtcNodeRPCUser = "rpcuser" + DefaultBtcNodeRPCPass = "rpcpass" DefaultBtcNodeEstimateMode = "CONSERVATIVE" - DefaultBtcblockCacheSize = 20 * 1024 * 1024 // 20 MB + DefaultBtcBlockCacheSize = 20 * 1024 * 1024 // 20 MB DefaultZmqSeqEndpoint = "tcp://127.0.0.1:28333" DefaultZmqBlockEndpoint = "tcp://127.0.0.1:29001" DefaultZmqTxEndpoint = "tcp://127.0.0.1:29002" @@ -96,7 +96,7 @@ const ( func DefaultBTCConfig() BTCConfig { return BTCConfig{ - Endpoint: DefaultRpcBtcNodeHost, + Endpoint: DefaultRPCBtcNodeHost, WalletPassword: "walletpass", WalletName: "default", WalletLockTime: 10, @@ -106,8 +106,8 @@ func DefaultBTCConfig() BTCConfig { EstimateMode: DefaultBtcNodeEstimateMode, TargetBlockNum: 1, NetParams: types.BtcSimnet.String(), - Username: DefaultBtcNodeRpcUser, - Password: DefaultBtcNodeRpcPass, + Username: DefaultBtcNodeRPCUser, + Password: DefaultBtcNodeRPCPass, ReconnectAttempts: 3, ZmqSeqEndpoint: DefaultZmqSeqEndpoint, ZmqBlockEndpoint: DefaultZmqBlockEndpoint, diff --git a/config/config.go b/config/config.go index 6ebbb979..9df6b623 100644 --- a/config/config.go +++ b/config/config.go @@ -112,22 +112,29 @@ func DefaultConfig() *Config { // New returns a fully parsed Config object from a given file directory func New(configFile string) (Config, error) { - if _, err := os.Stat(configFile); err == nil { // the given file exists, parse it - viper.SetConfigFile(configFile) - if err := viper.ReadInConfig(); err != nil { - return Config{}, err + if _, err := os.Stat(configFile); err != nil { + if errors.Is(err, os.ErrNotExist) { + // The given config file does not exist + return Config{}, fmt.Errorf("no config file found at %s", configFile) } - var cfg Config - if err := viper.Unmarshal(&cfg); err != nil { - return Config{}, err - } - if err := cfg.Validate(); err != nil { - return Config{}, err - } - return cfg, err - } else if errors.Is(err, os.ErrNotExist) { // the given config file does not exist, return error - return Config{}, fmt.Errorf("no config file found at %s", configFile) - } else { // other errors + // Other errors + return Config{}, err + } + + // File exists, so parse it + viper.SetConfigFile(configFile) + if err := viper.ReadInConfig(); err != nil { + return Config{}, err + } + + var cfg Config + if err := viper.Unmarshal(&cfg); err != nil { + return Config{}, err + } + + if err := cfg.Validate(); err != nil { return Config{}, err } + + return cfg, nil } diff --git a/config/dbconfig.go b/config/dbconfig.go index 2acf497e..8b044def 100644 --- a/config/dbconfig.go +++ b/config/dbconfig.go @@ -8,7 +8,7 @@ import ( ) const ( - defaultDbName = "vigilante.db" + defaultDBName = "vigilante.db" ) type DBConfig struct { @@ -48,7 +48,7 @@ func DefaultDBConfig() *DBConfig { func DefaultDBConfigWithHomePath(homePath string) *DBConfig { return &DBConfig{ DBPath: DataDir(homePath), - DBFileName: defaultDbName, + DBFileName: defaultDBName, NoFreelistSync: true, AutoCompact: false, AutoCompactMinAge: kvdb.DefaultBoltAutoCompactMinAge, @@ -78,6 +78,6 @@ func (cfg *DBConfig) Validate() error { return nil } -func (cfg *DBConfig) GetDbBackend() (kvdb.Backend, error) { +func (cfg *DBConfig) GetDBBackend() (kvdb.Backend, error) { return kvdb.GetBoltBackend(cfg.ToBoltBackendConfig()) } diff --git a/metrics/btcstaking_tracker.go b/metrics/btcstaking_tracker.go index 17165478..3a977d29 100644 --- a/metrics/btcstaking_tracker.go +++ b/metrics/btcstaking_tracker.go @@ -40,7 +40,7 @@ func newUnbondingWatcherMetrics(registry *prometheus.Registry) *UnbondingWatcher Registry: registry, ReportedUnbondingTransactionsCounter: registerer.NewCounter(prometheus.CounterOpts{ Name: "unbonding_watcher_reported_unbonding_transactions", - Help: "The total number of unbonding transactions successfuly reported to Babylon node", + Help: "The total number of unbonding transactions successfully reported to Babylon node", }), FailedReportedUnbondingTransactions: registerer.NewCounter(prometheus.CounterOpts{ Name: "unbonding_watcher_failed_reported_unbonding_transactions", @@ -64,7 +64,7 @@ func newUnbondingWatcherMetrics(registry *prometheus.Registry) *UnbondingWatcher }), ReportedActivateDelegationsCounter: registerer.NewCounter(prometheus.CounterOpts{ Name: "unbonding_watcher_reported_activate_delegations", - Help: "The total number of unbonding transactions successfuly reported to Babylon node", + Help: "The total number of unbonding transactions successfully reported to Babylon node", }), } @@ -112,7 +112,7 @@ func newSlasherMetrics(registry *prometheus.Registry) *SlasherMetrics { return metrics } -func (sm *SlasherMetrics) RecordSlashedDelegation(del *types.BTCDelegationResponse, txHashStr string) { +func (sm *SlasherMetrics) RecordSlashedDelegation(del *types.BTCDelegationResponse) { // refresh time of the slashed delegation gauge for each (fp, del) pair for _, pk := range del.FpBtcPkList { sm.SlashedDelegationGaugeVec.WithLabelValues( diff --git a/metrics/reporter.go b/metrics/reporter.go index f3f251ca..c31e76ea 100644 --- a/metrics/reporter.go +++ b/metrics/reporter.go @@ -88,5 +88,4 @@ func (sm *ReporterMetrics) RecordMetrics() { sm.SecondsSinceLastCheckpointGauge.Inc() } }() - } diff --git a/monitor/btcscanner/btc_scanner_test.go b/monitor/btcscanner/btc_scanner_test.go index 800d2c98..f8466f22 100644 --- a/monitor/btcscanner/btc_scanner_test.go +++ b/monitor/btcscanner/btc_scanner_test.go @@ -30,9 +30,9 @@ func FuzzBootStrap(f *testing.F) { defer ctl.Finish() mockBtcClient := mocks.NewMockBTCClient(ctl) confirmedBlocks := chainIndexedBlocks[:numBlocks-uint64(k)] - mockBtcClient.EXPECT().GetBestBlock().Return(uint32(bestHeight), nil) + mockBtcClient.EXPECT().GetBestBlock().Return(bestHeight, nil) for i := 0; i < int(numBlocks); i++ { - mockBtcClient.EXPECT().GetBlockByHeight(gomock.Eq(uint32(chainIndexedBlocks[i].Height))). + mockBtcClient.EXPECT().GetBlockByHeight(gomock.Eq(chainIndexedBlocks[i].Height)). Return(chainIndexedBlocks[i], nil, nil).AnyTimes() } @@ -40,7 +40,7 @@ func FuzzBootStrap(f *testing.F) { require.NoError(t, err) var btcScanner btcscanner.BtcScanner btcScanner.SetBtcClient(mockBtcClient) - btcScanner.SetBaseHeight(uint32(baseHeight)) + btcScanner.SetBaseHeight(baseHeight) btcScanner.SetK(k) btcScanner.SetConfirmedBlocksChan(make(chan *types.IndexedBlock)) btcScanner.SetUnconfirmedBlockCache(cache) diff --git a/monitor/monitor.go b/monitor/monitor.go index a913396c..b9618731 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -139,14 +139,14 @@ func (m *Monitor) Start(baseHeight uint32) { // get the height from db if it exists otherwise use the baseHeight provided from genesis var startHeight uint32 dbHeight, exists, err := m.store.LatestHeight() - if err != nil { + switch { + case err != nil: panic(fmt.Errorf("error getting latest height from db %w", err)) - } else if !exists { + case !exists: startHeight = baseHeight - } else { - if dbHeight > math.MaxUint32 { - panic(fmt.Errorf("dbHeight %d exceeds uint32 range", dbHeight)) - } + case dbHeight > math.MaxUint32: + panic(fmt.Errorf("dbHeight %d exceeds uint32 range", dbHeight)) + default: startHeight = uint32(dbHeight) + 1 } @@ -250,7 +250,6 @@ func (m *Monitor) VerifyCheckpoint(btcCkpt *checkpointingtypes.RawCheckpoint) er return errors.Wrapf(types.ErrInvalidEpochNum, "found a checkpoint with epoch %v, but the monitor expects epoch %v", btcCkpt.EpochNum, m.GetCurrentEpoch()) - } // verify BLS sig of the BTC checkpoint err := m.curEpoch.VerifyMultiSig(btcCkpt) diff --git a/monitor/store/store.go b/monitor/store/store.go index ff6e3681..5cd90ca4 100644 --- a/monitor/store/store.go +++ b/monitor/store/store.go @@ -21,8 +21,8 @@ var ( ) var ( - // ErrCorruptedDb For some reason, db on disk representation have changed - ErrCorruptedDb = errors.New("db is corrupted") + // ErrCorruptedDB For some reason, db on disk representation have changed + ErrCorruptedDB = errors.New("db is corrupted") // ErrNotFound Value not found ErrNotFound = errors.New("not found") ) @@ -76,7 +76,7 @@ func (s *MonitorStore) get(key, bucketName []byte) (uint64, bool, error) { err := s.db.View(func(tx walletdb.ReadTx) error { b := tx.ReadBucket(bucketName) if b == nil { - return ErrCorruptedDb + return ErrCorruptedDB } byteVal := b.Get(key) @@ -107,7 +107,7 @@ func (s *MonitorStore) put(key []byte, val uint64, bucketName []byte) error { return kvdb.Batch(s.db, func(tx kvdb.RwTx) error { bucket := tx.ReadWriteBucket(bucketName) if bucket == nil { - return ErrCorruptedDb + return ErrCorruptedDB } return bucket.Put(key, uint64ToBytes(val)) diff --git a/reporter/block_handler.go b/reporter/block_handler.go index 6c6ddd5c..19072c54 100644 --- a/reporter/block_handler.go +++ b/reporter/block_handler.go @@ -96,9 +96,7 @@ func (r *Reporter) processNewBlock(ib *types.IndexedBlock) error { } // Process checkpoints - if _, _, err := r.ProcessCheckpoints(signer, headersToProcess); err != nil { - r.logger.Warnf("Failed to submit checkpoints: %v", err) - } + _, _ = r.ProcessCheckpoints(signer, headersToProcess) return nil } diff --git a/reporter/bootstrapping.go b/reporter/bootstrapping.go index f2bfc0c5..6b47b66d 100644 --- a/reporter/bootstrapping.go +++ b/reporter/bootstrapping.go @@ -29,7 +29,6 @@ type consistencyCheckInfo struct { // between BBN header chain and BTC main chain.` This makes sure that already confirmed chain is the same from point // of view of both chains. func (r *Reporter) checkConsistency() (*consistencyCheckInfo, error) { - tipRes, err := r.babylonClient.BTCHeaderChainTip() if err != nil { return nil, err @@ -116,10 +115,7 @@ func (r *Reporter) bootstrap() error { // fetch k+w blocks from cache and submit checkpoints ibs = r.btcCache.GetAllBlocks() - _, _, err = r.ProcessCheckpoints(signer, ibs) - if err != nil { - r.logger.Warnf("Failed to submit checkpoints: %v", err) - } + _, _ = r.ProcessCheckpoints(signer, ibs) r.logger.Info("Successfully finished bootstrapping") @@ -158,7 +154,6 @@ func (r *Reporter) bootstrapWithRetries() { bootstrapErrReportType, retry.OnRetry(func(n uint, err error) { r.logger.Warnf("Failed to bootstap reporter: %v. Attempt: %d, Max attempts: %d", err, n+1, bootstrapAttempts) })); err != nil { - if errors.Is(err, context.Canceled) { // context was cancelled we do not need to anything more, app is quiting return diff --git a/reporter/utils.go b/reporter/utils.go index 73373f38..15d90300 100644 --- a/reporter/utils.go +++ b/reporter/utils.go @@ -6,15 +6,14 @@ import ( "github.com/babylonlabs-io/vigilante/retrywrap" "strconv" - pv "github.com/cosmos/relayer/v2/relayer/provider" - "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" ) -func chunkBy[T any](items []T, chunkSize int) (chunks [][]T) { +func chunkBy[T any](items []T, chunkSize int) [][]T { + var chunks [][]T for chunkSize < len(items) { items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize]) } @@ -144,19 +143,17 @@ func (r *Reporter) extractCheckpoints(ib *types.IndexedBlock) int { r.logger.Errorf("Failed to add the ckpt segment in tx %v to the ckptCache: %v", tx.Hash(), err) continue } - numCkptSegs += 1 + numCkptSegs++ } } return numCkptSegs } -func (r *Reporter) matchAndSubmitCheckpoints(signer string) (int, error) { +func (r *Reporter) matchAndSubmitCheckpoints(signer string) int { var ( - res *pv.RelayerTxResponse proofs []*btcctypes.BTCSpvProof msgInsertBTCSpvProof *btcctypes.MsgInsertBTCSpvProof - err error ) // get matched ckpt parts from the ckptCache @@ -166,7 +163,7 @@ func (r *Reporter) matchAndSubmitCheckpoints(signer string) (int, error) { if numMatchedCkpts == 0 { r.logger.Debug("Found no matched pair of checkpoint segments in this match attempt") - return numMatchedCkpts, nil + return numMatchedCkpts } // for each matched checkpoint, wrap to MsgInsertBTCSpvProof and send to Babylon @@ -188,7 +185,7 @@ func (r *Reporter) matchAndSubmitCheckpoints(signer string) (int, error) { msgInsertBTCSpvProof = types.MustNewMsgInsertBTCSpvProof(signer, proofs) // submit the checkpoint to Babylon - res, err = r.babylonClient.InsertBTCSpvProof(context.Background(), msgInsertBTCSpvProof) + res, err := r.babylonClient.InsertBTCSpvProof(context.Background(), msgInsertBTCSpvProof) if err != nil { r.logger.Errorf("Failed to submit MsgInsertBTCSpvProof with error %v", err) r.metrics.FailedCheckpointsCounter.Inc() @@ -207,12 +204,12 @@ func (r *Reporter) matchAndSubmitCheckpoints(signer string) (int, error) { ).SetToCurrentTime() } - return numMatchedCkpts, nil + return numMatchedCkpts } // ProcessCheckpoints tries to extract checkpoint segments from a list of blocks, find matched checkpoint segments, and report matched checkpoints // It returns the number of extracted checkpoint segments, and the number of matched checkpoints -func (r *Reporter) ProcessCheckpoints(signer string, ibs []*types.IndexedBlock) (int, int, error) { +func (r *Reporter) ProcessCheckpoints(signer string, ibs []*types.IndexedBlock) (int, int) { var numCkptSegs int // extract ckpt segments from the blocks @@ -225,7 +222,7 @@ func (r *Reporter) ProcessCheckpoints(signer string, ibs []*types.IndexedBlock) } // match and submit checkpoint segments - numMatchedCkpts, err := r.matchAndSubmitCheckpoints(signer) + numMatchedCkpts := r.matchAndSubmitCheckpoints(signer) - return numCkptSegs, numMatchedCkpts, err + return numCkptSegs, numMatchedCkpts } diff --git a/reporter/utils_test.go b/reporter/utils_test.go index 5f4b060a..71d03c55 100644 --- a/reporter/utils_test.go +++ b/reporter/utils_test.go @@ -22,7 +22,7 @@ import ( ) func newMockReporter(t *testing.T, ctrl *gomock.Controller) ( - *mocks.MockBTCClient, *reporter.MockBabylonClient, *reporter.Reporter) { + *reporter.MockBabylonClient, *reporter.Reporter) { cfg := config.DefaultConfig() logger, err := cfg.CreateLogger() require.NoError(t, err) @@ -47,7 +47,7 @@ func newMockReporter(t *testing.T, ctrl *gomock.Controller) ( ) require.NoError(t, err) - return mockBTCClient, mockBabylonClient, r + return mockBabylonClient, r } // FuzzProcessHeaders fuzz tests ProcessHeaders() @@ -70,7 +70,7 @@ func FuzzProcessHeaders(f *testing.F) { ibs = append(ibs, types.NewIndexedBlockFromMsgBlock(r.Uint32(), block)) } - _, mockBabylonClient, mockReporter := newMockReporter(t, ctrl) + mockBabylonClient, mockReporter := newMockReporter(t, ctrl) // a random number of blocks exists on chain numBlocksOnChain := r.Intn(int(numBlocks)) @@ -101,7 +101,7 @@ func FuzzProcessCheckpoints(f *testing.F) { defer ctrl.Finish() r := rand.New(rand.NewSource(seed)) - _, mockBabylonClient, mockReporter := newMockReporter(t, ctrl) + mockBabylonClient, mockReporter := newMockReporter(t, ctrl) // inserting SPV proofs is always successful mockBabylonClient.EXPECT().InsertBTCSpvProof(gomock.Any(), gomock.Any()).Return(&pv.RelayerTxResponse{Code: 0}, nil).AnyTimes() @@ -117,9 +117,8 @@ func FuzzProcessCheckpoints(f *testing.F) { } } - numCkptSegs, numMatchedCkpts, err := mockReporter.ProcessCheckpoints("", ibs) + numCkptSegs, numMatchedCkpts := mockReporter.ProcessCheckpoints("", ibs) require.Equal(t, numCkptSegsExpected, numCkptSegs) require.Equal(t, numMatchedCkptsExpected, numMatchedCkpts) - require.NoError(t, err) }) } diff --git a/rpcserver/server.go b/rpcserver/server.go index c223752b..92466824 100644 --- a/rpcserver/server.go +++ b/rpcserver/server.go @@ -59,7 +59,7 @@ func New( keyPair, err := openRPCKeyPair(cfg.OneTimeTLSKey, cfg.RPCKeyFile, cfg.RPCCertFile) if err != nil { - return nil, fmt.Errorf("open RPC key pair: %v", err) + return nil, fmt.Errorf("open RPC key pair: %w", err) } creds := credentials.NewServerTLSFromCert(&keyPair) diff --git a/rpcserver/service.go b/rpcserver/service.go index 83da6bd0..1059ec77 100644 --- a/rpcserver/service.go +++ b/rpcserver/service.go @@ -23,7 +23,7 @@ func StartVigilanteService(gs *grpc.Server) { pb.RegisterVigilanteServiceServer(gs, &service{}) } -func (s *service) Version(ctx context.Context, req *pb.VersionRequest) (*pb.VersionResponse, error) { +func (s *service) Version(_ context.Context, _ *pb.VersionRequest) (*pb.VersionResponse, error) { return &pb.VersionResponse{ VersionString: verString, Major: verMajor, diff --git a/rpcserver/tls.go b/rpcserver/tls.go index 6e9c94f2..8a8a908b 100644 --- a/rpcserver/tls.go +++ b/rpcserver/tls.go @@ -12,7 +12,7 @@ import ( // openRPCKeyPair creates or loads the RPC TLS keypair specified by the // application config. This function respects the cfg.OneTimeTLSKey setting. -func openRPCKeyPair(oneTimeTLSKey bool, RPCKeyFile string, RPCCertFile string) (tls.Certificate, error) { +func openRPCKeyPair(oneTimeTLSKey bool, rpcKeyFile string, rpcCertFile string) (tls.Certificate, error) { // Check for existence of the TLS key file. If one time TLS keys are // enabled but a key already exists, this function should error since // it's possible that a persistent certificate was copied to a remote @@ -21,28 +21,28 @@ func openRPCKeyPair(oneTimeTLSKey bool, RPCKeyFile string, RPCCertFile string) ( // acceptable if the previous execution used a one time TLS key. // Otherwise, both the cert and key should be read from disk. If the // cert is missing, the read error will occur in LoadX509KeyPair. - _, e := os.Stat(RPCKeyFile) + _, e := os.Stat(rpcKeyFile) keyExists := !os.IsNotExist(e) switch { case oneTimeTLSKey && keyExists: err := fmt.Errorf("one time TLS keys are enabled, but TLS key "+ - "`%s` already exists", RPCKeyFile) + "`%s` already exists", rpcKeyFile) return tls.Certificate{}, err case oneTimeTLSKey: - return generateRPCKeyPair(RPCKeyFile, RPCCertFile, false) + return generateRPCKeyPair(rpcKeyFile, rpcCertFile, false) case !keyExists: - return generateRPCKeyPair(RPCKeyFile, RPCCertFile, true) + return generateRPCKeyPair(rpcKeyFile, rpcCertFile, true) default: - return tls.LoadX509KeyPair(RPCCertFile, RPCKeyFile) + return tls.LoadX509KeyPair(rpcCertFile, rpcKeyFile) } } // generateRPCKeyPair generates a new RPC TLS keypair and writes the cert and // possibly also the key in PEM format to the paths specified by the config. If // successful, the new keypair is returned. -func generateRPCKeyPair(RPCKeyFile string, RPCCertFile string, writeKey bool) (tls.Certificate, error) { +func generateRPCKeyPair(rpcKeyFile string, rpcCertFile string, writeKey bool) (tls.Certificate, error) { // Create directories for cert and key files if they do not yet exist. - certDir, _ := filepath.Split(RPCCertFile) + certDir, _ := filepath.Split(rpcCertFile) err := os.MkdirAll(certDir, 0700) if err != nil { return tls.Certificate{}, err @@ -61,19 +61,19 @@ func generateRPCKeyPair(RPCKeyFile string, RPCCertFile string, writeKey bool) (t } // Write cert and (potentially) the key files. - err = os.WriteFile(RPCCertFile, cert, 0600) + err = os.WriteFile(rpcCertFile, cert, 0600) if err != nil { return tls.Certificate{}, err } if writeKey { - keyDir, _ := filepath.Split(RPCKeyFile) + keyDir, _ := filepath.Split(rpcKeyFile) err = os.MkdirAll(keyDir, 0700) if err != nil { return tls.Certificate{}, err } - err = os.WriteFile(RPCKeyFile, key, 0600) + err = os.WriteFile(rpcKeyFile, key, 0600) if err != nil { - _ = os.Remove(RPCCertFile) //nolint: errcheck + _ = os.Remove(rpcCertFile) //nolint: errcheck return tls.Certificate{}, err } } diff --git a/submitter/relayer/change_address_test.go b/submitter/relayer/change_address_test.go index 591a8c6d..4e5a768f 100644 --- a/submitter/relayer/change_address_test.go +++ b/submitter/relayer/change_address_test.go @@ -53,7 +53,8 @@ func TestGetChangeAddress(t *testing.T) { submitterMetrics.RelayerMetrics, nil, &cfg, logger, testutil.MakeTestBackend(t)) // 1. only SegWit Bech32 addresses - segWitBech32Addrs := append(SegWitBech32p2wshAddrsStr, SegWitBech32p2wpkhAddrsStr...) + SegWitBech32p2wshAddrsStr = append(SegWitBech32p2wshAddrsStr, SegWitBech32p2wpkhAddrsStr...) + segWitBech32Addrs := SegWitBech32p2wshAddrsStr wallet.EXPECT().ListUnspent().Return(getAddrsResult(segWitBech32Addrs), nil) changeAddr, err := testRelayer.GetChangeAddress() require.NoError(t, err) @@ -70,7 +71,8 @@ func TestGetChangeAddress(t *testing.T) { require.NoError(t, err) // 3. SegWit-Bech32 + legacy addresses, should only return SegWit-Bech32 addresses - addrs := append(segWitBech32Addrs, legacyAddrsStr...) + segWitBech32Addrs = append(segWitBech32Addrs, legacyAddrsStr...) + addrs := segWitBech32Addrs wallet.EXPECT().ListUnspent().Return(getAddrsResult(addrs), nil) changeAddr, err = testRelayer.GetChangeAddress() require.NoError(t, err) diff --git a/submitter/relayer/relayer.go b/submitter/relayer/relayer.go index fc03ebb4..fca0665e 100644 --- a/submitter/relayer/relayer.go +++ b/submitter/relayer/relayer.go @@ -33,10 +33,6 @@ const ( dustThreshold btcutil.Amount = 546 ) -var ( - TxNotFoundErr = errors.New("-5: No such mempool or blockchain transaction. Use gettransaction for wallet transactions") -) - type GetLatestCheckpointFunc func() (*store.StoredCheckpoint, bool, error) type GetRawTransactionFunc func(txHash *chainhash.Hash) (*btcutil.Tx, error) type SendTransactionFunc func(tx *wire.MsgTx) (*chainhash.Hash, error) @@ -140,7 +136,7 @@ func (rl *Relayer) SendCheckpointToBTC(ckpt *ckpttypes.RawCheckpointWithMetaResp return nil } else if rl.shouldSendTx2(ckptEpoch) { - rl.logger.Infof("Retrying to send tx2 for epoch %v, tx1 %s", ckptEpoch, rl.lastSubmittedCheckpoint.Tx1.TxId) + rl.logger.Infof("Retrying to send tx2 for epoch %v, tx1 %s", ckptEpoch, rl.lastSubmittedCheckpoint.Tx1.TxID) submittedCkpt, err := rl.retrySendTx2(ckpt.Ckpt) if err != nil { return err @@ -177,7 +173,7 @@ func (rl *Relayer) MaybeResubmitSecondCheckpointTx(ckpt *ckpttypes.RawCheckpoint return nil } - durSeconds := uint(time.Since(rl.lastSubmittedCheckpoint.Ts).Seconds()) + durSeconds := uint(time.Since(rl.lastSubmittedCheckpoint.TS).Seconds()) if durSeconds < rl.config.ResendIntervalSeconds { return nil } @@ -193,7 +189,7 @@ func (rl *Relayer) MaybeResubmitSecondCheckpointTx(ckpt *ckpttypes.RawCheckpoint } rl.logger.Debugf("Resending the second tx of the checkpoint %v, old fee of the second tx: %v Satoshis, txid: %s", - ckptEpoch, rl.lastSubmittedCheckpoint.Tx2.Fee, rl.lastSubmittedCheckpoint.Tx2.TxId.String()) + ckptEpoch, rl.lastSubmittedCheckpoint.Tx2.Fee, rl.lastSubmittedCheckpoint.Tx2.TxID.String()) resubmittedTx2, err := rl.resendSecondTxOfCheckpointToBTC(rl.lastSubmittedCheckpoint.Tx2, bumpedFee) if err != nil { @@ -205,13 +201,13 @@ func (rl *Relayer) MaybeResubmitSecondCheckpointTx(ckpt *ckpttypes.RawCheckpoint rl.metrics.NewSubmittedCheckpointSegmentGaugeVec.WithLabelValues( strconv.FormatUint(ckptEpoch, 10), "1", - resubmittedTx2.TxId.String(), + resubmittedTx2.TxID.String(), strconv.Itoa(int(resubmittedTx2.Fee)), ).SetToCurrentTime() rl.metrics.ResentCheckpointsCounter.Inc() rl.logger.Infof("Successfully re-sent the second tx of the checkpoint %v, txid: %s, bumped fee: %v Satoshis", - rl.lastSubmittedCheckpoint.Epoch, resubmittedTx2.TxId.String(), resubmittedTx2.Fee) + rl.lastSubmittedCheckpoint.Epoch, resubmittedTx2.TxID.String(), resubmittedTx2.Fee) // update the second tx of the last submitted checkpoint as it is replaced rl.lastSubmittedCheckpoint.Tx2 = resubmittedTx2 @@ -255,7 +251,7 @@ func (rl *Relayer) calculateBumpedFee(ckptInfo *types.CheckpointInfo) btcutil.Am // resendSecondTxOfCheckpointToBTC resends the second tx of the checkpoint with bumpedFee func (rl *Relayer) resendSecondTxOfCheckpointToBTC(tx2 *types.BtcTxInfo, bumpedFee btcutil.Amount) (*types.BtcTxInfo, error) { - _, status, err := rl.TxDetails(rl.lastSubmittedCheckpoint.Tx2.TxId, + _, status, err := rl.TxDetails(rl.lastSubmittedCheckpoint.Tx2.TxID, rl.lastSubmittedCheckpoint.Tx2.Tx.TxOut[changePosition].PkScript) if err != nil { return nil, err @@ -263,7 +259,7 @@ func (rl *Relayer) resendSecondTxOfCheckpointToBTC(tx2 *types.BtcTxInfo, bumpedF // No need to resend, transaction already confirmed if status == btcclient.TxInChain { - rl.logger.Debugf("Transaction %v is already confirmed", rl.lastSubmittedCheckpoint.Tx2.TxId) + rl.logger.Debugf("Transaction %v is already confirmed", rl.lastSubmittedCheckpoint.Tx2.TxID) return nil, nil } @@ -294,7 +290,7 @@ func (rl *Relayer) resendSecondTxOfCheckpointToBTC(tx2 *types.BtcTxInfo, bumpedF // update tx info tx2.Fee = bumpedFee - tx2.TxId = txID + tx2.TxID = txID return tx2, nil } @@ -404,7 +400,7 @@ func (rl *Relayer) convertCkptToTwoTxAndSubmit(ckpt *ckpttypes.RawCheckpointResp return &types.CheckpointInfo{ Epoch: ckpt.EpochNum, - Ts: time.Now(), + TS: time.Now(), Tx1: tx1, Tx2: tx2, }, nil @@ -432,7 +428,7 @@ func (rl *Relayer) retrySendTx2(ckpt *ckpttypes.RawCheckpointResponse) (*types.C return &types.CheckpointInfo{ Epoch: ckpt.EpochNum, - Ts: time.Now(), + TS: time.Now(), Tx1: tx1, Tx2: tx2, }, nil @@ -445,7 +441,7 @@ func (rl *Relayer) buildAndSendTx(data []byte, parentTx *wire.MsgTx) (*types.Btc return nil, fmt.Errorf("failed to add data to tx: %w", err) } - tx.TxId, err = rl.sendTxToBTC(tx.Tx) + tx.TxID, err = rl.sendTxToBTC(tx.Tx) if err != nil { return nil, fmt.Errorf("failed to send tx to BTC: %w", err) } @@ -616,7 +612,7 @@ func (rl *Relayer) getFeeRate() chainfee.SatPerKVByte { // check we are within the uint32 range if targetBlockNum < 0 || targetBlockNum > int64(^uint32(0)) { - panic(fmt.Errorf("targetBlockNum (%d) is out of uint32 range", targetBlockNum)) //software bug, panic + panic(fmt.Errorf("targetBlockNum (%d) is out of uint32 range", targetBlockNum)) // software bug, panic } fee, err := rl.EstimateFeePerKW(uint32(targetBlockNum)) if err != nil { diff --git a/submitter/relayer/relayer_test.go b/submitter/relayer/relayer_test.go index 75cf0161..9ce6dc3f 100644 --- a/submitter/relayer/relayer_test.go +++ b/submitter/relayer/relayer_test.go @@ -27,10 +27,10 @@ func Test_maybeResendFromStore(t *testing.T) { getLatestCheckpoint: func() (*store.StoredCheckpoint, bool, error) { return nil, false, nil }, - getRawTransaction: func(txHash *chainhash.Hash) (*btcutil.Tx, error) { + getRawTransaction: func(_ *chainhash.Hash) (*btcutil.Tx, error) { return nil, nil }, - sendTransaction: func(tx *wire.MsgTx) (*chainhash.Hash, error) { + sendTransaction: func(_ *wire.MsgTx) (*chainhash.Hash, error) { return nil, nil }, expectedResult: false, @@ -42,10 +42,10 @@ func Test_maybeResendFromStore(t *testing.T) { getLatestCheckpoint: func() (*store.StoredCheckpoint, bool, error) { return nil, false, errors.New("checkpoint error") }, - getRawTransaction: func(txHash *chainhash.Hash) (*btcutil.Tx, error) { + getRawTransaction: func(_ *chainhash.Hash) (*btcutil.Tx, error) { return nil, nil }, - sendTransaction: func(tx *wire.MsgTx) (*chainhash.Hash, error) { + sendTransaction: func(_ *wire.MsgTx) (*chainhash.Hash, error) { return nil, nil }, expectedResult: false, @@ -57,10 +57,10 @@ func Test_maybeResendFromStore(t *testing.T) { getLatestCheckpoint: func() (*store.StoredCheckpoint, bool, error) { return &store.StoredCheckpoint{Epoch: 456, Tx1: &wire.MsgTx{}, Tx2: &wire.MsgTx{}}, true, nil }, - getRawTransaction: func(txHash *chainhash.Hash) (*btcutil.Tx, error) { + getRawTransaction: func(_ *chainhash.Hash) (*btcutil.Tx, error) { return nil, nil }, - sendTransaction: func(tx *wire.MsgTx) (*chainhash.Hash, error) { + sendTransaction: func(_ *wire.MsgTx) (*chainhash.Hash, error) { return nil, nil }, expectedResult: false, @@ -72,10 +72,10 @@ func Test_maybeResendFromStore(t *testing.T) { getLatestCheckpoint: func() (*store.StoredCheckpoint, bool, error) { return &store.StoredCheckpoint{Epoch: 123, Tx1: &wire.MsgTx{}, Tx2: &wire.MsgTx{}}, true, nil }, - getRawTransaction: func(txHash *chainhash.Hash) (*btcutil.Tx, error) { + getRawTransaction: func(_ *chainhash.Hash) (*btcutil.Tx, error) { return nil, errors.New("transaction not found") // Simulate transaction not found }, - sendTransaction: func(tx *wire.MsgTx) (*chainhash.Hash, error) { + sendTransaction: func(_ *wire.MsgTx) (*chainhash.Hash, error) { return &chainhash.Hash{}, nil // Simulate successful send }, expectedResult: true, @@ -87,10 +87,10 @@ func Test_maybeResendFromStore(t *testing.T) { getLatestCheckpoint: func() (*store.StoredCheckpoint, bool, error) { return &store.StoredCheckpoint{Epoch: 123, Tx1: &wire.MsgTx{}, Tx2: &wire.MsgTx{}}, true, nil }, - getRawTransaction: func(txHash *chainhash.Hash) (*btcutil.Tx, error) { + getRawTransaction: func(_ *chainhash.Hash) (*btcutil.Tx, error) { return nil, errors.New("transaction not found") }, - sendTransaction: func(tx *wire.MsgTx) (*chainhash.Hash, error) { + sendTransaction: func(_ *wire.MsgTx) (*chainhash.Hash, error) { return nil, errors.New("send error") }, expectedResult: false, diff --git a/submitter/store/store.go b/submitter/store/store.go index 9fe2702b..63936ee3 100644 --- a/submitter/store/store.go +++ b/submitter/store/store.go @@ -21,8 +21,8 @@ var ( ) var ( - // ErrCorruptedDb For some reason, db on disk representation have changed - ErrCorruptedDb = errors.New("db is corrupted") + // ErrCorruptedDB For some reason, db on disk representation have changed + ErrCorruptedDB = errors.New("db is corrupted") // ErrNotFound Value not found ErrNotFound = errors.New("not found") ) @@ -109,7 +109,7 @@ func (s *SubmitterStore) get(key, bucketName []byte) ([]byte, bool, error) { err := s.db.View(func(tx walletdb.ReadTx) error { b := tx.ReadBucket(bucketName) if b == nil { - return ErrCorruptedDb + return ErrCorruptedDB } byteVal := b.Get(key) @@ -136,7 +136,7 @@ func (s *SubmitterStore) put(key []byte, val []byte, bucketName []byte) error { return kvdb.Batch(s.db, func(tx kvdb.RwTx) error { bucket := tx.ReadWriteBucket(bucketName) if bucket == nil { - return ErrCorruptedDb + return ErrCorruptedDB } return bucket.Put(key, val) diff --git a/testutil/datagen/reporter.go b/testutil/datagen/reporter.go index e8ab9b56..f627c054 100644 --- a/testutil/datagen/reporter.go +++ b/testutil/datagen/reporter.go @@ -13,7 +13,6 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" - _ "github.com/btcsuite/btcd/database/ffldb" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" ) @@ -144,16 +143,18 @@ func GenRandomBlock(r *rand.Rand, numBabylonTxs int, prevHash *chainhash.Hash) ( rawCkpt *btctxformatter.RawBtcCheckpoint ) - if numBabylonTxs == 2 { - randomTxs, rawCkpt = GenRandomBabylonTxPair(r) - } else if numBabylonTxs == 1 { + switch numBabylonTxs { + case 1: randomTxs, _ = GenRandomBabylonTxPair(r) randomTxs[1] = GenRandomTx(r) rawCkpt = nil - } else { + case 2: + randomTxs, rawCkpt = GenRandomBabylonTxPair(r) + default: randomTxs = []*wire.MsgTx{GenRandomTx(r), GenRandomTx(r)} rawCkpt = nil } + coinbaseTx := GenRandomTx(r) msgTxs := []*wire.MsgTx{coinbaseTx} msgTxs = append(msgTxs, randomTxs...) @@ -252,13 +253,14 @@ func GenRandomBlockchainWithBabylonTx(r *rand.Rand, n uint64, partialPercentage for i := uint64(1); i < n; i++ { var msgBlock *wire.MsgBlock prevHash := blocks[len(blocks)-1].BlockHash() - if r.Float32() < partialPercentage { + switch { + case r.Float32() < partialPercentage: msgBlock, rawCkpt = GenRandomBlock(r, 1, &prevHash) - numCkptSegs += 1 - } else if r.Float32() < partialPercentage+fullPercentage { + numCkptSegs++ + case r.Float32() < partialPercentage+fullPercentage: msgBlock, rawCkpt = GenRandomBlock(r, 2, &prevHash) numCkptSegs += 2 - } else { + default: msgBlock, rawCkpt = GenRandomBlock(r, 0, &prevHash) } diff --git a/testutil/store.go b/testutil/store.go index a198d35d..63d66dca 100644 --- a/testutil/store.go +++ b/testutil/store.go @@ -14,7 +14,7 @@ func MakeTestBackend(t *testing.T) kvdb.Backend { cfg.DBPath = tempDirName - backend, err := cfg.GetDbBackend() + backend, err := cfg.GetDBBackend() require.NoError(t, err) t.Cleanup(func() { diff --git a/types/btccache.go b/types/btccache.go index 973c7930..72c57f2b 100644 --- a/types/btccache.go +++ b/types/btccache.go @@ -38,7 +38,7 @@ func (b *BTCCache) Init(ibs []*IndexedBlock) error { if sortedByHeight := sort.SliceIsSorted(ibs, func(i, j int) bool { return ibs[i].Height < ibs[j].Height }); !sortedByHeight { - return ErrorUnsortedBlocks + return ErrUnsortedBlocks } for _, ib := range ibs { diff --git a/types/btccache_test.go b/types/btccache_test.go index c218e068..1d40e044 100644 --- a/types/btccache_test.go +++ b/types/btccache_test.go @@ -69,7 +69,7 @@ func FuzzBtcCache(f *testing.F) { // Find a random block in the cache randIdx := datagen.RandomInt(r, int(numBlocks)) randIb := ibs[randIdx] - randIbHeight := uint32(randIb.Height) + randIbHeight := randIb.Height foundIb := cache.FindBlock(randIbHeight) require.NotNil(t, foundIb) require.Equal(t, foundIb, randIb) diff --git a/types/btclightclient.go b/types/btclightclient.go index 72a39bc1..357c58da 100644 --- a/types/btclightclient.go +++ b/types/btclightclient.go @@ -9,7 +9,6 @@ func NewMsgInsertHeaders( signer string, headers []*IndexedBlock, ) *btcltypes.MsgInsertHeaders { - headerBytes := make([]babylontypes.BTCHeaderBytes, len(headers)) for i, h := range headers { header := h diff --git a/types/ckpt_bookkeeper.go b/types/ckpt_bookkeeper.go index 2ad6f5e6..1b1643e1 100644 --- a/types/ckpt_bookkeeper.go +++ b/types/ckpt_bookkeeper.go @@ -28,11 +28,9 @@ func (cb *CheckpointsBookkeeper) Add(cr *CheckpointRecord) { if !cb.has(id) { cb.checkpointRecords[id] = cr - } else { + } else if cb.checkpointRecords[id].FirstSeenBtcHeight > cr.FirstSeenBtcHeight { // replace with the older one if the checkpoint id exists - if cb.checkpointRecords[id].FirstSeenBtcHeight > cr.FirstSeenBtcHeight { - cb.checkpointRecords[id] = cr - } + cb.checkpointRecords[id] = cr } } diff --git a/types/ckpt_info.go b/types/ckpt_info.go index 0e87b890..692a08da 100644 --- a/types/ckpt_info.go +++ b/types/ckpt_info.go @@ -11,14 +11,14 @@ import ( // CheckpointInfo stores information of a BTC checkpoint type CheckpointInfo struct { Epoch uint64 - Ts time.Time // the timestamp of the checkpoint being sent + TS time.Time // the timestamp of the checkpoint being sent Tx1 *BtcTxInfo Tx2 *BtcTxInfo } // BtcTxInfo stores information of a BTC tx as part of a checkpoint type BtcTxInfo struct { - TxId *chainhash.Hash + TxID *chainhash.Hash Tx *wire.MsgTx Size int64 // the size of the BTC tx Fee btcutil.Amount // tx fee cost by the BTC tx diff --git a/types/errors.go b/types/errors.go index 285dcf45..fc74c380 100644 --- a/types/errors.go +++ b/types/errors.go @@ -6,7 +6,7 @@ var ( ErrEmptyCache = errors.New("empty cache") ErrInvalidMaxEntries = errors.New("invalid max entries") ErrTooManyEntries = errors.New("the number of blocks is more than maxEntries") - ErrorUnsortedBlocks = errors.New("blocks are not sorted by height") + ErrUnsortedBlocks = errors.New("blocks are not sorted by height") ErrInvalidMultiSig = errors.New("invalid multi-sig") ErrInsufficientPower = errors.New("insufficient power") ErrInvalidEpochNum = errors.New("invalid epoch number") diff --git a/types/genesis_info.go b/types/genesis_info.go index b7d3bed2..02e47534 100644 --- a/types/genesis_info.go +++ b/types/genesis_info.go @@ -54,7 +54,10 @@ func GetGenesisInfoFromFile(filePath string) (*GenesisInfo, error) { } tmpBabylon := app.NewTmpBabylonApp() - gentxModule := tmpBabylon.BasicModuleManager[genutiltypes.ModuleName].(genutil.AppModuleBasic) + gentxModule, ok := tmpBabylon.BasicModuleManager[genutiltypes.ModuleName].(genutil.AppModuleBasic) + if !ok { + return nil, fmt.Errorf("unexpected message type: %T", gentxModule) + } checkpointingGenState := checkpointingtypes.GetGenesisStateFromAppState(tmpBabylon.AppCodec(), appState) err = checkpointingGenState.Validate() @@ -76,7 +79,10 @@ func GetGenesisInfoFromFile(filePath string) (*GenesisInfo, error) { if len(msgs) == 0 { return nil, errors.New("invalid genesis transaction") } - msgCreateValidator := msgs[0].(*stakingtypes.MsgCreateValidator) + msgCreateValidator, ok := msgs[0].(*stakingtypes.MsgCreateValidator) + if !ok { + return nil, fmt.Errorf("unexpected message type: %T", msgs[0]) + } if gk.ValidatorAddress == msgCreateValidator.ValidatorAddress { power := sdk.TokensToConsensusPower(msgCreateValidator.Value.Amount, sdk.DefaultPowerReduction)