From 031e10133c094948eb224ae9b15b43b9093e130b Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Sat, 18 Nov 2017 22:17:53 -0700 Subject: [PATCH] p2p: make Switch.DialSeeds use a new PRNG per call Fixes https://github.com/tendermint/tendermint/issues/875 Ensure that every DialSeeds call uses a new PRNG seeded from tendermint/tmlibs/common.RandInt which internally uses crypto/rand to seed its source. --- p2p/switch.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/p2p/switch.go b/p2p/switch.go index b56e84a81..dcdc9c1d6 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -295,7 +295,6 @@ func (sw *Switch) startInitPeer(peer *peer) { // DialSeeds dials a list of seeds asynchronously in random order. func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error { - netAddrs, err := NewNetAddressStrings(seeds) if err != nil { return err @@ -315,11 +314,15 @@ func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error { addrBook.Save() } + // Ensure we have a completely undeterministic PRNG. cmd.RandInt64() draws + // from a seed that's initialized with OS entropy on process start. + rng := rand.New(rand.NewSource(cmn.RandInt64())) + // permute the list, dial them in random order. - perm := rand.Perm(len(netAddrs)) + perm := rng.Perm(len(netAddrs)) for i := 0; i < len(perm); i++ { go func(i int) { - time.Sleep(time.Duration(rand.Int63n(3000)) * time.Millisecond) + time.Sleep(time.Duration(rng.Int63n(3000)) * time.Millisecond) j := perm[i] sw.dialSeed(netAddrs[j]) }(i)