github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/hive.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 network
    26  
    27  import (
    28  	"fmt"
    29  	"sync"
    30  	"time"
    31  
    32  	"github.com/ethereum/go-ethereum/common/hexutil"
    33  	"github.com/ethereum/go-ethereum/p2p"
    34  	"github.com/ethereum/go-ethereum/p2p/discover"
    35  	"github.com/ethereum/go-ethereum/swarm/log"
    36  	"github.com/ethereum/go-ethereum/swarm/state"
    37  )
    38  
    39  /*
    40  
    41  
    42  
    43  
    44  
    45  */
    46  
    47  
    48  //
    49  type Overlay interface {
    50  //
    51  	SuggestPeer() (OverlayAddr, int, bool)
    52  //
    53  	On(OverlayConn) (depth uint8, changed bool)
    54  	Off(OverlayConn)
    55  //
    56  	Register([]OverlayAddr) error
    57  //
    58  	EachConn([]byte, int, func(OverlayConn, int, bool) bool)
    59  //
    60  	EachAddr([]byte, int, func(OverlayAddr, int, bool) bool)
    61  //
    62  	String() string
    63  //
    64  	BaseAddr() []byte
    65  //
    66  	Healthy(*PeerPot) *Health
    67  }
    68  
    69  //
    70  type HiveParams struct {
    71  Discovery             bool  //
    72  PeersBroadcastSetSize uint8 //
    73  MaxPeersPerRequest    uint8 //
    74  	KeepAliveInterval     time.Duration
    75  }
    76  
    77  //
    78  func NewHiveParams() *HiveParams {
    79  	return &HiveParams{
    80  		Discovery:             true,
    81  		PeersBroadcastSetSize: 3,
    82  		MaxPeersPerRequest:    5,
    83  		KeepAliveInterval:     500 * time.Millisecond,
    84  	}
    85  }
    86  
    87  //
    88  type Hive struct {
    89  *HiveParams                      //
    90  Overlay                          //
    91  Store       state.Store          //
    92  addPeer     func(*discover.Node) //
    93  //
    94  	lock   sync.Mutex
    95  	ticker *time.Ticker
    96  }
    97  
    98  //
    99  //
   100  //
   101  //
   102  func NewHive(params *HiveParams, overlay Overlay, store state.Store) *Hive {
   103  	return &Hive{
   104  		HiveParams: params,
   105  		Overlay:    overlay,
   106  		Store:      store,
   107  	}
   108  }
   109  
   110  //
   111  //
   112  //
   113  func (h *Hive) Start(server *p2p.Server) error {
   114  	log.Info("Starting hive", "baseaddr", fmt.Sprintf("%x", h.BaseAddr()[:4]))
   115  //
   116  	if h.Store != nil {
   117  		log.Info("Detected an existing store. trying to load peers")
   118  		if err := h.loadPeers(); err != nil {
   119  			log.Error(fmt.Sprintf("%08x hive encoutered an error trying to load peers", h.BaseAddr()[:4]))
   120  			return err
   121  		}
   122  	}
   123  //
   124  	h.addPeer = server.AddPeer
   125  //
   126  	h.ticker = time.NewTicker(h.KeepAliveInterval)
   127  //
   128  	go h.connect()
   129  	return nil
   130  }
   131  
   132  //
   133  func (h *Hive) Stop() error {
   134  	log.Info(fmt.Sprintf("%08x hive stopping, saving peers", h.BaseAddr()[:4]))
   135  	h.ticker.Stop()
   136  	if h.Store != nil {
   137  		if err := h.savePeers(); err != nil {
   138  			return fmt.Errorf("could not save peers to persistence store: %v", err)
   139  		}
   140  		if err := h.Store.Close(); err != nil {
   141  			return fmt.Errorf("could not close file handle to persistence store: %v", err)
   142  		}
   143  	}
   144  	log.Info(fmt.Sprintf("%08x hive stopped, dropping peers", h.BaseAddr()[:4]))
   145  	h.EachConn(nil, 255, func(p OverlayConn, _ int, _ bool) bool {
   146  		log.Info(fmt.Sprintf("%08x dropping peer %08x", h.BaseAddr()[:4], p.Address()[:4]))
   147  		p.Drop(nil)
   148  		return true
   149  	})
   150  
   151  	log.Info(fmt.Sprintf("%08x all peers dropped", h.BaseAddr()[:4]))
   152  	return nil
   153  }
   154  
   155  //
   156  //
   157  //
   158  func (h *Hive) connect() {
   159  	for range h.ticker.C {
   160  
   161  		addr, depth, changed := h.SuggestPeer()
   162  		if h.Discovery && changed {
   163  			NotifyDepth(uint8(depth), h)
   164  		}
   165  		if addr == nil {
   166  			continue
   167  		}
   168  
   169  		log.Trace(fmt.Sprintf("%08x hive connect() suggested %08x", h.BaseAddr()[:4], addr.Address()[:4]))
   170  		under, err := discover.ParseNode(string(addr.(Addr).Under()))
   171  		if err != nil {
   172  			log.Warn(fmt.Sprintf("%08x unable to connect to bee %08x: invalid node URL: %v", h.BaseAddr()[:4], addr.Address()[:4], err))
   173  			continue
   174  		}
   175  		log.Trace(fmt.Sprintf("%08x attempt to connect to bee %08x", h.BaseAddr()[:4], addr.Address()[:4]))
   176  		h.addPeer(under)
   177  	}
   178  }
   179  
   180  //
   181  func (h *Hive) Run(p *BzzPeer) error {
   182  	dp := newDiscovery(p, h)
   183  	depth, changed := h.On(dp)
   184  //
   185  	if h.Discovery {
   186  		if changed {
   187  //
   188  			NotifyDepth(depth, h)
   189  		} else {
   190  //
   191  			dp.NotifyDepth(depth)
   192  		}
   193  	}
   194  	NotifyPeer(p.Off(), h)
   195  	defer h.Off(dp)
   196  	return dp.Run(dp.HandleMsg)
   197  }
   198  
   199  //
   200  //
   201  func (h *Hive) NodeInfo() interface{} {
   202  	return h.String()
   203  }
   204  
   205  //
   206  //
   207  func (h *Hive) PeerInfo(id discover.NodeID) interface{} {
   208  	addr := NewAddrFromNodeID(id)
   209  	return struct {
   210  		OAddr hexutil.Bytes
   211  		UAddr hexutil.Bytes
   212  	}{
   213  		OAddr: addr.OAddr,
   214  		UAddr: addr.UAddr,
   215  	}
   216  }
   217  
   218  //
   219  func ToAddr(pa OverlayPeer) *BzzAddr {
   220  	if addr, ok := pa.(*BzzAddr); ok {
   221  		return addr
   222  	}
   223  	if p, ok := pa.(*discPeer); ok {
   224  		return p.BzzAddr
   225  	}
   226  	return pa.(*BzzPeer).BzzAddr
   227  }
   228  
   229  //
   230  func (h *Hive) loadPeers() error {
   231  	var as []*BzzAddr
   232  	err := h.Store.Get("peers", &as)
   233  	if err != nil {
   234  		if err == state.ErrNotFound {
   235  			log.Info(fmt.Sprintf("hive %08x: no persisted peers found", h.BaseAddr()[:4]))
   236  			return nil
   237  		}
   238  		return err
   239  	}
   240  	log.Info(fmt.Sprintf("hive %08x: peers loaded", h.BaseAddr()[:4]))
   241  
   242  	return h.Register(toOverlayAddrs(as...))
   243  }
   244  
   245  //
   246  func toOverlayAddrs(as ...*BzzAddr) (oas []OverlayAddr) {
   247  	for _, a := range as {
   248  		oas = append(oas, OverlayAddr(a))
   249  	}
   250  	return
   251  }
   252  
   253  //
   254  func (h *Hive) savePeers() error {
   255  	var peers []*BzzAddr
   256  	h.Overlay.EachAddr(nil, 256, func(pa OverlayAddr, i int, _ bool) bool {
   257  		if pa == nil {
   258  			log.Warn(fmt.Sprintf("empty addr: %v", i))
   259  			return true
   260  		}
   261  		apa := ToAddr(pa)
   262  		log.Trace("saving peer", "peer", apa)
   263  		peers = append(peers, apa)
   264  		return true
   265  	})
   266  	if err := h.Store.Put("peers", peers); err != nil {
   267  		return fmt.Errorf("could not save peers: %v", err)
   268  	}
   269  	return nil
   270  }