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