Skip to content
Draft
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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The following emojis are used to highlight certain changes:

### Changed

- updated Go in `go.mod` to 1.26.0

### Removed

### Fixed
Expand Down
18 changes: 9 additions & 9 deletions autoconf/fetch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,12 @@ func TestHTTPCachingBehavior(t *testing.T) {

etag := `"test-etag-123"`
lastModified := "Wed, 21 Oct 2015 07:28:00 GMT"
var requestCount int32
var conditionalRequestCount int32
var requestCount atomic.Int32
var conditionalRequestCount atomic.Int32

// Create server that tracks conditional requests
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
count := atomic.AddInt32(&requestCount, 1)
count := requestCount.Add(1)
t.Logf("HTTP caching test request #%d: %s, If-None-Match: %s, If-Modified-Since: %s",
count, r.Method, r.Header.Get("If-None-Match"), r.Header.Get("If-Modified-Since"))

Expand All @@ -483,7 +483,7 @@ func TestHTTPCachingBehavior(t *testing.T) {
ifModifiedSince := r.Header.Get("If-Modified-Since")

if ifNoneMatch == etag || ifModifiedSince == lastModified {
atomic.AddInt32(&conditionalRequestCount, 1)
conditionalRequestCount.Add(1)
// Return 304 Not Modified
t.Logf("Returning 304 Not Modified for conditional request")
w.WriteHeader(http.StatusNotModified)
Expand Down Expand Up @@ -528,12 +528,12 @@ func TestHTTPCachingBehavior(t *testing.T) {
require.NotNil(t, config1)
assert.Equal(t, int64(2025080101), config1.AutoConfVersion)

initialRequestCount := atomic.LoadInt32(&requestCount)
initialRequestCount := requestCount.Load()
require.GreaterOrEqual(t, int(initialRequestCount), 1, "Should have made at least one initial request")

// Reset counters to track only subsequent requests
atomic.StoreInt32(&requestCount, 0)
atomic.StoreInt32(&conditionalRequestCount, 0)
requestCount.Store(0)
conditionalRequestCount.Store(0)

// Wait to ensure cache is considered stale (100ms refresh interval)
time.Sleep(150 * time.Millisecond)
Expand All @@ -547,8 +547,8 @@ func TestHTTPCachingBehavior(t *testing.T) {
time.Sleep(100 * time.Millisecond)

// Should have made at least one conditional request
finalRequestCount := atomic.LoadInt32(&requestCount)
finalConditionalCount := atomic.LoadInt32(&conditionalRequestCount)
finalRequestCount := requestCount.Load()
finalConditionalCount := conditionalRequestCount.Load()

t.Logf("Final request count: %d, conditional count: %d", finalRequestCount, finalConditionalCount)

Expand Down
8 changes: 3 additions & 5 deletions bitswap/network/bsnet/ipfs_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -933,14 +933,12 @@ func TestSendMessageManyCallersDoNotSerialize(t *testing.T) {
start := time.Now()
var wg sync.WaitGroup
errs := make(chan error, callers)
for i := 0; i < callers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for range callers {
wg.Go(func() {
if err := bsnet1.SendMessage(ctx, p2.ID(), msg); err != nil {
errs <- err
}
}()
})
}
wg.Wait()
close(errs)
Expand Down
6 changes: 2 additions & 4 deletions bitswap/server/internal/decision/chokepoint_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ func BenchmarkContended(b *testing.B) {

// Writer goroutine: calls markServed at the target rate.
if writeHz > 0 {
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
interval := time.Second / time.Duration(writeHz)
t := time.NewTicker(interval)
defer t.Stop()
Expand All @@ -122,7 +120,7 @@ func BenchmarkContended(b *testing.B) {
i++
}
}
}()
})
}

var ops atomic.Uint64
Expand Down
6 changes: 3 additions & 3 deletions bitswap/server/internal/decision/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestFairSchedulerLowPendingPeerIsServed(t *testing.T) {

newPeerBlockCid := blocks.NewBlock([]byte(newPeerCid)).Cid()

for i := 0; i < maxEnvelopesToWait; i++ {
for i := range maxEnvelopesToWait {
select {
case next := <-e.Outbox():
env := <-next
Expand Down Expand Up @@ -190,7 +190,7 @@ func TestFairComparatorCappedPendingAndTiebreak(t *testing.T) {
if first == cmp(bMed, aBig) {
t.Fatal("salted tiebreak must be antisymmetric")
}
for i := 0; i < 100; i++ {
for range 100 {
if cmp(aBig, bMed) != first {
t.Fatal("salted tiebreak must be stable within a scheduler instance")
}
Expand All @@ -206,7 +206,7 @@ func TestFairComparatorTiebreakSaltVariesAcrossSchedulers(t *testing.T) {
now := time.Now()

flips := 0
for i := 0; i < pairs; i++ {
for i := range pairs {
s1 := newPeerScheduler()
s2 := newPeerScheduler()
idA := peer.ID(fmt.Sprintf("peer-a-%03d", i))
Expand Down
8 changes: 4 additions & 4 deletions blockstore/blockstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func NewGCLocker() GCLocker {

type gclocker struct {
lk sync.RWMutex
gcreq int32
gcreq atomic.Int32
}

// Unlocker represents an object which can Unlock
Expand All @@ -414,9 +414,9 @@ func (u *unlocker) Unlock(_ context.Context) {
}

func (bs *gclocker) GCLock(_ context.Context) Unlocker {
atomic.AddInt32(&bs.gcreq, 1)
bs.gcreq.Add(1)
bs.lk.Lock()
atomic.AddInt32(&bs.gcreq, -1)
bs.gcreq.Add(-1)
return &unlocker{bs.lk.Unlock}
}

Expand All @@ -426,5 +426,5 @@ func (bs *gclocker) PinLock(_ context.Context) Unlocker {
}

func (bs *gclocker) GCRequested(_ context.Context) bool {
return atomic.LoadInt32(&bs.gcreq) > 0
return bs.gcreq.Load() > 0
}
2 changes: 1 addition & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ipfs/boxo/examples

go 1.25.7
go 1.26

require (
github.com/ipfs/boxo v0.41.0
Expand Down
5 changes: 3 additions & 2 deletions fetcher/impl/blockservice/fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bsfetcher_test

import (
"context"
"slices"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -174,8 +175,8 @@ func TestFetchIPLDPath(t *testing.T) {
explorePath := func(p string, s builder.SelectorSpec) builder.SelectorSpec {
return ssb.ExploreFields(func(efsb builder.ExploreFieldsSpecBuilder) { efsb.Insert(p, s) })
}
for i := len(path) - 1; i >= 0; i-- {
spec = explorePath(path[i], spec)
for _, p := range slices.Backward(path) {
spec = explorePath(p, spec)
}
sel := spec.Node()

Expand Down
2 changes: 1 addition & 1 deletion files/webfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestWebFile(t *testing.T) {
t.Fatalf("expected %q but got %q", content, string(body))
}
if actual := wf.Mode(); actual != mode {
t.Fatalf("expected file mode %q but got 0%q", mode, strconv.FormatUint(uint64(actual), 8))
t.Fatalf("expected file mode %O but got %O", mode, uint64(actual))
}
if actual := wf.ModTime(); !actual.Equal(mtime) {
t.Fatalf("expected last modified time %q but got %q", mtime, actual)
Expand Down
4 changes: 2 additions & 2 deletions gateway/backend_car_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ func TestCarBackendTar(t *testing.T) {

// Track requests to handle exampleA being requested multiple times with partial responses
exampleARequests := make(map[string]int)
var requestCount int32
var requestCount atomic.Int32

s := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
atomic.AddInt32(&requestCount, 1)
requestCount.Add(1)

// Get the path, ignoring query parameters for comparison
requestPath := request.URL.Path
Expand Down
6 changes: 2 additions & 4 deletions gateway/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,7 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa
code := defaultCode

// Pass Retry-After hint to the client
var era *ErrorRetryAfter
if errors.As(err, &era) {
if era, ok := errors.AsType[*ErrorRetryAfter](err); ok {
if era.RetryAfter > 0 {
w.Header().Set("Retry-After", era.RetryAfterHeader())
// Adjust defaultCode if needed
Expand All @@ -256,8 +255,7 @@ func webError(w http.ResponseWriter, r *http.Request, c *Config, err error, defa
}

// Handle explicit code in ErrorResponse
var gwErr *ErrorStatusCode
if errors.As(err, &gwErr) {
if gwErr, ok := errors.AsType[*ErrorStatusCode](err); ok {
code = gwErr.StatusCode
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ipfs/boxo

go 1.25.7
go 1.26

require (
github.com/cespare/xxhash/v2 v2.3.0
Expand Down
28 changes: 14 additions & 14 deletions ipld/unixfs/unixfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func FilePBData(data []byte, totalsize uint64) []byte {
typ := pb.Data_File
pbfile.Type = &typ
pbfile.Data = data
pbfile.Filesize = proto.Uint64(totalsize)
pbfile.Filesize = new(totalsize)

data, err := proto.Marshal(pbfile)
if err != nil {
Expand All @@ -78,7 +78,7 @@ func FilePBDataWithStat(data []byte, totalsize uint64, mode os.FileMode, mtime t
typ := pb.Data_File
pbfile.Type = &typ
pbfile.Data = data
pbfile.Filesize = proto.Uint64(totalsize)
pbfile.Filesize = new(totalsize)

pbDataAddStat(pbfile, mode, mtime)

Expand Down Expand Up @@ -120,11 +120,11 @@ func FolderPBDataWithStat(mode os.FileMode, mtime time.Time) []byte {

func pbDataAddStat(data *pb.Data, mode os.FileMode, mtime time.Time) {
if mode != 0 {
data.Mode = proto.Uint32(files.ModePermsToUnixPerms(mode))
data.Mode = new(files.ModePermsToUnixPerms(mode))
}
if !mtime.IsZero() {
data.Mtime = &pb.IPFSTimestamp{
Seconds: proto.Int64(mtime.Unix()),
Seconds: new(mtime.Unix()),
}

if nanos := uint32(mtime.Nanosecond()); nanos > 0 {
Expand All @@ -139,7 +139,7 @@ func WrapData(b []byte) []byte {
typ := pb.Data_Raw
pbdata.Data = b
pbdata.Type = &typ
pbdata.Filesize = proto.Uint64(uint64(len(b)))
pbdata.Filesize = new(uint64(len(b)))

out, err := proto.Marshal(pbdata)
if err != nil {
Expand Down Expand Up @@ -176,16 +176,16 @@ func HAMTShardDataWithStat(data []byte, fanout uint64, hashType uint64, mode os.
pbdata := new(pb.Data)
typ := pb.Data_HAMTShard
pbdata.Type = &typ
pbdata.HashType = proto.Uint64(hashType)
pbdata.HashType = new(hashType)
pbdata.Data = data
pbdata.Fanout = proto.Uint64(fanout)
pbdata.Fanout = new(fanout)

if mode != 0 {
pbdata.Mode = proto.Uint32(files.ModePermsToUnixPerms(mode))
pbdata.Mode = new(files.ModePermsToUnixPerms(mode))
}
if !mtime.IsZero() {
pbdata.Mtime = &pb.IPFSTimestamp{
Seconds: proto.Int64(mtime.Unix()),
Seconds: new(mtime.Unix()),
}
if nanos := uint32(mtime.Nanosecond()); nanos > 0 {
pbdata.Mtime.Nanos = &nanos
Expand Down Expand Up @@ -315,7 +315,7 @@ func (n *FSNode) BlockSizes() []uint64 {
// RemoveAllBlockSizes removes all the child block sizes of this node.
func (n *FSNode) RemoveAllBlockSizes() {
n.format.Blocksizes = []uint64{}
n.format.Filesize = proto.Uint64(uint64(len(n.Data())))
n.format.Filesize = new(uint64(len(n.Data())))
}

// GetBytes marshals this node as a protobuf message.
Expand Down Expand Up @@ -352,7 +352,7 @@ func (n *FSNode) SetData(newData []byte) {
// by a signed difference (`filesizeDiff`).
// TODO: Add assert to check for `Filesize` > 0?
func (n *FSNode) UpdateFilesize(filesizeDiff int64) {
n.format.Filesize = proto.Uint64(uint64(
n.format.Filesize = new(uint64(
int64(n.format.GetFilesize()) + filesizeDiff))
}

Expand Down Expand Up @@ -450,9 +450,9 @@ func (n *FSNode) SetModTime(ts time.Time) {
n.format.Mtime = &pb.IPFSTimestamp{}
}

n.format.Mtime.Seconds = proto.Int64(ts.Unix())
n.format.Mtime.Seconds = new(ts.Unix())
if ts.Nanosecond() > 0 {
n.format.Mtime.Nanos = proto.Uint32(uint32(ts.Nanosecond()))
n.format.Mtime.Nanos = new(uint32(ts.Nanosecond()))
} else {
n.format.Mtime.Nanos = nil
}
Expand Down Expand Up @@ -498,7 +498,7 @@ func (m *Metadata) Bytes() ([]byte, error) {
// result of calling m.Bytes().
func BytesForMetadata(m *Metadata) ([]byte, error) {
pbd := new(pb.Data)
pbd.Filesize = proto.Uint64(m.Size)
pbd.Filesize = new(m.Size)
typ := pb.Data_Metadata
pbd.Type = &typ
mdd, err := m.Bytes()
Expand Down
2 changes: 1 addition & 1 deletion ipns/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ func newRecord(sk ic.PrivKey, value []byte, seq uint64, eol time.Time, ttl time.
pb.Sequence = &seq
pb.Validity = []byte(util.FormatRFC3339(eol))
ttlNs := uint64(ttl.Nanoseconds())
pb.Ttl = proto.Uint64(ttlNs)
pb.Ttl = new(ttlNs)

// For now we still create V1 signatures. These are deprecated, and not
// used during verification anymore (Validate func requires SignatureV2),
Expand Down
6 changes: 2 additions & 4 deletions ipns/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ipns
import (
"bytes"
"crypto/rand"
"maps"
"testing"
"time"

Expand Down Expand Up @@ -526,10 +527,7 @@ func TestMetadataAPI(t *testing.T) {
"_custom_b": int64(42),
}))

got := make(map[string]MetadataValue)
for k, v := range rec.MetadataEntries() {
got[k] = v
}
got := maps.Collect(rec.MetadataEntries())
require.Len(t, got, 2)

s, err := got["_custom_a"].AsString()
Expand Down
3 changes: 1 addition & 2 deletions namesys/dns_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ func workDomain(ctx context.Context, r *DNSResolver, name string, res chan Async

txt, ttl, err := r.lookupTXT(ctx, name)
if err != nil {
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) {
if dnsErr, ok := errors.AsType[*net.DNSError](err); ok {
// If no TXT records found, return same error as when no text
// records contain dnslink. Otherwise, return the actual error.
if dnsErr.IsNotFound {
Expand Down
5 changes: 3 additions & 2 deletions path/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package resolver
import (
"context"
"fmt"
"slices"
"time"

"github.com/ipfs/boxo/fetcher"
Expand Down Expand Up @@ -248,8 +249,8 @@ func pathAllSelector(path []string) ipld.Node {

func pathSelector(path []string, ssb builder.SelectorSpecBuilder, reduce func(string, builder.SelectorSpec) builder.SelectorSpec) ipld.Node {
spec := ssb.Matcher()
for i := len(path) - 1; i >= 0; i-- {
spec = reduce(path[i], spec)
for _, p := range slices.Backward(path) {
spec = reduce(p, spec)
}
return spec.Node()
}
Expand Down
Loading
Loading