all: remove deprecated uses of math.rand (#26710)

This PR is a (superior) alternative to https://github.com/ethereum/go-ethereum/pull/26708, it handles deprecation, primarily two specific cases. 

`rand.Seed` is typically used in two ways
- `rand.Seed(time.Now().UnixNano())` -- we seed it, just to be sure to get some random, and not always get the same thing on every run. This is not needed, with global seeding, so those are just removed. 
- `rand.Seed(1)` this is typically done to ensure we have a stable test. If we rely on this, we need to fix up the tests to use a deterministic prng-source. A few occurrences like this has been replaced with a proper custom source. 

`rand.Read` has been replaced by `crypto/rand`.`Read` in this PR.
This commit is contained in:
Martin Holst Swende 2023-02-16 14:36:58 -05:00 committed by GitHub
parent e9d42499bb
commit 4d3525610e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 75 additions and 75 deletions

@ -113,7 +113,6 @@ func TestWatchNewFile(t *testing.T) {
func TestWatchNoDir(t *testing.T) {
t.Parallel()
// Create ks but not the directory that it watches.
rand.Seed(time.Now().UnixNano())
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
list := ks.Accounts()
@ -322,7 +321,6 @@ func TestUpdatedKeyfileContents(t *testing.T) {
t.Parallel()
// Create a temporary keystore to test with
rand.Seed(time.Now().UnixNano())
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int()))
ks := NewKeyStore(dir, LightScryptN, LightScryptP)

@ -17,6 +17,7 @@
package lru
import (
crand "crypto/rand"
"fmt"
"io"
"math/rand"
@ -181,9 +182,9 @@ func BenchmarkLRU(b *testing.B) {
}
for i := range keys {
b := make([]byte, 32)
rand.Read(b)
crand.Read(b)
keys[i] = string(b)
rand.Read(b)
crand.Read(b)
values[i] = b
}

@ -56,7 +56,6 @@ func testSetIndex(a interface{}, i int) {
}
func TestLazyQueue(t *testing.T) {
rand.Seed(time.Now().UnixNano())
clock := &mclock.Simulated{}
q := NewLazyQueue(testSetIndex, testPriority, testMaxPriority, clock, testQueueRefresh)

@ -17,6 +17,7 @@
package ethash
import (
crand "crypto/rand"
"encoding/binary"
"encoding/json"
"math/big"
@ -90,16 +91,15 @@ func TestCalcDifficulty(t *testing.T) {
func randSlice(min, max uint32) []byte {
var b = make([]byte, 4)
rand.Read(b)
crand.Read(b)
a := binary.LittleEndian.Uint32(b)
size := min + a%(max-min)
out := make([]byte, size)
rand.Read(out)
crand.Read(out)
return out
}
func TestDifficultyCalculators(t *testing.T) {
rand.Seed(2)
for i := 0; i < 5000; i++ {
// 1 to 300 seconds diff
var timeDelta = uint64(1 + rand.Uint32()%3000)

@ -18,6 +18,7 @@ package bloombits
import (
"bytes"
crand "crypto/rand"
"math/rand"
"testing"
@ -78,7 +79,7 @@ func BenchmarkGenerator(b *testing.B) {
}
})
for i := 0; i < types.BloomBitLength; i++ {
rand.Read(input[i][:])
crand.Read(input[i][:])
}
b.Run("random", func(b *testing.B) {
b.ReportAllocs()

@ -27,17 +27,12 @@ import (
"sync/atomic"
"testing"
"testing/quick"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/metrics"
"github.com/stretchr/testify/require"
)
func init() {
rand.Seed(time.Now().Unix())
}
// TestFreezerBasics test initializing a freezertable from scratch, writing to the table,
// and reading it back.
func TestFreezerBasics(t *testing.T) {

@ -18,6 +18,7 @@ package snapshot
import (
"bytes"
crand "crypto/rand"
"math/rand"
"testing"
@ -73,7 +74,7 @@ func TestMergeBasics(t *testing.T) {
if rand.Intn(2) == 0 {
accStorage := make(map[common.Hash][]byte)
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[h] = accStorage
}
@ -294,7 +295,7 @@ func BenchmarkSearchSlot(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 5; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[accountKey] = accStorage
}
@ -330,7 +331,7 @@ func BenchmarkFlatten(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 20; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
}
storage[accountKey] = accStorage
@ -379,7 +380,7 @@ func BenchmarkJournal(b *testing.B) {
accStorage := make(map[common.Hash][]byte)
for i := 0; i < 200; i++ {
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
}
storage[accountKey] = accStorage

@ -18,6 +18,7 @@ package snapshot
import (
"bytes"
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/rand"
@ -47,7 +48,7 @@ func TestAccountIteratorBasics(t *testing.T) {
if rand.Intn(2) == 0 {
accStorage := make(map[common.Hash][]byte)
value := make([]byte, 32)
rand.Read(value)
crand.Read(value)
accStorage[randomHash()] = value
storage[h] = accStorage
}
@ -79,7 +80,7 @@ func TestStorageIteratorBasics(t *testing.T) {
var nilstorage int
for i := 0; i < 100; i++ {
rand.Read(value)
crand.Read(value)
if rand.Intn(2) == 0 {
accStorage[randomHash()] = common.CopyBytes(value)
} else {

@ -17,6 +17,7 @@
package snapshot
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/big"
@ -33,7 +34,7 @@ import (
// randomHash generates a random blob of data and returns it as a hash.
func randomHash() common.Hash {
var hash common.Hash
if n, err := rand.Read(hash[:]); n != common.HashLength || err != nil {
if n, err := crand.Read(hash[:]); n != common.HashLength || err != nil {
panic(err)
}
return hash

@ -18,6 +18,7 @@ package txpool
import (
"crypto/ecdsa"
crand "crypto/rand"
"errors"
"fmt"
"math/big"
@ -92,7 +93,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction {
data := make([]byte, bytes)
rand.Read(data)
crand.Read(data)
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
return tx

@ -20,10 +20,9 @@
package signify
import (
"math/rand"
"crypto/rand"
"os"
"testing"
"time"
"github.com/jedisct1/go-minisign"
)
@ -41,8 +40,6 @@ func TestSignify(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@ -85,8 +82,6 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@ -110,8 +105,6 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)
@ -135,8 +128,6 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) {
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
rand.Seed(time.Now().UnixNano())
data := make([]byte, 1024)
rand.Read(data)
tmpFile.Write(data)

@ -18,7 +18,7 @@ package dbtest
import (
"bytes"
"math/rand"
"crypto/rand"
"reflect"
"sort"
"testing"

@ -100,7 +100,6 @@ func TestSubscribeDuplicateType(t *testing.T) {
}
func TestMuxConcurrent(t *testing.T) {
rand.Seed(time.Now().Unix())
mux := new(TypeMux)
defer mux.Stop()

@ -18,6 +18,7 @@ package les
import (
"context"
crand "crypto/rand"
"errors"
"flag"
"math/rand"
@ -326,7 +327,7 @@ func getHead(ctx context.Context, t *testing.T, client *rpc.Client) (uint64, com
func testRequest(ctx context.Context, t *testing.T, client *rpc.Client) bool {
var res string
var addr common.Address
rand.Read(addr[:])
crand.Read(addr[:])
c, cancel := context.WithTimeout(ctx, time.Second*12)
defer cancel()
err := client.CallContext(c, &res, "eth_getBalance", addr, "latest")

@ -17,6 +17,7 @@
package les
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/big"
@ -114,7 +115,7 @@ func (b *benchmarkProofsOrCode) init(h *serverHandler, count int) error {
func (b *benchmarkProofsOrCode) request(peer *serverPeer, index int) error {
key := make([]byte, 32)
rand.Read(key)
crand.Read(key)
if b.code {
return peer.requestCode(0, []CodeReq{{BHash: b.headHash, AccKey: key}})
}
@ -176,7 +177,7 @@ func (b *benchmarkTxSend) init(h *serverHandler, count int) error {
for i := range b.txs {
data := make([]byte, txSizeCostLimit)
rand.Read(data)
crand.Read(data)
tx, err := types.SignTx(types.NewTransaction(0, addr, new(big.Int), 0, new(big.Int), data), signer, key)
if err != nil {
panic(err)
@ -200,7 +201,7 @@ func (b *benchmarkTxStatus) init(h *serverHandler, count int) error {
func (b *benchmarkTxStatus) request(peer *serverPeer, index int) error {
var hash common.Hash
rand.Read(hash[:])
crand.Read(hash[:])
return peer.requestTxStatus(0, []common.Hash{hash})
}
@ -278,7 +279,7 @@ func (h *serverHandler) measure(setup *benchmarkSetup, count int) error {
clientMeteredPipe := &meteredPipe{rw: clientPipe}
serverMeteredPipe := &meteredPipe{rw: serverPipe}
var id enode.ID
rand.Read(id[:])
crand.Read(id[:])
peer1 := newServerPeer(lpv2, NetworkId, false, p2p.NewPeer(id, "client", nil), clientMeteredPipe)
peer2 := newClientPeer(lpv2, NetworkId, p2p.NewPeer(id, "server", nil), serverMeteredPipe)

@ -17,7 +17,7 @@
package utils
import (
"math/rand"
"crypto/rand"
"testing"
"github.com/ethereum/go-ethereum/p2p/enode"

@ -17,7 +17,7 @@
package client
import (
"math/rand"
"crypto/rand"
"testing"
"time"

@ -135,7 +135,6 @@ func alwaysTrueFn() bool {
}
func testClientPool(t *testing.T, activeLimit, clientCount, paidCount int, randomDisconnect bool) {
rand.Seed(time.Now().UnixNano())
var (
clock mclock.Simulated
db = rawdb.NewMemoryDatabase()

@ -41,6 +41,7 @@ type ExpDecaySample struct {
reservoirSize int
t0, t1 time.Time
values *expDecaySampleHeap
rand *rand.Rand
}
// NewExpDecaySample constructs a new exponentially-decaying sample with the
@ -59,6 +60,12 @@ func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
return s
}
// SetRand sets the random source (useful in tests)
func (s *ExpDecaySample) SetRand(prng *rand.Rand) Sample {
s.rand = prng
return s
}
// Clear clears all samples.
func (s *ExpDecaySample) Clear() {
s.mutex.Lock()
@ -168,8 +175,14 @@ func (s *ExpDecaySample) update(t time.Time, v int64) {
if s.values.Size() == s.reservoirSize {
s.values.Pop()
}
var f64 float64
if s.rand != nil {
f64 = s.rand.Float64()
} else {
f64 = rand.Float64()
}
s.values.Push(expDecaySample{
k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / f64,
v: v,
})
if t.After(s.t1) {
@ -402,6 +415,7 @@ type UniformSample struct {
mutex sync.Mutex
reservoirSize int
values []int64
rand *rand.Rand
}
// NewUniformSample constructs a new uniform sample with the given reservoir
@ -416,6 +430,12 @@ func NewUniformSample(reservoirSize int) Sample {
}
}
// SetRand sets the random source (useful in tests)
func (s *UniformSample) SetRand(prng *rand.Rand) Sample {
s.rand = prng
return s
}
// Clear clears all samples.
func (s *UniformSample) Clear() {
s.mutex.Lock()
@ -511,7 +531,12 @@ func (s *UniformSample) Update(v int64) {
if len(s.values) < s.reservoirSize {
s.values = append(s.values, v)
} else {
r := rand.Int63n(s.count)
var r int64
if s.rand != nil {
r = s.rand.Int63n(s.count)
} else {
r = rand.Int63n(s.count)
}
if r < int64(len(s.values)) {
s.values[int(r)] = v
}

@ -80,7 +80,6 @@ func BenchmarkUniformSample1028(b *testing.B) {
}
func TestExpDecaySample10(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 10; i++ {
s.Update(int64(i))
@ -102,7 +101,6 @@ func TestExpDecaySample10(t *testing.T) {
}
func TestExpDecaySample100(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(1000, 0.01)
for i := 0; i < 100; i++ {
s.Update(int64(i))
@ -124,7 +122,6 @@ func TestExpDecaySample100(t *testing.T) {
}
func TestExpDecaySample1000(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 1000; i++ {
s.Update(int64(i))
@ -150,7 +147,6 @@ func TestExpDecaySample1000(t *testing.T) {
// The priority becomes +Inf quickly after starting if this is done,
// effectively freezing the set of samples until a rescale step happens.
func TestExpDecaySampleNanosecondRegression(t *testing.T) {
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
for i := 0; i < 100; i++ {
s.Update(10)
@ -183,8 +179,7 @@ func TestExpDecaySampleRescale(t *testing.T) {
func TestExpDecaySampleSnapshot(t *testing.T) {
now := time.Now()
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
}
@ -195,8 +190,7 @@ func TestExpDecaySampleSnapshot(t *testing.T) {
func TestExpDecaySampleStatistics(t *testing.T) {
now := time.Now()
rand.Seed(1)
s := NewExpDecaySample(100, 0.99)
s := NewExpDecaySample(100, 0.99).(*ExpDecaySample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
}
@ -204,7 +198,6 @@ func TestExpDecaySampleStatistics(t *testing.T) {
}
func TestUniformSample(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
for i := 0; i < 1000; i++ {
s.Update(int64(i))
@ -226,7 +219,6 @@ func TestUniformSample(t *testing.T) {
}
func TestUniformSampleIncludesTail(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
max := 100
for i := 0; i < max; i++ {
@ -244,7 +236,7 @@ func TestUniformSampleIncludesTail(t *testing.T) {
}
func TestUniformSampleSnapshot(t *testing.T) {
s := NewUniformSample(100)
s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.Update(int64(i))
}
@ -254,8 +246,7 @@ func TestUniformSampleSnapshot(t *testing.T) {
}
func TestUniformSampleStatistics(t *testing.T) {
rand.Seed(1)
s := NewUniformSample(100)
s := NewUniformSample(100).(*UniformSample).SetRand(rand.New(rand.NewSource(1)))
for i := 1; i <= 10000; i++ {
s.Update(int64(i))
}

@ -19,6 +19,7 @@ package main
import (
"crypto/ecdsa"
crand "crypto/rand"
"math/big"
"math/rand"
"os"
@ -162,7 +163,7 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
// Feecap and feetip are limited to 32 bytes. Offer a sightly
// larger buffer for creating both valid and invalid transactions.
var buf = make([]byte, 32+5)
rand.Read(buf)
crand.Read(buf)
gasTipCap := new(big.Int).SetBytes(buf)
// If the given base fee is nil(the 1559 is still not available),
@ -173,7 +174,7 @@ func makeTransaction(nonce uint64, privKey *ecdsa.PrivateKey, signer types.Signe
// Generate the feecap, 75% valid feecap and 25% unguaranteed.
var gasFeeCap *big.Int
if rand.Intn(4) == 0 {
rand.Read(buf)
crand.Read(buf)
gasFeeCap = new(big.Int).SetBytes(buf)
} else {
gasFeeCap = new(big.Int).Add(baseFee, gasTipCap)

@ -17,9 +17,9 @@
package miner
import (
"crypto/rand"
"errors"
"math/big"
"math/rand"
"sync/atomic"
"testing"
"time"
@ -105,8 +105,6 @@ func init() {
GasPrice: big.NewInt(params.InitialBaseFee),
})
newTxs = append(newTxs, tx2)
rand.Seed(time.Now().UnixNano())
}
// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.

@ -165,7 +165,6 @@ func TestUDPv4_responseTimeouts(t *testing.T) {
test := newUDPTest(t)
defer test.close()
rand.Seed(time.Now().UnixNano())
randomDuration := func(max time.Duration) time.Duration {
return time.Duration(rand.Int63n(int64(max)))
}

@ -17,7 +17,7 @@
package enode
import (
"math/rand"
"crypto/rand"
"net"
"testing"

@ -17,8 +17,8 @@
package netutil
import (
crand "crypto/rand"
"fmt"
mrand "math/rand"
"testing"
"time"
@ -123,8 +123,8 @@ func TestIPTrackerForceGC(t *testing.T) {
for i := 0; i < 5*max; i++ {
e1 := make([]byte, 4)
e2 := make([]byte, 4)
mrand.Read(e1)
mrand.Read(e2)
crand.Read(e1)
crand.Read(e2)
it.AddStatement(string(e1), string(e2))
it.AddContact(string(e1))
clock.Run(rate)

@ -18,6 +18,7 @@ package trie
import (
"bytes"
crand "crypto/rand"
"encoding/hex"
"math/rand"
"testing"
@ -97,7 +98,7 @@ func TestHexToCompactInPlaceRandom(t *testing.T) {
for i := 0; i < 10000; i++ {
l := rand.Intn(128)
key := make([]byte, l)
rand.Read(key)
crand.Read(key)
hexBytes := keybytesToHex(key)
hexOrig := []byte(string(hexBytes))
exp := hexToCompact(hexBytes)

@ -23,7 +23,6 @@ import (
mrand "math/rand"
"sort"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
@ -31,10 +30,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb/memorydb"
)
func init() {
mrand.Seed(time.Now().Unix())
}
// makeProvers creates Merkle trie provers based on different implementations to
// test all variations.
func makeProvers(trie *Trie) []func(key []byte) *memorydb.Database {

@ -18,6 +18,7 @@ package trie
import (
"bytes"
crand "crypto/rand"
"encoding/binary"
"errors"
"fmt"
@ -1127,8 +1128,8 @@ func TestDecodeNode(t *testing.T) {
elems = make([]byte, 20)
)
for i := 0; i < 5000000; i++ {
rand.Read(hash)
rand.Read(elems)
crand.Read(hash)
crand.Read(elems)
decodeNode(hash, elems)
}
}