github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/network/simulation/kademlia.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:47</date> 10 //</624342673888645120> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 package simulation 29 30 import ( 31 "context" 32 "encoding/hex" 33 "time" 34 35 "github.com/ethereum/go-ethereum/p2p/discover" 36 37 "github.com/ethereum/go-ethereum/common" 38 "github.com/ethereum/go-ethereum/log" 39 "github.com/ethereum/go-ethereum/swarm/network" 40 ) 41 42 // 43 // 44 var BucketKeyKademlia BucketKey = "kademlia" 45 46 // 47 // 48 func (s *Simulation) WaitTillHealthy(ctx context.Context, kadMinProxSize int) (ill map[discover.NodeID]*network.Kademlia, err error) { 49 // 50 var ppmap map[string]*network.PeerPot 51 kademlias := s.kademlias() 52 addrs := make([][]byte, 0, len(kademlias)) 53 for _, k := range kademlias { 54 addrs = append(addrs, k.BaseAddr()) 55 } 56 ppmap = network.NewPeerPotMap(kadMinProxSize, addrs) 57 58 // 59 ticker := time.NewTicker(200 * time.Millisecond) 60 defer ticker.Stop() 61 62 ill = make(map[discover.NodeID]*network.Kademlia) 63 for { 64 select { 65 case <-ctx.Done(): 66 return ill, ctx.Err() 67 case <-ticker.C: 68 for k := range ill { 69 delete(ill, k) 70 } 71 log.Debug("kademlia health check", "addr count", len(addrs)) 72 for id, k := range kademlias { 73 // 74 addr := common.Bytes2Hex(k.BaseAddr()) 75 pp := ppmap[addr] 76 // 77 h := k.Healthy(pp) 78 // 79 log.Debug(k.String()) 80 log.Debug("kademlia", "empty bins", pp.EmptyBins, "gotNN", h.GotNN, "knowNN", h.KnowNN, "full", h.Full) 81 log.Debug("kademlia", "health", h.GotNN && h.KnowNN && h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) 82 log.Debug("kademlia", "ill condition", !h.GotNN || !h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) 83 if !h.GotNN || !h.Full { 84 ill[id] = k 85 } 86 } 87 if len(ill) == 0 { 88 return nil, nil 89 } 90 } 91 } 92 } 93 94 // 95 // 96 func (s *Simulation) kademlias() (ks map[discover.NodeID]*network.Kademlia) { 97 items := s.UpNodesItems(BucketKeyKademlia) 98 ks = make(map[discover.NodeID]*network.Kademlia, len(items)) 99 for id, v := range items { 100 k, ok := v.(*network.Kademlia) 101 if !ok { 102 continue 103 } 104 ks[id] = k 105 } 106 return ks 107 } 108