github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/whisper/whisperv6/peer.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 19:16:46</date>
    10  //</624450125648891904>
    11  
    12  
    13  package whisperv6
    14  
    15  import (
    16  	"fmt"
    17  	"math"
    18  	"sync"
    19  	"time"
    20  
    21  	mapset "github.com/deckarep/golang-set"
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/log"
    24  	"github.com/ethereum/go-ethereum/p2p"
    25  	"github.com/ethereum/go-ethereum/rlp"
    26  )
    27  
    28  //Peer表示一个耳语协议对等连接。
    29  type Peer struct {
    30  	host *Whisper
    31  	peer *p2p.Peer
    32  	ws   p2p.MsgReadWriter
    33  
    34  	trusted        bool
    35  	powRequirement float64
    36  	bloomMu        sync.Mutex
    37  	bloomFilter    []byte
    38  	fullNode       bool
    39  
    40  known mapset.Set //对等方已经知道的消息,以避免浪费带宽
    41  
    42  	quit chan struct{}
    43  }
    44  
    45  //new peer创建一个新的whisper peer对象,但不运行握手本身。
    46  func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
    47  	return &Peer{
    48  		host:           host,
    49  		peer:           remote,
    50  		ws:             rw,
    51  		trusted:        false,
    52  		powRequirement: 0.0,
    53  		known:          mapset.NewSet(),
    54  		quit:           make(chan struct{}),
    55  		bloomFilter:    MakeFullNodeBloom(),
    56  		fullNode:       true,
    57  	}
    58  }
    59  
    60  //启动启动对等更新程序,定期广播低语数据包
    61  //进入网络。
    62  func (peer *Peer) start() {
    63  	go peer.update()
    64  	log.Trace("start", "peer", peer.ID())
    65  }
    66  
    67  //stop终止对等更新程序,停止向其转发消息。
    68  func (peer *Peer) stop() {
    69  	close(peer.quit)
    70  	log.Trace("stop", "peer", peer.ID())
    71  }
    72  
    73  //握手向远程对等端发送协议启动状态消息,并且
    74  //也验证远程状态。
    75  func (peer *Peer) handshake() error {
    76  //异步发送握手状态消息
    77  	errc := make(chan error, 1)
    78  	isLightNode := peer.host.LightClientMode()
    79  	isRestrictedLightNodeConnection := peer.host.LightClientModeConnectionRestricted()
    80  	go func() {
    81  		pow := peer.host.MinPow()
    82  		powConverted := math.Float64bits(pow)
    83  		bloom := peer.host.BloomFilter()
    84  
    85  		errc <- p2p.SendItems(peer.ws, statusCode, ProtocolVersion, powConverted, bloom, isLightNode)
    86  	}()
    87  
    88  //获取远程状态包并验证协议匹配
    89  	packet, err := peer.ws.ReadMsg()
    90  	if err != nil {
    91  		return err
    92  	}
    93  	if packet.Code != statusCode {
    94  		return fmt.Errorf("peer [%x] sent packet %x before status packet", peer.ID(), packet.Code)
    95  	}
    96  	s := rlp.NewStream(packet.Payload, uint64(packet.Size))
    97  	_, err = s.List()
    98  	if err != nil {
    99  		return fmt.Errorf("peer [%x] sent bad status message: %v", peer.ID(), err)
   100  	}
   101  	peerVersion, err := s.Uint()
   102  	if err != nil {
   103  		return fmt.Errorf("peer [%x] sent bad status message (unable to decode version): %v", peer.ID(), err)
   104  	}
   105  	if peerVersion != ProtocolVersion {
   106  		return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", peer.ID(), peerVersion, ProtocolVersion)
   107  	}
   108  
   109  //只有版本是必需的,后续参数是可选的
   110  	powRaw, err := s.Uint()
   111  	if err == nil {
   112  		pow := math.Float64frombits(powRaw)
   113  		if math.IsInf(pow, 0) || math.IsNaN(pow) || pow < 0.0 {
   114  			return fmt.Errorf("peer [%x] sent bad status message: invalid pow", peer.ID())
   115  		}
   116  		peer.powRequirement = pow
   117  
   118  		var bloom []byte
   119  		err = s.Decode(&bloom)
   120  		if err == nil {
   121  			sz := len(bloom)
   122  			if sz != BloomFilterSize && sz != 0 {
   123  				return fmt.Errorf("peer [%x] sent bad status message: wrong bloom filter size %d", peer.ID(), sz)
   124  			}
   125  			peer.setBloomFilter(bloom)
   126  		}
   127  	}
   128  
   129  	isRemotePeerLightNode, err := s.Bool()
   130  	if isRemotePeerLightNode && isLightNode && isRestrictedLightNodeConnection {
   131  		return fmt.Errorf("peer [%x] is useless: two light client communication restricted", peer.ID())
   132  	}
   133  
   134  	if err := <-errc; err != nil {
   135  		return fmt.Errorf("peer [%x] failed to send status packet: %v", peer.ID(), err)
   136  	}
   137  	return nil
   138  }
   139  
   140  //更新在对等机上执行定期操作,包括消息传输
   141  //和呼气。
   142  func (peer *Peer) update() {
   143  //启动更新的滚动条
   144  	expire := time.NewTicker(expirationCycle)
   145  	transmit := time.NewTicker(transmissionCycle)
   146  
   147  //循环并发送直到请求终止
   148  	for {
   149  		select {
   150  		case <-expire.C:
   151  			peer.expire()
   152  
   153  		case <-transmit.C:
   154  			if err := peer.broadcast(); err != nil {
   155  				log.Trace("broadcast failed", "reason", err, "peer", peer.ID())
   156  				return
   157  			}
   158  
   159  		case <-peer.quit:
   160  			return
   161  		}
   162  	}
   163  }
   164  
   165  //马克标记了一个同伴知道的信封,这样它就不会被送回。
   166  func (peer *Peer) mark(envelope *Envelope) {
   167  	peer.known.Add(envelope.Hash())
   168  }
   169  
   170  //标记检查远程对等机是否已经知道信封。
   171  func (peer *Peer) marked(envelope *Envelope) bool {
   172  	return peer.known.Contains(envelope.Hash())
   173  }
   174  
   175  //Expire迭代主机中的所有已知信封,并删除所有
   176  //已知列表中过期(未知)的。
   177  func (peer *Peer) expire() {
   178  	unmark := make(map[common.Hash]struct{})
   179  	peer.known.Each(func(v interface{}) bool {
   180  		if !peer.host.isEnvelopeCached(v.(common.Hash)) {
   181  			unmark[v.(common.Hash)] = struct{}{}
   182  		}
   183  		return true
   184  	})
   185  //转储所有已知但不再缓存的内容
   186  	for hash := range unmark {
   187  		peer.known.Remove(hash)
   188  	}
   189  }
   190  
   191  //广播在信封集合上迭代,传输未知信息
   192  //在网络上。
   193  func (peer *Peer) broadcast() error {
   194  	envelopes := peer.host.Envelopes()
   195  	bundle := make([]*Envelope, 0, len(envelopes))
   196  	for _, envelope := range envelopes {
   197  		if !peer.marked(envelope) && envelope.PoW() >= peer.powRequirement && peer.bloomMatch(envelope) {
   198  			bundle = append(bundle, envelope)
   199  		}
   200  	}
   201  
   202  	if len(bundle) > 0 {
   203  //发送一批信封
   204  		if err := p2p.Send(peer.ws, messagesCode, bundle); err != nil {
   205  			return err
   206  		}
   207  
   208  //仅当信封成功发送时才标记信封
   209  		for _, e := range bundle {
   210  			peer.mark(e)
   211  		}
   212  
   213  		log.Trace("broadcast", "num. messages", len(bundle))
   214  	}
   215  	return nil
   216  }
   217  
   218  //ID返回对等方的ID
   219  func (peer *Peer) ID() []byte {
   220  	id := peer.peer.ID()
   221  	return id[:]
   222  }
   223  
   224  func (peer *Peer) notifyAboutPowRequirementChange(pow float64) error {
   225  	i := math.Float64bits(pow)
   226  	return p2p.Send(peer.ws, powRequirementCode, i)
   227  }
   228  
   229  func (peer *Peer) notifyAboutBloomFilterChange(bloom []byte) error {
   230  	return p2p.Send(peer.ws, bloomFilterExCode, bloom)
   231  }
   232  
   233  func (peer *Peer) bloomMatch(env *Envelope) bool {
   234  	peer.bloomMu.Lock()
   235  	defer peer.bloomMu.Unlock()
   236  	return peer.fullNode || BloomFilterMatch(peer.bloomFilter, env.Bloom())
   237  }
   238  
   239  func (peer *Peer) setBloomFilter(bloom []byte) {
   240  	peer.bloomMu.Lock()
   241  	defer peer.bloomMu.Unlock()
   242  	peer.bloomFilter = bloom
   243  	peer.fullNode = isFullNode(bloom)
   244  	if peer.fullNode && peer.bloomFilter == nil {
   245  		peer.bloomFilter = MakeFullNodeBloom()
   246  	}
   247  }
   248  
   249  func MakeFullNodeBloom() []byte {
   250  	bloom := make([]byte, BloomFilterSize)
   251  	for i := 0; i < BloomFilterSize; i++ {
   252  		bloom[i] = 0xFF
   253  	}
   254  	return bloom
   255  }
   256