diff --git a/.github/workflows/golangci_lint.yml b/.github/workflows/golangci_lint.yml new file mode 100644 index 000000000..69f6c8d67 --- /dev/null +++ b/.github/workflows/golangci_lint.yml @@ -0,0 +1,23 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - main + pull_request: + +jobs: + golangci: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.58 + skip-cache: true diff --git a/.golangci.yml b/.golangci.yml index a8cba5db2..b69bea76f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,31 +1,76 @@ run: concurrency: 4 timeout: 5m + tests: true modules-download-mode: readonly - # mempool and indexer code is borrowed from Tendermint + +output: + # Format: colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity + # + # Multiple can be specified by separating them by comma, output can be provided + # for each of them by separating format name and path by colon symbol. + # Output path can be either `stdout`, `stderr` or path to the file to write to. + # Example: "checkstyle:report.xml,json:stdout,colored-line-number" + # + # Default: colored-line-number + format: colored-line-number + # Print lines of code with issue. + # Default: true + print-issued-lines: true + # Print linter name in the end of issue text. + # Default: true + print-linter-name: true + # Make issues output unique by line. + # Default: true + uniq-by-line: true + # Add a prefix to the output file references. + # Default: "" + path-prefix: "" + # Sort results by: filepath, line and column. + # Default: false + sort-results: true + linters: disable-all: true enable: - errcheck + - gocyclo - gofmt + - gofumpt - goimports + - gosec - gosimple - govet - ineffassign - misspell + - revive - staticcheck - typecheck + - unconvert - unused - - gosec - - gocyclo issues: exclude-use-default: false + exclude: + - "^.*SA1019.*$" # Excluding SA1019 errors exclude-files: - da/celestia/mock/server.go - - ./*_test.go + - ./*_test.go # TODO: bring back exclude-dirs: + # mempool and indexer code is borrowed from Tendermint - mempool - state/indexer - - state/txindex \ No newline at end of file + - state/txindex + + +linters-settings: + go-version-checker: + min-version: "1.22" + revive: + rules: + - name: exported + severity: warning + disabled: true + errcheck: + check-type-assertions: true \ No newline at end of file diff --git a/block/manager.go b/block/manager.go index ecdfeae30..fb1baa9e3 100644 --- a/block/manager.go +++ b/block/manager.go @@ -214,7 +214,7 @@ func getAddress(key crypto.PrivKey) ([]byte, error) { // TODO: move to gossip.go // onNewGossippedBlock will take a block and apply it func (m *Manager) onNewGossipedBlock(event pubsub.Message) { - eventData := event.Data().(p2p.GossipedBlock) + eventData, _ := event.Data().(p2p.GossipedBlock) block := eventData.Block commit := eventData.Commit m.retrieverMutex.Lock() // needed to protect blockCache access diff --git a/block/synctarget.go b/block/synctarget.go index 1ea9a7ec6..dfe8c9922 100644 --- a/block/synctarget.go +++ b/block/synctarget.go @@ -23,7 +23,7 @@ func (m *Manager) SyncTargetLoop(ctx context.Context) { case <-ctx.Done(): return case event := <-subscription.Out(): - eventData := event.Data().(*settlement.EventDataNewBatchAccepted) + eventData, _ := event.Data().(*settlement.EventDataNewBatchAccepted) if eventData.EndHeight <= m.Store.Height() { m.logger.Debug( diff --git a/p2p/client.go b/p2p/client.go index 047cd3124..ac84fcd72 100644 --- a/p2p/client.go +++ b/p2p/client.go @@ -321,13 +321,13 @@ func (c *Client) setupGossiping(ctx context.Context) error { pubsub.GossipSubHistoryGossip = c.conf.GossipCacheSize pubsub.GossipSubHistoryLength = c.conf.GossipCacheSize - //We add WithSeenMessagesTTL (with 1 year time) option to avoid ever requesting already seen blocks + // We add WithSeenMessagesTTL (with 1 year time) option to avoid ever requesting already seen blocks ps, err := pubsub.NewGossipSub(ctx, c.Host) if err != nil { return err } - //tx gossiper receives the tx to add to the mempool through validation process, since it is a joint process + // tx gossiper receives the tx to add to the mempool through validation process, since it is a joint process c.txGossiper, err = NewGossiper(c.Host, ps, c.getTxTopic(), nil, c.logger, WithValidator(c.txValidator)) if err != nil { return err diff --git a/p2p/validator_test.go b/p2p/validator_test.go index 2c90b44a9..ef7bc806f 100644 --- a/p2p/validator_test.go +++ b/p2p/validator_test.go @@ -95,10 +95,9 @@ func TestValidator_TxValidator(t *testing.T) { } func TestValidator_BlockValidator(t *testing.T) { - - //Create proposer for the block + // Create proposer for the block proposerKey := ed25519.GenPrivKey() - //Create another key + // Create another key attackerKey := ed25519.GenPrivKey() tests := []struct { @@ -120,7 +119,7 @@ func TestValidator_BlockValidator(t *testing.T) { t.Run(tt.name, func(t *testing.T) { logger := log.TestingLogger() - //Create Block executor + // Create Block executor app := &tmmocks.MockApplication{} clientCreator := proxy.NewLocalClientCreator(app) @@ -133,17 +132,17 @@ func TestValidator_BlockValidator(t *testing.T) { executor, err := block.NewExecutor([]byte("test address"), namespaceId, "test", mpool, proxy.NewAppConns(clientCreator), nil, logger) assert.NoError(t, err) - //Create state + // Create state maxBytes := uint64(100) state := types.State{} state.ConsensusParams.Block.MaxBytes = int64(maxBytes) state.ConsensusParams.Block.MaxGas = 100000 state.Validators = tmtypes.NewValidatorSet(nil) - //Create empty block + // Create empty block block := executor.CreateBlock(1, &types.Commit{}, [32]byte{}, state, maxBytes) - //Create slclient + // Create slclient client := registry.GetClient(registry.Local) pubsubServer := pubsub.NewServer() err = pubsubServer.Start() @@ -169,16 +168,16 @@ func TestValidator_BlockValidator(t *testing.T) { Signatures: []types.Signature{signature}, } - //Create gossiped block + // Create gossiped block gossipedBlock := p2p.GossipedBlock{Block: *block, Commit: *commit} gossipedBlockBytes, err := gossipedBlock.MarshalBinary() require.NoError(t, err) - var blockMsg = &p2p.GossipMessage{ + blockMsg := &p2p.GossipMessage{ Data: gossipedBlockBytes, From: peer.ID("from"), } - //Check block validity + // Check block validity validateBlock := p2p.NewValidator(logger, client).BlockValidator() valid := validateBlock(blockMsg) require.Equal(t, tt.valid, valid) diff --git a/rpc/client/client.go b/rpc/client/client.go index 17d3c42d5..5589e7d65 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -154,7 +154,7 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx tmtypes.Tx) (*ctypes. // Wait for the tx to be included in a block or timeout. select { case msg := <-deliverTxSub.Out(): // The tx was included in a block. - deliverTxRes := msg.Data().(tmtypes.EventDataTx) + deliverTxRes, _ := msg.Data().(tmtypes.EventDataTx) return &ctypes.ResultBroadcastTxCommit{ CheckTx: *checkTxRes, DeliverTx: deliverTxRes.Result, diff --git a/rpc/json/handler.go b/rpc/json/handler.go index 164b1f329..af33eed97 100644 --- a/rpc/json/handler.go +++ b/rpc/json/handler.go @@ -104,7 +104,7 @@ func (h *handler) serveJSONRPCforWS(w http.ResponseWriter, r *http.Request, wsCo errInter := rets[1].Interface() if errInter != nil { statusCode = http.StatusBadRequest - errResult = errInter.(error) + errResult, _ = errInter.(error) } // Prevents Internet Explorer from MIME-sniffing a response away @@ -177,7 +177,7 @@ func (h *handler) newHandler(methodSpec *method) func(http.ResponseWriter, *http errInter := rets[1].Interface() if errInter != nil { statusCode = int(json2.E_INTERNAL) - err = errInter.(error) + err, _ = errInter.(error) } h.encodeAndWriteResponse(w, rets[0].Interface(), err, statusCode) @@ -200,7 +200,7 @@ func (h *handler) encodeAndWriteResponse(w http.ResponseWriter, result interface } else { bytes, err := tmjson.Marshal(result) if err != nil { - resp.Error = &json2.Error{Code: json2.ErrorCode(json2.E_INTERNAL), Data: err.Error()} + resp.Error = &json2.Error{Code: json2.E_INTERNAL, Data: err.Error()} } else { resp.Result = bytes } diff --git a/rpc/server.go b/rpc/server.go index feea78a00..6368d4ff1 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -106,7 +106,7 @@ func (s *Server) startEventListener() { // onNodeHealthUpdate is a callback function that handles health status events from the node. func (s *Server) onNodeHealthUpdate(event pubsub.Message) { - eventData := event.Data().(*events.DataHealthStatus) + eventData, _ := event.Data().(*events.DataHealthStatus) if eventData.Error != nil { s.Logger.Error("node is unhealthy", "error", eventData.Error) } diff --git a/settlement/base.go b/settlement/base.go index 1e82c3846..562f4369c 100644 --- a/settlement/base.go +++ b/settlement/base.go @@ -43,9 +43,9 @@ func (b *BaseLayerClient) Init(config Config, pubsub *pubsub.Server, logger type apply(b) } - //TODO(srene): For a correct validation, sequencer list would need to be updated after a sequencer list change on the Hub. - //e.g. after receiving an event from the Hub. Right now, node will need to be restarted after a sequencer change, since it is - //only getting the sequencers list during Init. + // TODO(srene): For a correct validation, sequencer list would need to be updated after a sequencer list change on the Hub. + // e.g. after receiving an event from the Hub. Right now, node will need to be restarted after a sequencer change, since it is + // only getting the sequencers list during Init. b.sequencersList, err = b.fetchSequencersList() if err != nil { return err diff --git a/settlement/events.go b/settlement/events.go index 77eead134..09de1b07a 100644 --- a/settlement/events.go +++ b/settlement/events.go @@ -22,9 +22,7 @@ const ( // Convenience objects -var ( - EventNewBatchAcceptedList = map[string][]string{EventTypeKey: {EventNewBatchAccepted}} -) +var EventNewBatchAcceptedList = map[string][]string{EventTypeKey: {EventNewBatchAccepted}} // Data diff --git a/test/loadtime/cmd/report/main.go b/test/loadtime/cmd/report/main.go index 0bc1ae98e..605a955cb 100644 --- a/test/loadtime/cmd/report/main.go +++ b/test/loadtime/cmd/report/main.go @@ -39,7 +39,7 @@ func getStore(directory string) *store.PrefixKV { } func newBlockStore(kvstore store.KVStore, baseHeight uint64) *BlockStore { - store := store.New(kvstore).(*store.DefaultStore) + store, _ := store.New(kvstore).(*store.DefaultStore) _, err := store.LoadState() if err != nil { log.Fatalf("loading state %s", err) diff --git a/types/validation.go b/types/validation.go index 9533d7e7b..f7f9f47b7 100644 --- a/types/validation.go +++ b/types/validation.go @@ -51,7 +51,7 @@ func (b *Block) ValidateWithState(state State) error { if state.LastBlockHeight <= 0 && b.Header.Height != uint64(state.InitialHeight) { return errors.New("initial b height mismatch") } - if state.LastBlockHeight > 0 && b.Header.Height != uint64(state.LastStoreHeight)+1 { + if state.LastBlockHeight > 0 && b.Header.Height != state.LastStoreHeight+1 { return errors.New("b height mismatch") } if !bytes.Equal(b.Header.AppHash[:], state.AppHash[:]) {