github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/discovery.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  	"context"
    29  	"fmt"
    30  	"sync"
    31  
    32  	"github.com/ethereum/go-ethereum/swarm/pot"
    33  )
    34  
    35  //
    36  
    37  //
    38  type discPeer struct {
    39  	*BzzPeer
    40  	overlay   Overlay
    41  sentPeers bool //
    42  	mtx       sync.RWMutex
    43  peers     map[string]bool //
    44  depth     uint8           //
    45  }
    46  
    47  //
    48  func newDiscovery(p *BzzPeer, o Overlay) *discPeer {
    49  	d := &discPeer{
    50  		overlay: o,
    51  		BzzPeer: p,
    52  		peers:   make(map[string]bool),
    53  	}
    54  //
    55  	d.seen(d)
    56  	return d
    57  }
    58  
    59  //
    60  func (d *discPeer) HandleMsg(ctx context.Context, msg interface{}) error {
    61  	switch msg := msg.(type) {
    62  
    63  	case *peersMsg:
    64  		return d.handlePeersMsg(msg)
    65  
    66  	case *subPeersMsg:
    67  		return d.handleSubPeersMsg(msg)
    68  
    69  	default:
    70  		return fmt.Errorf("unknown message type: %T", msg)
    71  	}
    72  }
    73  
    74  //
    75  func NotifyDepth(depth uint8, h Overlay) {
    76  	f := func(val OverlayConn, po int, _ bool) bool {
    77  		dp, ok := val.(*discPeer)
    78  		if ok {
    79  			dp.NotifyDepth(depth)
    80  		}
    81  		return true
    82  	}
    83  	h.EachConn(nil, 255, f)
    84  }
    85  
    86  //
    87  func NotifyPeer(p OverlayAddr, k Overlay) {
    88  	f := func(val OverlayConn, po int, _ bool) bool {
    89  		dp, ok := val.(*discPeer)
    90  		if ok {
    91  			dp.NotifyPeer(p, uint8(po))
    92  		}
    93  		return true
    94  	}
    95  	k.EachConn(p.Address(), 255, f)
    96  }
    97  
    98  //
    99  //
   100  //
   101  //
   102  func (d *discPeer) NotifyPeer(a OverlayAddr, po uint8) {
   103  //
   104  	if (po < d.getDepth() && pot.ProxCmp(d.localAddr, d, a) != 1) || d.seen(a) {
   105  		return
   106  	}
   107  //
   108  	resp := &peersMsg{
   109  		Peers: []*BzzAddr{ToAddr(a)},
   110  	}
   111  	go d.Send(context.TODO(), resp)
   112  }
   113  
   114  //
   115  //
   116  func (d *discPeer) NotifyDepth(po uint8) {
   117  //
   118  	go d.Send(context.TODO(), &subPeersMsg{Depth: po})
   119  }
   120  
   121  /*
   122  
   123  
   124  
   125  
   126  
   127  
   128  
   129  
   130  
   131  
   132  
   133  
   134  
   135  */
   136  
   137  
   138  //
   139  //
   140  //
   141  type peersMsg struct {
   142  	Peers []*BzzAddr
   143  }
   144  
   145  //
   146  func (msg peersMsg) String() string {
   147  	return fmt.Sprintf("%T: %v", msg, msg.Peers)
   148  }
   149  
   150  //
   151  //
   152  //
   153  func (d *discPeer) handlePeersMsg(msg *peersMsg) error {
   154  //
   155  	if len(msg.Peers) == 0 {
   156  		return nil
   157  	}
   158  
   159  	for _, a := range msg.Peers {
   160  		d.seen(a)
   161  		NotifyPeer(a, d.overlay)
   162  	}
   163  	return d.overlay.Register(toOverlayAddrs(msg.Peers...))
   164  }
   165  
   166  //
   167  type subPeersMsg struct {
   168  	Depth uint8
   169  }
   170  
   171  //
   172  func (msg subPeersMsg) String() string {
   173  	return fmt.Sprintf("%T: request peers > PO%02d. ", msg, msg.Depth)
   174  }
   175  
   176  func (d *discPeer) handleSubPeersMsg(msg *subPeersMsg) error {
   177  	if !d.sentPeers {
   178  		d.setDepth(msg.Depth)
   179  		var peers []*BzzAddr
   180  		d.overlay.EachConn(d.Over(), 255, func(p OverlayConn, po int, isproxbin bool) bool {
   181  			if pob, _ := pof(d, d.localAddr, 0); pob > po {
   182  				return false
   183  			}
   184  			if !d.seen(p) {
   185  				peers = append(peers, ToAddr(p.Off()))
   186  			}
   187  			return true
   188  		})
   189  		if len(peers) > 0 {
   190  //
   191  			go d.Send(context.TODO(), &peersMsg{Peers: peers})
   192  		}
   193  	}
   194  	d.sentPeers = true
   195  	return nil
   196  }
   197  
   198  //
   199  //
   200  func (d *discPeer) seen(p OverlayPeer) bool {
   201  	d.mtx.Lock()
   202  	defer d.mtx.Unlock()
   203  	k := string(p.Address())
   204  	if d.peers[k] {
   205  		return true
   206  	}
   207  	d.peers[k] = true
   208  	return false
   209  }
   210  
   211  func (d *discPeer) getDepth() uint8 {
   212  	d.mtx.RLock()
   213  	defer d.mtx.RUnlock()
   214  	return d.depth
   215  }
   216  func (d *discPeer) setDepth(depth uint8) {
   217  	d.mtx.Lock()
   218  	defer d.mtx.Unlock()
   219  	d.depth = depth
   220  }