Browse Source

standardize PRNG access (#1411)

* replace math/rand with tmlibs equivalent.

* update tmlibs dependency
pull/1451/head
Thomas Corbière 7 years ago
committed by Anton Kaliaev
parent
commit
ab00bf7c8b
7 changed files with 18 additions and 24 deletions
  1. +1
    -2
      consensus/wal_generator.go
  2. +4
    -3
      p2p/fuzz.go
  3. +3
    -4
      p2p/pex/addrbook.go
  4. +4
    -5
      p2p/pex/pex_reactor.go
  5. +3
    -5
      p2p/switch.go
  6. +2
    -3
      p2p/test_util.go
  7. +1
    -2
      rpc/lib/client/ws_client.go

+ 1
- 2
consensus/wal_generator.go View File

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"math/rand"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -117,7 +116,7 @@ func makePathname() string {
func randPort() int { func randPort() int {
// returns between base and base + spread // returns between base and base + spread
base, spread := 20000, 20000 base, spread := 20000, 20000
return base + rand.Intn(spread)
return base + cmn.RandIntn(spread)
} }
func makeAddrs() (string, string, string) { func makeAddrs() (string, string, string) {


+ 4
- 3
p2p/fuzz.go View File

@ -1,10 +1,11 @@
package p2p package p2p
import ( import (
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
cmn "github.com/tendermint/tmlibs/common"
) )
const ( const (
@ -124,7 +125,7 @@ func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error {
func (fc *FuzzedConnection) randomDuration() time.Duration { func (fc *FuzzedConnection) randomDuration() time.Duration {
maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000) maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000)
return time.Millisecond * time.Duration(rand.Int()%maxDelayMillis) // nolint: gas
return time.Millisecond * time.Duration(cmn.RandInt()%maxDelayMillis) // nolint: gas
} }
// implements the fuzz (delay, kill conn) // implements the fuzz (delay, kill conn)
@ -137,7 +138,7 @@ func (fc *FuzzedConnection) fuzz() bool {
switch fc.config.Mode { switch fc.config.Mode {
case FuzzModeDrop: case FuzzModeDrop:
// randomly drop the r/w, drop the conn, or sleep // randomly drop the r/w, drop the conn, or sleep
r := rand.Float64()
r := cmn.RandFloat64()
if r <= fc.config.ProbDropRW { if r <= fc.config.ProbDropRW {
return true return true
} else if r < fc.config.ProbDropRW+fc.config.ProbDropConn { } else if r < fc.config.ProbDropRW+fc.config.ProbDropConn {


+ 3
- 4
p2p/pex/addrbook.go View File

@ -9,7 +9,6 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"math" "math"
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
@ -82,7 +81,7 @@ type addrBook struct {
// accessed concurrently // accessed concurrently
mtx sync.Mutex mtx sync.Mutex
rand *rand.Rand
rand *cmn.Rand
ourAddrs map[string]struct{} ourAddrs map[string]struct{}
addrLookup map[p2p.ID]*knownAddress // new & old addrLookup map[p2p.ID]*knownAddress // new & old
bucketsOld []map[string]*knownAddress bucketsOld []map[string]*knownAddress
@ -97,7 +96,7 @@ type addrBook struct {
// Use Start to begin processing asynchronous address updates. // Use Start to begin processing asynchronous address updates.
func NewAddrBook(filePath string, routabilityStrict bool) *addrBook { func NewAddrBook(filePath string, routabilityStrict bool) *addrBook {
am := &addrBook{ am := &addrBook{
rand: rand.New(rand.NewSource(time.Now().UnixNano())), // TODO: seed from outside
rand: cmn.NewRand(),
ourAddrs: make(map[string]struct{}), ourAddrs: make(map[string]struct{}),
addrLookup: make(map[p2p.ID]*knownAddress), addrLookup: make(map[p2p.ID]*knownAddress),
filePath: filePath, filePath: filePath,
@ -320,7 +319,7 @@ func (a *addrBook) GetSelection() []*p2p.NetAddress {
// XXX: What's the point of this if we already loop randomly through addrLookup ? // XXX: What's the point of this if we already loop randomly through addrLookup ?
for i := 0; i < numAddresses; i++ { for i := 0; i < numAddresses; i++ {
// pick a number between current index and the end // pick a number between current index and the end
j := rand.Intn(len(allAddr)-i) + i
j := cmn.RandIntn(len(allAddr)-i) + i
allAddr[i], allAddr[j] = allAddr[j], allAddr[i] allAddr[i], allAddr[j] = allAddr[j], allAddr[i]
} }


+ 4
- 5
p2p/pex/pex_reactor.go View File

@ -2,7 +2,6 @@ package pex
import ( import (
"fmt" "fmt"
"math/rand"
"reflect" "reflect"
"sort" "sort"
"sync" "sync"
@ -288,7 +287,7 @@ func (r *PEXReactor) SetEnsurePeersPeriod(d time.Duration) {
// Ensures that sufficient peers are connected. (continuous) // Ensures that sufficient peers are connected. (continuous)
func (r *PEXReactor) ensurePeersRoutine() { func (r *PEXReactor) ensurePeersRoutine() {
var ( var (
seed = rand.New(rand.NewSource(time.Now().UnixNano()))
seed = cmn.NewRand()
jitter = seed.Int63n(r.ensurePeersPeriod.Nanoseconds()) jitter = seed.Int63n(r.ensurePeersPeriod.Nanoseconds())
) )
@ -375,7 +374,7 @@ func (r *PEXReactor) ensurePeers() {
peers := r.Switch.Peers().List() peers := r.Switch.Peers().List()
peersCount := len(peers) peersCount := len(peers)
if peersCount > 0 { if peersCount > 0 {
peer := peers[rand.Int()%peersCount] // nolint: gas
peer := peers[cmn.RandInt()%peersCount] // nolint: gas
r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer) r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer)
r.RequestAddrs(peer) r.RequestAddrs(peer)
} }
@ -404,7 +403,7 @@ func (r *PEXReactor) dialPeer(addr *p2p.NetAddress) {
// exponential backoff if it's not our first attempt to dial given address // exponential backoff if it's not our first attempt to dial given address
if attempts > 0 { if attempts > 0 {
jitterSeconds := time.Duration(rand.Float64() * float64(time.Second)) // 1s == (1e9 ns)
jitterSeconds := time.Duration(cmn.RandFloat64() * float64(time.Second)) // 1s == (1e9 ns)
backoffDuration := jitterSeconds + ((1 << uint(attempts)) * time.Second) backoffDuration := jitterSeconds + ((1 << uint(attempts)) * time.Second)
sinceLastDialed := time.Since(lastDialed) sinceLastDialed := time.Since(lastDialed)
if sinceLastDialed < backoffDuration { if sinceLastDialed < backoffDuration {
@ -457,7 +456,7 @@ func (r *PEXReactor) dialSeeds() {
} }
seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds) seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds)
perm := rand.Perm(lSeeds)
perm := cmn.RandPerm(lSeeds)
// perm := r.Switch.rng.Perm(lSeeds) // perm := r.Switch.rng.Perm(lSeeds)
for _, i := range perm { for _, i := range perm {
// dial a random seed // dial a random seed


+ 3
- 5
p2p/switch.go View File

@ -3,7 +3,6 @@ package p2p
import ( import (
"fmt" "fmt"
"math" "math"
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
@ -67,7 +66,7 @@ type Switch struct {
filterConnByAddr func(net.Addr) error filterConnByAddr func(net.Addr) error
filterConnByID func(ID) error filterConnByID func(ID) error
rng *rand.Rand // seed for randomizing dial times and orders
rng *cmn.Rand // seed for randomizing dial times and orders
} }
// NewSwitch creates a new Switch with the given config. // NewSwitch creates a new Switch with the given config.
@ -82,9 +81,8 @@ func NewSwitch(config *cfg.P2PConfig) *Switch {
dialing: cmn.NewCMap(), dialing: cmn.NewCMap(),
} }
// Ensure we have a completely undeterministic PRNG. cmd.RandInt64() draws
// from a seed that's initialized with OS entropy on process start.
sw.rng = rand.New(rand.NewSource(cmn.RandInt64()))
// Ensure we have a completely undeterministic PRNG.
sw.rng = cmn.NewRand()
// TODO: collapse the peerConfig into the config ? // TODO: collapse the peerConfig into the config ?
sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond


+ 2
- 3
p2p/test_util.go View File

@ -1,7 +1,6 @@
package p2p package p2p
import ( import (
"math/rand"
"net" "net"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
@ -35,7 +34,7 @@ func CreateRandomPeer(outbound bool) *peer {
func CreateRoutableAddr() (addr string, netAddr *NetAddress) { func CreateRoutableAddr() (addr string, netAddr *NetAddress) {
for { for {
var err error var err error
addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256)
addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256)
netAddr, err = NewNetAddressString(addr) netAddr, err = NewNetAddressString(addr)
if err != nil { if err != nil {
panic(err) panic(err)
@ -141,7 +140,7 @@ func MakeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch f
Moniker: cmn.Fmt("switch%d", i), Moniker: cmn.Fmt("switch%d", i),
Network: network, Network: network,
Version: version, Version: version,
ListenAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023),
ListenAddr: cmn.Fmt("%v:%v", network, cmn.RandIntn(64512)+1023),
} }
for ch := range sw.reactorsByCh { for ch := range sw.reactorsByCh {
ni.Channels = append(ni.Channels, ch) ni.Channels = append(ni.Channels, ch)


+ 1
- 2
rpc/lib/client/ws_client.go View File

@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@ -266,7 +265,7 @@ func (c *WSClient) reconnect() error {
}() }()
for { for {
jitterSeconds := time.Duration(rand.Float64() * float64(time.Second)) // 1s == (1e9 ns)
jitterSeconds := time.Duration(cmn.RandFloat64() * float64(time.Second)) // 1s == (1e9 ns)
backoffDuration := jitterSeconds + ((1 << uint(attempt)) * time.Second) backoffDuration := jitterSeconds + ((1 << uint(attempt)) * time.Second)
c.Logger.Info("reconnecting", "attempt", attempt+1, "backoff_duration", backoffDuration) c.Logger.Info("reconnecting", "attempt", attempt+1, "backoff_duration", backoffDuration)


Loading…
Cancel
Save