github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/simulation/kademlia.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package simulation 26 27 import ( 28 "context" 29 "encoding/hex" 30 "time" 31 32 "github.com/ethereum/go-ethereum/p2p/discover" 33 34 "github.com/ethereum/go-ethereum/common" 35 "github.com/ethereum/go-ethereum/log" 36 "github.com/ethereum/go-ethereum/swarm/network" 37 ) 38 39 // 40 // 41 var BucketKeyKademlia BucketKey = "kademlia" 42 43 // 44 // 45 func (s *Simulation) WaitTillHealthy(ctx context.Context, kadMinProxSize int) (ill map[discover.NodeID]*network.Kademlia, err error) { 46 // 47 var ppmap map[string]*network.PeerPot 48 kademlias := s.kademlias() 49 addrs := make([][]byte, 0, len(kademlias)) 50 for _, k := range kademlias { 51 addrs = append(addrs, k.BaseAddr()) 52 } 53 ppmap = network.NewPeerPotMap(kadMinProxSize, addrs) 54 55 // 56 ticker := time.NewTicker(200 * time.Millisecond) 57 defer ticker.Stop() 58 59 ill = make(map[discover.NodeID]*network.Kademlia) 60 for { 61 select { 62 case <-ctx.Done(): 63 return ill, ctx.Err() 64 case <-ticker.C: 65 for k := range ill { 66 delete(ill, k) 67 } 68 log.Debug("kademlia health check", "addr count", len(addrs)) 69 for id, k := range kademlias { 70 // 71 addr := common.Bytes2Hex(k.BaseAddr()) 72 pp := ppmap[addr] 73 // 74 h := k.Healthy(pp) 75 // 76 log.Debug(k.String()) 77 log.Debug("kademlia", "empty bins", pp.EmptyBins, "gotNN", h.GotNN, "knowNN", h.KnowNN, "full", h.Full) 78 log.Debug("kademlia", "health", h.GotNN && h.KnowNN && h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) 79 log.Debug("kademlia", "ill condition", !h.GotNN || !h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) 80 if !h.GotNN || !h.Full { 81 ill[id] = k 82 } 83 } 84 if len(ill) == 0 { 85 return nil, nil 86 } 87 } 88 } 89 } 90 91 // 92 // 93 func (s *Simulation) kademlias() (ks map[discover.NodeID]*network.Kademlia) { 94 items := s.UpNodesItems(BucketKeyKademlia) 95 ks = make(map[discover.NodeID]*network.Kademlia, len(items)) 96 for id, v := range items { 97 k, ok := v.(*network.Kademlia) 98 if !ok { 99 continue 100 } 101 ks[id] = k 102 } 103 return ks 104 }