From 092ec9f63f4b7eff4d280e482e0b7ebe5e70c12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=C5=A1=20Gulja=C5=A1?= Date: Thu, 19 Feb 2026 16:59:51 +0100 Subject: [PATCH 1/3] chore: use go 1.26 and golangci-lint 2.10.1 --- .golangci.yml | 6 +++ Dockerfile | 2 +- Dockerfile.dev | 2 +- Makefile | 2 +- cmd/bee/cmd/db_test.go | 3 -- go.mod | 4 +- pkg/accesscontrol/grantee.go | 1 + pkg/accesscontrol/session.go | 1 + pkg/api/chunk_stream_test.go | 2 +- pkg/api/util.go | 6 +-- pkg/bmt/proof_test.go | 4 +- pkg/crypto/crypto.go | 5 ++ pkg/crypto/crypto_test.go | 18 +++---- pkg/crypto/dh.go | 1 + pkg/crypto/signer.go | 1 + pkg/crypto/signer_test.go | 10 ++-- pkg/file/buffer_test.go | 4 +- pkg/file/pipeline/bmt/bmt_test.go | 2 +- pkg/hive/hive_test.go | 2 +- pkg/keystore/file/key.go | 2 +- pkg/keystore/test/test.go | 7 ++- pkg/log/formatter.go | 4 +- pkg/log/formatter_test.go | 22 ++++---- pkg/log/logger.go | 2 +- pkg/metrics/metrics.go | 6 +-- pkg/p2p/libp2p/version_test.go | 7 +-- pkg/postage/mock/service.go | 2 +- pkg/shed/index_test.go | 38 +++++++------- pkg/storage/migration/steps_chain_test.go | 2 +- pkg/storage/storagetest/storage.go | 2 +- pkg/storer/internal/reserve/reserve_test.go | 4 +- pkg/storer/mock/mockstorer.go | 2 +- pkg/storer/reserve_test.go | 4 +- pkg/storer/sample_test.go | 2 +- pkg/topology/kademlia/kademlia_test.go | 58 +++++++++------------ 35 files changed, 118 insertions(+), 122 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f6c9c2e8bed..ad34693a925 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -67,6 +67,12 @@ linters: - linters: - paralleltest path: pkg/log + - linters: + - staticcheck + text: 'SA5008: should encoding/json ignore this field or name it "-"\? Either use `json:"-"` to ignore the field or use `json:"''-'',"` to specify "-" as the name' + - linters: + - staticcheck + text: "SA5008: malformed `json` tag: invalid trailing ',' character" paths: - third_party$ - builtin$ diff --git a/Dockerfile b/Dockerfile index 26e9920166f..965cb3ce79f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.25 AS build +FROM golang:1.26 AS build WORKDIR /src # enable modules caching in separate layer diff --git a/Dockerfile.dev b/Dockerfile.dev index 60f6f175cb3..c6c00c19d1e 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,4 +1,4 @@ -FROM golang:1.25 AS build +FROM golang:1.26 AS build ARG REACHABILITY_OVERRIDE_PUBLIC=false ARG BATCHFACTOR_OVERRIDE_PUBLIC=5 diff --git a/Makefile b/Makefile index 504f87cb190..dd80f2ba1e3 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ GO ?= go GOBIN ?= $$($(GO) env GOPATH)/bin GOLANGCI_LINT ?= $(GOBIN)/golangci-lint -GOLANGCI_LINT_VERSION ?= v2.5.0 +GOLANGCI_LINT_VERSION ?= v2.10.1 GOGOPROTOBUF ?= protoc-gen-gogofaster GOGOPROTOBUF_VERSION ?= v1.3.1 BEEKEEPER_INSTALL_DIR ?= $(GOBIN) diff --git a/cmd/bee/cmd/db_test.go b/cmd/bee/cmd/db_test.go index 7d32b5c3080..85593ab0fbe 100644 --- a/cmd/bee/cmd/db_test.go +++ b/cmd/bee/cmd/db_test.go @@ -214,9 +214,6 @@ func TestDBNuke_FLAKY(t *testing.T) { Logger: log.Noop, ReserveCapacity: storer.DefaultReserveCapacity, }, path.Join(dataDir, "localstore")) - if err != nil { - t.Fatal(err) - } defer db.Close() info, err = db.DebugInfo(ctx) diff --git a/go.mod b/go.mod index cf602914109..a387ae7fd45 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/ethersphere/bee/v2 -go 1.25 - -toolchain go1.25.2 +go 1.26 require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 diff --git a/pkg/accesscontrol/grantee.go b/pkg/accesscontrol/grantee.go index a7ae1df32a0..6bec42ca29e 100644 --- a/pkg/accesscontrol/grantee.go +++ b/pkg/accesscontrol/grantee.go @@ -149,6 +149,7 @@ func serialize(publicKeys []*ecdsa.PublicKey) ([]byte, error) { // TODO: check if this is the correct way to serialize the public key // Is this the only curve we support? // Should we have switch case for different curves? + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh pubBytes := crypto.S256().Marshal(key.X, key.Y) b = append(b, pubBytes...) } diff --git a/pkg/accesscontrol/session.go b/pkg/accesscontrol/session.go index f3996264970..d785856b325 100644 --- a/pkg/accesscontrol/session.go +++ b/pkg/accesscontrol/session.go @@ -37,6 +37,7 @@ func (s *SessionStruct) Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]by if publicKey == nil { return nil, ErrInvalidPublicKey } + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh x, y := publicKey.ScalarMult(publicKey.X, publicKey.Y, s.key.D.Bytes()) if x == nil || y == nil { return nil, ErrSecretKeyInfinity diff --git a/pkg/api/chunk_stream_test.go b/pkg/api/chunk_stream_test.go index 5ba62cdd76c..05a77e79ef3 100644 --- a/pkg/api/chunk_stream_test.go +++ b/pkg/api/chunk_stream_test.go @@ -37,7 +37,7 @@ func TestChunkUploadStream(t *testing.T) { ) t.Run("upload and verify", func(t *testing.T) { - chsToGet := []swarm.Chunk{} + chsToGet := make([]swarm.Chunk, 0, 5) for range 5 { ch := testingc.GenerateTestRandomChunk() diff --git a/pkg/api/util.go b/pkg/api/util.go index d8911f4ecf4..b2e1933154d 100644 --- a/pkg/api/util.go +++ b/pkg/api/util.go @@ -150,7 +150,7 @@ func mapStructure(input, output any, hooks map[string]func(v string) (string, er // Do input sanity checks. inputVal = reflect.ValueOf(input) - if inputVal.Kind() == reflect.Ptr { + if inputVal.Kind() == reflect.Pointer { inputVal = inputVal.Elem() } switch { @@ -163,7 +163,7 @@ func mapStructure(input, output any, hooks map[string]func(v string) (string, er // Do output sanity checks. outputVal = reflect.ValueOf(output) switch { - case outputVal.Kind() != reflect.Ptr: + case outputVal.Kind() != reflect.Pointer: return errors.New("output is not a pointer") case outputVal.Elem().Kind() != reflect.Struct: return errors.New("output is not a struct") @@ -174,7 +174,7 @@ func mapStructure(input, output any, hooks map[string]func(v string) (string, er var set func(string, reflect.Value) error set = func(value string, field reflect.Value) error { switch fieldKind := field.Kind(); fieldKind { - case reflect.Ptr: + case reflect.Pointer: if field.IsNil() { field.Set(reflect.New(field.Type().Elem())) } diff --git a/pkg/bmt/proof_test.go b/pkg/bmt/proof_test.go index 5b3625acefb..4658cb353c7 100644 --- a/pkg/bmt/proof_test.go +++ b/pkg/bmt/proof_test.go @@ -26,7 +26,7 @@ func TestProofCorrectness(t *testing.T) { verifySegments := func(t *testing.T, exp []string, found [][]byte) { t.Helper() - var expSegments [][]byte + expSegments := make([][]byte, 0, len(exp)) for _, v := range exp { decoded, err := hex.DecodeString(v) if err != nil { @@ -154,7 +154,7 @@ func TestProofCorrectness(t *testing.T) { "745bae095b6ff5416b4a351a167f731db6d6f5924f30cd88d48e74261795d27b", } - var segments [][]byte + segments := make([][]byte, 0, len(segmentStrings)) for _, v := range segmentStrings { decoded, err := hex.DecodeString(v) if err != nil { diff --git a/pkg/crypto/crypto.go b/pkg/crypto/crypto.go index 6c43a1e4528..310e5b93c09 100644 --- a/pkg/crypto/crypto.go +++ b/pkg/crypto/crypto.go @@ -65,6 +65,7 @@ func GenerateSecp256k1Key() (*ecdsa.PrivateKey, error) { // EncodeSecp256k1PrivateKey encodes raw ECDSA private key. func EncodeSecp256k1PrivateKey(k *ecdsa.PrivateKey) ([]byte, error) { + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh pvk, _ := btcec.PrivKeyFromBytes(k.D.Bytes()) return pvk.Serialize(), nil } @@ -72,7 +73,9 @@ func EncodeSecp256k1PrivateKey(k *ecdsa.PrivateKey) ([]byte, error) { // EncodeSecp256k1PublicKey encodes raw ECDSA public key in a 33-byte compressed format. func EncodeSecp256k1PublicKey(k *ecdsa.PublicKey) []byte { var x, y btcec.FieldVal + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh x.SetByteSlice(k.X.Bytes()) + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh y.SetByteSlice(k.Y.Bytes()) return btcec.NewPublicKey(&x, &y).SerializeCompressed() } @@ -112,9 +115,11 @@ func Secp256k1PrivateKeyFromBytes(data []byte) *ecdsa.PrivateKey { // NewEthereumAddress returns a binary representation of ethereum blockchain address. // This function is based on github.com/ethereum/go-ethereum/crypto.PubkeyToAddress. func NewEthereumAddress(p ecdsa.PublicKey) ([]byte, error) { + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh if p.X == nil || p.Y == nil { return nil, errors.New("invalid public key") } + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh pubBytes := crypto.S256().Marshal(p.X, p.Y) pubHash, err := LegacyKeccak256(pubBytes[1:]) if err != nil { diff --git a/pkg/crypto/crypto_test.go b/pkg/crypto/crypto_test.go index 8a477730108..a28eb3f3ca0 100644 --- a/pkg/crypto/crypto_test.go +++ b/pkg/crypto/crypto_test.go @@ -33,7 +33,7 @@ func TestGenerateSecp256k1Key(t *testing.T) { t.Fatal("nil key") } - if bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if k1.Equal(k2) { t.Fatal("two generated keys are equal") } } @@ -56,7 +56,7 @@ func TestGenerateSecp256k1EDG(t *testing.T) { t.Fatal("nil key") } - if bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if k1.Equal(k2) { t.Fatal("two generated keys are equal") } } @@ -97,7 +97,7 @@ func TestEncodeSecp256k1PrivateKey(t *testing.T) { if err != nil { t.Fatal(err) } - if !bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if !k1.Equal(k2) { t.Fatal("encoded and decoded keys are not equal") } } @@ -117,7 +117,7 @@ func TestEncodeSecp256k1EDG(t *testing.T) { if err != nil { t.Fatal(err) } - if !bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if !k1.Equal(k2) { t.Fatal("encoded and decoded keys are not equal") } } @@ -137,7 +137,7 @@ func TestSecp256k1PrivateKeyFromBytes(t *testing.T) { t.Fatal("nil key") } - if !bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if !k1.Equal(k2) { t.Fatal("two generated keys are not equal") } } @@ -160,7 +160,7 @@ func TestGenerateSecp256r1Key(t *testing.T) { t.Fatal("nil key") } - if bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if k1.Equal(k2) { t.Fatal("two generated keys are equal") } } @@ -183,7 +183,7 @@ func TestGenerateSecp256r1EDG(t *testing.T) { t.Fatal("nil key") } - if bytes.Equal(r1.D.Bytes(), r2.D.Bytes()) { + if r1.Equal(r2) { t.Fatal("two generated keys are equal") } } @@ -203,7 +203,7 @@ func TestEncodeSecp256r1PrivateKey(t *testing.T) { if err != nil { t.Fatal(err) } - if !bytes.Equal(r1.D.Bytes(), r2.D.Bytes()) { + if !r1.Equal(r2) { t.Fatal("encoded and decoded keys are not equal") } } @@ -223,7 +223,7 @@ func TestEncodeSecp256r1EDG(t *testing.T) { if err != nil { t.Fatal(err) } - if !bytes.Equal(r1.D.Bytes(), r2.D.Bytes()) { + if !r1.Equal(r2) { t.Fatal("encoded and decoded keys are not equal") } } diff --git a/pkg/crypto/dh.go b/pkg/crypto/dh.go index f3ea41facc4..8b20af98a1a 100644 --- a/pkg/crypto/dh.go +++ b/pkg/crypto/dh.go @@ -29,6 +29,7 @@ func NewDH(key *ecdsa.PrivateKey) DH { // safety warning: this method is not meant to be exposed as it does not validate private and public keys // are on the same curve func (dh *defaultDH) SharedKey(pub *ecdsa.PublicKey, salt []byte) ([]byte, error) { + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh x, _ := pub.ScalarMult(pub.X, pub.Y, dh.key.D.Bytes()) if x == nil { return nil, errors.New("shared secret is point at infinity") diff --git a/pkg/crypto/signer.go b/pkg/crypto/signer.go index 9c3ee670ded..586f93535ba 100644 --- a/pkg/crypto/signer.go +++ b/pkg/crypto/signer.go @@ -139,6 +139,7 @@ func (d *defaultSigner) SignTypedData(typedData *eip712.TypedData) ([]byte, erro // sign the provided hash and convert it to the ethereum (r,s,v) format. func (d *defaultSigner) sign(sighash []byte, isCompressedKey bool) ([]byte, error) { + //nolint:staticcheck // SA1019: ecdsa fields are deprecated, but secp256k1 is not supported by crypto/ecdh pvk, _ := btcec.PrivKeyFromBytes(d.key.D.Bytes()) signature, err := btcecdsa.SignCompact(pvk, sighash, isCompressedKey) if err != nil { diff --git a/pkg/crypto/signer_test.go b/pkg/crypto/signer_test.go index 6d6690ec27e..adf7104948c 100644 --- a/pkg/crypto/signer_test.go +++ b/pkg/crypto/signer_test.go @@ -41,7 +41,7 @@ func TestDefaultSigner(t *testing.T) { t.Fatal(err) } - if pubKey.X.Cmp(privKey.X) != 0 || pubKey.Y.Cmp(privKey.Y) != 0 { + if !pubKey.Equal(&privKey.PublicKey) { t.Fatalf("wanted %v but got %v", pubKey, &privKey.PublicKey) } }) @@ -54,7 +54,7 @@ func TestDefaultSigner(t *testing.T) { t.Fatal(err) } - if pubKey.X.Cmp(privKey.X) == 0 && pubKey.Y.Cmp(privKey.Y) == 0 { + if pubKey.Equal(&privKey.PublicKey) { t.Fatal("expected different public key") } }) @@ -228,11 +228,7 @@ func TestRecoverEIP712(t *testing.T) { t.Fatal(err) } - if privKey.X.Cmp(pubKey.X) != 0 { - t.Fatalf("recovered wrong public key. wanted %x, got %x", privKey.PublicKey, pubKey) - } - - if privKey.Y.Cmp(pubKey.Y) != 0 { + if !privKey.PublicKey.Equal(pubKey) { t.Fatalf("recovered wrong public key. wanted %x, got %x", privKey.PublicKey, pubKey) } } diff --git a/pkg/file/buffer_test.go b/pkg/file/buffer_test.go index 71b374b7f4b..a41f9d4426b 100644 --- a/pkg/file/buffer_test.go +++ b/pkg/file/buffer_test.go @@ -114,10 +114,10 @@ func TestCopyBuffer(t *testing.T) { swarm.ChunkSize*17 + 3, } - testCases := []struct { + testCases := make([]struct { readBufferSize int dataSize int - }{} + }, 0, len(dataSizes)*len(readBufferSizes)) for i := range readBufferSizes { for j := range dataSizes { diff --git a/pkg/file/pipeline/bmt/bmt_test.go b/pkg/file/pipeline/bmt/bmt_test.go index 7fba1d763d0..30e3f12280c 100644 --- a/pkg/file/pipeline/bmt/bmt_test.go +++ b/pkg/file/pipeline/bmt/bmt_test.go @@ -52,7 +52,7 @@ func TestBmtWriter(t *testing.T) { mockChainWriter := mock.NewChainWriter() writer := bmt.NewBmtWriter(mockChainWriter) - var data []byte + data := make([]byte, 0, len(tc.data)) if !tc.noSpan { data = make([]byte, 8) diff --git a/pkg/hive/hive_test.go b/pkg/hive/hive_test.go index ec603c8bb2b..dbad90dac04 100644 --- a/pkg/hive/hive_test.go +++ b/pkg/hive/hive_test.go @@ -146,7 +146,7 @@ func TestBroadcastPeers(t *testing.T) { underlays = []ma.Multiaddr{u, u2} } else { n := (i % 3) + 1 - for j := 0; j < n; j++ { + for j := range n { port := i + j*10000 u, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/" + strconv.Itoa(port)) if err != nil { diff --git a/pkg/keystore/file/key.go b/pkg/keystore/file/key.go index 5844b0dd1ef..104c01609af 100644 --- a/pkg/keystore/file/key.go +++ b/pkg/keystore/file/key.go @@ -11,6 +11,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "crypto/sha3" "encoding/hex" "encoding/json" "fmt" @@ -21,7 +22,6 @@ import ( "github.com/ethersphere/bee/v2/pkg/keystore" "github.com/google/uuid" "golang.org/x/crypto/scrypt" - "golang.org/x/crypto/sha3" ) var _ keystore.Service = (*Service)(nil) diff --git a/pkg/keystore/test/test.go b/pkg/keystore/test/test.go index 47309a6afe0..3bea51e8ac8 100644 --- a/pkg/keystore/test/test.go +++ b/pkg/keystore/test/test.go @@ -5,7 +5,6 @@ package test import ( - "bytes" "errors" "testing" @@ -52,7 +51,7 @@ func Service(t *testing.T, s keystore.Service, edg keystore.EDG) { if created { t.Fatal("key is created, but should not be") } - if !bytes.Equal(k1.D.Bytes(), k2.D.Bytes()) { + if !k1.Equal(k2) { t.Fatal("two keys are not equal") } @@ -70,7 +69,7 @@ func Service(t *testing.T, s keystore.Service, edg keystore.EDG) { if !created { t.Fatal("key is not created") } - if bytes.Equal(k1.D.Bytes(), k3.D.Bytes()) { + if k1.Equal(k3) { t.Fatal("two keys are equal, but should not be") } @@ -82,7 +81,7 @@ func Service(t *testing.T, s keystore.Service, edg keystore.EDG) { if created { t.Fatal("key is created, but should not be") } - if !bytes.Equal(k3.D.Bytes(), k4.D.Bytes()) { + if !k3.Equal(k4) { t.Fatal("two keys are not equal") } } diff --git a/pkg/log/formatter.go b/pkg/log/formatter.go index 558e445376a..da8f645c01c 100644 --- a/pkg/log/formatter.go +++ b/pkg/log/formatter.go @@ -362,7 +362,7 @@ func (f *formatter) prettyWithFlags(value any, flags uint32, depth int) string { } buf.WriteByte('}') return buf.String() - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: if v.IsNil() { return null } @@ -434,7 +434,7 @@ func isEmpty(v reflect.Value) bool { return v.Float() == 0 case reflect.Complex64, reflect.Complex128: return v.Complex() == 0 - case reflect.Interface, reflect.Ptr: + case reflect.Interface, reflect.Pointer: return v.IsNil() } return false diff --git a/pkg/log/formatter_test.go b/pkg/log/formatter_test.go index c78cce38453..4425cafa185 100644 --- a/pkg/log/formatter_test.go +++ b/pkg/log/formatter_test.go @@ -94,7 +94,7 @@ type ( String2 string `json:"-"` // ignored String3 string `json:"-,"` // named "-" String4 string `json:"string4,omitempty"` // renamed, ignore if empty - String5 string `json:","` // no-op + String5 string `json:""` // no-op String6 string `json:",omitempty"` // ignore if empty } @@ -103,7 +103,7 @@ type ( Bool2 bool `json:"-"` // ignored Bool3 bool `json:"-,"` // named "-" Bool4 bool `json:"bool4,omitempty"` // renamed, ignore if empty - Bool5 bool `json:","` // no-op + Bool5 bool `json:""` // no-op Bool6 bool `json:",omitempty"` // ignore if empty } @@ -112,7 +112,7 @@ type ( Int2 int `json:"-"` // ignored Int3 int `json:"-,"` // named "-" Int4 int `json:"int4,omitempty"` // renamed, ignore if empty - Int5 int `json:","` // no-op + Int5 int `json:""` // no-op Int6 int `json:",omitempty"` // ignore if empty } @@ -121,7 +121,7 @@ type ( Uint2 uint `json:"-"` // ignored Uint3 uint `json:"-,"` // named "-" Uint4 uint `json:"uint4,omitempty"` // renamed, ignore if empty - Uint5 uint `json:","` // no-op + Uint5 uint `json:""` // no-op Uint6 uint `json:",omitempty"` // ignore if empty } @@ -130,7 +130,7 @@ type ( Float2 float64 `json:"-"` // ignored Float3 float64 `json:"-,"` // named "-" Float4 float64 `json:"float4,omitempty"` // renamed, ignore if empty - Float5 float64 `json:","` // no-op + Float5 float64 `json:""` // no-op Float6 float64 `json:",omitempty"` // ignore if empty } @@ -139,7 +139,7 @@ type ( Complex2 complex128 `json:"-"` // ignored Complex3 complex128 `json:"-,"` // named "-" Complex4 complex128 `json:"complex4,omitempty"` // renamed, ignore if empty - Complex5 complex128 `json:","` // no-op + Complex5 complex128 `json:""` // no-op Complex6 complex128 `json:",omitempty"` // ignore if empty } @@ -148,7 +148,7 @@ type ( Ptr2 *string `json:"-"` // ignored Ptr3 *string `json:"-,"` // named "-" Ptr4 *string `json:"ptr4,omitempty"` // renamed, ignore if empty - Ptr5 *string `json:","` // no-op + Ptr5 *string `json:""` // no-op Ptr6 *string `json:",omitempty"` // ignore if empty } @@ -157,7 +157,7 @@ type ( Array2 [2]string `json:"-"` // ignored Array3 [2]string `json:"-,"` // named "-" Array4 [2]string `json:"array4,omitempty"` // renamed, ignore if empty - Array5 [2]string `json:","` // no-op + Array5 [2]string `json:""` // no-op Array6 [2]string `json:",omitempty"` // ignore if empty } @@ -166,7 +166,7 @@ type ( Slice2 []string `json:"-"` // ignored Slice3 []string `json:"-,"` // named "-" Slice4 []string `json:"slice4,omitempty"` // renamed, ignore if empty - Slice5 []string `json:","` // no-op + Slice5 []string `json:""` // no-op Slice6 []string `json:",omitempty"` // ignore if empty } @@ -175,7 +175,7 @@ type ( Map2 map[string]string `json:"-"` // ignored Map3 map[string]string `json:"-,"` // named "-" Map4 map[string]string `json:"map4,omitempty"` // renamed, ignore if empty - Map5 map[string]string `json:","` // no-op + Map5 map[string]string `json:""` // no-op Map6 map[string]string `json:",omitempty"` // ignore if empty } @@ -208,7 +208,7 @@ type ( Inner2Test `json:"-"` Inner3Test `json:"-,"` Inner4Test `json:"inner4"` - Inner5Test `json:","` + Inner5Test `json:""` Inner6Test `json:"inner6"` } ) diff --git a/pkg/log/logger.go b/pkg/log/logger.go index bb81d327172..f90d76ece47 100644 --- a/pkg/log/logger.go +++ b/pkg/log/logger.go @@ -260,7 +260,7 @@ func (l *logger) log(vl Level, mc MessageCategory, err error, msg string, keysAn // hash is a hashing function for creating unique identifiers. func hash(prefix string, v uint, values string, w io.Writer) string { var sink uintptr - if reflect.ValueOf(w).Kind() == reflect.Ptr { + if reflect.ValueOf(w).Kind() == reflect.Pointer { sink = reflect.ValueOf(w).Pointer() } else { sink = reflect.ValueOf(&w).Pointer() diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 64ceef0c51e..ad334157d48 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -20,11 +20,11 @@ type Collector interface { func PrometheusCollectorsFromFields(i any) (cs []prometheus.Collector) { v := reflect.Indirect(reflect.ValueOf(i)) - for i := 0; i < v.NumField(); i++ { - if !v.Field(i).CanInterface() { + for _, field := range v.Fields() { + if !field.CanInterface() { continue } - if u, ok := v.Field(i).Interface().(prometheus.Collector); ok { + if u, ok := field.Interface().(prometheus.Collector); ok { cs = append(cs, u) } } diff --git a/pkg/p2p/libp2p/version_test.go b/pkg/p2p/libp2p/version_test.go index 15e0ce3eba6..0e18b1ba820 100644 --- a/pkg/p2p/libp2p/version_test.go +++ b/pkg/p2p/libp2p/version_test.go @@ -5,7 +5,6 @@ package libp2p import ( - "context" "testing" "github.com/ethersphere/bee/v2/pkg/crypto" @@ -120,8 +119,7 @@ func TestBee260BackwardCompatibility(t *testing.T) { t.Parallel() // Create a service with minimal configuration - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() swarmKey, err := crypto.GenerateSecp256k1Key() if err != nil { @@ -167,8 +165,7 @@ func TestBee260BackwardCompatibility(t *testing.T) { func TestBee260Cache(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() swarmKey, err := crypto.GenerateSecp256k1Key() if err != nil { diff --git a/pkg/postage/mock/service.go b/pkg/postage/mock/service.go index b4fffd07761..9584ffeeb1c 100644 --- a/pkg/postage/mock/service.go +++ b/pkg/postage/mock/service.go @@ -70,7 +70,7 @@ func (m *mockPostage) StampIssuers() []*postage.StampIssuer { m.issuerLock.Lock() defer m.issuerLock.Unlock() - issuers := make([]*postage.StampIssuer, 0) + issuers := make([]*postage.StampIssuer, 0, len(m.issuersMap)) for _, v := range m.issuersMap { issuers = append(issuers, v) } diff --git a/pkg/shed/index_test.go b/pkg/shed/index_test.go index 91eb657b649..ccf0fa36c18 100644 --- a/pkg/shed/index_test.go +++ b/pkg/shed/index_test.go @@ -345,11 +345,11 @@ func TestIndex(t *testing.T) { } t.Run("not found", func(t *testing.T) { - items := make([]Item, len(want)) - for i, w := range want { - items[i] = Item{ + items := make([]Item, 0, len(want)+1) + for _, w := range want { + items = append(items, Item{ Address: w.Address, - } + }) } items = append(items, Item{ Address: []byte("put-hash-missing"), @@ -373,28 +373,29 @@ func TestIndex_Iterate(t *testing.T) { t.Fatal(err) } - items := []Item{ - { + items := make([]Item, 0, 6) + items = append(items, + Item{ Address: []byte("iterate-hash-01"), Data: []byte("data80"), }, - { + Item{ Address: []byte("iterate-hash-03"), Data: []byte("data22"), }, - { + Item{ Address: []byte("iterate-hash-05"), Data: []byte("data41"), }, - { + Item{ Address: []byte("iterate-hash-02"), Data: []byte("data84"), }, - { + Item{ Address: []byte("iterate-hash-06"), Data: []byte("data1"), }, - } + ) batch := new(leveldb.Batch) for _, i := range items { err = index.PutInBatch(batch, i) @@ -555,28 +556,29 @@ func TestIndex_IterateReverse(t *testing.T) { t.Fatal(err) } - items := []Item{ - { + items := make([]Item, 0, 6) + items = append(items, + Item{ Address: []byte("iterate-hash-01"), Data: []byte("data80"), }, - { + Item{ Address: []byte("iterate-hash-03"), Data: []byte("data22"), }, - { + Item{ Address: []byte("iterate-hash-05"), Data: []byte("data41"), }, - { + Item{ Address: []byte("iterate-hash-02"), Data: []byte("data84"), }, - { + Item{ Address: []byte("iterate-hash-06"), Data: []byte("data1"), }, - } + ) batch := new(leveldb.Batch) for _, i := range items { err = index.PutInBatch(batch, i) diff --git a/pkg/storage/migration/steps_chain_test.go b/pkg/storage/migration/steps_chain_test.go index 327a41331d7..5bcc1cb6aeb 100644 --- a/pkg/storage/migration/steps_chain_test.go +++ b/pkg/storage/migration/steps_chain_test.go @@ -19,7 +19,7 @@ func TestNewStepsChain(t *testing.T) { store := inmemstore.New() populateStore(t, store, populateItemsCount) - stepsFn := make([]migration.StepFn, 0) + stepsFn := make([]migration.StepFn, 0, 10) // Create 10 step functions where each would remove single element, having value [0-10) for i := range 10 { diff --git a/pkg/storage/storagetest/storage.go b/pkg/storage/storagetest/storage.go index 9ee41971b43..7869227e43c 100644 --- a/pkg/storage/storagetest/storage.go +++ b/pkg/storage/storagetest/storage.go @@ -95,7 +95,7 @@ func (o *obj1) ID() string { return o.Id } func (obj1) Namespace() string { return "obj1" } func (o *obj1) Marshal() ([]byte, error) { - buf := make([]byte, 40) + buf := make([]byte, 40, 40+len(o.Buf)) copy(buf[:32], o.Id) binary.LittleEndian.PutUint64(buf[32:], o.SomeInt) buf = append(buf, o.Buf[:]...) diff --git a/pkg/storer/internal/reserve/reserve_test.go b/pkg/storer/internal/reserve/reserve_test.go index 87f700a98c8..e0dbd6a4305 100644 --- a/pkg/storer/internal/reserve/reserve_test.go +++ b/pkg/storer/internal/reserve/reserve_test.go @@ -537,7 +537,7 @@ func TestEvict(t *testing.T) { ts := internal.NewInmemStorage() chunksPerBatch := 50 - var chunks []swarm.Chunk + chunks := make([]swarm.Chunk, 0, 3*chunksPerBatch) batches := []*postage.Batch{postagetesting.MustNewBatch(), postagetesting.MustNewBatch(), postagetesting.MustNewBatch()} evictBatch := batches[1] @@ -690,7 +690,7 @@ func TestEvictMaxCount(t *testing.T) { t.Fatal(err) } - var chunks []swarm.Chunk + chunks := make([]swarm.Chunk, 0, 20) batch := postagetesting.MustNewBatch() diff --git a/pkg/storer/mock/mockstorer.go b/pkg/storer/mock/mockstorer.go index efdce20bbf4..2d851355714 100644 --- a/pkg/storer/mock/mockstorer.go +++ b/pkg/storer/mock/mockstorer.go @@ -132,7 +132,7 @@ func (m *mockStorer) ListSessions(offset, limit int) ([]storer.SessionInfo, erro m.mu.Lock() defer m.mu.Unlock() - sessions := []storer.SessionInfo{} + sessions := make([]storer.SessionInfo, 0, len(m.activeSessions)) for _, v := range m.activeSessions { sessions = append(sessions, *v) } diff --git a/pkg/storer/reserve_test.go b/pkg/storer/reserve_test.go index 3126a45015c..a54eac30ad7 100644 --- a/pkg/storer/reserve_test.go +++ b/pkg/storer/reserve_test.go @@ -191,8 +191,8 @@ func TestEvictBatch(t *testing.T) { ctx := context.Background() - var chunks []swarm.Chunk var chunksPerPO uint64 = 10 + chunks := make([]swarm.Chunk, 0, int(chunksPerPO)*3) batches := []*postage.Batch{postagetesting.MustNewBatch(), postagetesting.MustNewBatch(), postagetesting.MustNewBatch()} evictBatch := batches[1] @@ -475,8 +475,8 @@ func TestSubscribeBin(t *testing.T) { testF := func(t *testing.T, baseAddr swarm.Address, storer *storer.DB) { t.Helper() var ( - chunks []swarm.Chunk chunksPerPO uint64 = 50 + chunks = make([]swarm.Chunk, 0, int(chunksPerPO)*2) putter = storer.ReservePutter() ) diff --git a/pkg/storer/sample_test.go b/pkg/storer/sample_test.go index 49745c4b24f..31c3a6bb7bb 100644 --- a/pkg/storer/sample_test.go +++ b/pkg/storer/sample_test.go @@ -24,7 +24,7 @@ func TestReserveSampler(t *testing.T) { const maxPO = 10 randChunks := func(baseAddr swarm.Address, timeVar uint64) []swarm.Chunk { - var chs []swarm.Chunk + chs := make([]swarm.Chunk, 0, chunkCountPerPO*maxPO) for po := range maxPO { for range chunkCountPerPO { ch := chunk.GenerateValidRandomChunkAt(t, baseAddr, po).WithBatch(3, 2, false) diff --git a/pkg/topology/kademlia/kademlia_test.go b/pkg/topology/kademlia/kademlia_test.go index 6750ebe2284..9349f283278 100644 --- a/pkg/topology/kademlia/kademlia_test.go +++ b/pkg/topology/kademlia/kademlia_test.go @@ -58,7 +58,7 @@ func TestNeighborhoodDepth(t *testing.T) { var ( conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - SaturationPeers: ptrInt(4), + SaturationPeers: new(4), ExcludeFunc: defaultExcludeFunc, }) ) @@ -205,7 +205,7 @@ func TestNeighborhoodDepthWithReachability(t *testing.T) { var ( conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - SaturationPeers: ptrInt(4), + SaturationPeers: new(4), }) ) @@ -353,7 +353,7 @@ func TestManage(t *testing.T) { conns int32 // how many connect calls were made to the p2p mock saturation = kademlia.DefaultSaturationPeers base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - BitSuffixLength: ptrInt(-1), + BitSuffixLength: new(-1), ExcludeFunc: defaultExcludeFunc, }) ) @@ -405,8 +405,8 @@ func TestManageWithBalancing(t *testing.T) { } base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ SaturationFunc: saturationFunc, - SaturationPeers: ptrInt(4), - BitSuffixLength: ptrInt(2), + SaturationPeers: new(4), + BitSuffixLength: new(2), ExcludeFunc: defaultExcludeFunc, }) ) @@ -451,8 +451,8 @@ func TestBinSaturation(t *testing.T) { var ( conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - SaturationPeers: ptrInt(2), - BitSuffixLength: ptrInt(-1), + SaturationPeers: new(2), + BitSuffixLength: new(-1), ExcludeFunc: defaultExcludeFunc, }) ) @@ -554,8 +554,8 @@ func TestOversaturationBootnode(t *testing.T) { overSaturationPeers = 4 conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - OverSaturationPeers: ptrInt(overSaturationPeers), - SaturationPeers: ptrInt(4), + OverSaturationPeers: new(overSaturationPeers), + SaturationPeers: new(4), BootnodeMode: true, ExcludeFunc: defaultExcludeFunc, }) @@ -612,8 +612,8 @@ func TestBootnodeMaxConnections(t *testing.T) { bootnodeOverSaturationPeers = 4 conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - BootnodeOverSaturationPeers: ptrInt(bootnodeOverSaturationPeers), - SaturationPeers: ptrInt(4), + BootnodeOverSaturationPeers: new(bootnodeOverSaturationPeers), + SaturationPeers: new(4), BootnodeMode: true, ExcludeFunc: defaultExcludeFunc, }) @@ -772,7 +772,7 @@ func TestBackoff(t *testing.T) { var ( conns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, nil, kademlia.Options{ - TimeToRetry: ptrDuration(500 * time.Millisecond), + TimeToRetry: new(500 * time.Millisecond), }) ) kad.SetStorageRadius(0) @@ -815,7 +815,7 @@ func TestAddressBookPrune(t *testing.T) { var ( conns, failedConns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, &failedConns, kademlia.Options{ - TimeToRetry: ptrDuration(0), + TimeToRetry: new(time.Duration), }) ) @@ -893,7 +893,7 @@ func TestAddressBookQuickPrune_FLAKY(t *testing.T) { var ( conns, failedConns int32 // how many connect calls were made to the p2p mock base, kad, ab, _, signer = newTestKademlia(t, &conns, &failedConns, kademlia.Options{ - TimeToRetry: ptrDuration(time.Millisecond), + TimeToRetry: new(time.Millisecond), }) ) kad.SetStorageRadius(2) @@ -1311,8 +1311,8 @@ func TestOutofDepthPrune(t *testing.T) { } base, kad, ab, _, signer = newTestKademlia(t, &conns, &failedConns, kademlia.Options{ - SaturationPeers: ptrInt(saturationPeers), - OverSaturationPeers: ptrInt(overSaturationPeers), + SaturationPeers: new(saturationPeers), + OverSaturationPeers: new(overSaturationPeers), PruneFunc: pruneFunc, ExcludeFunc: defaultExcludeFunc, PruneWakeup: &pruneWakeup, @@ -1415,8 +1415,8 @@ func TestPruneExcludeOps(t *testing.T) { } base, kad, ab, _, signer = newTestKademlia(t, &conns, &failedConns, kademlia.Options{ - SaturationPeers: ptrInt(saturationPeers), - OverSaturationPeers: ptrInt(overSaturationPeers), + SaturationPeers: new(saturationPeers), + OverSaturationPeers: new(overSaturationPeers), PruneFunc: pruneFunc, }) ) @@ -1519,10 +1519,10 @@ func TestBootnodeProtectedNodes(t *testing.T) { conns int32 // how many connect calls were made to the p2p mock overSaturationPeers = 1 _, kad, ab, _, signer = newTestKademliaWithAddr(t, base, &conns, nil, kademlia.Options{ - BootnodeOverSaturationPeers: ptrInt(1), - OverSaturationPeers: ptrInt(overSaturationPeers), - SaturationPeers: ptrInt(1), - LowWaterMark: ptrInt(0), + BootnodeOverSaturationPeers: new(1), + OverSaturationPeers: new(overSaturationPeers), + SaturationPeers: new(1), + LowWaterMark: new(0), BootnodeMode: true, StaticNodes: protected, ExcludeFunc: defaultExcludeFunc, @@ -1685,8 +1685,8 @@ func TestAnnounceNeighborhoodToNeighbor(t *testing.T) { ) base, kad, ab, _, signer = newTestKademliaWithDiscovery(t, disc, &conns, nil, kademlia.Options{ ExcludeFunc: defaultExcludeFunc, - OverSaturationPeers: ptrInt(4), - SaturationPeers: ptrInt(4), + OverSaturationPeers: new(4), + SaturationPeers: new(4), }) ) @@ -2232,19 +2232,11 @@ func waitBalanced(t *testing.T, k *kademlia.Kad, bin uint8) { } } -func ptrInt(v int) *int { - return &v -} - -func ptrDuration(v time.Duration) *time.Duration { - return &v -} - func generateMultipleUnderlays(t *testing.T, n int, baseUnderlay string) []ma.Multiaddr { t.Helper() underlays := make([]ma.Multiaddr, n) - for i := 0; i < n; i++ { + for i := range n { multiaddr, err := ma.NewMultiaddr(baseUnderlay + strconv.Itoa(i)) if err != nil { t.Fatal(err) From 9a87eb9f33e792a5ec304f6102160f5b13a9b0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=C5=A1=20Gulja=C5=A1?= Date: Thu, 19 Feb 2026 17:12:27 +0100 Subject: [PATCH 2/3] chore: modernize snapshot load benchmark --- pkg/node/snapshot_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/node/snapshot_test.go b/pkg/node/snapshot_test.go index eab031067fd..2fbf0323ccd 100644 --- a/pkg/node/snapshot_test.go +++ b/pkg/node/snapshot_test.go @@ -198,8 +198,8 @@ func TestSnapshotLogFilterer_RealSnapshot(t *testing.T) { func BenchmarkNewSnapshotLogFilterer_Load(b *testing.B) { getter := realSnapshotGetter{} - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for b.Loop() { filterer := node.NewSnapshotLogFilterer(log.Noop, getter) _, err := filterer.BlockNumber(context.Background()) if err != nil { From 4cd42eb0003b3833c0806ccac23752667aa5da38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jano=C5=A1=20Gulja=C5=A1?= Date: Thu, 19 Feb 2026 17:17:20 +0100 Subject: [PATCH 3/3] chore: bump golangci-lint in github workflow --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4bbfa5be9bd..60328fc2854 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -78,10 +78,10 @@ jobs: with: configFile: commitlint.config.js - name: GolangCI-Lint - uses: golangci/golangci-lint-action@v8 + uses: golangci/golangci-lint-action@v9 with: skip-cache: false - version: v2.5.0 + version: v2.10.1 - name: Whitespace check run: make check-whitespace - name: go mod tidy check