diff --git a/cmd/common/cli_test.go b/cmd/common/cli_test.go index 62923c33d56..329f880ace8 100644 --- a/cmd/common/cli_test.go +++ b/cmd/common/cli_test.go @@ -9,7 +9,7 @@ package common import ( "bytes" "fmt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "testing" diff --git a/cmd/common/config_test.go b/cmd/common/config_test.go index 6787c35d122..74795a915c3 100644 --- a/cmd/common/config_test.go +++ b/cmd/common/config_test.go @@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 package common import ( + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "testing" @@ -20,7 +21,9 @@ import ( ) func TestConfig(t *testing.T) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) configFilePath := filepath.Join(os.TempDir(), fmt.Sprintf("config-%d.yaml", r.Int())) fmt.Println(configFilePath) t.Run("save and load a config", func(t *testing.T) { diff --git a/common/configtx/util_test.go b/common/configtx/util_test.go index 1cdc644385e..fac8bd9d497 100644 --- a/common/configtx/util_test.go +++ b/common/configtx/util_test.go @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package configtx import ( - "math/rand" + "math/rand/v2" "testing" cb "github.com/hyperledger/fabric-protos-go-apiv2/common" @@ -101,7 +101,7 @@ func randomLowerAlphaString(size int) string { letters := []rune("abcdefghijklmnopqrstuvwxyz") output := make([]rune, size) for i := range output { - output[i] = letters[rand.Intn(len(letters))] + output[i] = letters[rand.IntN(len(letters))] } return string(output) } @@ -110,7 +110,7 @@ func randomAlphaString(size int) string { letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") output := make([]rune, size) for i := range output { - output[i] = letters[rand.Intn(len(letters))] + output[i] = letters[rand.IntN(len(letters))] } return string(output) } diff --git a/common/deliverclient/orderers/connection.go b/common/deliverclient/orderers/connection.go index 45f37431680..d319c70ef6c 100644 --- a/common/deliverclient/orderers/connection.go +++ b/common/deliverclient/orderers/connection.go @@ -11,7 +11,7 @@ import ( "crypto/md5" "crypto/sha256" "fmt" - "math/rand" + "math/rand/v2" "sync" "github.com/hyperledger/fabric-lib-go/common/flogging" @@ -73,7 +73,7 @@ func (cs *ConnectionSource) RandomEndpoint() (*Endpoint, error) { if len(cs.allEndpoints) == 0 { return nil, errors.Errorf("no endpoints currently defined") } - return cs.allEndpoints[rand.Intn(len(cs.allEndpoints))], nil + return cs.allEndpoints[rand.IntN(len(cs.allEndpoints))], nil } func (cs *ConnectionSource) Endpoints() []*Endpoint { diff --git a/common/graph/perm.go b/common/graph/perm.go index 1cc35fd59cd..341c8018a59 100644 --- a/common/graph/perm.go +++ b/common/graph/perm.go @@ -7,14 +7,16 @@ SPDX-License-Identifier: Apache-2.0 package graph import ( - "math/rand" - "time" + crand "crypto/rand" + "math/rand/v2" ) var r *rand.Rand func init() { - r = rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) } // treePermutations represents possible permutations @@ -112,7 +114,7 @@ func (tp *treePermutations) computeDescendantPermutations() { // Ensure we don't have too much combinations of descendants for CombinationsExceed(len(v.Descendants), v.Threshold, tp.combinationUpperBound) { // Randomly pick a descendant, and remove it - victim := r.Intn(len(v.Descendants)) + victim := r.IntN(len(v.Descendants)) v.Descendants = append(v.Descendants[:victim], v.Descendants[victim+1:]...) } diff --git a/core/common/validation/fullflow_test.go b/core/common/validation/fullflow_test.go index 6a28d38e66b..29ad2aa07b6 100644 --- a/core/common/validation/fullflow_test.go +++ b/core/common/validation/fullflow_test.go @@ -7,11 +7,11 @@ SPDX-License-Identifier: Apache-2.0 package validation import ( + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "os" "testing" - "time" "github.com/hyperledger/fabric-lib-go/bccsp/sw" "github.com/hyperledger/fabric-protos-go-apiv2/common" @@ -206,8 +206,10 @@ func TestTXWithTwoActionsRejected(t *testing.T) { } func corrupt(bytes []byte) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - bytes[r.Intn(len(bytes))]-- + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) + bytes[r.IntN(len(bytes))]-- } func TestBadTx(t *testing.T) { diff --git a/core/common/validation/statebased/vpmanager_test.go b/core/common/validation/statebased/vpmanager_test.go index 0247467c577..589e34aa01a 100644 --- a/core/common/validation/statebased/vpmanager_test.go +++ b/core/common/validation/statebased/vpmanager_test.go @@ -7,13 +7,13 @@ SPDX-License-Identifier: Apache-2.0 package statebased import ( + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "runtime" "strconv" "sync" "testing" - "time" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset/kvrwset" @@ -169,8 +169,8 @@ func pvtRwsetUpdatingMetadataFor(cc, coll, key string) []byte { }) } -func runFunctions(t *testing.T, seed int64, funcs ...func()) { - r := rand.New(rand.NewSource(seed)) +func runFunctions(t *testing.T, seed [32]byte, funcs ...func()) { + r := rand.New(rand.NewChaCha8(seed)) c := make(chan struct{}) for _, i := range r.Perm(len(funcs)) { iLcl := i @@ -186,7 +186,8 @@ func runFunctions(t *testing.T, seed int64, funcs ...func()) { func TestTranslatorBadPolicy(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: we verify that translation from SignaturePolicyEnvelope to ApplicationPolicy fails appropriately @@ -226,7 +227,8 @@ func TestTranslatorBadPolicy(t *testing.T) { func TestTranslatorBadPolicyPvt(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: we verify that translation from SignaturePolicyEnvelope to ApplicationPolicy fails appropriately with private data @@ -266,7 +268,8 @@ func TestTranslatorBadPolicyPvt(t *testing.T) { func TestDependencyNoConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: validation parameter is retrieved successfully // for a ledger key for transaction (1,1) after waiting for @@ -309,7 +312,8 @@ func TestDependencyNoConflict(t *testing.T) { func TestDependencyConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: validation parameter is retrieved // for a ledger key for transaction (1,1) after waiting for @@ -353,7 +357,8 @@ func TestDependencyConflict(t *testing.T) { func TestMultipleDependencyNoConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: validation parameter is retrieved successfully // for a ledger key for transaction (1,2) after waiting for @@ -402,7 +407,8 @@ func TestMultipleDependencyNoConflict(t *testing.T) { func TestMultipleDependencyConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: validation parameter is retrieved // for a ledger key for transaction (1,2) after waiting for @@ -452,7 +458,8 @@ func TestMultipleDependencyConflict(t *testing.T) { func TestPvtDependencyNoConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: like TestDependencyNoConflict but for private data @@ -490,7 +497,8 @@ func TestPvtDependencyNoConflict(t *testing.T) { func TestPvtDependencyConflict(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: like TestDependencyConflict but for private data @@ -553,7 +561,8 @@ func TestBlockValidationTerminatesBeforeNewBlock(t *testing.T) { func TestLedgerErrors(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: we check that if a ledger error occurs, // GetValidationParameterForKey returns an error @@ -625,7 +634,8 @@ func TestLedgerErrors(t *testing.T) { func TestBadRwsetIsNoDependency(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: a transaction has a bogus read-write set. // While the transaction will fail eventually, we check @@ -663,7 +673,8 @@ func TestBadRwsetIsNoDependency(t *testing.T) { func TestWritesIntoDifferentNamespaces(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: transaction (1,0) writes to namespace cc1. // Transaction (1,1) attempts to retrieve validation @@ -701,7 +712,8 @@ func TestWritesIntoDifferentNamespaces(t *testing.T) { func TestCombinedCalls(t *testing.T) { t.Parallel() - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // Scenario: transaction (1,3) requests validation parameters // for different keys - one succeeds and one fails. @@ -760,7 +772,8 @@ func TestCombinedCalls(t *testing.T) { } func TestForRaces(t *testing.T) { - seed := time.Now().Unix() + var seed [32]byte + _, _ = crand.Read(seed[:]) // scenario to stress test the parallel validation // this is an extended combined test diff --git a/core/ledger/kvledger/benchmark/experiments/readwrite_txs_test.go b/core/ledger/kvledger/benchmark/experiments/readwrite_txs_test.go index f9bb011367f..538ca57b0e2 100644 --- a/core/ledger/kvledger/benchmark/experiments/readwrite_txs_test.go +++ b/core/ledger/kvledger/benchmark/experiments/readwrite_txs_test.go @@ -7,11 +7,11 @@ SPDX-License-Identifier: Apache-2.0 package experiments import ( + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "sync" "testing" - "time" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/ledger/kvledger/benchmark/chainmgmt" @@ -51,7 +51,9 @@ func runReadWriteClientsForChain(chain *chainmgmt.Chain) { wg.Add(numClients) for i := 0; i < numClients; i++ { numTxForClient := calculateShare(numTxForChain, numClients, i) - randomNumGen := rand.New(rand.NewSource(int64(time.Now().Nanosecond()) + int64(chain.ID))) + var seed [32]byte + _, _ = crand.Read(seed[:]) + randomNumGen := rand.New(rand.NewChaCha8(seed)) go runReadWriteClient(chain, randomNumGen, numTxForClient, wg) } wg.Wait() @@ -66,16 +68,16 @@ func runReadWriteClient(chain *chainmgmt.Chain, rand *rand.Rand, numTx int, wg * useJSON := conf.dataConf.useJSON var value []byte - for i := 0; i < numTx; i++ { + for range numTx { simulator, err := chain.NewTxSimulator(util.GenerateUUID()) panicOnError(err) maxKeys := max(numReadsPerTx, numWritesPerTx) keysToOperateOn := []int{} - for i := 0; i < maxKeys; i++ { - keysToOperateOn = append(keysToOperateOn, rand.Intn(maxKeyNumber)) + for range maxKeys { + keysToOperateOn = append(keysToOperateOn, rand.IntN(maxKeyNumber)) } - for i := 0; i < numReadsPerTx; i++ { + for i := range numReadsPerTx { keyNumber := keysToOperateOn[i] value, err = simulator.GetState(chaincodeName, constructKey(keyNumber)) panicOnError(err) @@ -90,7 +92,7 @@ func runReadWriteClient(chain *chainmgmt.Chain, rand *rand.Rand, numTx int, wg * } } - for i := 0; i < numWritesPerTx; i++ { + for i := range numWritesPerTx { keyNumber := keysToOperateOn[i] key := constructKey(keyNumber) if useJSON { @@ -109,10 +111,3 @@ func runReadWriteClient(chain *chainmgmt.Chain, rand *rand.Rand, numTx int, wg * } wg.Done() } - -func max(a, b int) int { - if a > b { - return a - } - return b -} diff --git a/core/ledger/kvledger/benchmark/experiments/util.go b/core/ledger/kvledger/benchmark/experiments/util.go index 218f30d6b7b..b51ba841b4c 100644 --- a/core/ledger/kvledger/benchmark/experiments/util.go +++ b/core/ledger/kvledger/benchmark/experiments/util.go @@ -8,10 +8,10 @@ package experiments import ( "bytes" - crypto "crypto/rand" + crand "crypto/rand" "encoding/json" "fmt" - "math/rand" + "math/rand/v2" "strconv" ) @@ -64,10 +64,13 @@ func constructValue(keyNumber int, kvSize int) []byte { func constructJSONValue(keyNumber int, kvSize int) []byte { prefix := constructValuePrefix(keyNumber) - r := rand.New(rand.NewSource(int64(keyNumber))) - color := colors[r.Intn(len(colors))] - size := r.Intn(len(colors))*10 + 10 - owner := owners[r.Intn(len(owners))] + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) + + color := colors[r.IntN(len(colors))] + size := r.IntN(len(colors))*10 + 10 + owner := owners[r.IntN(len(owners))] assetName := "marble" + strconv.Itoa(keyNumber) testRecord := marbleRecord{Prefix: string(prefix), AssetType: "marble", AssetName: assetName, Color: color, Size: size, Owner: owner} @@ -127,7 +130,7 @@ func calculateShare(total int, numParts int, partNum int) int { func constructRandomBytes(length int) []byte { b := make([]byte, length) - crypto.Read(b) + crand.Read(b) return b } diff --git a/core/peer/peer_test.go b/core/peer/peer_test.go index c01a45b20c1..c646026c823 100644 --- a/core/peer/peer_test.go +++ b/core/peer/peer_test.go @@ -8,19 +8,18 @@ package peer import ( "fmt" - "math/rand" + "math/rand/v2" "os" "path/filepath" "runtime" "testing" "time" - "github.com/hyperledger/fabric/common/channelconfig" - "github.com/hyperledger/fabric-lib-go/bccsp/sw" "github.com/hyperledger/fabric-lib-go/common/metrics/disabled" "github.com/hyperledger/fabric-protos-go-apiv2/common" pb "github.com/hyperledger/fabric-protos-go-apiv2/peer" + "github.com/hyperledger/fabric/common/channelconfig" configtxtest "github.com/hyperledger/fabric/common/configtx/test" "github.com/hyperledger/fabric/common/crypto/tlsgen" "github.com/hyperledger/fabric/core/committer/txvalidator/plugin" diff --git a/core/tx/endorser/endorsertx_suite_test.go b/core/tx/endorser/endorsertx_suite_test.go index 1b80c798f6a..dad85b4ad12 100644 --- a/core/tx/endorser/endorsertx_suite_test.go +++ b/core/tx/endorser/endorsertx_suite_test.go @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package endorsertx_test import ( - "math/rand" + "math/rand/v2" "testing" "github.com/hyperledger/fabric-protos-go-apiv2/common" @@ -22,7 +22,7 @@ func randomLowerAlphaString(size int) string { letters := []rune("abcdefghijklmnopqrstuvwxyz") output := make([]rune, size) for i := range output { - output[i] = letters[rand.Intn(len(letters))] + output[i] = letters[rand.IntN(len(letters))] } return string(output) } diff --git a/discovery/client/client.go b/discovery/client/client.go index 182dcf652b3..db787484430 100644 --- a/discovery/client/client.go +++ b/discovery/client/client.go @@ -8,10 +8,10 @@ package discovery import ( "context" + crand "crypto/rand" "encoding/json" "fmt" - "math/rand" - "time" + "math/rand/v2" "github.com/hyperledger/fabric-protos-go-apiv2/discovery" "github.com/hyperledger/fabric-protos-go-apiv2/msp" @@ -266,7 +266,9 @@ func (cr *channelResponse) Endorsers(invocationChain InvocationChain, f Filter) } desc := res.(*endorsementDescriptor) - r := rand.New(rand.NewSource(time.Now().Unix())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) // We iterate over all layouts to find one that we have enough peers to select for _, index := range r.Perm(len(desc.layouts)) { layout := desc.layouts[index] diff --git a/discovery/client/selection.go b/discovery/client/selection.go index 126c8bc1df3..f90ad56d801 100644 --- a/discovery/client/selection.go +++ b/discovery/client/selection.go @@ -7,9 +7,9 @@ SPDX-License-Identifier: Apache-2.0 package discovery import ( - "math/rand" + crand "crypto/rand" + "math/rand/v2" "sort" - "time" "github.com/hyperledger/fabric/gossip/protoext" ) @@ -120,7 +120,9 @@ func (endorsers Endorsers) Filter(f ExclusionFilter) Endorsers { // Shuffle sorts the endorsers in random order func (endorsers Endorsers) Shuffle() Endorsers { res := make(Endorsers, len(endorsers)) - r := rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) for i, index := range r.Perm(len(endorsers)) { res[i] = endorsers[index] } diff --git a/gossip/comm/comm_test.go b/gossip/comm/comm_test.go index 46d6b6fd01f..740a82bd33e 100644 --- a/gossip/comm/comm_test.go +++ b/gossip/comm/comm_test.go @@ -10,12 +10,13 @@ import ( "bytes" "context" "crypto/hmac" + crand "crypto/rand" "crypto/sha256" "crypto/tls" "errors" "fmt" "io" - "math/rand" + "math/rand/v2" "net" "strconv" "sync" @@ -48,7 +49,9 @@ var r *rand.Rand func init() { util.SetupTestLogging() - r = rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) factory.InitFactories(nil) naiveSec.On("OrgByPeerIdentity", mock.Anything).Return(api.OrgIdentityType{}) } diff --git a/gossip/discovery/discovery_test.go b/gossip/discovery/discovery_test.go index 6d8f4dbcdf4..3e873ec8063 100644 --- a/gossip/discovery/discovery_test.go +++ b/gossip/discovery/discovery_test.go @@ -11,7 +11,7 @@ import ( "context" "fmt" "io" - "math/rand" + "math/rand/v2" "net" "sort" "strconv" @@ -576,7 +576,7 @@ func TestConnect(t *testing.T) { } waitUntilOrFail(t, fullMembership) - discInst := instances[rand.Intn(len(instances))].Discovery.(*gossipDiscoveryImpl) + discInst := instances[rand.IntN(len(instances))].Discovery.(*gossipDiscoveryImpl) mr, _ := discInst.createMembershipRequest(true) am, _ := protoext.EnvelopeToGossipMessage(mr.GetMemReq().SelfInformation) require.NotNil(t, am.SecretEnvelope) diff --git a/gossip/filter/filter.go b/gossip/filter/filter.go index 164f91b0348..452550383d9 100644 --- a/gossip/filter/filter.go +++ b/gossip/filter/filter.go @@ -7,17 +7,19 @@ SPDX-License-Identifier: Apache-2.0 package filter import ( - "math/rand" + crand "crypto/rand" + "math/rand/v2" "github.com/hyperledger/fabric/gossip/comm" "github.com/hyperledger/fabric/gossip/discovery" - "github.com/hyperledger/fabric/gossip/util" ) var r *rand.Rand func init() { // do we really need this? - r = rand.New(rand.NewSource(int64(util.RandomUInt64()))) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) } // RoutingFilter defines a predicate on a NetworkMember diff --git a/gossip/gossip/gossip_test.go b/gossip/gossip/gossip_test.go index 2e01892ecd4..f26cd6c1d8b 100644 --- a/gossip/gossip/gossip_test.go +++ b/gossip/gossip/gossip_test.go @@ -8,9 +8,10 @@ package gossip import ( "bytes" + crand "crypto/rand" "errors" "fmt" - "math/rand" + "math/rand/v2" "os" "sync" "sync/atomic" @@ -43,7 +44,9 @@ var ( func TestMain(m *testing.M) { util.SetupTestLogging() - r = rand.New(rand.NewSource(int64(time.Now().Second()))) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) factory.InitFactories(nil) os.Exit(m.Run()) } @@ -535,7 +538,7 @@ func TestConnectToAnchorPeers(t *testing.T) { waitUntilOrFailBlocking(t, wg.Wait, "waiting until all peers join the channel") // Now start a random anchor peer - index := r.Intn(anchorPeercount) + index := r.IntN(anchorPeercount) anchorPeer := newGossipInstanceWithGRPC(index, ports[index], grpcs[index], certs[index], secDialOpts[index], 100) anchorPeer.JoinChan(jcm, common.ChannelID("A")) anchorPeer.UpdateLedgerHeight(1, common.ChannelID("A")) @@ -1443,7 +1446,7 @@ func TestIdentityExpiration(t *testing.T) { // Now revoke some peer var ports []int ports = append(ports, port1, port2, port3, port4) - revokedPeerIndex := r.Intn(4) + revokedPeerIndex := r.IntN(4) revokedPkiID := common.PKIidType(fmt.Sprintf("127.0.0.1:%d", ports[revokedPeerIndex])) for i, p := range peers { if i == revokedPeerIndex { diff --git a/gossip/gossip/msgstore/msgs_test.go b/gossip/gossip/msgstore/msgs_test.go index 368b558b0eb..1d54c5a3f39 100644 --- a/gossip/gossip/msgstore/msgs_test.go +++ b/gossip/gossip/msgstore/msgs_test.go @@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package msgstore import ( - "math/rand" + crand "crypto/rand" + "math/rand/v2" "sync" "sync/atomic" "testing" @@ -22,7 +23,9 @@ var r *rand.Rand func init() { util.SetupTestLogging() - r = rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) } func alwaysNoAction(_ interface{}, _ interface{}) common.InvalidationResult { diff --git a/gossip/privdata/distributor.go b/gossip/privdata/distributor.go index 728fcdaeacf..c027d8cfbe7 100644 --- a/gossip/privdata/distributor.go +++ b/gossip/privdata/distributor.go @@ -8,8 +8,9 @@ package privdata import ( "bytes" + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "sync" "sync/atomic" "time" @@ -256,7 +257,9 @@ func (d *distributorImpl) disseminationPlanForMsg(colAP privdata.CollectionAcces remainingPeersAcrossOrgs := []api.PeerIdentityInfo{} selectedPeerEndpointsForDebug := []string{} - r := rand.New(rand.NewSource(time.Now().Unix())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) // PHASE 1 - Select one peer from each eligible org if maximumPeerRemainingCount > 0 { @@ -269,7 +272,7 @@ func (d *distributorImpl) disseminationPlanForMsg(colAP privdata.CollectionAcces acksRequired = 0 } - selectedPeerIndex := r.Intn(len(selectionPeersForOrg)) + selectedPeerIndex := r.IntN(len(selectionPeersForOrg)) peer2SendPerOrg := selectionPeersForOrg[selectedPeerIndex] selectedPeerEndpointsForDebug = append(selectedPeerEndpointsForDebug, peerEndpoints[string(peer2SendPerOrg.PKIId)]) sc := gossipgossip.SendCriteria{ @@ -322,7 +325,7 @@ func (d *distributorImpl) disseminationPlanForMsg(colAP privdata.CollectionAcces if requiredPeerRemainingCount == 0 { required = 0 } - selectedPeerIndex := r.Intn(len(remainingPeersAcrossOrgs)) + selectedPeerIndex := r.IntN(len(remainingPeersAcrossOrgs)) peer2Send := remainingPeersAcrossOrgs[selectedPeerIndex] selectedPeerEndpointsForDebug = append(selectedPeerEndpointsForDebug, peerEndpoints[string(peer2Send.PKIId)]) sc := gossipgossip.SendCriteria{ diff --git a/gossip/privdata/pull.go b/gossip/privdata/pull.go index c7afb3c780e..31208c6198d 100644 --- a/gossip/privdata/pull.go +++ b/gossip/privdata/pull.go @@ -8,10 +8,11 @@ package privdata import ( "bytes" + crand "crypto/rand" "encoding/hex" "fmt" "math" - "math/rand" + "math/rand/v2" "sync" "time" @@ -681,7 +682,9 @@ func (p *puller) isEligibleByLatestConfig(channel string, collection string, cha } func randomizeMemberList(members []discovery.NetworkMember) []discovery.NetworkMember { - r := rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) res := make([]discovery.NetworkMember, len(members)) for i, j := range r.Perm(len(members)) { res[i] = members[j] diff --git a/gossip/state/state.go b/gossip/state/state.go index fd2c5f3d69e..70c587c9965 100644 --- a/gossip/state/state.go +++ b/gossip/state/state.go @@ -809,7 +809,3 @@ func (s *GossipStateProviderImpl) commitBlock(block *common.Block, pvtData util. return nil } - -func min(a uint64, b uint64) uint64 { - return b ^ ((a ^ b) & (-((a - b) >> 63))) -} diff --git a/gossip/state/state_test.go b/gossip/state/state_test.go index 9c1dca137ff..e2020037256 100644 --- a/gossip/state/state_test.go +++ b/gossip/state/state_test.go @@ -8,9 +8,10 @@ package state import ( "bytes" + crand "crypto/rand" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "sync" "sync/atomic" @@ -770,9 +771,11 @@ func TestBlockingEnqueue(t *testing.T) { // Get a block from gossip every 1ms too go func() { - r := rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) for i := 1; i <= numBlocksReceived/2; i++ { - blockSeq := r.Intn(numBlocksReceived) + blockSeq := r.IntN(numBlocksReceived) rawblock := protoutil.NewBlock(uint64(blockSeq), []byte{}) b, _ := pb.Marshal(rawblock) block := &proto.Payload{ diff --git a/gossip/util/misc.go b/gossip/util/misc.go index e6eef8adc29..7d9b6d1350e 100644 --- a/gossip/util/misc.go +++ b/gossip/util/misc.go @@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 package util import ( + crand "crypto/rand" "fmt" - "math/rand" + "math/rand/v2" "reflect" "runtime" "sync" @@ -20,7 +21,9 @@ import ( var r *rand.Rand func init() { // do we really need this? - r = rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + r = rand.New(rand.NewChaCha8(seed)) } // Equals returns whether a and b are the same @@ -176,7 +179,7 @@ func SetVal(key string, val interface{}) { // RandomInt returns, as an int, a non-negative pseudo-random integer in [0,n) // It panics if n <= 0 func RandomInt(n int) int { - return r.Intn(n) + return r.IntN(n) } // RandomUInt64 returns a random uint64 diff --git a/internal/pkg/gateway/registry.go b/internal/pkg/gateway/registry.go index 628ad8370a2..828a546c422 100644 --- a/internal/pkg/gateway/registry.go +++ b/internal/pkg/gateway/registry.go @@ -8,7 +8,7 @@ package gateway import ( "fmt" - "math/rand" + "math/rand/v2" "sort" "strings" "sync" diff --git a/internal/pkg/gateway/submit.go b/internal/pkg/gateway/submit.go index 5dc58607e09..d47d2145664 100644 --- a/internal/pkg/gateway/submit.go +++ b/internal/pkg/gateway/submit.go @@ -10,7 +10,7 @@ import ( "context" "fmt" "math" - "math/rand" + "math/rand/v2" "sync/atomic" "time" diff --git a/orderer/common/cluster/deliver.go b/orderer/common/cluster/deliver.go index 487231e39c6..4fbc0120ce1 100644 --- a/orderer/common/cluster/deliver.go +++ b/orderer/common/cluster/deliver.go @@ -8,9 +8,10 @@ package cluster import ( "context" + crand "crypto/rand" "crypto/x509" "math" - "math/rand" + "math/rand/v2" "reflect" "sync" "sync/atomic" @@ -388,8 +389,10 @@ func randomEndpoint(endpointsToHeight map[string]*endpointInfo) string { candidates = append(candidates, endpoint) } - r := rand.New(rand.NewSource(time.Now().UnixNano())) - return candidates[r.Intn(len(candidates))] + var seed [32]byte + _, _ = crand.Read(seed[:]) + r := rand.New(rand.NewChaCha8(seed)) + return candidates[r.IntN(len(candidates))] } // fetchLastBlockSeq returns the last block sequence of an endpoint with the given gRPC connection. diff --git a/orderer/common/cluster/util.go b/orderer/common/cluster/util.go index 2d0e1410425..bc5a229097a 100644 --- a/orderer/common/cluster/util.go +++ b/orderer/common/cluster/util.go @@ -10,6 +10,7 @@ import ( "bytes" "context" "crypto/ecdsa" + crand "crypto/rand" "crypto/sha256" "crypto/tls" "crypto/x509" @@ -18,7 +19,7 @@ import ( "encoding/json" "encoding/pem" "fmt" - "math/rand" + "math/rand/v2" "strconv" "sync" "sync/atomic" @@ -650,7 +651,9 @@ func (cm *ComparisonMemoizer) shrink() { func (cm *ComparisonMemoizer) setup() { cm.lock.Lock() defer cm.lock.Unlock() - cm.rand = rand.New(rand.NewSource(time.Now().UnixNano())) + var seed [32]byte + _, _ = crand.Read(seed[:]) + cm.rand = rand.New(rand.NewChaCha8(seed)) cm.cache = make(map[arguments]bool) }