Skip to content
Open
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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,18 @@ enumeration. [#1184](https://github.com/ipfs/boxo/pull/1184)
### Changed

- 🛠 `mfs`: `File.Open` now takes a `context.Context`. Writing to a file whose data has to be fetched from the network (for example, a lazy reference created with `ipfs files cp`) now uses that context, so the write stops when the context is cancelled, such as on a client timeout or when MFS shuts down, instead of waiting forever for a block that never arrives. Callers must add a context argument; pass the request's context to let a timeout cancel the write. [#1185](https://github.com/ipfs/boxo/pull/1185)

- 🧪 `testing`: tests now use `go-test` v0.4.0 and `math/rand/v2`. `go-test/random` no longer has a global seed or a global sequence, so one test can no longer change the values another test expects to generate deterministically, a class of failure that showed up as an intermittent break in an unrelated test. A generator can also be reused now, instead of being rebuilt for every value. [#1187](https://github.com/ipfs/boxo/pull/1187)
- upgrade to `go-libp2p-kad-dht` [v0.41.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.41.0)
- upgrade to `go-unixfsnode` [v1.10.5](https://github.com/ipfs/go-unixfsnode/releases/tag/v1.10.5)
- upgrade to `go-cid` [v0.6.2](https://github.com/ipfs/go-cid/releases/tag/v0.6.2)

### Removed

- 🛠 `util`: removed the deprecated `NewSeededRand` and `NewTimeSeededRand`. Use [`go-test/random`](https://github.com/ipfs/go-test) instead. [#1187](https://github.com/ipfs/boxo/pull/1187)

### Fixed

- `gateway`: fixed a data race in the remote blockstore, CAR fetcher, and value store. Each picked a gateway URL out of its list using a per-instance `*rand.Rand`, which is not safe to use from more than one goroutine, so a gateway serving requests in parallel was racing on every request. They now use the top-level `math/rand/v2` functions, which are safe to share. [#1187](https://github.com/ipfs/boxo/pull/1187)
- `blockstore`: the Bloom filter cache no longer activates after an incomplete
build. Previously, if `AllKeysChan` enumeration was truncated by a
mid-iteration datastore error (which was only logged, never propagated) or by a
Expand Down
4 changes: 2 additions & 2 deletions autoconf/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"crypto/tls"
"fmt"
"hash/fnv"
"math/rand"
"math/rand/v2"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -279,7 +279,7 @@ func (c *Client) selectURL() string {
if len(c.urls) == 1 {
return c.urls[0]
}
return c.urls[rand.Intn(len(c.urls))]
return c.urls[rand.IntN(len(c.urls))]
}

// readMetadata reads cached ETag and Last-Modified values
Expand Down
4 changes: 2 additions & 2 deletions autoconf/expansion.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package autoconf

import (
"math/rand"
"math/rand/v2"
"slices"
"strings"
)
Expand Down Expand Up @@ -40,7 +40,7 @@ func selectRandom(items []string) string {
if len(items) == 0 {
return ""
}
return items[rand.Intn(len(items))]
return items[rand.IntN(len(items))]
}

// ExpandDNSResolvers expands DNS resolvers with "auto" values replaced by autoconf values.
Expand Down
47 changes: 25 additions & 22 deletions bitswap/benchmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import (
"encoding/json"
"fmt"
"math"
"math/rand"
"os"
"strconv"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -135,6 +133,7 @@ func BenchmarkFetchFromOldBitswap(b *testing.B) {
fixedDelay := delay.Fixed(10 * time.Millisecond)
bstoreLatency := time.Duration(0)
router := mockrouting.NewServer()
rnd := random.New()

for _, bch := range mixedBenches {
b.Run(bch.name, func(b *testing.B) {
Expand Down Expand Up @@ -169,8 +168,8 @@ func BenchmarkFetchFromOldBitswap(b *testing.B) {
testinstance.ConnectInstances(instances)

// Generate blocks, with a smaller root block
rootBlock := random.BlocksOfSize(1, rootBlockSize)
blocks := random.BlocksOfSize(bch.blockCount, stdBlockSize)
rootBlock := rnd.BlocksOfSize(1, rootBlockSize)
blocks := rnd.BlocksOfSize(bch.blockCount, stdBlockSize)
blocks[0] = rootBlock[0]

// Run the distribution
Expand Down Expand Up @@ -209,10 +208,10 @@ const (

func BenchmarkRealWorld(b *testing.B) {
benchmarkLog = nil
benchmarkSeed, err := strconv.ParseInt(os.Getenv("BENCHMARK_SEED"), 10, 64)
var randomGen *rand.Rand = nil
if err == nil {
randomGen = rand.New(rand.NewSource(benchmarkSeed))
var randomGen *random.Random
seed := os.Getenv("BENCHMARK_SEED")
if seed != "" {
randomGen = random.NewSeeded(random.StringToSeed(seed))
}

fastNetworkDelayGenerator := tn.InternetLatencyDelayGenerator(
Expand Down Expand Up @@ -248,10 +247,10 @@ func BenchmarkRealWorld(b *testing.B) {

func BenchmarkDatacenter(b *testing.B) {
benchmarkLog = nil
benchmarkSeed, err := strconv.ParseInt(os.Getenv("BENCHMARK_SEED"), 10, 64)
var randomGen *rand.Rand = nil
if err == nil {
randomGen = rand.New(rand.NewSource(benchmarkSeed))
var randomGen *random.Random
seed := os.Getenv("BENCHMARK_SEED")
if seed != "" {
randomGen = random.NewSeeded(random.StringToSeed(seed))
}

datacenterNetworkDelayGenerator := tn.InternetLatencyDelayGenerator(
Expand All @@ -271,10 +270,10 @@ func BenchmarkDatacenter(b *testing.B) {

func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {
benchmarkLog = nil
benchmarkSeed, err := strconv.ParseInt(os.Getenv("BENCHMARK_SEED"), 10, 64)
var randomGen *rand.Rand = nil
if err == nil {
randomGen = rand.New(rand.NewSource(benchmarkSeed))
var randomGen *random.Random
seed := os.Getenv("BENCHMARK_SEED")
if seed != "" {
randomGen = random.NewSeeded(random.StringToSeed(seed))
}

datacenterNetworkDelayGenerator := tn.InternetLatencyDelayGenerator(
Expand All @@ -292,6 +291,7 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {
ff := unixfsFileFetchLarge
numnodes := 6
numblks := 1000
rnd := random.New()

for i := 0; i < b.N; i++ {
net := tn.RateLimitedVirtualNetwork(d, rateLimitGenerator)
Expand All @@ -301,7 +301,7 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {
defer ig.Close()

instances := ig.Instances(numnodes)
blocks := random.BlocksOfSize(numblks, int(blockSize))
blocks := rnd.BlocksOfSize(numblks, blockSize)
runDistributionMulti(b, instances[:3], instances[3:], blocks, bstoreLatency, df, ff)
}
})
Expand All @@ -312,30 +312,32 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {
}

func subtestDistributeAndFetch(b *testing.B, numnodes, numblks int, d delay.D, bstoreLatency time.Duration, df distFunc, ff fetchFunc) {
rnd := random.New()
for i := 0; i < b.N; i++ {
net := tn.VirtualNetwork(d)
router := mockrouting.NewServer()
ig := testinstance.NewTestInstanceGenerator(net, router, nil, nil)

instances := ig.Instances(numnodes)
rootBlock := random.BlocksOfSize(1, rootBlockSize)
blocks := random.BlocksOfSize(numblks, stdBlockSize)
rootBlock := rnd.BlocksOfSize(1, rootBlockSize)
blocks := rnd.BlocksOfSize(numblks, stdBlockSize)
blocks[0] = rootBlock[0]
runDistribution(b, instances, blocks, bstoreLatency, df, ff)
ig.Close()
}
}

func subtestDistributeAndFetchRateLimited(b *testing.B, numnodes, numblks int, d delay.D, rateLimitGenerator tn.RateLimitGenerator, blockSize int64, bstoreLatency time.Duration, df distFunc, ff fetchFunc) {
rnd := random.New()
for i := 0; i < b.N; i++ {
net := tn.RateLimitedVirtualNetwork(d, rateLimitGenerator)
router := mockrouting.NewServer()
ig := testinstance.NewTestInstanceGenerator(net, router, nil, nil)
defer ig.Close()

instances := ig.Instances(numnodes)
rootBlock := random.BlocksOfSize(1, rootBlockSize)
blocks := random.BlocksOfSize(numblks, int(blockSize))
rootBlock := rnd.BlocksOfSize(1, rootBlockSize)
blocks := rnd.BlocksOfSize(numblks, blockSize)
blocks[0] = rootBlock[0]
runDistribution(b, instances, blocks, bstoreLatency, df, ff)
}
Expand Down Expand Up @@ -490,8 +492,9 @@ func overlap2(b *testing.B, provs []testinstance.Instance, blks []blocks.Block)
// with this layout, we shouldnt actually ever see any duplicate blocks
// but we're mostly just testing performance of the sync algorithm
func onePeerPerBlock(b *testing.B, provs []testinstance.Instance, blks []blocks.Block) {
rnd := random.New()
for _, blk := range blks {
err := provs[rand.Intn(len(provs))].Blockstore.Put(context.Background(), blk)
err := provs[rnd.IntN(len(provs))].Blockstore.Put(context.Background(), blk)
if err != nil {
b.Fatal(err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const (
func TestBlockPresenceManager(t *testing.T) {
bpm := New()

p := random.Peers(1)[0]
cids := random.Cids(2)
rnd := random.New()
p := rnd.Peers(1)[0]
cids := rnd.Cids(2)
c0 := cids[0]
c1 := cids[1]

Expand Down Expand Up @@ -81,10 +82,11 @@ func TestBlockPresenceManager(t *testing.T) {
func TestAddRemoveMulti(t *testing.T) {
bpm := New()

peers := random.Peers(2)
rnd := random.New()
peers := rnd.Peers(2)
p0 := peers[0]
p1 := peers[1]
cids := random.Cids(3)
cids := rnd.Cids(3)
c0 := cids[0]
c1 := cids[1]
c2 := cids[2]
Expand Down Expand Up @@ -132,12 +134,13 @@ func TestAddRemoveMulti(t *testing.T) {
func TestAllPeersDoNotHaveBlock(t *testing.T) {
bpm := New()

peers := random.Peers(3)
rnd := random.New()
peers := rnd.Peers(3)
p0 := peers[0]
p1 := peers[1]
p2 := peers[2]

cids := random.Cids(3)
cids := rnd.Cids(3)
c0 := cids[0]
c1 := cids[1]
c2 := cids[2]
Expand Down
Loading
Loading