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  }