From 93c2bc0f2aaf83c46029350e36ee80fc9a72c195 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Sun, 8 Sep 2024 11:47:55 +0200 Subject: [PATCH] all: update math/rand to math/rand/v2 To ease the potential error and confusion among math/rand and crypto/rand. math/rand/v2 has been introduced from 1.22. This can avoid critical errors wehn calling rand.Read() in the security-sensitive places. Other improvement can refer the golang doc --- accounts/keystore/account_cache_test.go | 2 +- accounts/keystore/keystore_test.go | 2 +- beacon/light/test_helpers.go | 4 +- cmd/devp2p/internal/ethtest/snap.go | 10 +- cmd/geth/logging_test.go | 6 +- common/bitutil/compress_test.go | 8 +- common/lru/basiclru_test.go | 4 +- common/prque/lazyqueue_test.go | 10 +- common/prque/prque_test.go | 6 +- common/prque/sstack_test.go | 6 +- common/types.go | 4 +- consensus/clique/clique.go | 6 +- consensus/ethash/consensus_test.go | 2 +- core/blockchain_test.go | 2 +- core/bloombits/generator_test.go | 2 +- core/bloombits/matcher_test.go | 4 +- core/chain_indexer_test.go | 8 +- core/rawdb/accessors_chain_test.go | 2 +- core/rawdb/freezer_table_test.go | 14 +-- core/rawdb/freezer_test.go | 4 +- core/state/snapshot/difflayer.go | 10 +- core/state/snapshot/difflayer_test.go | 6 +- core/state/snapshot/iterator_test.go | 10 +- core/state/snapshot/snapshot_test.go | 2 +- core/state/statedb_fuzz_test.go | 16 +-- core/state/statedb_test.go | 10 +- core/txpool/blobpool/evictheap_test.go | 32 +++++- core/txpool/legacypool/legacypool_test.go | 8 +- core/txpool/legacypool/list_test.go | 2 +- core/types/hashing_test.go | 16 +-- eth/catalyst/api_test.go | 2 +- eth/downloader/queue_test.go | 10 +- eth/downloader/skeleton.go | 4 +- eth/fetcher/tx_fetcher.go | 4 +- eth/fetcher/tx_fetcher_test.go | 6 +- eth/filters/filter_system_test.go | 2 +- eth/protocols/eth/handler_test.go | 4 +- eth/protocols/eth/peer.go | 2 +- eth/protocols/snap/gentrie_test.go | 28 ++--- eth/protocols/snap/sync.go | 12 +-- eth/protocols/snap/sync_test.go | 4 +- ethclient/simulated/backend_test.go | 4 +- event/event_test.go | 4 +- internal/jsre/jsre.go | 6 +- internal/testrand/rand.go | 8 +- log/format_test.go | 4 +- metrics/sample.go | 6 +- metrics/sample_test.go | 14 +-- miner/ordering_test.go | 6 +- p2p/dial.go | 8 +- p2p/dial_test.go | 4 +- p2p/discover/common.go | 16 +-- p2p/discover/table.go | 4 +- p2p/discover/table_reval.go | 4 +- p2p/discover/table_test.go | 6 +- p2p/discover/table_util_test.go | 4 +- p2p/discover/v4_udp_test.go | 6 +- p2p/discover/v5_udp_test.go | 4 +- p2p/dnsdisc/client.go | 4 +- p2p/dnsdisc/sync.go | 4 +- p2p/dnsdisc/sync_test.go | 4 +- p2p/enode/localnode_test.go | 4 +- p2p/enr/enr_test.go | 8 +- p2p/nat/natupnp.go | 7 +- p2p/netutil/addrutil.go | 8 +- p2p/netutil/net_test.go | 4 +- p2p/peer_test.go | 4 +- p2p/rlpx/rlpx.go | 4 +- p2p/rlpx/rlpx_test.go | 8 +- p2p/server_test.go | 4 +- rpc/client_test.go | 10 +- rpc/subscription.go | 14 +-- tests/block_test.go | 2 +- tests/fuzzers/txfetcher/txfetcher_fuzzer.go | 8 +- tests/state_test.go | 4 +- trie/encoding_test.go | 4 +- trie/iterator_test.go | 6 +- trie/proof_test.go | 42 ++++---- trie/sync_test.go | 4 +- trie/trie_test.go | 109 ++++++++++++++------ triedb/pathdb/database_test.go | 6 +- 81 files changed, 382 insertions(+), 294 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index c9a8cdfcef..ce0a9d86e0 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -19,7 +19,7 @@ package keystore import ( "errors" "fmt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "reflect" diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index f8922a3f3f..89b72dedbb 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -17,7 +17,7 @@ package keystore import ( - "math/rand" + "math/rand/v2" "os" "runtime" "slices" diff --git a/beacon/light/test_helpers.go b/beacon/light/test_helpers.go index f537d963a6..65f5bbde0d 100644 --- a/beacon/light/test_helpers.go +++ b/beacon/light/test_helpers.go @@ -19,7 +19,7 @@ package light import ( "crypto/rand" "crypto/sha256" - mrand "math/rand" + mrand "math/rand/v2" "github.com/ethereum/go-ethereum/beacon/merkle" "github.com/ethereum/go-ethereum/beacon/params" @@ -74,7 +74,7 @@ func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommit func makeBitmask(signerCount int) (bitmask [params.SyncCommitteeBitmaskSize]byte) { for i := 0; i < params.SyncCommitteeSize; i++ { - if mrand.Intn(params.SyncCommitteeSize-i) < signerCount { + if mrand.IntN(params.SyncCommitteeSize-i) < signerCount { bitmask[i/8] += byte(1) << (i & 7) signerCount-- } diff --git a/cmd/devp2p/internal/ethtest/snap.go b/cmd/devp2p/internal/ethtest/snap.go index 4f1b6f8656..7ada0012f4 100644 --- a/cmd/devp2p/internal/ethtest/snap.go +++ b/cmd/devp2p/internal/ethtest/snap.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "reflect" "github.com/ethereum/go-ethereum/common" @@ -758,7 +758,7 @@ func (s *Suite) snapGetAccountRange(t *utesting.T, tc *accRangeTest) error { } // write request req := &snap.GetAccountRangePacket{ - ID: uint64(rand.Int63()), + ID: uint64(rand.Int64()), Root: tc.root, Origin: tc.startingHash, Limit: tc.limitHash, @@ -828,7 +828,7 @@ func (s *Suite) snapGetStorageRanges(t *utesting.T, tc *stRangesTest) error { // write request req := &snap.GetStorageRangesPacket{ - ID: uint64(rand.Int63()), + ID: uint64(rand.Int64()), Root: tc.root, Accounts: tc.accounts, Origin: tc.origin, @@ -882,7 +882,7 @@ func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error { } // write request req := &snap.GetByteCodesPacket{ - ID: uint64(rand.Int63()), + ID: uint64(rand.Int64()), Hashes: tc.hashes, Bytes: tc.nBytes, } @@ -942,7 +942,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error { // write0 request req := &snap.GetTrieNodesPacket{ - ID: uint64(rand.Int63()), + ID: uint64(rand.Int64()), Root: tc.root, Paths: tc.paths, Bytes: tc.nBytes, diff --git a/cmd/geth/logging_test.go b/cmd/geth/logging_test.go index 4293a860ec..eca65a3097 100644 --- a/cmd/geth/logging_test.go +++ b/cmd/geth/logging_test.go @@ -24,7 +24,7 @@ import ( "encoding/json" "fmt" "io" - "math/rand" + "math/rand/v2" "os" "os/exec" "strings" @@ -201,7 +201,7 @@ func TestFileOut(t *testing.T) { var ( have, want []byte err error - path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int64()) ) if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil { t.Fatal(err) @@ -221,7 +221,7 @@ func TestRotatingFileOut(t *testing.T) { var ( have, want []byte err error - path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63()) + path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int64()) ) if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil { t.Fatal(err) diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go index c6f6fe8bcf..75c0b21d12 100644 --- a/common/bitutil/compress_test.go +++ b/common/bitutil/compress_test.go @@ -19,7 +19,7 @@ package bitutil import ( "bytes" "fmt" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common/hexutil" @@ -167,14 +167,14 @@ func BenchmarkEncoding4KBSaturated(b *testing.B) { benchmarkEncoding(b, 4096, 0. func benchmarkEncoding(b *testing.B, bytes int, fill float64) { // Generate a random slice of bytes to compress - random := rand.NewSource(0) // reproducible and comparable + random := rand.New(rand.NewPCG(0, 0)) // reproducible and comparable data := make([]byte, bytes) bits := int(float64(bytes) * 8 * fill) for i := 0; i < bits; i++ { - idx := random.Int63() % int64(len(data)) - bit := uint(random.Int63() % 8) + idx := random.Int64() % int64(len(data)) + bit := uint(random.Int64() % 8) data[idx] |= 1 << bit } // Reset the benchmark and measure encoding/decoding diff --git a/common/lru/basiclru_test.go b/common/lru/basiclru_test.go index 29812bda15..f70952d128 100644 --- a/common/lru/basiclru_test.go +++ b/common/lru/basiclru_test.go @@ -20,7 +20,7 @@ import ( crand "crypto/rand" "fmt" "io" - "math/rand" + "math/rand/v2" "testing" ) @@ -192,7 +192,7 @@ func BenchmarkLRU(b *testing.B) { values = make([][]byte, capacity) ) for i := range indexes { - indexes[i] = rand.Intn(capacity) + indexes[i] = rand.IntN(capacity) } for i := range keys { b := make([]byte, 32) diff --git a/common/prque/lazyqueue_test.go b/common/prque/lazyqueue_test.go index ffb7e5e9e3..5b39a4d203 100644 --- a/common/prque/lazyqueue_test.go +++ b/common/prque/lazyqueue_test.go @@ -17,7 +17,7 @@ package prque import ( - "math/rand" + "math/rand/v2" "sync" "testing" "time" @@ -65,7 +65,7 @@ func TestLazyQueue(t *testing.T) { ) for i := range items[:] { - items[i].p = rand.Int63n(testPriorityStep * 10) + items[i].p = rand.Int64N(testPriorityStep * 10) if items[i].p > maxPri { maxPri = items[i].p } @@ -95,9 +95,9 @@ func TestLazyQueue(t *testing.T) { }() for c := 0; c < testSteps; c++ { - i := rand.Intn(testItems) + i := rand.IntN(testItems) lock.Lock() - items[i].p += rand.Int63n(testPriorityStep*2-1) + 1 + items[i].p += rand.Int64N(testPriorityStep*2-1) + 1 if items[i].p > maxPri { maxPri = items[i].p } @@ -105,7 +105,7 @@ func TestLazyQueue(t *testing.T) { if items[i].p > items[i].maxp { q.Update(items[i].index) } - if rand.Intn(100) == 0 { + if rand.IntN(100) == 0 { p := q.PopItem().(*lazyItem) if p.p != maxPri { lock.Unlock() diff --git a/common/prque/prque_test.go b/common/prque/prque_test.go index c4910f205a..e73b9f871c 100644 --- a/common/prque/prque_test.go +++ b/common/prque/prque_test.go @@ -9,7 +9,7 @@ package prque import ( - "math/rand" + "math/rand/v2" "testing" ) @@ -103,7 +103,7 @@ func BenchmarkPush(b *testing.B) { prio := make([]int64, b.N) for i := 0; i < len(data); i++ { data[i] = rand.Int() - prio[i] = rand.Int63() + prio[i] = rand.Int64() } // Execute the benchmark b.ResetTimer() @@ -119,7 +119,7 @@ func BenchmarkPop(b *testing.B) { prio := make([]int64, b.N) for i := 0; i < len(data); i++ { data[i] = rand.Int() - prio[i] = rand.Int63() + prio[i] = rand.Int64() } queue := New[int64, int](nil) for i := 0; i < len(data); i++ { diff --git a/common/prque/sstack_test.go b/common/prque/sstack_test.go index edc99955e8..5510247253 100644 --- a/common/prque/sstack_test.go +++ b/common/prque/sstack_test.go @@ -9,7 +9,7 @@ package prque import ( - "math/rand" + "math/rand/v2" "sort" "testing" ) @@ -19,7 +19,7 @@ func TestSstack(t *testing.T) { size := 16 * blockSize data := make([]*item[int64, int], size) for i := 0; i < size; i++ { - data[i] = &item[int64, int]{rand.Int(), rand.Int63()} + data[i] = &item[int64, int]{rand.Int(), rand.Int64()} } stack := newSstack[int64, int](nil) for rep := 0; rep < 2; rep++ { @@ -74,7 +74,7 @@ func TestSstackReset(t *testing.T) { size := 16 * blockSize data := make([]*item[int64, int], size) for i := 0; i < size; i++ { - data[i] = &item[int64, int]{rand.Int(), rand.Int63()} + data[i] = &item[int64, int]{rand.Int(), rand.Int64()} } stack := newSstack[int64, int](nil) for rep := 0; rep < 2; rep++ { diff --git a/common/types.go b/common/types.go index fdb25f1b34..38fdedf9e9 100644 --- a/common/types.go +++ b/common/types.go @@ -24,7 +24,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "reflect" "strconv" "strings" @@ -154,7 +154,7 @@ func (h *Hash) SetBytes(b []byte) { // Generate implements testing/quick.Generator. func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { - m := rand.Intn(len(h)) + m := rand.IntN(len(h)) for i := len(h) - 1; i > m; i-- { h[i] = byte(rand.Uint32()) } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index c9e9484002..9b4a1e78c0 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -23,7 +23,7 @@ import ( "fmt" "io" "math/big" - "math/rand" + "math/rand/v2" "sync" "time" @@ -534,7 +534,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header } // If there's pending proposals, cast a vote on them if len(addresses) > 0 { - header.Coinbase = addresses[rand.Intn(len(addresses))] + header.Coinbase = addresses[rand.IntN(len(addresses))] if c.proposals[header.Coinbase] { copy(header.Nonce[:], nonceAuthVote) } else { @@ -651,7 +651,7 @@ func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, res if header.Difficulty.Cmp(diffNoTurn) == 0 { // It's not our turn explicitly to sign, delay it a bit wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime - delay += time.Duration(rand.Int63n(int64(wiggle))) + delay += time.Duration(rand.Int64N(int64(wiggle))) log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) } diff --git a/consensus/ethash/consensus_test.go b/consensus/ethash/consensus_test.go index e3793cd1b0..7daa7f6c75 100644 --- a/consensus/ethash/consensus_test.go +++ b/consensus/ethash/consensus_test.go @@ -21,7 +21,7 @@ import ( "encoding/binary" "encoding/json" "math/big" - "math/rand" + "math/rand/v2" "os" "path/filepath" "testing" diff --git a/core/blockchain_test.go b/core/blockchain_test.go index d8c436fcd6..aeecadac26 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -20,7 +20,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "os" "path" "sync" diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go index ac1aee0b25..0b0d74efb2 100644 --- a/core/bloombits/generator_test.go +++ b/core/bloombits/generator_test.go @@ -19,7 +19,7 @@ package bloombits import ( "bytes" crand "crypto/rand" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/core/types" diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go index 7f3d5f279c..444dc7dbb1 100644 --- a/core/bloombits/matcher_test.go +++ b/core/bloombits/matcher_test.go @@ -18,7 +18,7 @@ package bloombits import ( "context" - "math/rand" + "math/rand/v2" "sync/atomic" "testing" "time" @@ -115,7 +115,7 @@ func makeRandomIndexes(lengths []int, max int) [][]bloomIndexes { res[i] = make([]bloomIndexes, topics) for j := 0; j < topics; j++ { for k := 0; k < len(res[i][j]); k++ { - res[i][j][k] = uint(rand.Intn(max-1) + 2) + res[i][j][k] = uint(rand.IntN(max-1) + 2) } } } diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go index bf3bde756c..61b3888e28 100644 --- a/core/chain_indexer_test.go +++ b/core/chain_indexer_test.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "testing" "time" @@ -56,8 +56,8 @@ func testChainIndexer(t *testing.T, count int) { backends := make([]*testChainIndexBackend, count) for i := 0; i < count; i++ { var ( - sectionSize = uint64(rand.Intn(100) + 1) - confirmsReq = uint64(rand.Intn(10)) + sectionSize = uint64(rand.IntN(100) + 1) + confirmsReq = uint64(rand.IntN(10)) ) backends[i] = &testChainIndexBackend{t: t, processCh: make(chan uint64)} backends[i].indexer = NewChainIndexer(db, rawdb.NewTable(db, string([]byte{byte(i)})), backends[i], sectionSize, confirmsReq, 0, fmt.Sprintf("indexer-%d", i)) @@ -92,7 +92,7 @@ func testChainIndexer(t *testing.T, count int) { } // inject inserts a new random canonical header into the database directly inject := func(number uint64) { - header := &types.Header{Number: big.NewInt(int64(number)), Extra: big.NewInt(rand.Int63()).Bytes()} + header := &types.Header{Number: big.NewInt(int64(number)), Extra: big.NewInt(rand.Int64()).Bytes()} if number > 0 { header.ParentHash = rawdb.ReadCanonicalHash(db, number-1) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 2d30af4b3d..685507ecf4 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -21,7 +21,7 @@ import ( "encoding/hex" "fmt" "math/big" - "math/rand" + "math/rand/v2" "os" "reflect" "testing" diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go index 91b4943e59..06feb2f5b0 100644 --- a/core/rawdb/freezer_table_test.go +++ b/core/rawdb/freezer_table_test.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/binary" "fmt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "reflect" @@ -1205,7 +1205,7 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { return nil } var ret []uint64 - index := rand.Intn(length) + index := rand.IntN(length) for i := index; len(ret) < n && i < length; i++ { ret = append(ret, items[i]) } @@ -1229,11 +1229,11 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { var steps randTest for i := 0; i < size; i++ { - step := randTestStep{op: r.Intn(opMax)} + step := randTestStep{op: r.IntN(opMax)} switch step.op { case opReload, opCheckAll: case opAppend: - num := r.Intn(3) + num := r.IntN(3) step.items = addItems(num) if len(step.items) == 0 { step.blobs = nil @@ -1241,12 +1241,12 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { step.blobs = getVals(step.items[0], num) } case opRetrieve: - step.items = getItems(r.Intn(3)) + step.items = getItems(r.IntN(3)) case opTruncateHead: if len(items) == 0 { step.target = deleted } else { - index := r.Intn(len(items)) + index := r.IntN(len(items)) items = items[:index] step.target = deleted + uint64(index) } @@ -1257,7 +1257,7 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { if len(items) == 0 { step.target = deleted } else { - index := r.Intn(len(items)) + index := r.IntN(len(items)) items = items[index:] deleted += uint64(index) step.target = deleted diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go index 7d82ea305f..81df73e3fc 100644 --- a/core/rawdb/freezer_test.go +++ b/core/rawdb/freezer_test.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "sync" "testing" @@ -166,7 +166,7 @@ func TestFreezerConcurrentModifyRetrieve(t *testing.T) { defer wg.Done() for frozen := range written { for rc := 0; rc < 80; rc++ { - num := uint64(rand.Intn(int(frozen))) + num := uint64(rand.IntN(int(frozen))) value, err := f.Ancient("test", num) if err != nil { panic(fmt.Errorf("error reading %d (frozen %d): %v", num, frozen, err)) diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index 779c1ea98c..23ccc198ef 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -20,7 +20,7 @@ import ( "encoding/binary" "fmt" "math" - "math/rand" + "math/rand/v2" "slices" "sync" "sync/atomic" @@ -80,15 +80,15 @@ var ( func init() { // Init the bloom offsets in the range [0:24] (requires 8 bytes) - bloomDestructHasherOffset = rand.Intn(25) - bloomAccountHasherOffset = rand.Intn(25) - bloomStorageHasherOffset = rand.Intn(25) + bloomDestructHasherOffset = rand.IntN(25) + bloomAccountHasherOffset = rand.IntN(25) + bloomStorageHasherOffset = rand.IntN(25) // The destruct and account blooms must be different, as the storage slots // will check for destruction too for every bloom miss. It should not collide // with modified accounts. for bloomAccountHasherOffset == bloomDestructHasherOffset { - bloomAccountHasherOffset = rand.Intn(25) + bloomAccountHasherOffset = rand.IntN(25) } } diff --git a/core/state/snapshot/difflayer_test.go b/core/state/snapshot/difflayer_test.go index 674a031b16..c26a3f7ad3 100644 --- a/core/state/snapshot/difflayer_test.go +++ b/core/state/snapshot/difflayer_test.go @@ -19,7 +19,7 @@ package snapshot import ( "bytes" crand "crypto/rand" - "math/rand" + "math/rand/v2" "testing" "github.com/VictoriaMetrics/fastcache" @@ -68,10 +68,10 @@ func TestMergeBasics(t *testing.T) { data := randomAccount() accounts[h] = data - if rand.Intn(4) == 0 { + if rand.IntN(4) == 0 { destructs[h] = struct{}{} } - if rand.Intn(2) == 0 { + if rand.IntN(2) == 0 { accStorage := make(map[common.Hash][]byte) value := make([]byte, 32) crand.Read(value) diff --git a/core/state/snapshot/iterator_test.go b/core/state/snapshot/iterator_test.go index daa8cdcc54..90e974c6f6 100644 --- a/core/state/snapshot/iterator_test.go +++ b/core/state/snapshot/iterator_test.go @@ -21,7 +21,7 @@ import ( crand "crypto/rand" "encoding/binary" "fmt" - "math/rand" + "math/rand/v2" "testing" "github.com/VictoriaMetrics/fastcache" @@ -42,10 +42,10 @@ func TestAccountIteratorBasics(t *testing.T) { data := randomAccount() accounts[h] = data - if rand.Intn(4) == 0 { + if rand.IntN(4) == 0 { destructs[h] = struct{}{} } - if rand.Intn(2) == 0 { + if rand.IntN(2) == 0 { accStorage := make(map[common.Hash][]byte) value := make([]byte, 32) crand.Read(value) @@ -81,7 +81,7 @@ func TestStorageIteratorBasics(t *testing.T) { var nilstorage int for i := 0; i < 100; i++ { crand.Read(value) - if rand.Intn(2) == 0 { + if rand.IntN(2) == 0 { accStorage[randomHash()] = common.CopyBytes(value) } else { accStorage[randomHash()] = nil // delete slot @@ -1028,7 +1028,7 @@ func benchmarkAccountIteration(b *testing.B, iterator func(snap snapshot) Accoun layers[i] = make(map[common.Hash][]byte) } for i := 0; i < b.N; i++ { - depth := rand.Intn(len(layers)) + depth := rand.IntN(len(layers)) layers[depth][randomHash()] = randomAccount() } stack := snapshot(emptyLayer()) diff --git a/core/state/snapshot/snapshot_test.go b/core/state/snapshot/snapshot_test.go index a9ab3eaea3..3028910ca5 100644 --- a/core/state/snapshot/snapshot_test.go +++ b/core/state/snapshot/snapshot_test.go @@ -20,7 +20,7 @@ import ( crand "crypto/rand" "encoding/binary" "fmt" - "math/rand" + "math/rand/v2" "testing" "time" diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 90250819e3..7270e48059 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -22,7 +22,7 @@ import ( "errors" "fmt" "math" - "math/rand" + "math/rand/v2" "reflect" "strings" "testing" @@ -109,7 +109,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction } var nonRandom = index != -1 if index == -1 { - index = r.Intn(len(actions)) + index = r.IntN(len(actions)) } action := actions[index] var names []string @@ -118,9 +118,9 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction } for i := range action.args { if nonRandom { - action.args[i] = rand.Int63n(10000) + 1 // set balance to non-zero + action.args[i] = rand.Int64N(10000) + 1 // set balance to non-zero } else { - action.args[i] = rand.Int63n(10000) + action.args[i] = rand.Int64N(10000) } names = append(names, fmt.Sprint(action.args[i])) } @@ -135,7 +135,7 @@ func (*stateTest) Generate(r *rand.Rand, size int) reflect.Value { for i := range addrs { addrs[i][0] = byte(i) } - actions := make([][]testAction, rand.Intn(5)+1) + actions := make([][]testAction, rand.IntN(5)+1) for i := 0; i < len(actions); i++ { actions[i] = make([]testAction, size) @@ -146,7 +146,7 @@ func (*stateTest) Generate(r *rand.Rand, size int) reflect.Value { actions[i][j] = newStateTestAction(common.HexToAddress("0xdeadbeef"), r, 0) continue } - actions[i][j] = newStateTestAction(addrs[r.Intn(len(addrs))], r, -1) + actions[i][j] = newStateTestAction(addrs[r.IntN(len(addrs))], r, -1) } } chunk := int(math.Sqrt(float64(size))) @@ -197,13 +197,13 @@ func (test *stateTest) run() bool { } disk = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults}) - byzantium = rand.Intn(2) == 0 + byzantium = rand.IntN(2) == 0 ) defer disk.Close() defer tdb.Close() var snaps *snapshot.Tree - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { snaps, _ = snapshot.New(snapshot.Config{ CacheSize: 1, Recovery: false, diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 9441834c6a..c6884dca5a 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -22,7 +22,7 @@ import ( "fmt" "maps" "math" - "math/rand" + "math/rand/v2" "reflect" "slices" "strings" @@ -471,13 +471,13 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { args: make([]int64, 2), }, } - action := actions[r.Intn(len(actions))] + action := actions[r.IntN(len(actions))] var nameargs []string if !action.noAddr { nameargs = append(nameargs, addr.Hex()) } for i := range action.args { - action.args[i] = rand.Int63n(100) + action.args[i] = rand.Int64N(100) nameargs = append(nameargs, fmt.Sprint(action.args[i])) } action.name += strings.Join(nameargs, ", ") @@ -494,7 +494,7 @@ func (*snapshotTest) Generate(r *rand.Rand, size int) reflect.Value { } actions := make([]testAction, size) for i := range actions { - addr := addrs[r.Intn(len(addrs))] + addr := addrs[r.IntN(len(addrs))] actions[i] = newTestAction(addr, r) } // Generate snapshot indexes. @@ -506,7 +506,7 @@ func (*snapshotTest) Generate(r *rand.Rand, size int) reflect.Value { snaplen := len(actions) / nsnapshots for i := range snapshots { // Try to place the snapshots some number of actions apart from each other. - snapshots[i] = (i * snaplen) + r.Intn(snaplen) + snapshots[i] = (i * snaplen) + r.IntN(snaplen) } return reflect.ValueOf(&snapshotTest{addrs, actions, snapshots, nil}) } diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go index 1cf577cb00..8a192426db 100644 --- a/core/txpool/blobpool/evictheap_test.go +++ b/core/txpool/blobpool/evictheap_test.go @@ -18,7 +18,7 @@ package blobpool import ( "container/heap" - mrand "math/rand" + mrand "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -26,7 +26,7 @@ import ( "github.com/holiman/uint256" ) -var rand = mrand.New(mrand.NewSource(1)) +var rand = mrand.New(mrand.NewPCG(1, 1)) // verifyHeapInternals verifies that all accounts present in the index are also // present in the heap and internals are consistent across various indices. @@ -193,7 +193,15 @@ func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) { index := make(map[common.Address][]*blobTxMeta) for i := 0; i < int(blobs); i++ { var addr common.Address - rand.Read(addr[:]) + + addr.SetBytes(func() []byte { + ret := make([]byte, common.AddressLength) + randInts := rand.Perm(256) + for i, v := range randInts { + ret[i] = byte(v) + } + return ret + }()) var ( execTip = uint256.NewInt(rand.Uint64()) @@ -253,7 +261,14 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { index := make(map[common.Address][]*blobTxMeta) for i := 0; i < int(blobs); i++ { var addr common.Address - rand.Read(addr[:]) + addr.SetBytes(func() []byte { + ret := make([]byte, common.AddressLength) + randInts := rand.Perm(256) + for i, v := range randInts { + ret[i] = byte(v) + } + return ret + }()) var ( execTip = uint256.NewInt(rand.Uint64()) @@ -284,7 +299,14 @@ func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) { metas = make([]*blobTxMeta, b.N) ) for i := 0; i < b.N; i++ { - rand.Read(addrs[i][:]) + addrs[i].SetBytes(func() []byte { + ret := make([]byte, common.AddressLength) + randInts := rand.Perm(256) + for i, v := range randInts { + ret[i] = byte(v) + } + return ret + }()) var ( execTip = uint256.NewInt(rand.Uint64()) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 39673d176d..9e1512343d 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -22,7 +22,7 @@ import ( "errors" "fmt" "math/big" - "math/rand" + "math/rand/v2" "os" "sync" "sync/atomic" @@ -933,7 +933,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) { txs := make(types.Transactions, 0, 3*config.GlobalQueue) for len(txs) < cap(txs) { - key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account + key := keys[rand.IntN(len(keys)-1)] // skip adding transactions with the local account addr := crypto.PubkeyToAddress(key.PublicKey) txs = append(txs, transaction(nonces[addr]+1, 100000, key)) @@ -1261,7 +1261,7 @@ func TestAllowedTxSize(t *testing.T) { t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err) } // Try adding a transaction with random allowed size - if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil { + if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentHead.Load().GasLimit, big.NewInt(1), key, uint64(rand.IntN(int(dataSize))))); err != nil { t.Fatalf("failed to add transaction of random allowed size: %v", err) } // Try adding a transaction of minimal not allowed size @@ -1269,7 +1269,7 @@ func TestAllowedTxSize(t *testing.T) { t.Fatalf("expected rejection on slightly oversize transaction") } // Try adding a transaction of random not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil { + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentHead.Load().GasLimit, big.NewInt(1), key, dataSize+1+uint64(rand.IntN(10*txMaxSize)))); err == nil { t.Fatalf("expected rejection on oversize transaction") } // Run some sanity checks on the pool internals diff --git a/core/txpool/legacypool/list_test.go b/core/txpool/legacypool/list_test.go index 8587c66f7d..30c6146f91 100644 --- a/core/txpool/legacypool/list_test.go +++ b/core/txpool/legacypool/list_test.go @@ -18,7 +18,7 @@ package legacypool import ( "math/big" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" diff --git a/core/types/hashing_test.go b/core/types/hashing_test.go index a6949414f3..a0dae7c582 100644 --- a/core/types/hashing_test.go +++ b/core/types/hashing_test.go @@ -21,7 +21,7 @@ import ( "fmt" "io" "math/big" - mrand "math/rand" + mrand "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -174,9 +174,9 @@ type dummyDerivableList struct { func newDummy(seed int) *dummyDerivableList { d := &dummyDerivableList{} - src := mrand.NewSource(int64(seed)) + src := mrand.New(mrand.NewPCG(uint64(seed), uint64(seed))) // don't use lists longer than 4K items - d.len = int(src.Int63() & 0x0FFF) + d.len = int(src.Int64() & 0x0FFF) d.seed = seed return d } @@ -186,10 +186,14 @@ func (d *dummyDerivableList) Len() int { } func (d *dummyDerivableList) EncodeIndex(i int, w *bytes.Buffer) { - src := mrand.NewSource(int64(d.seed + i)) + src := mrand.New(mrand.NewPCG(uint64(d.seed+i), uint64(d.seed+i))) // max item size 256, at least 1 byte per item - size := 1 + src.Int63()&0x00FF - io.CopyN(w, mrand.New(src), size) + size := 1 + src.Int64()&0x00FF + b := make([]byte, size) + for i := range size { + b[i] = byte(src.Int()) + } + io.CopyN(w, bytes.NewBuffer(b), size) } func printList(l types.DerivableList) { diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index 0a58e1eaee..e7ac44fb5d 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -22,7 +22,7 @@ import ( crand "crypto/rand" "fmt" "math/big" - "math/rand" + "math/rand/v2" "reflect" "sync" "testing" diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go index e29d23f80b..4eee0513c1 100644 --- a/eth/downloader/queue_test.go +++ b/eth/downloader/queue_test.go @@ -20,7 +20,7 @@ import ( "fmt" "log/slog" "math/big" - "math/rand" + "math/rand/v2" "os" "sync" "testing" @@ -317,14 +317,14 @@ func XTestDelivery(t *testing.T) { i := 4 for { peer := dummyPeer(fmt.Sprintf("peer-%d", i)) - f, _, _ := q.ReserveBodies(peer, rand.Intn(30)) + f, _, _ := q.ReserveBodies(peer, rand.IntN(30)) if f != nil { var ( emptyList []*types.Header txset [][]*types.Transaction uncleset [][]*types.Header ) - numToSkip := rand.Intn(len(f.Headers)) + numToSkip := rand.IntN(len(f.Headers)) for _, hdr := range f.Headers[0 : len(f.Headers)-numToSkip] { txset = append(txset, world.getTransactions(hdr.Number.Uint64())) uncleset = append(uncleset, emptyList) @@ -356,7 +356,7 @@ func XTestDelivery(t *testing.T) { // reserve receiptfetch peer := dummyPeer("peer-3") for { - f, _, _ := q.ReserveReceipts(peer, rand.Intn(50)) + f, _, _ := q.ReserveReceipts(peer, rand.IntN(50)) if f != nil { var rcs [][]*types.Receipt for _, hdr := range f.Headers { @@ -384,7 +384,7 @@ func XTestDelivery(t *testing.T) { time.Sleep(300 * time.Millisecond) //world.tick() //fmt.Printf("trying to progress\n") - world.progress(rand.Intn(100)) + world.progress(rand.IntN(100)) } for i := 0; i < 50; i++ { time.Sleep(2990 * time.Millisecond) diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go index 04421a2bf5..12ce3b9369 100644 --- a/eth/downloader/skeleton.go +++ b/eth/downloader/skeleton.go @@ -20,7 +20,7 @@ import ( "encoding/json" "errors" "fmt" - "math/rand" + "math/rand/v2" "sort" "time" @@ -712,7 +712,7 @@ func (s *skeleton) assignTasks(success chan *headerResponse, fail chan *headerRe // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 97d1e29862..908bfe6e24 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -20,7 +20,7 @@ import ( "errors" "fmt" "math" - mrand "math/rand" + mrand "math/rand/v2" "sort" "time" @@ -988,7 +988,7 @@ func (f *TxFetcher) forEachPeer(peers map[string]struct{}, do func(peer string)) list = append(list, peer) } sort.Strings(list) - rotateStrings(list, f.rand.Intn(len(list))) + rotateStrings(list, f.rand.IntN(len(list))) for _, peer := range list { do(peer) } diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index f80b1d6096..fcad8166cf 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -19,7 +19,7 @@ package fetcher import ( "errors" "math/big" - "math/rand" + "math/rand/v2" "slices" "testing" "time" @@ -1292,7 +1292,7 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) { // Create a slew of transactions to max out the underpriced set var txs []*types.Transaction for i := 0; i < maxTxUnderpricedSetSize+1; i++ { - txs = append(txs, types.NewTransaction(rand.Uint64(), common.Address{byte(rand.Intn(256))}, new(big.Int), 0, new(big.Int), nil)) + txs = append(txs, types.NewTransaction(rand.Uint64(), common.Address{byte(rand.IntN(256))}, new(big.Int), 0, new(big.Int), nil)) } var ( hashes []common.Hash @@ -1842,7 +1842,7 @@ func testTransactionFetcher(t *testing.T, tt txFetcherTest) { fetcher := tt.init() fetcher.clock = clock fetcher.step = wait - fetcher.rand = rand.New(rand.NewSource(0x3a29)) + fetcher.rand = rand.New(rand.New(rand.NewPCG(uint64(0x3a29), uint64(0x3a29)))) fetcher.Start() defer fetcher.Stop() diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 013b9f7bc2..b863dd69f6 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -20,7 +20,7 @@ import ( "context" "errors" "math/big" - "math/rand" + "math/rand/v2" "reflect" "runtime" "testing" diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index fc82b42947..9313ed5163 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -19,7 +19,7 @@ package eth import ( "math" "math/big" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -393,7 +393,7 @@ func testGetBlockBodies(t *testing.T, protocol uint) { ) for j := 0; j < tt.random; j++ { for { - num := rand.Int63n(int64(backend.chain.CurrentBlock().Number.Uint64())) + num := rand.Int64N(int64(backend.chain.CurrentBlock().Number.Uint64())) if !seen[num] { seen[num] = true diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index f53782a053..3e7be65253 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -18,7 +18,7 @@ package eth import ( "math/big" - "math/rand" + "math/rand/v2" "sync" mapset "github.com/deckarep/golang-set/v2" diff --git a/eth/protocols/snap/gentrie_test.go b/eth/protocols/snap/gentrie_test.go index 2da4f3c866..918f014728 100644 --- a/eth/protocols/snap/gentrie_test.go +++ b/eth/protocols/snap/gentrie_test.go @@ -18,7 +18,7 @@ package snap import ( "bytes" - "math/rand" + "math/rand/v2" "slices" "testing" @@ -163,12 +163,12 @@ func buildPartial(owner common.Hash, db ethdb.KeyValueReader, batch ethdb.Batch, func TestPartialGentree(t *testing.T) { for round := 0; round < 100; round++ { var ( - n = rand.Intn(1024) + 10 + n = rand.IntN(1024) + 10 entries []*kv ) for i := 0; i < n; i++ { var val []byte - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { val = testrand.Bytes(3) } else { val = testrand.Bytes(32) @@ -223,8 +223,8 @@ func TestPartialGentree(t *testing.T) { last int ) for { - first = rand.Intn(len(entries)) - last = rand.Intn(len(entries)) + first = rand.IntN(len(entries)) + last = rand.IntN(len(entries)) if first <= last { break } @@ -255,12 +255,12 @@ func TestPartialGentree(t *testing.T) { func TestGentreeDanglingClearing(t *testing.T) { for round := 0; round < 100; round++ { var ( - n = rand.Intn(1024) + 10 + n = rand.IntN(1024) + 10 entries []*kv ) for i := 0; i < n; i++ { var val []byte - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { val = testrand.Bytes(3) } else { val = testrand.Bytes(32) @@ -332,8 +332,8 @@ func TestGentreeDanglingClearing(t *testing.T) { last int ) for { - first = rand.Intn(len(entries)) - last = rand.Intn(len(entries)) + first = rand.IntN(len(entries)) + last = rand.IntN(len(entries)) if first <= last { break } @@ -365,7 +365,7 @@ func TestFlushPartialTree(t *testing.T) { var entries []*kv for i := 0; i < 1024; i++ { var val []byte - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { val = testrand.Bytes(3) } else { val = testrand.Bytes(32) @@ -410,7 +410,7 @@ func TestFlushPartialTree(t *testing.T) { tr := newPathTrie(common.Hash{}, c.first != 0, db, batch) for i := c.first; i <= c.last; i++ { tr.update(entries[i].k, entries[i].v) - if rand.Intn(2) == 0 { + if rand.IntN(2) == 0 { tr.commit(false) batch.Replay(combined) @@ -449,7 +449,7 @@ func TestBoundSplit(t *testing.T) { var entries []*kv for i := 0; i < 1024; i++ { var val []byte - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { val = testrand.Bytes(3) } else { val = testrand.Bytes(32) @@ -473,7 +473,7 @@ func TestBoundSplit(t *testing.T) { if next == len(entries) { break } - last = rand.Intn(len(entries)-next) + next + last = rand.IntN(len(entries)-next) + next r := buildPartial(common.Hash{}, db, db.NewBatch(), entries, next, last) set := r.modifies() @@ -523,7 +523,7 @@ func TestTinyPartialTree(t *testing.T) { var entries []*kv for i := 0; i < 1024; i++ { var val []byte - if rand.Intn(3) == 0 { + if rand.IntN(3) == 0 { val = testrand.Bytes(3) } else { val = testrand.Bytes(32) diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index cdd03e6a0c..92a0f70c65 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -23,7 +23,7 @@ import ( "fmt" gomath "math" "math/big" - "math/rand" + "math/rand/v2" "sort" "sync" "sync/atomic" @@ -1046,7 +1046,7 @@ func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *ac // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } @@ -1147,7 +1147,7 @@ func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan * // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } @@ -1251,7 +1251,7 @@ func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *st // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } @@ -1419,7 +1419,7 @@ func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fai // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } @@ -1547,7 +1547,7 @@ func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fai // Matched a pending task to an idle peer, allocate a unique request id var reqid uint64 for { - reqid = uint64(rand.Int63()) + reqid = uint64(rand.Int64()) if reqid == 0 { continue } diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index c97c3b99b3..bbd247ebf5 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -22,7 +22,7 @@ import ( "encoding/binary" "fmt" "math/big" - mrand "math/rand" + mrand "math/rand/v2" "slices" "sync" "testing" @@ -1797,7 +1797,7 @@ func makeUnevenStorageTrie(owner common.Hash, slots int, db *triedb.Database) (c for i := 0; i < 3; i++ { var n int for { - n = mrand.Intn(15) // the last range is set empty deliberately + n = mrand.IntN(15) // the last range is set empty deliberately if _, ok := chosen[byte(n)]; ok { continue } diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index 308f5c44c9..590c6a7781 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -20,7 +20,7 @@ import ( "context" "crypto/ecdsa" "math/big" - "math/rand" + "math/rand/v2" "testing" "time" @@ -161,7 +161,7 @@ func TestFork(t *testing.T) { parent, _ := client.HeaderByNumber(ctx, nil) // 2. - n := int(rand.Int31n(21)) + n := int(rand.Int32N(21)) for i := 0; i < n; i++ { sim.Commit() } diff --git a/event/event_test.go b/event/event_test.go index 84b37eca3b..58077844c3 100644 --- a/event/event_test.go +++ b/event/event_test.go @@ -17,7 +17,7 @@ package event import ( - "math/rand" + "math/rand/v2" "sync" "testing" "time" @@ -113,7 +113,7 @@ func TestMuxConcurrent(t *testing.T) { } } sub := func(i int) { - time.Sleep(time.Duration(rand.Intn(99)) * time.Millisecond) + time.Sleep(time.Duration(rand.IntN(99)) * time.Millisecond) sub := mux.Subscribe(testEvent(0)) <-sub.Chan() sub.Unsubscribe() diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index f6e21d2ef7..8182c003c7 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -23,7 +23,7 @@ import ( "errors" "fmt" "io" - "math/rand" + "math/rand/v2" "os" "time" @@ -90,9 +90,7 @@ func randomSource() *rand.Rand { if _, err := crand.Read(bytes); err == nil { seed = int64(binary.LittleEndian.Uint64(bytes)) } - - src := rand.NewSource(seed) - return rand.New(src) + return rand.New(rand.New(rand.NewPCG(uint64(seed), uint64(seed)))) } // This function runs the main event loop from a goroutine that is started diff --git a/internal/testrand/rand.go b/internal/testrand/rand.go index 690993de05..72cfe9bfa4 100644 --- a/internal/testrand/rand.go +++ b/internal/testrand/rand.go @@ -19,7 +19,7 @@ package testrand import ( crand "crypto/rand" "encoding/binary" - mrand "math/rand" + mrand "math/rand/v2" "github.com/ethereum/go-ethereum/common" ) @@ -31,14 +31,16 @@ var prng = initRand() func initRand() *mrand.Rand { var seed [8]byte crand.Read(seed[:]) - rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) + rnd := mrand.New(mrand.NewPCG(binary.LittleEndian.Uint64(seed[:]), binary.LittleEndian.Uint64(seed[:]))) return rnd } // Bytes generates a random byte slice with specified length. func Bytes(n int) []byte { r := make([]byte, n) - prng.Read(r) + for i := range r { + r[i] = byte(mrand.Int()) + } return r } diff --git a/log/format_test.go b/log/format_test.go index d4c1df4abc..dc57063d39 100644 --- a/log/format_test.go +++ b/log/format_test.go @@ -1,7 +1,7 @@ package log import ( - "math/rand" + "math/rand/v2" "testing" ) @@ -11,7 +11,7 @@ func BenchmarkPrettyInt64Logfmt(b *testing.B) { buf := make([]byte, 100) b.ReportAllocs() for i := 0; i < b.N; i++ { - sink = appendInt64(buf, rand.Int63()) + sink = appendInt64(buf, rand.Int64()) } } diff --git a/metrics/sample.go b/metrics/sample.go index 17b2bee28f..36cd79941c 100644 --- a/metrics/sample.go +++ b/metrics/sample.go @@ -2,7 +2,7 @@ package metrics import ( "math" - "math/rand" + "math/rand/v2" "slices" "sync" "time" @@ -359,9 +359,9 @@ func (s *UniformSample) Update(v int64) { } else { var r int64 if s.rand != nil { - r = s.rand.Int63n(s.count) + r = s.rand.Int64N(s.count) } else { - r = rand.Int63n(s.count) + r = rand.Int64N(s.count) } if r < int64(len(s.values)) { s.values[int(r)] = v diff --git a/metrics/sample_test.go b/metrics/sample_test.go index 4227b43ef7..c0920e28b8 100644 --- a/metrics/sample_test.go +++ b/metrics/sample_test.go @@ -2,7 +2,7 @@ package metrics import ( "math" - "math/rand" + "math/rand/v2" "runtime" "testing" "time" @@ -158,7 +158,7 @@ func TestExpDecaySampleRescale(t *testing.T) { func TestExpDecaySampleSnapshot(t *testing.T) { now := time.Now() - s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1))) + s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewPCG(1, 1))) for i := 1; i <= 10000; i++ { s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) } @@ -169,7 +169,7 @@ func TestExpDecaySampleSnapshot(t *testing.T) { func TestExpDecaySampleStatistics(t *testing.T) { now := time.Now() - s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1))) + s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewPCG(1, 1))) for i := 1; i <= 10000; i++ { s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i)) } @@ -219,7 +219,7 @@ func TestUniformSampleIncludesTail(t *testing.T) { } func TestUniformSampleSnapshot(t *testing.T) { - s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1))) + s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewPCG(1, 1))) for i := 1; i <= 10000; i++ { s.Update(int64(i)) } @@ -229,7 +229,7 @@ func TestUniformSampleSnapshot(t *testing.T) { } func TestUniformSampleStatistics(t *testing.T) { - s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1))) + s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewPCG(1, 1))) for i := 1; i <= 10000; i++ { s.Update(int64(i)) } @@ -327,7 +327,7 @@ func TestUniformSampleConcurrentUpdateCount(t *testing.T) { for { select { case <-t.C: - s.Update(rand.Int63()) + s.Update(rand.Int64()) case <-quit: t.Stop() return @@ -345,7 +345,7 @@ func BenchmarkCalculatePercentiles(b *testing.B) { pss := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} var vals []int64 for i := 0; i < 1000; i++ { - vals = append(vals, int64(rand.Int31())) + vals = append(vals, int64(rand.Int32())) } v := make([]int64, len(vals)) b.ResetTimer() diff --git a/miner/ordering_test.go b/miner/ordering_test.go index 3587a835c8..96d7f14484 100644 --- a/miner/ordering_test.go +++ b/miner/ordering_test.go @@ -19,7 +19,7 @@ package miner import ( "crypto/ecdsa" "math/big" - "math/rand" + "math/rand/v2" "testing" "time" @@ -61,7 +61,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) { count := 25 for i := 0; i < 25; i++ { var tx *types.Transaction - gasFeeCap := rand.Intn(50) + gasFeeCap := rand.IntN(50) if baseFee == nil { tx = types.NewTx(&types.LegacyTx{ Nonce: uint64(start + i), @@ -78,7 +78,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) { Value: big.NewInt(100), Gas: 100, GasFeeCap: big.NewInt(int64(gasFeeCap)), - GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))), + GasTipCap: big.NewInt(int64(rand.IntN(gasFeeCap + 1))), Data: nil, }) if count == 25 && int64(gasFeeCap) < baseFee.Int64() { diff --git a/p2p/dial.go b/p2p/dial.go index 24d4dc2e89..1d10b289a9 100644 --- a/p2p/dial.go +++ b/p2p/dial.go @@ -22,7 +22,7 @@ import ( "encoding/binary" "errors" "fmt" - mrand "math/rand" + mrand "math/rand/v2" "net" "sync" "sync/atomic" @@ -150,8 +150,8 @@ func (cfg dialConfig) withDefaults() dialConfig { if cfg.rand == nil { seedb := make([]byte, 8) crand.Read(seedb) - seed := int64(binary.BigEndian.Uint64(seedb)) - cfg.rand = mrand.New(mrand.NewSource(seed)) + seed := binary.BigEndian.Uint64(seedb) + cfg.rand = mrand.New(mrand.NewPCG(seed, seed)) } return cfg } @@ -397,7 +397,7 @@ func (d *dialScheduler) checkDial(n *enode.Node) error { // startStaticDials starts n static dial tasks. func (d *dialScheduler) startStaticDials(n int) (started int) { for started = 0; started < n && len(d.staticPool) > 0; started++ { - idx := d.rand.Intn(len(d.staticPool)) + idx := d.rand.IntN(len(d.staticPool)) task := d.staticPool[idx] d.startDial(task) d.removeFromStaticPool(idx) diff --git a/p2p/dial_test.go b/p2p/dial_test.go index 13908f11ea..e8f2c444aa 100644 --- a/p2p/dial_test.go +++ b/p2p/dial_test.go @@ -20,7 +20,7 @@ import ( "context" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "reflect" "sync" @@ -423,7 +423,7 @@ func runDialTest(t *testing.T, config dialConfig, rounds []dialTestRound) { config.dialer = dialer config.resolver = resolver config.log = testlog.Logger(t, log.LvlTrace) - config.rand = rand.New(rand.NewSource(0x1111)) + config.rand = rand.New(rand.NewPCG(0x1111, 0x1111)) // Set up the dialer. The setup function below runs on the dialTask // goroutine and adds the peer. diff --git a/p2p/discover/common.go b/p2p/discover/common.go index 0716f7472f..4302b2d5cb 100644 --- a/p2p/discover/common.go +++ b/p2p/discover/common.go @@ -20,7 +20,7 @@ import ( "crypto/ecdsa" crand "crypto/rand" "encoding/binary" - "math/rand" + "math/rand/v2" "net" "net/netip" "sync" @@ -99,8 +99,8 @@ type ReadPacket struct { } type randomSource interface { - Intn(int) int - Int63n(int64) int64 + IntN(int) int + Int64N(int64) int64 Shuffle(int, func(int, int)) } @@ -114,23 +114,23 @@ func (r *reseedingRandom) seed() { var b [8]byte crand.Read(b[:]) seed := binary.BigEndian.Uint64(b[:]) - new := rand.New(rand.NewSource(int64(seed))) + new := rand.New(rand.NewPCG(seed, seed)) r.mu.Lock() r.cur = new r.mu.Unlock() } -func (r *reseedingRandom) Intn(n int) int { +func (r *reseedingRandom) IntN(n int) int { r.mu.Lock() defer r.mu.Unlock() - return r.cur.Intn(n) + return r.cur.IntN(n) } -func (r *reseedingRandom) Int63n(n int64) int64 { +func (r *reseedingRandom) Int64N(n int64) int64 { r.mu.Lock() defer r.mu.Unlock() - return r.cur.Int63n(n) + return r.cur.Int64N(n) } func (r *reseedingRandom) Shuffle(n int, swap func(i, j int)) { diff --git a/p2p/discover/table.go b/p2p/discover/table.go index 8045f1389e..b85fdef751 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -460,7 +460,7 @@ func (tab *Table) loadSeedNodes() { func (tab *Table) nextRefreshTime() time.Duration { half := tab.cfg.RefreshInterval / 2 - return half + time.Duration(tab.rand.Int63n(int64(half))) + return half + time.Duration(tab.rand.Int64N(int64(half))) } // bucket returns the bucket for the given node ID hash. @@ -605,7 +605,7 @@ func (tab *Table) deleteInBucket(b *bucket, id enode.ID) *tableNode { tab.log.Debug("Removed dead node", "b", b.index, "id", n.ID(), "ip", n.IPAddr()) return nil } - rindex := tab.rand.Intn(len(b.replacements)) + rindex := tab.rand.IntN(len(b.replacements)) rep := b.replacements[rindex] b.replacements = slices.Delete(b.replacements, rindex, rindex+1) b.entries = append(b.entries, rep) diff --git a/p2p/discover/table_reval.go b/p2p/discover/table_reval.go index 2465fee906..772e9c4dfb 100644 --- a/p2p/discover/table_reval.go +++ b/p2p/discover/table_reval.go @@ -208,7 +208,7 @@ func (list *revalidationList) get(now mclock.AbsTime, rand randomSource, exclude return nil } for i := 0; i < len(list.nodes)*3; i++ { - n := list.nodes[rand.Intn(len(list.nodes))] + n := list.nodes[rand.IntN(len(list.nodes))] _, excluded := exclude[n.ID()] if !excluded { return n @@ -218,7 +218,7 @@ func (list *revalidationList) get(now mclock.AbsTime, rand randomSource, exclude } func (list *revalidationList) schedule(now mclock.AbsTime, rand randomSource) { - list.nextTime = now.Add(time.Duration(rand.Int63n(int64(list.interval)))) + list.nextTime = now.Add(time.Duration(rand.Int64N(int64(list.interval)))) } func (list *revalidationList) push(n *tableNode, now mclock.AbsTime, rand randomSource) { diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go index 8cc4ae33b2..92c566f98b 100644 --- a/p2p/discover/table_test.go +++ b/p2p/discover/table_test.go @@ -19,7 +19,7 @@ package discover import ( "crypto/ecdsa" "fmt" - "math/rand" + "math/rand/v2" "net" "reflect" "slices" @@ -264,7 +264,7 @@ func (*closeTest) Generate(rand *rand.Rand, size int) reflect.Value { t := &closeTest{ Self: gen(enode.ID{}, rand).(enode.ID), Target: gen(enode.ID{}, rand).(enode.ID), - N: rand.Intn(bucketSize), + N: rand.IntN(bucketSize), } for _, id := range gen([]enode.ID{}, rand).([]enode.ID) { r := new(enr.Record) @@ -486,7 +486,7 @@ func gen(typ interface{}, rand *rand.Rand) interface{} { func quickcfg() *quick.Config { return &quick.Config{ MaxCount: 5000, - Rand: rand.New(rand.NewSource(time.Now().Unix())), + Rand: rand.New(rand.NewPCG(uint64(time.Now().Unix()), uint64(time.Now().Unix()))), } } diff --git a/p2p/discover/table_util_test.go b/p2p/discover/table_util_test.go index fe10883fe6..fc604d8c9e 100644 --- a/p2p/discover/table_util_test.go +++ b/p2p/discover/table_util_test.go @@ -22,7 +22,7 @@ import ( "encoding/hex" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "slices" "sync" @@ -96,7 +96,7 @@ func idAtDistance(a enode.ID, n int) (b enode.ID) { } b[pos] = a[pos]&^bit | ^a[pos]&bit // TODO: randomize end bits for i := pos + 1; i < len(a); i++ { - b[i] = byte(rand.Intn(255)) + b[i] = byte(rand.IntN(255)) } return b } diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go index 1af31f4f1b..6bba21c9b9 100644 --- a/p2p/discover/v4_udp_test.go +++ b/p2p/discover/v4_udp_test.go @@ -24,7 +24,7 @@ import ( "errors" "fmt" "io" - "math/rand" + "math/rand/v2" "net" "net/netip" "reflect" @@ -167,7 +167,7 @@ func TestUDPv4_responseTimeouts(t *testing.T) { defer test.close() randomDuration := func(max time.Duration) time.Duration { - return time.Duration(rand.Int63n(int64(max))) + return time.Duration(rand.Int64N(int64(max))) } var ( @@ -182,7 +182,7 @@ func TestUDPv4_responseTimeouts(t *testing.T) { // For all other requests, a reply is scheduled to arrive // within the timeout window. p := &replyMatcher{ - ptype: byte(rand.Intn(255)), + ptype: byte(rand.IntN(255)), callback: func(v4wire.Packet) (bool, bool) { return true, true }, } binary.BigEndian.PutUint64(p.from[:], uint64(i)) diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 8631b918ff..0d1698e7c1 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -21,7 +21,7 @@ import ( "crypto/ecdsa" "encoding/binary" "fmt" - "math/rand" + "math/rand/v2" "net" "net/netip" "reflect" @@ -56,7 +56,7 @@ func TestUDPv5_lookupE2E(t *testing.T) { defer node.Close() } last := nodes[N-1] - target := nodes[rand.Intn(N-2)].Self() + target := nodes[rand.IntN(N-2)].Self() // It is expected that all nodes can be found. expectedResult := make([]*enode.Node, len(nodes)) diff --git a/p2p/dnsdisc/client.go b/p2p/dnsdisc/client.go index 4f14d860e1..1c0c252e2d 100644 --- a/p2p/dnsdisc/client.go +++ b/p2p/dnsdisc/client.go @@ -21,7 +21,7 @@ import ( "context" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "strings" "sync" @@ -312,7 +312,7 @@ func (it *randomIterator) pickTree() *clientTree { switch { case canSync: // Pick a random tree. - return trees[rand.Intn(len(trees))] + return trees[rand.IntN(len(trees))] case len(trees) > 0: // No sync action can be performed on any tree right now. The only meaningful // thing to do is waiting for any root record to get updated. diff --git a/p2p/dnsdisc/sync.go b/p2p/dnsdisc/sync.go index 073547c90d..3860e0ea44 100644 --- a/p2p/dnsdisc/sync.go +++ b/p2p/dnsdisc/sync.go @@ -18,7 +18,7 @@ package dnsdisc import ( "context" - "math/rand" + "math/rand/v2" "time" "github.com/ethereum/go-ethereum/common/mclock" @@ -131,7 +131,7 @@ func (ct *clientTree) syncNextLink(ctx context.Context) error { } func (ct *clientTree) syncNextRandomENR(ctx context.Context) (*enode.Node, error) { - index := rand.Intn(len(ct.enrs.missing)) + index := rand.IntN(len(ct.enrs.missing)) hash := ct.enrs.missing[index] e, err := ct.enrs.resolveNext(ctx, hash) if err != nil { diff --git a/p2p/dnsdisc/sync_test.go b/p2p/dnsdisc/sync_test.go index ce1cb90bae..b71dc0f980 100644 --- a/p2p/dnsdisc/sync_test.go +++ b/p2p/dnsdisc/sync_test.go @@ -17,7 +17,7 @@ package dnsdisc import ( - "math/rand" + "math/rand/v2" "strconv" "testing" ) @@ -67,7 +67,7 @@ func TestLinkCacheRandom(t *testing.T) { var lc linkCache var remove []string for i := 0; i < 100; i++ { - a, b := tags[rand.Intn(len(tags))], tags[rand.Intn(len(tags))] + a, b := tags[rand.IntN(len(tags))], tags[rand.IntN(len(tags))] lc.addLink(a, b) remove = append(remove, a) } diff --git a/p2p/enode/localnode_test.go b/p2p/enode/localnode_test.go index 86b962a74e..acb1cb1f40 100644 --- a/p2p/enode/localnode_test.go +++ b/p2p/enode/localnode_test.go @@ -17,7 +17,7 @@ package enode import ( - "math/rand" + "math/rand/v2" "net" "net/netip" "testing" @@ -90,7 +90,7 @@ func TestLocalNodeSeqPersist(t *testing.T) { // This test checks behavior of the endpoint predictor. func TestLocalNodeEndpoint(t *testing.T) { var ( - rng = rand.New(rand.NewSource(4)) + rng = rand.New(rand.NewPCG(4, 4)) fallback = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: 80} predicted = &net.UDPAddr{IP: net.IP{127, 0, 1, 2}, Port: 81} staticIP = net.IP{127, 0, 1, 2} diff --git a/p2p/enr/enr_test.go b/p2p/enr/enr_test.go index 4fccb0cce9..5625dc387e 100644 --- a/p2p/enr/enr_test.go +++ b/p2p/enr/enr_test.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/binary" "fmt" - "math/rand" + "math/rand/v2" "testing" "time" @@ -29,11 +29,13 @@ import ( "github.com/stretchr/testify/require" ) -var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) +var rnd = rand.New(rand.NewPCG(uint64(time.Now().Unix()), uint64(time.Now().Unix()))) func randomString(strlen int) string { b := make([]byte, strlen) - rnd.Read(b) + for i := range b { + b[i] = byte(rand.Int()) + } return string(b) } diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index f1bb955892..e2789aa8df 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -20,7 +20,7 @@ import ( "errors" "fmt" "math" - "math/rand" + "math/rand/v2" "net" "strings" "sync" @@ -120,9 +120,10 @@ func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.I func (n *upnp) randomPort() int { if n.rand == nil { - n.rand = rand.New(rand.NewSource(time.Now().UnixNano())) + seed := uint64(time.Now().UnixNano()) + n.rand = rand.New(rand.NewPCG(seed, seed)) } - return n.rand.Intn(math.MaxUint16-10000) + 10000 + return n.rand.IntN(math.MaxUint16-10000) + 10000 } func (n *upnp) internalAddress() (net.IP, error) { diff --git a/p2p/netutil/addrutil.go b/p2p/netutil/addrutil.go index b8b318571b..329027abaf 100644 --- a/p2p/netutil/addrutil.go +++ b/p2p/netutil/addrutil.go @@ -18,7 +18,7 @@ package netutil import ( "fmt" - "math/rand" + "math/rand/v2" "net" "net/netip" ) @@ -54,12 +54,14 @@ func IPToAddr(ip net.IP) netip.Addr { // RandomAddr creates a random IP address. func RandomAddr(rng *rand.Rand, ipv4 bool) netip.Addr { var bytes []byte - if ipv4 || rng.Intn(2) == 0 { + if ipv4 || rng.IntN(2) == 0 { bytes = make([]byte, 4) } else { bytes = make([]byte, 16) } - rng.Read(bytes) + for i := range bytes { + bytes[i] = byte(rand.Int()) + } addr, ok := netip.AddrFromSlice(bytes) if !ok { panic(fmt.Errorf("BUG! invalid IP %v", bytes)) diff --git a/p2p/netutil/net_test.go b/p2p/netutil/net_test.go index 569c7ac454..14a5a74ac6 100644 --- a/p2p/netutil/net_test.go +++ b/p2p/netutil/net_test.go @@ -18,7 +18,7 @@ package netutil import ( "fmt" - "math/rand" + "math/rand/v2" "net" "net/netip" "reflect" @@ -264,7 +264,7 @@ func TestDistinctNetSet(t *testing.T) { func TestDistinctNetSetAddRemove(t *testing.T) { cfg := &quick.Config{ Values: func(s []reflect.Value, rng *rand.Rand) { - slice := make([]netip.Addr, rng.Intn(20)+1) + slice := make([]netip.Addr, rng.IntN(20)+1) for i := range slice { slice[i] = RandomAddr(rng, false) } diff --git a/p2p/peer_test.go b/p2p/peer_test.go index 4308bbd2eb..6a43224083 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -20,7 +20,7 @@ import ( "encoding/binary" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "reflect" "strconv" @@ -201,7 +201,7 @@ func TestPeerDisconnect(t *testing.T) { // This test is supposed to verify that Peer can reliably handle // multiple causes of disconnection occurring at the same time. func TestPeerDisconnectRace(t *testing.T) { - maybe := func() bool { return rand.Intn(2) == 1 } + maybe := func() bool { return rand.IntN(2) == 1 } for i := 0; i < 1000; i++ { protoclose := make(chan error) diff --git a/p2p/rlpx/rlpx.go b/p2p/rlpx/rlpx.go index dd14822dee..b1beacf535 100644 --- a/p2p/rlpx/rlpx.go +++ b/p2p/rlpx/rlpx.go @@ -29,7 +29,7 @@ import ( "fmt" "hash" "io" - mrand "math/rand" + mrand "math/rand/v2" "net" "time" @@ -635,7 +635,7 @@ func (h *handshakeState) sealEIP8(msg interface{}) ([]byte, error) { } // Pad with random amount of data. the amount needs to be at least 100 bytes to make // the message distinguishable from pre-EIP-8 handshakes. - h.wbuf.appendZero(mrand.Intn(100) + 100) + h.wbuf.appendZero(mrand.IntN(100) + 100) prefix := make([]byte, 2) binary.BigEndian.PutUint16(prefix, uint16(len(h.wbuf.data)+eciesOverhead)) diff --git a/p2p/rlpx/rlpx_test.go b/p2p/rlpx/rlpx_test.go index 27d51546e7..dc4baec2a4 100644 --- a/p2p/rlpx/rlpx_test.go +++ b/p2p/rlpx/rlpx_test.go @@ -22,7 +22,7 @@ import ( "encoding/hex" "fmt" "io" - "math/rand" + "math/rand/v2" "net" "reflect" "strings" @@ -392,9 +392,11 @@ func BenchmarkThroughput(b *testing.B) { conn1, conn2 = NewConn(pipe1, nil), NewConn(pipe2, &keyA.PublicKey) handshakeDone = make(chan error, 1) msgdata = make([]byte, 1024) - rand = rand.New(rand.NewSource(1337)) + rand = rand.New(rand.NewPCG(1337, 1337)) ) - rand.Read(msgdata) + for i := range msgdata { + msgdata[i] = byte(rand.Int()) + } // Server side. go func() { diff --git a/p2p/server_test.go b/p2p/server_test.go index a0491e984a..6d51c906b1 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -21,7 +21,7 @@ import ( "crypto/sha256" "errors" "io" - "math/rand" + "math/rand/v2" "net" "reflect" "strconv" @@ -508,7 +508,7 @@ func newkey() *ecdsa.PrivateKey { func randomID() (id enode.ID) { for i := range id { - id[i] = byte(rand.Intn(255)) + id[i] = byte(rand.IntN(255)) } return id } diff --git a/rpc/client_test.go b/rpc/client_test.go index b7607adfce..9f7a3d10f8 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "net/http" "net/http/httptest" @@ -357,7 +357,7 @@ func testClientCancel(transport string, t *testing.T) { var ( ctx context.Context cancel func() - timeout = time.Duration(rand.Int63n(int64(maxContextCancelTimeout))) + timeout = time.Duration(rand.Int64N(int64(maxContextCancelTimeout))) ) if index < ncallers/2 { // For half of the callers, create a context without deadline @@ -899,7 +899,7 @@ func httpTestClient(srv *Server, transport string, fl *flakeyListener) (*Client, func ipcTestClient(srv *Server, fl *flakeyListener) (*Client, net.Listener) { // Listen on a random endpoint. - endpoint := fmt.Sprintf("go-ethereum-test-ipc-%d-%d", os.Getpid(), rand.Int63()) + endpoint := fmt.Sprintf("go-ethereum-test-ipc-%d-%d", os.Getpid(), rand.Int64()) if runtime.GOOS == "windows" { endpoint = `\\.\pipe\` + endpoint } else { @@ -931,12 +931,12 @@ type flakeyListener struct { } func (l *flakeyListener) Accept() (net.Conn, error) { - delay := time.Duration(rand.Int63n(int64(l.maxAcceptDelay))) + delay := time.Duration(rand.Int64N(int64(l.maxAcceptDelay))) time.Sleep(delay) c, err := l.Listener.Accept() if err == nil { - timeout := time.Duration(rand.Int63n(int64(l.maxKillTimeout))) + timeout := time.Duration(rand.Int64N(int64(l.maxKillTimeout))) time.AfterFunc(timeout, func() { log.Debug(fmt.Sprintf("killing conn %v after %v", c.LocalAddr(), timeout)) c.Close() diff --git a/rpc/subscription.go b/rpc/subscription.go index 9e400c8b60..a6bd0679c4 100644 --- a/rpc/subscription.go +++ b/rpc/subscription.go @@ -24,7 +24,7 @@ import ( "encoding/hex" "encoding/json" "errors" - "math/rand" + "math/rand/v2" "reflect" "strings" "sync" @@ -60,22 +60,24 @@ func NewID() ID { // randomIDGenerator returns a function generates a random IDs. func randomIDGenerator() func() ID { var buf = make([]byte, 8) - var seed int64 + var seed uint64 if _, err := crand.Read(buf); err == nil { - seed = int64(binary.BigEndian.Uint64(buf)) + seed = binary.BigEndian.Uint64(buf) } else { - seed = int64(time.Now().Nanosecond()) + seed = uint64(time.Now().Nanosecond()) } var ( mu sync.Mutex - rng = rand.New(rand.NewSource(seed)) + rng = rand.New(rand.NewPCG(seed, seed)) ) return func() ID { mu.Lock() defer mu.Unlock() id := make([]byte, 16) - rng.Read(id) + for i := range id { + id[i] = byte(rng.Int()) + } return encodeID(id) } } diff --git a/tests/block_test.go b/tests/block_test.go index 4bbd2571d7..16dbcaaec9 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -17,7 +17,7 @@ package tests import ( - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" diff --git a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go index 51f2fc3b4d..8af5d4bcf8 100644 --- a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go +++ b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go @@ -20,7 +20,7 @@ import ( "bytes" "fmt" "math/big" - "math/rand" + "math/rand/v2" "time" "github.com/ethereum/go-ethereum/common" @@ -36,7 +36,7 @@ var ( func init() { // Random is nice, but we need it deterministic - rand := rand.New(rand.NewSource(0x3a29)) + rand := rand.New(rand.NewPCG(0x3a29, 0x3a29)) peers = make([]string, 10) for i := 0; i < len(peers); i++ { @@ -44,7 +44,7 @@ func init() { } txs = make([]*types.Transaction, 65536) // We need to bump enough to hit all the limits for i := 0; i < len(txs); i++ { - txs[i] = types.NewTransaction(rand.Uint64(), common.Address{byte(rand.Intn(256))}, new(big.Int), 0, new(big.Int), nil) + txs[i] = types.NewTransaction(rand.Uint64(), common.Address{byte(rand.IntN(256))}, new(big.Int), 0, new(big.Int), nil) } } @@ -75,7 +75,7 @@ func fuzz(input []byte) int { } // Create a fetcher and hook into it's simulated fields clock := new(mclock.Simulated) - rand := rand.New(rand.NewSource(0x3a29)) // Same used in package tests!!! + rand := rand.New(rand.NewPCG(0x3a29, 0x3a29)) // Same used in package tests!!! f := fetcher.NewTxFetcherForTests( func(common.Hash) bool { return false }, diff --git a/tests/state_test.go b/tests/state_test.go index 76fec97de0..09760b129e 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -21,7 +21,7 @@ import ( "bytes" "fmt" "math/big" - "math/rand" + "math/rand/v2" "os" "path/filepath" "reflect" @@ -111,7 +111,7 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { // one. executionMask := 0xf if testing.Short() { - executionMask = (1 << (rand.Int63() & 4)) + executionMask = (1 << (rand.Int64() & 4)) } t.Run(key+"/hash/trie", func(t *testing.T) { if executionMask&0x1 == 0 { diff --git a/trie/encoding_test.go b/trie/encoding_test.go index ac50b5d025..827589523f 100644 --- a/trie/encoding_test.go +++ b/trie/encoding_test.go @@ -20,7 +20,7 @@ import ( "bytes" crand "crypto/rand" "encoding/hex" - "math/rand" + "math/rand/v2" "testing" ) @@ -95,7 +95,7 @@ func TestHexToCompactInPlace(t *testing.T) { func TestHexToCompactInPlaceRandom(t *testing.T) { for i := 0; i < 10000; i++ { - l := rand.Intn(128) + l := rand.IntN(128) key := make([]byte, l) crand.Read(key) hexBytes := keybytesToHex(key) diff --git a/trie/iterator_test.go b/trie/iterator_test.go index b463294b09..0760f7a94b 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -19,7 +19,7 @@ package trie import ( "bytes" "fmt" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -413,14 +413,14 @@ func testIteratorContinueAfterError(t *testing.T, memonly bool, scheme string) { ) for { if memonly { - rpath = paths[rand.Intn(len(paths))] + rpath = paths[rand.IntN(len(paths))] n := nodes.Nodes[string(rpath)] if n == nil { continue } rhash = n.Hash } else { - index := rand.Intn(len(paths)) + index := rand.IntN(len(paths)) rpath = paths[index] rhash = hashes[index] } diff --git a/trie/proof_test.go b/trie/proof_test.go index fab3a97650..cbf2e9e6a6 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -21,7 +21,7 @@ import ( crand "crypto/rand" "encoding/binary" "fmt" - mrand "math/rand" + mrand "math/rand/v2" "slices" "testing" @@ -38,14 +38,16 @@ var prng = initRnd() func initRnd() *mrand.Rand { var seed [8]byte crand.Read(seed[:]) - rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) + rnd := mrand.New(mrand.NewPCG(binary.LittleEndian.Uint64(seed[:]), binary.LittleEndian.Uint64(seed[:]))) fmt.Printf("Seed: %x\n", seed) return rnd } func randBytes(n int) []byte { r := make([]byte, n) - prng.Read(r) + for i := range r { + r[i] = byte(prng.Int()) + } return r } @@ -124,7 +126,7 @@ func TestBadProof(t *testing.T) { t.Fatalf("prover %d: nil proof", i) } it := proof.NewIterator(nil, nil) - for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ { + for i, d := 0, mrand.IntN(proof.Len()); i <= d; i++ { it.Next() } key := it.Key() @@ -175,8 +177,8 @@ func TestRangeProof(t *testing.T) { } slices.SortFunc(entries, (*kv).cmp) for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 + start := mrand.IntN(len(entries)) + end := mrand.IntN(len(entries)-start) + start + 1 proof := memorydb.New() if err := trie.Prove(entries[start].k, proof); err != nil { @@ -208,8 +210,8 @@ func TestRangeProofWithNonExistentProof(t *testing.T) { } slices.SortFunc(entries, (*kv).cmp) for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 + start := mrand.IntN(len(entries)) + end := mrand.IntN(len(entries)-start) + start + 1 proof := memorydb.New() // Short circuit if the decreased key is same with the previous key @@ -457,8 +459,8 @@ func TestBadRangeProof(t *testing.T) { slices.SortFunc(entries, (*kv).cmp) for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 + start := mrand.IntN(len(entries)) + end := mrand.IntN(len(entries)-start) + start + 1 proof := memorydb.New() if err := trie.Prove(entries[start].k, proof); err != nil { t.Fatalf("Failed to prove the first node %v", err) @@ -473,20 +475,20 @@ func TestBadRangeProof(t *testing.T) { vals = append(vals, entries[i].v) } var first = keys[0] - testcase := mrand.Intn(6) + testcase := mrand.IntN(6) var index int switch testcase { case 0: // Modified key - index = mrand.Intn(end - start) + index = mrand.IntN(end - start) keys[index] = randBytes(32) // In theory it can't be same case 1: // Modified val - index = mrand.Intn(end - start) + index = mrand.IntN(end - start) vals[index] = randBytes(20) // In theory it can't be same case 2: // Gapped entry slice - index = mrand.Intn(end - start) + index = mrand.IntN(end - start) if (index == 0 && start < 100) || (index == end-start-1) { continue } @@ -494,8 +496,8 @@ func TestBadRangeProof(t *testing.T) { vals = append(vals[:index], vals[index+1:]...) case 3: // Out of order - index1 := mrand.Intn(end - start) - index2 := mrand.Intn(end - start) + index1 := mrand.IntN(end - start) + index2 := mrand.IntN(end - start) if index1 == index2 { continue } @@ -503,11 +505,11 @@ func TestBadRangeProof(t *testing.T) { vals[index1], vals[index2] = vals[index2], vals[index1] case 4: // Set random key to nil, do nothing - index = mrand.Intn(end - start) + index = mrand.IntN(end - start) keys[index] = nil case 5: // Set random value to nil, deletion - index = mrand.Intn(end - start) + index = mrand.IntN(end - start) vals[index] = nil } _, err := VerifyRangeProof(trie.Hash(), first, keys, vals, proof) @@ -801,8 +803,8 @@ func TestAllElementsEmptyValueRangeProof(t *testing.T) { // mutateByte changes one byte in b. func mutateByte(b []byte) { - for r := mrand.Intn(len(b)); ; { - new := byte(mrand.Intn(255)) + for r := mrand.IntN(len(b)); ; { + new := byte(mrand.IntN(255)) if new != b[r] { b[r] = new break diff --git a/trie/sync_test.go b/trie/sync_test.go index ccdee7d014..571ba4650a 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -20,7 +20,7 @@ import ( "bytes" "fmt" "maps" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -589,7 +589,7 @@ func testIncompleteSync(t *testing.T, scheme string) { } // Sanity check that removing any node from the database is detected for i, path := range addedKeys { - if rand.Int31n(100) > 5 { + if rand.Int32N(100) > 5 { // Only check 5 percent of added keys as a sanity check continue } diff --git a/trie/trie_test.go b/trie/trie_test.go index 505b517bc5..2748f3dc56 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -23,7 +23,8 @@ import ( "fmt" "hash" "io" - "math/rand" + "math" + "math/rand/v2" "reflect" "sort" "testing" @@ -404,27 +405,29 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { return reflect.ValueOf(generateSteps(finishedFn, r)) } -func generateSteps(finished func() bool, r io.Reader) randTest { +func generateSteps(finished func() bool, r *rand.Rand) randTest { var allKeys [][]byte - var one = []byte{0} + one := 0 genKey := func() []byte { - r.Read(one) - if len(allKeys) < 2 || one[0]%100 > 90 { + one = r.IntN(math.MaxInt8) + if len(allKeys) < 2 || one%100 > 90 { // new key - size := one[0] % 50 + size := one % 50 key := make([]byte, size) - r.Read(key) + for i := 0; i < size; i++ { + key[i] = byte(r.IntN(math.MaxInt8)) + } allKeys = append(allKeys, key) return key } // use existing key - idx := int(one[0]) % len(allKeys) + idx := int(one) % len(allKeys) return allKeys[idx] } var steps randTest for !finished() { - r.Read(one) - step := randTestStep{op: int(one[0]) % opMax} + one = r.IntN(math.MaxInt8) + step := randTestStep{op: int(one) % opMax} switch step.op { case opUpdate: step.key = genKey() @@ -487,7 +490,7 @@ func runRandTestBool(rt randTest) bool { func runRandTest(rt randTest) error { var scheme = rawdb.HashScheme - if rand.Intn(2) == 0 { + if rand.IntN(2) == 0 { scheme = rawdb.PathScheme } var ( @@ -776,18 +779,20 @@ func TestCommitAfterHash(t *testing.T) { func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { // Make the random benchmark deterministic - random := rand.New(rand.NewSource(0)) + random := rand.New(rand.NewPCG(0, 0)) // Create a realistic account trie to hash addresses = make([][20]byte, size) for i := 0; i < len(addresses); i++ { data := make([]byte, 20) - random.Read(data) + for i := range data { + data[i] = byte(random.Int()) + } copy(addresses[i][:], data) } accounts = make([][]byte, len(addresses)) for i := 0; i < len(accounts); i++ { var ( - nonce = uint64(random.Int63()) + nonce = uint64(random.Int64()) root = types.EmptyRootHash code = crypto.Keccak256(nil) ) @@ -797,7 +802,9 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { // Therefore, we instead just read via byte buffer numBytes := random.Uint32() % 33 // [0, 32] bytes balanceBytes := make([]byte, numBytes) - random.Read(balanceBytes) + for i := range balanceBytes { + balanceBytes[i] = byte(prng.Int()) + } balance := new(uint256.Int).SetBytes(balanceBytes) data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code}) accounts[i] = data @@ -914,7 +921,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { {200, common.FromHex("dde92ca9812e068e6982d04b40846dc65a61a9fd4996fc0f55f2fde172a8e13c")}, {2000, common.FromHex("ab553a7f9aff82e3929c382908e30ef7dd17a332933e92ba3fe873fc661ef382")}, } { - prng := rand.New(rand.NewSource(int64(i))) + prng := rand.New(rand.NewPCG(uint64(i), uint64(i))) // This spongeDb is used to check the sequence of disk-db-writes s := &spongeDb{sponge: crypto.NewKeccakState()} db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) @@ -924,13 +931,17 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { key := make([]byte, 32) var val []byte // 50% short elements, 50% large elements - if prng.Intn(2) == 0 { - val = make([]byte, 1+prng.Intn(32)) + if prng.IntN(2) == 0 { + val = make([]byte, 1+prng.IntN(32)) } else { - val = make([]byte, 1+prng.Intn(4096)) + val = make([]byte, 1+prng.IntN(4096)) + } + for i := range key { + key[i] = byte(prng.Int()) + } + for i := range val { + val[i] = byte(prng.Int()) } - prng.Read(key) - prng.Read(val) trie.MustUpdate(key, val) } // Flush trie -> database @@ -946,7 +957,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { func TestCommitSequenceStackTrie(t *testing.T) { for count := 1; count < 200; count++ { - prng := rand.New(rand.NewSource(int64(count))) + prng := rand.New(rand.NewPCG(uint64(count), uint64(count))) // This spongeDb is used to check the sequence of disk-db-writes s := &spongeDb{ sponge: sha3.NewLegacyKeccak256(), @@ -973,12 +984,14 @@ func TestCommitSequenceStackTrie(t *testing.T) { binary.BigEndian.PutUint64(key, uint64(i)) var val []byte // 50% short elements, 50% large elements - if prng.Intn(2) == 0 { - val = make([]byte, 1+prng.Intn(32)) + if prng.IntN(2) == 0 { + val = make([]byte, 1+prng.IntN(32)) } else { - val = make([]byte, 1+prng.Intn(1024)) + val = make([]byte, 1+prng.IntN(1024)) + } + for i := range val { + val[i] = byte(prng.Int()) } - prng.Read(val) trie.Update(key, val) stTrie.Update(key, val) } @@ -1187,8 +1200,12 @@ func TestDecodeNode(t *testing.T) { elems = make([]byte, 20) ) for i := 0; i < 5000000; i++ { - prng.Read(hash) - prng.Read(elems) + for i := range hash { + hash[i] = byte(prng.Int()) + } + for i := range elems { + elems[i] = byte(prng.Int()) + } decodeNode(hash, elems) } } @@ -1201,8 +1218,42 @@ func FuzzTrie(f *testing.F) { steps-- return steps < 0 || input.Len() == 0 } - if err := runRandTest(generateSteps(finishedFn, input)); err != nil { + if err := runRandTest(generateFuzzSteps(finishedFn, input)); err != nil { t.Fatal(err) } }) } + +func generateFuzzSteps(finished func() bool, r io.Reader) randTest { + var allKeys [][]byte + var one = []byte{0} + genKey := func() []byte { + r.Read(one) + if len(allKeys) < 2 || one[0]%100 > 90 { + // new key + size := one[0] % 50 + key := make([]byte, size) + r.Read(key) + allKeys = append(allKeys, key) + return key + } + // use existing key + idx := int(one[0]) % len(allKeys) + return allKeys[idx] + } + var steps randTest + for !finished() { + r.Read(one) + step := randTestStep{op: int(one[0]) % opMax} + switch step.op { + case opUpdate: + step.key = genKey() + step.value = make([]byte, 8) + binary.BigEndian.PutUint64(step.value, uint64(len(steps))) + case opGet, opDelete, opProve: + step.key = genKey() + } + steps = append(steps, step) + } + return steps +} diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index f667944784..5be4e879da 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -20,7 +20,7 @@ import ( "bytes" "errors" "fmt" - "math/rand" + "math/rand/v2" "testing" "github.com/ethereum/go-ethereum/common" @@ -58,7 +58,7 @@ func updateTrie(db *Database, stateRoot common.Hash, addrHash common.Hash, root func generateAccount(storageRoot common.Hash) types.StateAccount { return types.StateAccount{ - Nonce: uint64(rand.Intn(100)), + Nonce: uint64(rand.IntN(100)), Balance: uint256.NewInt(rand.Uint64()), CodeHash: testrand.Bytes(32), Root: storageRoot, @@ -223,7 +223,7 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode dirties = make(map[common.Hash]struct{}) ) for i := 0; i < 20; i++ { - switch rand.Intn(opLen) { + switch rand.IntN(opLen) { case createAccountOp: // account creation addr := testrand.Address()