github.com/annchain/OG@v0.0.9/og/peer.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package og 15 16 import ( 17 "errors" 18 "fmt" 19 "github.com/annchain/OG/arefactor/common/goroutine" 20 "github.com/annchain/OG/arefactor/og/types" 21 "github.com/annchain/OG/common/math" 22 "github.com/annchain/OG/og/message_archive" 23 "github.com/annchain/OG/types/msg" 24 "sync" 25 "time" 26 27 "github.com/annchain/OG/p2p" 28 "github.com/deckarep/golang-set" 29 ) 30 31 var ( 32 errClosed = errors.New("peer set is closed") 33 errAlreadyRegistered = errors.New("peer is already registered") 34 errNotRegistered = errors.New("peer is not registered") 35 ) 36 37 const ( 38 maxknownMsg = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) 39 40 // maxqueuedMsg is the maximum number of transaction lists to queue up before 41 // dropping broadcasts. This is a sensitive number as a transaction list might 42 // contain a single transaction, or thousands. 43 maxqueuedMsg = 128 44 45 // maxQueuedProps is the maximum number of block propagations to queue up before 46 // dropping broadcasts. There's not much point in queueing stale blocks, so a few 47 // that might cover uncles should be enough. 48 maxQueuedProps = 4 49 50 // maxQueuedAnns is the maximum number of block announcements to queue up before 51 // dropping broadcasts. Similarly to block propagations, there's no point to queue 52 // above some healthy uncle limit, so use that. 53 maxQueuedAnns = 4 54 55 handshakeTimeout = 5 * time.Second 56 ) 57 58 type peer struct { 59 id string 60 61 *p2p.Peer 62 rw p2p.MsgReadWriter 63 64 version int // Protocol Version negotiated 65 forkDrop *time.Timer // Timed connection dropper if forks aren't validated in time 66 67 head types.Hash 68 seqId uint64 69 lock sync.RWMutex 70 knownMsg mapset.Set // Set of transaction hashes known to be known by this peer 71 queuedMsg chan []msg.OgMessage // Queue of transactions to broadcast to the peer 72 term chan struct{} // Termination channel to stop the broadcaster 73 outPath bool 74 inPath bool 75 inBound bool 76 } 77 78 type PeerInfo struct { 79 Version int `json:"Version"` // Ethereum protocol Version negotiated 80 SequencerId uint64 `json:"sequencer_id"` // Total difficulty of the peer's blockchain 81 Head string `json:"head"` // SHA3 Hash of the peer's best owned block 82 ShortId string `json:"short_id"` 83 Link bool `json:"link"` 84 Addrs string `json:"addrs"` 85 InBound bool `json:"in_bound"` 86 } 87 88 func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 89 return &peer{ 90 Peer: p, 91 rw: rw, 92 version: version, 93 id: fmt.Sprintf("%x", p.ID().Bytes()[:8]), 94 knownMsg: mapset.NewSet(), 95 queuedMsg: make(chan []msg.OgMessage, maxqueuedMsg), 96 term: make(chan struct{}), 97 outPath: true, 98 inPath: true, 99 inBound: p.Inbound(), 100 } 101 } 102 103 // broadcast is a write loop that multiplexes block propagations, announcements 104 // and transaction broadcasts into the remote peer. The goal is to have an async 105 // writer that does not lock up node internals. 106 func (p *peer) broadcast() { 107 for { 108 select { 109 case msg := <-p.queuedMsg: 110 if err := p.SendMessages(msg); err != nil { 111 msgLog.WithError(err).Warn("send msg failed,quiting") 112 return 113 } 114 msgLog.WithField("count", len(msg)).Trace("Multicast messages") 115 116 case <-p.term: 117 msgLog.Debug("peer terminating,quiting") 118 return 119 } 120 } 121 } 122 123 func (p *peer) SetOutPath(v bool) bool { 124 if p.outPath == v { 125 return false 126 } 127 p.outPath = v 128 return true 129 } 130 131 func (p *peer) SetInPath(v bool) { 132 p.inPath = v 133 } 134 135 func (p *peer) CheckPath() (outPath, inpath bool) { 136 return p.outPath, p.inPath 137 } 138 139 // close signals the broadcast goroutine to terminate. 140 func (p *peer) close() { 141 close(p.term) 142 } 143 144 // Info gathers and returns a collection of metadata known about a peer. 145 func (p *peer) Info() *PeerInfo { 146 hash, seqId := p.Head() 147 148 return &PeerInfo{ 149 Version: p.version, 150 Head: hash.Hex(), 151 SequencerId: seqId, 152 ShortId: p.id, 153 Link: p.outPath, 154 Addrs: p.RemoteAddr().String(), 155 InBound: p.inBound, 156 } 157 } 158 159 // Head retrieves a copy of the current head Hash and total difficulty of the 160 // peer. 161 func (p *peer) Head() (hash types.Hash, seqId uint64) { 162 p.lock.RLock() 163 defer p.lock.RUnlock() 164 165 copy(hash.Bytes[:], p.head.Bytes[:]) 166 return hash, p.seqId 167 } 168 169 // SetHead updates the head Hash and total difficulty of the peer. 170 func (p *peer) SetHead(hash types.Hash, seqId uint64) { 171 p.lock.Lock() 172 defer p.lock.Unlock() 173 174 copy(p.head.Bytes[:], hash.Bytes[:]) 175 p.seqId = seqId 176 } 177 178 // MarkMessage marks a Message as known for the peer, ensuring that it 179 // will never be propagated to this particular peer. 180 func (p *peer) MarkMessage(m message_archive.BinaryMessageType, hash types.Hash) { 181 // If we reached the memory allowance, drop a previously known transaction Hash 182 for p.knownMsg.Cardinality() >= maxknownMsg { 183 p.knownMsg.Pop() 184 } 185 key := message_archive.NewMsgKey(m, hash) 186 p.knownMsg.Add(key) 187 } 188 189 // SendTransactions sends transactions to the peer and includes the hashes 190 // in its transaction Hash set for future reference. 191 func (p *peer) SendMessages(messages []msg.OgMessage) error { 192 var msgType msg.BinaryMessageType 193 var msgBytes []byte 194 if len(messages) == 0 { 195 return nil 196 } 197 for _, msg := range messages { 198 //duplicated 199 //key := msg.MsgKey() 200 //p.knownMsg.Add(key) 201 msgType = msg.MessageType 202 msgBytes = append(msgBytes, msg.Data...) 203 } 204 return p.sendRawMessage(msgType, msgBytes) 205 } 206 207 func (p *peer) sendRawMessage(msgType msg.BinaryMessageType, msgBytes []byte) error { 208 msgLog.WithField("to ", p.id).WithField("type ", msgType).WithField("size", len(msgBytes)).Trace("send msg") 209 return p2p.Send(p.rw, msgType.Code(), msgBytes) 210 211 } 212 213 // AsyncSendTransactions queues list of transactions propagation to a remote 214 // peer. If the peer's broadcast queue is full, the event is silently dropped. 215 func (p *peer) AsyncSendMessages(messages []*message_archive.types) { 216 select { 217 case p.queuedMsg <- messages: 218 for _, msg := range messages { 219 key := msg.MsgKey() 220 p.knownMsg.Add(key) 221 } 222 default: 223 msgLog.WithField("count", len(messages)).Debug("Dropping transaction propagation") 224 } 225 } 226 227 func (p *peer) AsyncSendMessage(msg *message_archive.types) { 228 var messages []*message_archive.types 229 messages = append(messages, msg) 230 select { 231 case p.queuedMsg <- messages: 232 key := msg.MsgKey() 233 p.knownMsg.Add(key) 234 default: 235 msgLog.Debug("Dropping transaction propagation") 236 } 237 } 238 239 // SendNodeData sends a batch of arbitrary internal Data, corresponding to the 240 // hashes requested. 241 func (p *peer) SendNodeData(data []byte) error { 242 return p.sendRawMessage(message_archive.NodeDataMsg, data) 243 } 244 245 // RequestNodeData fetches a batch of arbitrary Data from a node's known state 246 // Data, corresponding to the specified hashes. 247 func (p *peer) RequestNodeData(hashes types.Hashes) error { 248 msgLog.WithField("count", len(hashes)).Debug("Fetching batch of state Data") 249 hashsStruct := types.Hashes(hashes) 250 b, _ := hashsStruct.MarshalMsg(nil) 251 return p.sendRawMessage(message_archive.GetNodeDataMsg, b) 252 } 253 254 // RequestReceipts fetches a batch of transaction receipts from a remote node. 255 func (p *peer) RequestReceipts(hashes types.Hashes) error { 256 msgLog.WithField("count", len(hashes)).Debug("Fetching batch of receipts") 257 b, _ := hashes.MarshalMsg(nil) 258 return p.sendRawMessage(message_archive.GetReceiptsMsg, b) 259 } 260 261 // RequestHeadersByHash fetches a batch of blocks' headers corresponding to the 262 // specified header query, based on the Hash of an origin block. 263 func (p *peer) RequestTxsByHash(seqHash types.Hash, seqId uint64) error { 264 hash := seqHash 265 msg := &p2p_message.MessageTxsRequest{ 266 SeqHash: &hash, 267 Id: &seqId, 268 RequestId: message_archive.MsgCounter.Get(), 269 } 270 return p.sendRequest(message_archive.MessageTypeTxsRequest, msg) 271 } 272 273 func (p *peer) RequestTxs(hashs types.Hashes) error { 274 msg := &p2p_message.MessageTxsRequest{ 275 Hashes: &hashs, 276 RequestId: message_archive.MsgCounter.Get(), 277 } 278 279 return p.sendRequest(message_archive.MessageTypeTxsRequest, msg) 280 } 281 282 func (p *peer) RequestTxsById(seqId uint64) error { 283 msg := &p2p_message.MessageTxsRequest{ 284 Id: &seqId, 285 RequestId: message_archive.MsgCounter.Get(), 286 } 287 return p.sendRequest(message_archive.MessageTypeTxsRequest, msg) 288 } 289 290 func (p *peer) RequestBodies(seqHashs types.Hashes) error { 291 msg := &p2p_message.MessageBodiesRequest{ 292 SeqHashes: seqHashs, 293 RequestId: message_archive.MsgCounter.Get(), 294 } 295 return p.sendRequest(message_archive.MessageTypeBodiesRequest, msg) 296 } 297 298 func (h *Hub) RequestOneHeader(peerId string, hash types.Hash) error { 299 p := h.peers.Peer(peerId) 300 if p == nil { 301 return fmt.Errorf("peer not found") 302 } 303 return p.RequestOneHeader(hash) 304 } 305 306 func (h *Hub) RequestBodies(peerId string, hashs types.Hashes) error { 307 p := h.peers.Peer(peerId) 308 if p == nil { 309 return fmt.Errorf("peer not found") 310 } 311 return p.RequestBodies(hashs) 312 } 313 314 func (p *peer) RequestOneHeader(hash types.Hash) error { 315 tmpHash := hash 316 msg := &p2p_message.MessageHeaderRequest{ 317 Origin: p2p_message.HashOrNumber{ 318 Hash: &tmpHash, 319 }, 320 Amount: uint64(1), 321 Skip: uint64(0), 322 Reverse: false, 323 RequestId: message_archive.MsgCounter.Get(), 324 } 325 return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg) 326 } 327 328 // RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the 329 // specified header query, based on the number of an origin block. 330 func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { 331 msg := &p2p_message.MessageHeaderRequest{ 332 Origin: p2p_message.HashOrNumber{ 333 Number: &origin, 334 }, 335 Amount: uint64(amount), 336 Skip: uint64(skip), 337 Reverse: reverse, 338 RequestId: message_archive.MsgCounter.Get(), 339 } 340 return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg) 341 } 342 343 func (p *peer) RequestHeadersByHash(hash types.Hash, amount int, skip int, reverse bool) error { 344 tmpHash := hash 345 msg := &p2p_message.MessageHeaderRequest{ 346 Origin: p2p_message.HashOrNumber{ 347 Hash: &tmpHash, 348 }, 349 Amount: uint64(amount), 350 Skip: uint64(skip), 351 Reverse: reverse, 352 RequestId: message_archive.MsgCounter.Get(), 353 } 354 return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg) 355 } 356 357 func (p *peer) sendRequest(msgType message_archive.BinaryMessageType, request p2p_message.Message) error { 358 clog := msgLog.WithField("msgType", msgType).WithField("request ", request).WithField("to", p.id) 359 data, err := request.MarshalMsg(nil) 360 if err != nil { 361 clog.WithError(err).Warn("encode request error") 362 return err 363 } 364 clog.WithField("size", len(data)).Debug("send") 365 err = p2p.Send(p.rw, p2p.MsgCodeType(msgType), data) 366 if err != nil { 367 clog.WithError(err).Warn("send failed") 368 } 369 return err 370 } 371 372 // String implements fmt.Stringer. 373 func (p *peer) String() string { 374 return fmt.Sprintf("Sender-%s-[%s]-[%s]", p.id, 375 fmt.Sprintf("og/%2d", p.version), p.RemoteAddr().String(), 376 ) 377 } 378 379 // peerSet represents the collection of active peers currently participating in 380 // the Ethereum sub-protocol. 381 type peerSet struct { 382 peers map[string]*peer 383 lock sync.RWMutex 384 closed bool 385 } 386 387 // newPeerSet creates a new peer set to track the active participants. 388 func newPeerSet() *peerSet { 389 return &peerSet{ 390 peers: make(map[string]*peer), 391 } 392 } 393 394 // Register injects a new peer into the working set, or returns an error if the 395 // peer is already known. If a new peer it registered, its broadcast loop is also 396 // started. 397 func (ps *peerSet) Register(p *peer) error { 398 ps.lock.Lock() 399 defer ps.lock.Unlock() 400 401 if ps.closed { 402 return errClosed 403 } 404 if _, ok := ps.peers[p.id]; ok { 405 return errAlreadyRegistered 406 } 407 ps.peers[p.id] = p 408 goroutine.New(p.broadcast) 409 410 return nil 411 } 412 413 // Unregister removes a remote peer from the active set, disabling any further 414 // actions to/from that particular entity. 415 func (ps *peerSet) Unregister(id string) error { 416 ps.lock.Lock() 417 defer ps.lock.Unlock() 418 419 p, ok := ps.peers[id] 420 if !ok { 421 return errNotRegistered 422 } 423 delete(ps.peers, id) 424 p.close() 425 426 return nil 427 } 428 429 // Sender retrieves the registered peer with the given id. 430 func (ps *peerSet) Peer(id string) *peer { 431 ps.lock.RLock() 432 defer ps.lock.RUnlock() 433 434 return ps.peers[id] 435 } 436 437 // Len returns if the current number of peers in the set. 438 func (ps *peerSet) Len() int { 439 ps.lock.RLock() 440 defer ps.lock.RUnlock() 441 442 return len(ps.peers) 443 } 444 445 func (ps *peerSet) Peers() []*peer { 446 ps.lock.RLock() 447 defer ps.lock.RUnlock() 448 list := make([]*peer, 0, len(ps.peers)) 449 for _, p := range ps.peers { 450 list = append(list, p) 451 } 452 return list 453 } 454 455 func (ps *peerSet) ValidPathNum() (outPath, inPath int) { 456 ps.lock.RLock() 457 defer ps.lock.RUnlock() 458 var out, in int 459 for _, p := range ps.peers { 460 if p.outPath { 461 out++ 462 } 463 if p.inPath { 464 in++ 465 } 466 } 467 return out, in 468 } 469 470 func (ps *peerSet) GetPeers(ids []string, n int) []*peer { 471 if len(ids) == 0 || n <= 0 { 472 return nil 473 } 474 ps.lock.RLock() 475 defer ps.lock.RUnlock() 476 all := make([]*peer, 0, len(ids)) 477 list := make([]*peer, 0, n) 478 for _, id := range ids { 479 peer := ps.peers[id] 480 if peer != nil { 481 all = append(all, peer) 482 } 483 } 484 indices := math.GenerateRandomIndices(n, len(all)) 485 for _, i := range indices { 486 list = append(list, all[i]) 487 } 488 return list 489 } 490 491 func (ps *peerSet) GetRandomPeers(n int) []*peer { 492 ps.lock.RLock() 493 defer ps.lock.RUnlock() 494 all := make([]*peer, 0, len(ps.peers)) 495 list := make([]*peer, 0, n) 496 for _, p := range ps.peers { 497 all = append(all, p) 498 } 499 indices := math.GenerateRandomIndices(n, len(all)) 500 for _, i := range indices { 501 list = append(list, all[i]) 502 } 503 return list 504 } 505 506 // PeersWithoutTx retrieves a list of peers that do not have a given transaction 507 // in their set of known hashes. 508 func (ps *peerSet) PeersWithoutMsg(hash types.Hash, m message_archive.BinaryMessageType) []*peer { 509 ps.lock.RLock() 510 defer ps.lock.RUnlock() 511 512 list := make([]*peer, 0, len(ps.peers)) 513 if m == message_archive.MessageTypeNewTx || m == message_archive.MessageTypeNewSequencer { 514 keyControl := message_archive.NewMsgKey(message_archive.MessageTypeControl, hash) 515 key := message_archive.NewMsgKey(m, hash) 516 for _, p := range ps.peers { 517 if !p.knownMsg.Contains(key) && !p.knownMsg.Contains(keyControl) { 518 list = append(list, p) 519 } 520 } 521 return list 522 } 523 key := message_archive.NewMsgKey(m, hash) 524 for _, p := range ps.peers { 525 if !p.knownMsg.Contains(key) { 526 list = append(list, p) 527 } 528 } 529 return list 530 } 531 532 // BestPeer retrieves the known peer with the currently highest total difficulty. 533 func (ps *peerSet) BestPeer() *peer { 534 ps.lock.RLock() 535 defer ps.lock.RUnlock() 536 537 var ( 538 bestPeer *peer 539 bestId uint64 540 ) 541 for _, p := range ps.peers { 542 if _, seqId := p.Head(); bestPeer == nil || seqId > bestId { 543 bestPeer, bestId = p, seqId 544 } 545 } 546 return bestPeer 547 } 548 549 // Close disconnects all peers. 550 // No new peers can be registered after Close has returned. 551 func (ps *peerSet) Close() { 552 ps.lock.Lock() 553 defer ps.lock.Unlock() 554 555 for _, p := range ps.peers { 556 p.Disconnect(p2p.DiscQuitting) 557 } 558 ps.closed = true 559 } 560 561 // Handshake executes the og protocol handshake, negotiating Version number, 562 // network IDs, head and genesis blocks. 563 func (p *peer) Handshake(network uint64, head types.Hash, seqId uint64, genesis types.Hash) error { 564 // Send out own handshake in a new thread 565 errc := make(chan error, 2) 566 var status message_archive.StatusData // safe to read after two values have been received from errc 567 568 sendStatusFunc := func() { 569 s := message_archive.StatusData{ 570 ProtocolVersion: uint32(p.version), 571 NetworkId: network, 572 CurrentBlock: head, 573 CurrentId: seqId, 574 GenesisBlock: genesis, 575 } 576 data, _ := s.MarshalMsg(nil) 577 errc <- p2p.Send(p.rw, p2p.MsgCodeType(message_archive.StatusMsg), data) 578 } 579 goroutine.New(sendStatusFunc) 580 readFunc := func() { 581 errc <- p.readStatus(network, &status, genesis) 582 } 583 goroutine.New(readFunc) 584 timeout := time.NewTimer(handshakeTimeout) 585 defer timeout.Stop() 586 for i := 0; i < 2; i++ { 587 select { 588 case err := <-errc: 589 if err != nil { 590 return err 591 } 592 case <-timeout.C: 593 return p2p.DiscReadTimeout 594 } 595 } 596 p.head = status.CurrentBlock 597 p.seqId = status.CurrentId 598 return nil 599 }