From 97bbc6f798371e8e650d2f9e4c1ce4ecde8304b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:04:41 +0000 Subject: [PATCH 1/6] chore(deps): update dependency golangci/golangci-lint to v2.11.3 --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 70505b3f5..8c2062ffa 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -19,4 +19,4 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 with: - version: v2.10.1 + version: v2.11.3 From fa058149de72df13dace6cabf55b631af389bcd3 Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Mon, 16 Mar 2026 11:28:53 +0200 Subject: [PATCH 2/6] Bump linter in script as well --- .pre-commit/run_linter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit/run_linter.sh b/.pre-commit/run_linter.sh index af6134d0c..a25466f35 100755 --- a/.pre-commit/run_linter.sh +++ b/.pre-commit/run_linter.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="2.10.1" +VERSION="2.11.3" if ! command -v golangci-lint &>/dev/null; then echo "golangci-lint could not be found" From 6b5b51adb3ac0523112533db7bfc62d508bbbbc1 Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Mon, 16 Mar 2026 12:04:55 +0200 Subject: [PATCH 3/6] Fix linter --- app/errors/go113.go | 2 +- app/lifecycle/manager.go | 10 +++++----- app/log/config.go | 1 + app/log/config_internal_test.go | 1 + app/log/filter.go | 1 + app/log/log.go | 2 ++ app/log/metrics.go | 1 + app/log/wrapper.go | 1 + app/obolapi/exit.go | 14 +++++++++++--- app/retry/retry.go | 2 +- app/utils.go | 4 ++-- cmd/relay/relay.go | 14 +++++++++----- cmd/test.go | 13 ++++++++++--- core/fetcher/graffiti.go | 1 + core/parsigex/parsigex.go | 2 ++ core/priority/calculate.go | 30 ++++++++++++++++++++++------- core/scheduler/scheduler.go | 14 ++++++++++---- dkg/frost.go | 4 ++-- dkg/pedersen/dkg.go | 3 +-- dkg/share/share.go | 4 ++-- dkg/sync/client.go | 1 + dkg/sync/server.go | 2 ++ dkg/sync/server_internal_test.go | 1 + eth2util/deposit/deposit.go | 13 ++++++++++--- eth2util/enr/enr.go | 4 ++-- p2p/bootnode.go | 14 +++++++++++--- p2p/sender.go | 2 +- testutil/genchangelog/main.go | 13 ++++++++++--- testutil/obolapimock/exit.go | 13 ++++++++++--- testutil/validatormock/component.go | 14 +++++++++++--- 30 files changed, 146 insertions(+), 55 deletions(-) diff --git a/app/errors/go113.go b/app/errors/go113.go index 4b3fe526a..10e03ccae 100644 --- a/app/errors/go113.go +++ b/app/errors/go113.go @@ -1,6 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:wrapcheck +//nolint:wrapcheck,revive package errors import ( diff --git a/app/lifecycle/manager.go b/app/lifecycle/manager.go index 8cf1ee0a1..9a9ef3de8 100644 --- a/app/lifecycle/manager.go +++ b/app/lifecycle/manager.go @@ -15,7 +15,7 @@ package lifecycle import ( "context" - "sort" + "slices" "sync" ) @@ -74,11 +74,11 @@ func (m *Manager) Run(appCtx context.Context) error { m.mu.Unlock() - sort.Slice(startHooks, func(i, j int) bool { - return startHooks[i].Order < startHooks[j].Order + slices.SortFunc(startHooks, func(a, b hook) int { + return a.Order - b.Order }) - sort.Slice(stopHooks, func(i, j int) bool { - return stopHooks[i].Order < stopHooks[j].Order + slices.SortFunc(stopHooks, func(a, b hook) int { + return a.Order - b.Order }) return runHooks(appCtx, startHooks, stopHooks) diff --git a/app/log/config.go b/app/log/config.go index 3fde5d9b0..4433da721 100644 --- a/app/log/config.go +++ b/app/log/config.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package log import ( diff --git a/app/log/config_internal_test.go b/app/log/config_internal_test.go index f2da29a49..44071672b 100644 --- a/app/log/config_internal_test.go +++ b/app/log/config_internal_test.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package log import ( diff --git a/app/log/filter.go b/app/log/filter.go index 15dae0b73..2fafa90d8 100644 --- a/app/log/filter.go +++ b/app/log/filter.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package log import ( diff --git a/app/log/log.go b/app/log/log.go index 8369ce94e..a475192c0 100644 --- a/app/log/log.go +++ b/app/log/log.go @@ -3,6 +3,8 @@ // Package log provides global logging functions to be used throughout the charon app. // It supports contextual logging via WithCtx and structured logging and structured errors // via z.Field. +// +//nolint:revive package log import ( diff --git a/app/log/metrics.go b/app/log/metrics.go index 287b5859c..d70fdc12e 100644 --- a/app/log/metrics.go +++ b/app/log/metrics.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package log import ( diff --git a/app/log/wrapper.go b/app/log/wrapper.go index 8ff8cb94d..814344764 100644 --- a/app/log/wrapper.go +++ b/app/log/wrapper.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package log import ( diff --git a/app/obolapi/exit.go b/app/obolapi/exit.go index 45c747e80..d62a24894 100644 --- a/app/obolapi/exit.go +++ b/app/obolapi/exit.go @@ -8,7 +8,7 @@ import ( "encoding/json" "fmt" "net/url" - "sort" + "slices" "strconv" "strings" @@ -86,8 +86,16 @@ func (c Client) PostPartialExits(ctx context.Context, lockHash []byte, shareInde u.Path = path // sort by validator index ascending - sort.Slice(exitBlobs, func(i, j int) bool { - return exitBlobs[i].SignedExitMessage.Message.ValidatorIndex < exitBlobs[j].SignedExitMessage.Message.ValidatorIndex + slices.SortFunc(exitBlobs, func(i, j ExitBlob) int { + if i.SignedExitMessage.Message.ValidatorIndex < j.SignedExitMessage.Message.ValidatorIndex { + return -1 + } + + if i.SignedExitMessage.Message.ValidatorIndex > j.SignedExitMessage.Message.ValidatorIndex { + return 1 + } + + return 0 }) msg := UnsignedPartialExitRequest{ diff --git a/app/retry/retry.go b/app/retry/retry.go index 8f580c04c..2788f55c9 100644 --- a/app/retry/retry.go +++ b/app/retry/retry.go @@ -76,7 +76,7 @@ func newInternal[T any]( backoffProvider func() func(int) *time.Timer, ) *Retryer[T] { // Create a fresh context used as parent of all async contexts - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(context.Background()) //nolint:gosec // Context cancelation is in fact called, just outside of this function. return &Retryer[T]{ asyncCtx: ctx, diff --git a/app/utils.go b/app/utils.go index d8afe7b7a..ccbbd49fb 100644 --- a/app/utils.go +++ b/app/utils.go @@ -81,7 +81,7 @@ func BundleOutput(targetDir string, filename string) error { return errors.Wrap(err, "write header") } - f, err := os.Open(path) + f, err := os.Open(path) //nolint:gosec // no TOCTOU condition as BundleOutput is used only in CLI non-concurrent context. if err != nil { return errors.Wrap(err, "open file") } @@ -244,7 +244,7 @@ func CompareDirectories(originalDir, extractedDir string) error { } // Read and compare file contents - originalContent, err := os.ReadFile(path) + originalContent, err := os.ReadFile(path) //nolint:gosec // no TOCTOU condition as CompareDirectories is used only in CLI non-concurrent context. if err != nil { return errors.Wrap(err, "read original file", z.Str("path", path)) } diff --git a/cmd/relay/relay.go b/cmd/relay/relay.go index d342b43f6..62c6ab384 100644 --- a/cmd/relay/relay.go +++ b/cmd/relay/relay.go @@ -10,7 +10,7 @@ import ( "net/http" "net/http/pprof" "os" - "sort" + "slices" "sync" "time" @@ -210,13 +210,17 @@ func newENRHandler(ctx context.Context, p2pNode host.Host, p2pKey *k1.PrivateKey } // Order public addresses first. - sort.SliceStable(addrs, func(i, j int) bool { - iPublic, jPublic := manet.IsPublicAddr(addrs[i]), manet.IsPublicAddr(addrs[j]) + slices.SortStableFunc(addrs, func(i, j ma.Multiaddr) int { + iPublic, jPublic := manet.IsPublicAddr(i), manet.IsPublicAddr(j) if jPublic && !iPublic { - return true // Only swap if j is public and i is not. + return 1 // j should come before i as it is public } - return false + if iPublic && !jPublic { + return -1 // i should come before j as it is public + } + + return 0 // no change }) var ( diff --git a/cmd/test.go b/cmd/test.go index 29f8879a2..9db10b1fd 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -15,7 +15,6 @@ import ( "os/signal" "path/filepath" "slices" - "sort" "strings" "syscall" "time" @@ -538,8 +537,16 @@ func filterTests(supportedTestCases []testCaseName, cfg testConfig) []testCaseNa } func sortTests(tests []testCaseName) { - sort.Slice(tests, func(i, j int) bool { - return tests[i].order < tests[j].order + slices.SortFunc(tests, func(a, b testCaseName) int { + if a.order < b.order { + return -1 + } + + if a.order > b.order { + return 1 + } + + return 0 }) } diff --git a/core/fetcher/graffiti.go b/core/fetcher/graffiti.go index ae353221f..9cb387788 100644 --- a/core/fetcher/graffiti.go +++ b/core/fetcher/graffiti.go @@ -66,6 +66,7 @@ func NewGraffitiBuilder(pubkeys []core.PubKey, graffiti []string, disableClientA // Handle multiple graffiti case for idx, pubkey := range pubkeys { + //nolint: gosec // Slice is not out of bounds as we make this check couple of lines above. builder.graffiti[pubkey] = buildGraffiti(graffiti[idx], token, disableClientAppend) } diff --git a/core/parsigex/parsigex.go b/core/parsigex/parsigex.go index acdb77cb0..35f90d9fc 100644 --- a/core/parsigex/parsigex.go +++ b/core/parsigex/parsigex.go @@ -108,11 +108,13 @@ func (m *ParSigEx) handle(ctx context.Context, _ peer.ID, req proto.Message) (pr // Verify partial signatures and record timing verifyStart := time.Now() + for pubkey, data := range set { if err = m.verifyFunc(ctx, duty, pubkey, data); err != nil { return nil, false, errors.Wrap(err, "invalid partial signature") } } + setVerificationDuration.WithLabelValues(duty.Type.String()).Observe(time.Since(verifyStart).Seconds()) for _, sub := range m.subs { diff --git a/core/priority/calculate.go b/core/priority/calculate.go index 119313c85..b1397a5bf 100644 --- a/core/priority/calculate.go +++ b/core/priority/calculate.go @@ -4,7 +4,7 @@ package priority import ( "bytes" - "sort" + "slices" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -70,8 +70,16 @@ func calculateResult(msgs []*pbv1.PriorityMsg, minRequired int) (*pbv1.PriorityR } // Order by score decreasing - sort.Slice(allPriorities, func(i, j int) bool { - return scores[allPriorities[i]] > scores[allPriorities[j]] + slices.SortFunc(allPriorities, func(i, j [32]byte) int { + if scores[i] > scores[j] { + return -1 + } + + if scores[i] < scores[j] { + return 1 + } + + return 0 }) // Extract scores with min required count. @@ -125,8 +133,8 @@ func orderTopicResults(values []*pbv1.PriorityTopicResult) ([]*pbv1.PriorityTopi }) } - sort.Slice(tuples, func(i, j int) bool { - return bytes.Compare(tuples[i].Hash, tuples[j].Hash) < 0 + slices.SortFunc(tuples, func(i, j tuple) int { + return bytes.Compare(i.Hash, j.Hash) }) var resp []*pbv1.PriorityTopicResult @@ -141,8 +149,16 @@ func orderTopicResults(values []*pbv1.PriorityTopicResult) ([]*pbv1.PriorityTopi // by peer. func sortInput(msgs []*pbv1.PriorityMsg) []*pbv1.PriorityMsg { resp := append([]*pbv1.PriorityMsg(nil), msgs...) // Copy to not mutate input param. - sort.Slice(resp, func(i, j int) bool { - return resp[i].GetPeerId() < resp[j].GetPeerId() + slices.SortFunc(resp, func(i, j *pbv1.PriorityMsg) int { + if i.GetPeerId() < j.GetPeerId() { + return -1 + } + + if i.GetPeerId() > j.GetPeerId() { + return 1 + } + + return 0 }) return resp diff --git a/core/scheduler/scheduler.go b/core/scheduler/scheduler.go index 16ea1c5f3..e727de4be 100644 --- a/core/scheduler/scheduler.go +++ b/core/scheduler/scheduler.go @@ -5,7 +5,7 @@ package scheduler import ( "context" "math" - "sort" + "slices" "sync" "testing" "time" @@ -230,7 +230,7 @@ func (s *Scheduler) HandleBlockEvent(ctx context.Context, slot eth2p0.Slot, bnAd // Fetch attestation data early without triggering consensus // Use background context to prevent cancellation if SSE connection drops go func() { - fetchCtx := log.CopyFields(context.Background(), ctx) + fetchCtx := log.CopyFields(context.Background(), ctx) //nolint:gosec // The use of background context is intentional. if err := s.fetcherFetchOnly(fetchCtx, duty, clonedDefSet, bnAddr); err != nil { log.Warn(fetchCtx, "Early attestation data fetch failed", err, z.U64("slot", uint64(slot)), z.Str("bn_addr", bnAddr)) } @@ -505,8 +505,14 @@ func (s *Scheduler) resolveAttDuties(ctx context.Context, slot core.Slot, vals v } // Sort so logging below in ascending slot order. - sort.Slice(attDuties, func(i, j int) bool { - return attDuties[i].Slot < attDuties[j].Slot + slices.SortFunc(attDuties, func(i, j *eth2v1.AttesterDuty) int { + if i.Slot < j.Slot { + return -1 + } + if i.Slot > j.Slot { + return 1 + } + return 0 }) for _, attDuty := range attDuties { diff --git a/dkg/frost.go b/dkg/frost.go index 209e84513..d99879cad 100644 --- a/dkg/frost.go +++ b/dkg/frost.go @@ -4,7 +4,7 @@ package dkg import ( "context" - "sort" + "slices" "github.com/coinbase/kryptology/pkg/core/curves" "github.com/coinbase/kryptology/pkg/dkg/frost" @@ -231,7 +231,7 @@ func makeShares( vIdxs = append(vIdxs, int(vIdx)) } - sort.Ints(vIdxs) + slices.Sort(vIdxs) // Construct DKG result shares. var shares []share.Share diff --git a/dkg/pedersen/dkg.go b/dkg/pedersen/dkg.go index ae89f6665..6b42c8154 100644 --- a/dkg/pedersen/dkg.go +++ b/dkg/pedersen/dkg.go @@ -5,7 +5,6 @@ package pedersen import ( "context" "slices" - "sort" kbls "github.com/drand/kyber-bls12381" kdkg "github.com/drand/kyber/share/dkg" @@ -191,7 +190,7 @@ func processKey(ctx context.Context, config *Config, board *Board, key *kdkg.Dis oldShareRevMap[shareIndex] = spk.ValidatorPubKey } - sort.Ints(oldShareIndices) + slices.Sort(oldShareIndices) publicShares := make(map[int]tbls.PublicKey) diff --git a/dkg/share/share.go b/dkg/share/share.go index 71f5da5f2..c0703cf25 100644 --- a/dkg/share/share.go +++ b/dkg/share/share.go @@ -3,7 +3,7 @@ package share import ( - "sort" + "slices" "github.com/obolnetwork/charon/tbls" ) @@ -34,7 +34,7 @@ func MsgFromShare(s Share) Msg { pubSharesIDs = append(pubSharesIDs, id) } - sort.Ints(pubSharesIDs) + slices.Sort(pubSharesIDs) var pubShares [][]byte diff --git a/dkg/sync/client.go b/dkg/sync/client.go index ef8300b22..e41cecc25 100644 --- a/dkg/sync/client.go +++ b/dkg/sync/client.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package sync import ( diff --git a/dkg/sync/server.go b/dkg/sync/server.go index 5f1869bb5..456cb8778 100644 --- a/dkg/sync/server.go +++ b/dkg/sync/server.go @@ -2,6 +2,8 @@ // Package sync provides Client and Server APIs that ensures robust network connectivity between all peers in the DKG. // It supports cluster_definition verification, soft shutdown and reconnect on connection loss. +// +//nolint:revive package sync import ( diff --git a/dkg/sync/server_internal_test.go b/dkg/sync/server_internal_test.go index cec3d9a6a..6057265fb 100644 --- a/dkg/sync/server_internal_test.go +++ b/dkg/sync/server_internal_test.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive package sync import ( diff --git a/eth2util/deposit/deposit.go b/eth2util/deposit/deposit.go index 077a8e859..d17ea3d72 100644 --- a/eth2util/deposit/deposit.go +++ b/eth2util/deposit/deposit.go @@ -11,7 +11,6 @@ import ( "path" "path/filepath" "slices" - "sort" "strconv" "strings" @@ -137,8 +136,16 @@ func MarshalDepositData(depositDatas []eth2p0.DepositData, network string) ([]by }) } - sort.Slice(ddList, func(i, j int) bool { - return ddList[i].PubKey < ddList[j].PubKey + slices.SortFunc(ddList, func(i, j depositDataJSON) int { + if i.PubKey < j.PubKey { + return -1 + } + + if i.PubKey > j.PubKey { + return 1 + } + + return 0 }) bytes, err := json.MarshalIndent(ddList, "", " ") diff --git a/eth2util/enr/enr.go b/eth2util/enr/enr.go index f980c8d38..9be36583b 100644 --- a/eth2util/enr/enr.go +++ b/eth2util/enr/enr.go @@ -6,7 +6,7 @@ package enr import ( "encoding/base64" "net" - "sort" + "slices" "strings" k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" @@ -188,7 +188,7 @@ func encodeElements(signature []byte, kvs map[string][]byte) []byte { keys = append(keys, k) } - sort.Strings(keys) + slices.Sort(keys) elements := [][]byte{toBigEndian(0)} // Sequence number=0 for _, key := range keys { diff --git a/p2p/bootnode.go b/p2p/bootnode.go index edc70458c..1432faac0 100644 --- a/p2p/bootnode.go +++ b/p2p/bootnode.go @@ -9,7 +9,7 @@ import ( "io" "net/http" "net/url" - "sort" + "slices" "strings" "time" @@ -103,8 +103,16 @@ func resolveRelay(ctx context.Context, rawURL, lockHashHex, uuid string, callbac reset() - sort.Slice(addrs, func(i, j int) bool { - return addrs[i].String() < addrs[j].String() + slices.SortFunc(addrs, func(i, j ma.Multiaddr) int { + if i.String() < j.String() { + return -1 + } + + if i.String() > j.String() { + return 1 + } + + return 0 }) newAddrs := fmt.Sprint(addrs) diff --git a/p2p/sender.go b/p2p/sender.go index 7816c72ee..1e89e3dc7 100644 --- a/p2p/sender.go +++ b/p2p/sender.go @@ -154,7 +154,7 @@ func (s *Sender) SendAsync(parent context.Context, p2pNode host.Host, protoID pr ) error { go func() { // Clone the context since parent context may be closed soon. - ctx := log.CopyFields(context.Background(), parent) + ctx := log.CopyFields(context.Background(), parent) //nolint:gosec // The use of background context is intentional. err := withRelayRetry(func() error { return Send(ctx, p2pNode, protoID, peerID, msg, opts...) diff --git a/testutil/genchangelog/main.go b/testutil/genchangelog/main.go index 8c498ce6e..7c793e112 100644 --- a/testutil/genchangelog/main.go +++ b/testutil/genchangelog/main.go @@ -23,7 +23,6 @@ import ( "os/exec" "regexp" "slices" - "sort" "strconv" "strings" "text/template" @@ -301,8 +300,16 @@ func tplDataFromPRs(prs []pullRequest, gitRange string, issueData func(int) (str catSlice = append(catSlice, cat) } - sort.Slice(catSlice, func(i, j int) bool { - return categoryOrder[catSlice[i].Name] < categoryOrder[catSlice[j].Name] + slices.SortFunc(catSlice, func(i, j tplCategory) int { + if categoryOrder[i.Name] < categoryOrder[j.Name] { + return -1 + } + + if categoryOrder[i.Name] > categoryOrder[j.Name] { + return 1 + } + + return 0 }) tag := "v0.0.0" diff --git a/testutil/obolapimock/exit.go b/testutil/obolapimock/exit.go index dd743bde5..6cef0f6aa 100644 --- a/testutil/obolapimock/exit.go +++ b/testutil/obolapimock/exit.go @@ -9,7 +9,6 @@ import ( "fmt" "net/http" "slices" - "sort" "strconv" "strings" @@ -210,8 +209,16 @@ func (ts *testServer) HandleGetFullExit(writer http.ResponseWriter, request *htt var ret obolapi.FullExitResponse // order partial exits by share index - sort.Slice(partialExits, func(i, j int) bool { - return partialExits[i].shareIdx < partialExits[j].shareIdx + slices.SortFunc(partialExits, func(i, j exitBlob) int { + if i.shareIdx < j.shareIdx { + return -1 + } + + if i.shareIdx > j.shareIdx { + return 1 + } + + return 0 }) for _, pExit := range partialExits { diff --git a/testutil/validatormock/component.go b/testutil/validatormock/component.go index 6e51ae1ed..d0b62e7d8 100644 --- a/testutil/validatormock/component.go +++ b/testutil/validatormock/component.go @@ -4,7 +4,7 @@ package validatormock import ( "context" - "sort" + "slices" "sync" "time" @@ -411,8 +411,16 @@ func orderByTime(duties map[scheduleTuple]struct{}) []scheduleTuple { resp = append(resp, duty) } - sort.Slice(resp, func(i, j int) bool { - return resp[i].startTime.Before(resp[j].startTime) + slices.SortFunc(resp, func(i, j scheduleTuple) int { + if i.startTime.Before(j.startTime) { + return -1 + } + + if i.startTime.After(j.startTime) { + return 1 + } + + return 0 }) return resp From 16d97acff4986eb29878c6d3adf7f7f94988621f Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Mon, 16 Mar 2026 13:02:08 +0200 Subject: [PATCH 4/6] Fix linter 2 --- app/log/config.go | 1 - app/log/config_internal_test.go | 1 - app/log/filter.go | 1 - app/log/log.go | 2 +- app/log/metrics.go | 1 - app/log/wrapper.go | 1 - core/scheduler/scheduler.go | 5 ++++- dkg/sync/client.go | 1 - dkg/sync/server.go | 2 +- dkg/sync/server_internal_test.go | 1 - p2p/sender.go | 3 ++- 11 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/log/config.go b/app/log/config.go index 4433da721..3fde5d9b0 100644 --- a/app/log/config.go +++ b/app/log/config.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package log import ( diff --git a/app/log/config_internal_test.go b/app/log/config_internal_test.go index 44071672b..f2da29a49 100644 --- a/app/log/config_internal_test.go +++ b/app/log/config_internal_test.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package log import ( diff --git a/app/log/filter.go b/app/log/filter.go index 2fafa90d8..15dae0b73 100644 --- a/app/log/filter.go +++ b/app/log/filter.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package log import ( diff --git a/app/log/log.go b/app/log/log.go index a475192c0..69afb506f 100644 --- a/app/log/log.go +++ b/app/log/log.go @@ -4,7 +4,7 @@ // It supports contextual logging via WithCtx and structured logging and structured errors // via z.Field. // -//nolint:revive + package log import ( diff --git a/app/log/metrics.go b/app/log/metrics.go index d70fdc12e..287b5859c 100644 --- a/app/log/metrics.go +++ b/app/log/metrics.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package log import ( diff --git a/app/log/wrapper.go b/app/log/wrapper.go index 814344764..8ff8cb94d 100644 --- a/app/log/wrapper.go +++ b/app/log/wrapper.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package log import ( diff --git a/core/scheduler/scheduler.go b/core/scheduler/scheduler.go index e727de4be..e5f3d9ee0 100644 --- a/core/scheduler/scheduler.go +++ b/core/scheduler/scheduler.go @@ -229,8 +229,9 @@ func (s *Scheduler) HandleBlockEvent(ctx context.Context, slot eth2p0.Slot, bnAd // Fetch attestation data early without triggering consensus // Use background context to prevent cancellation if SSE connection drops + //nolint:gosec // The use of background context is intentional. go func() { - fetchCtx := log.CopyFields(context.Background(), ctx) //nolint:gosec // The use of background context is intentional. + fetchCtx := log.CopyFields(context.Background(), ctx) if err := s.fetcherFetchOnly(fetchCtx, duty, clonedDefSet, bnAddr); err != nil { log.Warn(fetchCtx, "Early attestation data fetch failed", err, z.U64("slot", uint64(slot)), z.Str("bn_addr", bnAddr)) } @@ -509,9 +510,11 @@ func (s *Scheduler) resolveAttDuties(ctx context.Context, slot core.Slot, vals v if i.Slot < j.Slot { return -1 } + if i.Slot > j.Slot { return 1 } + return 0 }) diff --git a/dkg/sync/client.go b/dkg/sync/client.go index e41cecc25..ef8300b22 100644 --- a/dkg/sync/client.go +++ b/dkg/sync/client.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package sync import ( diff --git a/dkg/sync/server.go b/dkg/sync/server.go index 456cb8778..824eb0e78 100644 --- a/dkg/sync/server.go +++ b/dkg/sync/server.go @@ -3,7 +3,7 @@ // Package sync provides Client and Server APIs that ensures robust network connectivity between all peers in the DKG. // It supports cluster_definition verification, soft shutdown and reconnect on connection loss. // -//nolint:revive + package sync import ( diff --git a/dkg/sync/server_internal_test.go b/dkg/sync/server_internal_test.go index 6057265fb..cec3d9a6a 100644 --- a/dkg/sync/server_internal_test.go +++ b/dkg/sync/server_internal_test.go @@ -1,6 +1,5 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:revive package sync import ( diff --git a/p2p/sender.go b/p2p/sender.go index 1e89e3dc7..f175ba1eb 100644 --- a/p2p/sender.go +++ b/p2p/sender.go @@ -152,9 +152,10 @@ func (s *Sender) addResult(ctx context.Context, peerID peer.ID, err error) { func (s *Sender) SendAsync(parent context.Context, p2pNode host.Host, protoID protocol.ID, peerID peer.ID, msg proto.Message, opts ...SendRecvOption, ) error { + //nolint:gosec // The use of background context is intentional. go func() { // Clone the context since parent context may be closed soon. - ctx := log.CopyFields(context.Background(), parent) //nolint:gosec // The use of background context is intentional. + ctx := log.CopyFields(context.Background(), parent) err := withRelayRetry(func() error { return Send(ctx, p2pNode, protoID, peerID, msg, opts...) From e7e8f7516a92c719d37a32f2385d2bb80c276ece Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Mon, 16 Mar 2026 15:52:12 +0200 Subject: [PATCH 5/6] Fix linter 3 --- app/eth2wrap/cache.go | 9 ++++++--- app/log/log.go | 2 +- cmd/createcluster.go | 3 ++- dkg/sync/server.go | 2 +- testutil/promrated/promrated/main.go | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/eth2wrap/cache.go b/app/eth2wrap/cache.go index a0a916064..324494798 100644 --- a/app/eth2wrap/cache.go +++ b/app/eth2wrap/cache.go @@ -358,7 +358,8 @@ func (c *DutiesCache) UpdateActiveValIndices(vidxs []eth2p0.ValidatorIndex) { } // ProposerDutiesCache returns the cached proposer duties, or fetches them if not available, populating the cache with the newly fetched ones. -// nolint: dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. +// +//nolint:dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. func (c *DutiesCache) ProposerDutiesCache(ctx context.Context, epoch eth2p0.Epoch, vidxs []eth2p0.ValidatorIndex) (ProposerDutyWithMeta, error) { cacheUsed := false @@ -446,7 +447,8 @@ func (c *DutiesCache) ProposerDutiesCache(ctx context.Context, epoch eth2p0.Epoc } // AttesterDutiesCache returns the cached attester duties, or fetches them if not available, populating the cache with the newly fetched ones. -// nolint: dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. +// +//nolint:dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. func (c *DutiesCache) AttesterDutiesCache(ctx context.Context, epoch eth2p0.Epoch, vidxs []eth2p0.ValidatorIndex) (AttesterDutyWithMeta, error) { cacheUsed := false @@ -534,7 +536,8 @@ func (c *DutiesCache) AttesterDutiesCache(ctx context.Context, epoch eth2p0.Epoc } // SyncCommDutiesCache returns the cached sync duties, or fetches them if not available, populating the cache with the newly fetched ones. -// nolint: dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. +// +//nolint:dupl // The logic is very similar between proposer, attester and sync duties, but the code is not easily reusable without adding complexity, hence the duplication. func (c *DutiesCache) SyncCommDutiesCache(ctx context.Context, epoch eth2p0.Epoch, vidxs []eth2p0.ValidatorIndex) (SyncDutyWithMeta, error) { cacheUsed := false diff --git a/app/log/log.go b/app/log/log.go index 69afb506f..a475192c0 100644 --- a/app/log/log.go +++ b/app/log/log.go @@ -4,7 +4,7 @@ // It supports contextual logging via WithCtx and structured logging and structured errors // via z.Field. // - +//nolint:revive package log import ( diff --git a/cmd/createcluster.go b/cmd/createcluster.go index 390042e85..ad903296f 100644 --- a/cmd/createcluster.go +++ b/cmd/createcluster.go @@ -1164,7 +1164,8 @@ func writeLockToAPI(ctx context.Context, publishAddr string, lock cluster.Lock) } // validateAddresses checks if we have sufficient addresses. It also fills addresses slices if only one is provided. -// nolint: revive // Not really confusing here as they are passed as arguments as well. +// +//nolint:revive // Not really confusing here as they are passed as arguments as well. func validateAddresses(numVals int, feeRecipientAddrs []string, withdrawalAddrs []string) ([]string, []string, error) { if len(feeRecipientAddrs) != numVals && len(feeRecipientAddrs) != 1 { return nil, nil, errors.New("mismatching --num-validators and --fee-recipient-addresses", diff --git a/dkg/sync/server.go b/dkg/sync/server.go index 824eb0e78..03bfec7be 100644 --- a/dkg/sync/server.go +++ b/dkg/sync/server.go @@ -3,7 +3,7 @@ // Package sync provides Client and Server APIs that ensures robust network connectivity between all peers in the DKG. // It supports cluster_definition verification, soft shutdown and reconnect on connection loss. // - +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package sync import ( diff --git a/testutil/promrated/promrated/main.go b/testutil/promrated/promrated/main.go index 4116745d3..c8b44e6ec 100644 --- a/testutil/promrated/promrated/main.go +++ b/testutil/promrated/promrated/main.go @@ -28,7 +28,7 @@ func newRootCmd(runFunc func(context.Context, promrated.Config) error) *cobra.Co Short: "Starts a promrated server", Long: `Starts a promrated server that polls rated and makes metrics available to prometheus`, Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { //nolint:revive // keep args variable name for clarity + RunE: func(cmd *cobra.Command, args []string) error { return runFunc(cmd.Context(), config) }, } From f68283bdfaab2bfdfd77d04d37f2f06cca9af0ff Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Mon, 16 Mar 2026 16:50:48 +0200 Subject: [PATCH 6/6] Fix linter 4 --- app/errors/context.go | 1 + app/errors/errors.go | 2 ++ app/errors/go113.go | 2 +- app/log/config.go | 1 + app/log/config_internal_test.go | 1 + app/log/filter.go | 1 + app/log/log.go | 4 ++-- app/log/metrics.go | 1 + app/log/wrapper.go | 1 + dkg/sync/client.go | 1 + dkg/sync/server.go | 2 +- testutil/promrated/promrated/main.go | 2 +- 12 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/errors/context.go b/app/errors/context.go index 7bb487342..e89eac8ef 100644 --- a/app/errors/context.go +++ b/app/errors/context.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package errors import ( diff --git a/app/errors/errors.go b/app/errors/errors.go index 470be3128..dc19c6c67 100644 --- a/app/errors/errors.go +++ b/app/errors/errors.go @@ -2,6 +2,8 @@ // Package errors provides errors with structured fields and stack traces. // It is a drop-in replacement for stdlib errors and should be used as such throughout the app. + +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package errors import ( diff --git a/app/errors/go113.go b/app/errors/go113.go index 10e03ccae..dae50ac11 100644 --- a/app/errors/go113.go +++ b/app/errors/go113.go @@ -1,6 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 -//nolint:wrapcheck,revive +//nolint:wrapcheck,revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package errors import ( diff --git a/app/log/config.go b/app/log/config.go index 3fde5d9b0..bdd2636fb 100644 --- a/app/log/config.go +++ b/app/log/config.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/app/log/config_internal_test.go b/app/log/config_internal_test.go index f2da29a49..9baf5c59c 100644 --- a/app/log/config_internal_test.go +++ b/app/log/config_internal_test.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/app/log/filter.go b/app/log/filter.go index 15dae0b73..fa0775e73 100644 --- a/app/log/filter.go +++ b/app/log/filter.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/app/log/log.go b/app/log/log.go index a475192c0..e4166fd5e 100644 --- a/app/log/log.go +++ b/app/log/log.go @@ -3,8 +3,8 @@ // Package log provides global logging functions to be used throughout the charon app. // It supports contextual logging via WithCtx and structured logging and structured errors // via z.Field. -// -//nolint:revive + +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/app/log/metrics.go b/app/log/metrics.go index 287b5859c..aa68355d4 100644 --- a/app/log/metrics.go +++ b/app/log/metrics.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/app/log/wrapper.go b/app/log/wrapper.go index 8ff8cb94d..7e0a0461f 100644 --- a/app/log/wrapper.go +++ b/app/log/wrapper.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package log import ( diff --git a/dkg/sync/client.go b/dkg/sync/client.go index ef8300b22..101de7497 100644 --- a/dkg/sync/client.go +++ b/dkg/sync/client.go @@ -1,5 +1,6 @@ // Copyright © 2022-2026 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1 +//nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package sync import ( diff --git a/dkg/sync/server.go b/dkg/sync/server.go index 03bfec7be..e59b17a17 100644 --- a/dkg/sync/server.go +++ b/dkg/sync/server.go @@ -2,7 +2,7 @@ // Package sync provides Client and Server APIs that ensures robust network connectivity between all peers in the DKG. // It supports cluster_definition verification, soft shutdown and reconnect on connection loss. -// + //nolint:revive,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is package sync diff --git a/testutil/promrated/promrated/main.go b/testutil/promrated/promrated/main.go index c8b44e6ec..110ce5d3e 100644 --- a/testutil/promrated/promrated/main.go +++ b/testutil/promrated/promrated/main.go @@ -28,7 +28,7 @@ func newRootCmd(runFunc func(context.Context, promrated.Config) error) *cobra.Co Short: "Starts a promrated server", Long: `Starts a promrated server that polls rated and makes metrics available to prometheus`, Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { return runFunc(cmd.Context(), config) }, }