github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/eth/peer.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 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package eth 26 27 import ( 28 "errors" 29 "fmt" 30 "math/big" 31 "sync" 32 "time" 33 34 mapset "github.com/deckarep/golang-set" 35 "github.com/ethereum/go-ethereum/common" 36 "github.com/ethereum/go-ethereum/core/types" 37 "github.com/ethereum/go-ethereum/p2p" 38 "github.com/ethereum/go-ethereum/rlp" 39 ) 40 41 42 43 var ( 44 errClosed = errors.New("peer set is closed") 45 errAlreadyRegistered = errors.New("peer is already registered") 46 errNotRegistered = errors.New("peer is not registered") 47 ) 48 49 const ( 50 maxKnownTxs = 32768 //要保留在已知列表中的最大事务哈希数(防止DOS) 51 maxKnownBlocks = 1024 //要保留在已知列表中的最大块哈希数(防止DOS) 52 53 //maxqueuedtxs是要在之前排队的事务列表的最大数目 54 //正在删除广播。这是一个敏感的数字,因为事务列表可能 55 //包含一个或数千个事务。 56 maxQueuedTxs = 128 57 58 //MaxQueuedProps是在之前排队的最大块传播数 59 //正在删除广播。排队的陈旧街区没什么意义,所以有一些 60 //这可能足以覆盖叔叔们。 61 maxQueuedProps = 4 62 63 //MaxQueuedanns是要在之前排队的最大块通知数 64 //正在删除广播。与块传播类似,没有排队点 65 //超过一些健康的叔叔限制,所以使用。 66 maxQueuedAnns = 4 67 68 handshakeTimeout = 5 * time.Second 69 ) 70 71 //PeerInfo表示已知以太坊子协议元数据的简短摘要 72 //关于连接的对等机。 73 type PeerInfo struct { 74 Version int `json:"version"` //已协商以太坊协议版本 75 Difficulty *big.Int `json:"difficulty"` //同行区块链的总难度 76 Head string `json:"head"` //对等机最好拥有的块的sha3哈希 77 } 78 79 //propevent是一个块传播,在广播队列中等待它的循环。 80 type propEvent struct { 81 block *types.Block 82 td *big.Int 83 } 84 85 type peer struct { 86 id string 87 88 *p2p.Peer 89 rw p2p.MsgReadWriter 90 91 version int //协议版本协商 92 forkDrop *time.Timer //如果未及时验证分叉,则为定时连接滴管 93 94 head common.Hash 95 td *big.Int 96 lock sync.RWMutex 97 98 knownTxs mapset.Set //此对等方已知的事务哈希集 99 knownBlocks mapset.Set //此对等方已知的块哈希集 100 queuedTxs chan []*types.Transaction //要广播到对等机的事务队列 101 queuedProps chan *propEvent //向对等机广播的块队列 102 queuedAnns chan *types.Block //向对等机宣布的块队列 103 term chan struct{} //终止频道以停止广播 104 } 105 106 func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 107 return &peer{ 108 Peer: p, 109 rw: rw, 110 version: version, 111 id: fmt.Sprintf("%x", p.ID().Bytes()[:8]), 112 knownTxs: mapset.NewSet(), 113 knownBlocks: mapset.NewSet(), 114 queuedTxs: make(chan []*types.Transaction, maxQueuedTxs), 115 queuedProps: make(chan *propEvent, maxQueuedProps), 116 queuedAnns: make(chan *types.Block, maxQueuedAnns), 117 term: make(chan struct{}), 118 } 119 } 120 121 //广播是一个写循环,它多路复用块传播、通知 122 //事务广播到远程对等机。目标是要有一个异步 123 //不锁定节点内部的编写器。 124 func (p *peer) broadcast() { 125 for { 126 select { 127 case txs := <-p.queuedTxs: 128 if err := p.SendTransactions(txs); err != nil { 129 return 130 } 131 p.Log().Trace("Broadcast transactions", "count", len(txs)) 132 133 case prop := <-p.queuedProps: 134 if err := p.SendNewBlock(prop.block, prop.td); err != nil { 135 return 136 } 137 p.Log().Trace("Propagated block", "number", prop.block.Number(), "hash", prop.block.Hash(), "td", prop.td) 138 139 case block := <-p.queuedAnns: 140 if err := p.SendNewBlockHashes([]common.Hash{block.Hash()}, []uint64{block.NumberU64()}); err != nil { 141 return 142 } 143 p.Log().Trace("Announced block", "number", block.Number(), "hash", block.Hash()) 144 145 case <-p.term: 146 return 147 } 148 } 149 } 150 151 //关闭向广播线路发出终止信号。 152 func (p *peer) close() { 153 close(p.term) 154 } 155 156 //INFO收集并返回有关对等机的已知元数据集合。 157 func (p *peer) Info() *PeerInfo { 158 hash, td := p.Head() 159 160 return &PeerInfo{ 161 Version: p.version, 162 Difficulty: td, 163 Head: hash.Hex(), 164 } 165 } 166 167 //head检索当前head哈希的副本以及 168 //同龄人。 169 func (p *peer) Head() (hash common.Hash, td *big.Int) { 170 p.lock.RLock() 171 defer p.lock.RUnlock() 172 173 copy(hash[:], p.head[:]) 174 return hash, new(big.Int).Set(p.td) 175 } 176 177 //sethead更新头散列和对等端的总难度。 178 func (p *peer) SetHead(hash common.Hash, td *big.Int) { 179 p.lock.Lock() 180 defer p.lock.Unlock() 181 182 copy(p.head[:], hash[:]) 183 p.td.Set(td) 184 } 185 186 //markblock将一个块标记为对等方已知的块,确保该块 187 //永远不要传播到这个特定的对等端。 188 func (p *peer) MarkBlock(hash common.Hash) { 189 //如果达到了内存允许值,请删除以前已知的块哈希 190 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 191 p.knownBlocks.Pop() 192 } 193 p.knownBlocks.Add(hash) 194 } 195 196 //marktransaction将事务标记为对等方已知的事务,确保 197 //永远不会传播到这个特定的对等。 198 func (p *peer) MarkTransaction(hash common.Hash) { 199 //如果达到了内存允许值,请删除以前已知的事务哈希 200 for p.knownTxs.Cardinality() >= maxKnownTxs { 201 p.knownTxs.Pop() 202 } 203 p.knownTxs.Add(hash) 204 } 205 206 //sendTransactions将事务发送到对等端,并包括哈希 207 //在其事务哈希集中,以供将来参考。 208 func (p *peer) SendTransactions(txs types.Transactions) error { 209 for _, tx := range txs { 210 p.knownTxs.Add(tx.Hash()) 211 } 212 return p2p.Send(p.rw, TxMsg, txs) 213 } 214 215 //AsyncSendTransactions队列将事务传播到远程的列表 216 //同龄人。如果对等方的广播队列已满,则会静默地删除事件。 217 func (p *peer) AsyncSendTransactions(txs []*types.Transaction) { 218 select { 219 case p.queuedTxs <- txs: 220 for _, tx := range txs { 221 p.knownTxs.Add(tx.Hash()) 222 } 223 default: 224 p.Log().Debug("Dropping transaction propagation", "count", len(txs)) 225 } 226 } 227 228 //sendNewBlockHashes宣布通过 229 //哈希通知。 230 func (p *peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error { 231 for _, hash := range hashes { 232 p.knownBlocks.Add(hash) 233 } 234 request := make(newBlockHashesData, len(hashes)) 235 for i := 0; i < len(hashes); i++ { 236 request[i].Hash = hashes[i] 237 request[i].Number = numbers[i] 238 } 239 return p2p.Send(p.rw, NewBlockHashesMsg, request) 240 } 241 242 //AsyncSendNewBlockHash将用于传播到 243 //远程对等体。如果对等方的广播队列已满,则事件将静默 244 //下降。 245 func (p *peer) AsyncSendNewBlockHash(block *types.Block) { 246 select { 247 case p.queuedAnns <- block: 248 p.knownBlocks.Add(block.Hash()) 249 default: 250 p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash()) 251 } 252 } 253 254 //sendNewBlock将整个块传播到远程对等机。 255 func (p *peer) SendNewBlock(block *types.Block, td *big.Int) error { 256 p.knownBlocks.Add(block.Hash()) 257 return p2p.Send(p.rw, NewBlockMsg, []interface{}{block, td}) 258 } 259 260 //AsyncSendNewBlock将整个块排队,以便传播到远程对等端。如果 261 //对等机的广播队列已满,事件将被静默丢弃。 262 func (p *peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { 263 select { 264 case p.queuedProps <- &propEvent{block: block, td: td}: 265 p.knownBlocks.Add(block.Hash()) 266 default: 267 p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash()) 268 } 269 } 270 271 //sendblockheaders向远程对等端发送一批块头。 272 func (p *peer) SendBlockHeaders(headers []*types.Header) error { 273 return p2p.Send(p.rw, BlockHeadersMsg, headers) 274 } 275 276 //sendblockbody向远程对等发送一批块内容。 277 func (p *peer) SendBlockBodies(bodies []*blockBody) error { 278 return p2p.Send(p.rw, BlockBodiesMsg, blockBodiesData(bodies)) 279 } 280 281 //sendblockbodiesrlp从发送一批块内容到远程对等机 282 //已经用rlp编码的格式。 283 func (p *peer) SendBlockBodiesRLP(bodies []rlp.RawValue) error { 284 return p2p.Send(p.rw, BlockBodiesMsg, bodies) 285 } 286 287 //sendNoedatarlp发送一批任意内部数据,与 288 //已请求哈希。 289 func (p *peer) SendNodeData(data [][]byte) error { 290 return p2p.Send(p.rw, NodeDataMsg, data) 291 } 292 293 //sendReceiptsRLP发送一批交易凭证,与 294 //从已经RLP编码的格式请求的。 295 func (p *peer) SendReceiptsRLP(receipts []rlp.RawValue) error { 296 return p2p.Send(p.rw, ReceiptsMsg, receipts) 297 } 298 299 //RequestOneHeader是一个包装器,它围绕头查询函数来获取 300 //单头。它仅由取纸器使用。 301 func (p *peer) RequestOneHeader(hash common.Hash) error { 302 p.Log().Debug("Fetching single header", "hash", hash) 303 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: uint64(1), Skip: uint64(0), Reverse: false}) 304 } 305 306 //RequestHeadersByHash获取与 307 //基于源块哈希的指定头查询。 308 func (p *peer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { 309 p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) 310 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 311 } 312 313 //RequestHeadersByNumber获取与 314 //指定的头查询,基于源块的编号。 315 func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { 316 p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) 317 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 318 } 319 320 //请求主体获取一批与哈希对应的块的主体 321 //明确规定。 322 func (p *peer) RequestBodies(hashes []common.Hash) error { 323 p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) 324 return p2p.Send(p.rw, GetBlockBodiesMsg, hashes) 325 } 326 327 //RequestNodeData从节点的已知状态获取一批任意数据 328 //与指定哈希对应的数据。 329 func (p *peer) RequestNodeData(hashes []common.Hash) error { 330 p.Log().Debug("Fetching batch of state data", "count", len(hashes)) 331 return p2p.Send(p.rw, GetNodeDataMsg, hashes) 332 } 333 334 //RequestReceipts从远程节点获取一批事务收据。 335 func (p *peer) RequestReceipts(hashes []common.Hash) error { 336 p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) 337 return p2p.Send(p.rw, GetReceiptsMsg, hashes) 338 } 339 340 //握手执行ETH协议握手,协商版本号, 341 //网络ID,困难,头和创世块。 342 func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash) error { 343 //在新线程中发送自己的握手 344 errc := make(chan error, 2) 345 var status statusData //从errc收到两个值后可以安全读取 346 347 go func() { 348 errc <- p2p.Send(p.rw, StatusMsg, &statusData{ 349 ProtocolVersion: uint32(p.version), 350 NetworkId: network, 351 TD: td, 352 CurrentBlock: head, 353 GenesisBlock: genesis, 354 }) 355 }() 356 go func() { 357 errc <- p.readStatus(network, &status, genesis) 358 }() 359 timeout := time.NewTimer(handshakeTimeout) 360 defer timeout.Stop() 361 for i := 0; i < 2; i++ { 362 select { 363 case err := <-errc: 364 if err != nil { 365 return err 366 } 367 case <-timeout.C: 368 return p2p.DiscReadTimeout 369 } 370 } 371 p.td, p.head = status.TD, status.CurrentBlock 372 return nil 373 } 374 375 func (p *peer) readStatus(network uint64, status *statusData, genesis common.Hash) (err error) { 376 msg, err := p.rw.ReadMsg() 377 if err != nil { 378 return err 379 } 380 if msg.Code != StatusMsg { 381 return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 382 } 383 if msg.Size > ProtocolMaxMsgSize { 384 return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) 385 } 386 //解码握手并确保所有内容都匹配 387 if err := msg.Decode(&status); err != nil { 388 return errResp(ErrDecode, "msg %v: %v", msg, err) 389 } 390 if status.GenesisBlock != genesis { 391 return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", status.GenesisBlock[:8], genesis[:8]) 392 } 393 if status.NetworkId != network { 394 return errResp(ErrNetworkIdMismatch, "%d (!= %d)", status.NetworkId, network) 395 } 396 if int(status.ProtocolVersion) != p.version { 397 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version) 398 } 399 return nil 400 } 401 402 //字符串实现fmt.stringer。 403 func (p *peer) String() string { 404 return fmt.Sprintf("Peer %s [%s]", p.id, 405 fmt.Sprintf("eth/%2d", p.version), 406 ) 407 } 408 409 //Peerset表示当前参与的活动对等机的集合 410 //以太坊子协议。 411 type peerSet struct { 412 peers map[string]*peer 413 lock sync.RWMutex 414 closed bool 415 } 416 417 //new peer set创建一个新的对等集来跟踪活动参与者。 418 func newPeerSet() *peerSet { 419 return &peerSet{ 420 peers: make(map[string]*peer), 421 } 422 } 423 424 //寄存器向工作集中注入一个新的对等点,或者返回一个错误,如果 425 //对等机已经知道。如果注册了一个新的对等点,其广播循环也 426 //起动。 427 func (ps *peerSet) Register(p *peer) error { 428 ps.lock.Lock() 429 defer ps.lock.Unlock() 430 431 if ps.closed { 432 return errClosed 433 } 434 if _, ok := ps.peers[p.id]; ok { 435 return errAlreadyRegistered 436 } 437 ps.peers[p.id] = p 438 go p.broadcast() 439 440 return nil 441 } 442 443 //注销从活动集删除远程对等,进一步禁用 444 //对该特定实体采取的行动。 445 func (ps *peerSet) Unregister(id string) error { 446 ps.lock.Lock() 447 defer ps.lock.Unlock() 448 449 p, ok := ps.peers[id] 450 if !ok { 451 return errNotRegistered 452 } 453 delete(ps.peers, id) 454 p.close() 455 456 return nil 457 } 458 459 //对等端检索具有给定ID的注册对等端。 460 func (ps *peerSet) Peer(id string) *peer { 461 ps.lock.RLock() 462 defer ps.lock.RUnlock() 463 464 return ps.peers[id] 465 } 466 467 //len返回集合中当前的对等数。 468 func (ps *peerSet) Len() int { 469 ps.lock.RLock() 470 defer ps.lock.RUnlock() 471 472 return len(ps.peers) 473 } 474 475 //peerswithoutblock检索没有给定块的对等机列表 476 //他们的一组已知散列。 477 func (ps *peerSet) PeersWithoutBlock(hash common.Hash) []*peer { 478 ps.lock.RLock() 479 defer ps.lock.RUnlock() 480 481 list := make([]*peer, 0, len(ps.peers)) 482 for _, p := range ps.peers { 483 if !p.knownBlocks.Contains(hash) { 484 list = append(list, p) 485 } 486 } 487 return list 488 } 489 490 //PeerSwithouttx检索没有给定事务的对等方列表 491 //在他们的一组已知散列中。 492 func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer { 493 ps.lock.RLock() 494 defer ps.lock.RUnlock() 495 496 list := make([]*peer, 0, len(ps.peers)) 497 for _, p := range ps.peers { 498 if !p.knownTxs.Contains(hash) { 499 list = append(list, p) 500 } 501 } 502 return list 503 } 504 505 //BestPeer以当前最高的总难度检索已知的对等。 506 func (ps *peerSet) BestPeer() *peer { 507 ps.lock.RLock() 508 defer ps.lock.RUnlock() 509 510 var ( 511 bestPeer *peer 512 bestTd *big.Int 513 ) 514 for _, p := range ps.peers { 515 if _, td := p.Head(); bestPeer == nil || td.Cmp(bestTd) > 0 { 516 bestPeer, bestTd = p, td 517 } 518 } 519 return bestPeer 520 } 521 522 //关闭将断开所有对等机的连接。 523 //关闭后不能注册新的对等方。 524 func (ps *peerSet) Close() { 525 ps.lock.Lock() 526 defer ps.lock.Unlock() 527 528 for _, p := range ps.peers { 529 p.Disconnect(p2p.DiscQuitting) 530 } 531 ps.closed = true 532 }