Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion .pre-commit/run_linter.sh
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
1 change: 1 addition & 0 deletions app/errors/context.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
2 changes: 2 additions & 0 deletions app/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
2 changes: 1 addition & 1 deletion app/errors/go113.go
Original file line number Diff line number Diff line change
@@ -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,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is
package errors

import (
Expand Down
9 changes: 6 additions & 3 deletions app/eth2wrap/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
10 changes: 5 additions & 5 deletions app/lifecycle/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package lifecycle

import (
"context"
"sort"
"slices"
"sync"
)

Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions app/log/config.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
1 change: 1 addition & 0 deletions app/log/config_internal_test.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
1 change: 1 addition & 0 deletions app/log/filter.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
2 changes: 2 additions & 0 deletions app/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,nolintlint // somehow the nolintlint linter catches revive as unnecessary, while it is
package log

import (
Expand Down
1 change: 1 addition & 0 deletions app/log/metrics.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
1 change: 1 addition & 0 deletions app/log/wrapper.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
14 changes: 11 additions & 3 deletions app/obolapi/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"sort"
"slices"
"strconv"
"strings"

Expand Down Expand Up @@ -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{
Expand Down
2 changes: 1 addition & 1 deletion app/retry/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions app/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down Expand Up @@ -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))
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
14 changes: 9 additions & 5 deletions cmd/relay/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"net/http"
"net/http/pprof"
"os"
"sort"
"slices"
"sync"
"time"

Expand Down Expand Up @@ -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 (
Expand Down
13 changes: 10 additions & 3 deletions cmd/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"os/signal"
"path/filepath"
"slices"
"sort"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -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
})
}

Expand Down
1 change: 1 addition & 0 deletions core/fetcher/graffiti.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
2 changes: 2 additions & 0 deletions core/parsigex/parsigex.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 23 additions & 7 deletions core/priority/calculate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package priority

import (
"bytes"
"sort"
"slices"

"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
15 changes: 12 additions & 3 deletions core/scheduler/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package scheduler
import (
"context"
"math"
"sort"
"slices"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -229,6 +229,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
//nolint:gosec // The use of background context is intentional.
go func() {
fetchCtx := log.CopyFields(context.Background(), ctx)
if err := s.fetcherFetchOnly(fetchCtx, duty, clonedDefSet, bnAddr); err != nil {
Expand Down Expand Up @@ -505,8 +506,16 @@ 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 {
Expand Down
4 changes: 2 additions & 2 deletions dkg/frost.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package dkg

import (
"context"
"sort"
"slices"

"github.com/coinbase/kryptology/pkg/core/curves"
"github.com/coinbase/kryptology/pkg/dkg/frost"
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading