github.com/annchain/OG@v0.0.9/og/hub.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/og/message_archive" 22 "github.com/annchain/OG/types/p2p_message" 23 "math/big" 24 25 "github.com/annchain/OG/common/crypto" 26 "github.com/annchain/OG/og/downloader" 27 "github.com/annchain/OG/og/fetcher" 28 "github.com/annchain/OG/p2p" 29 log "github.com/sirupsen/logrus" 30 31 "sync" 32 "time" 33 34 "github.com/annchain/OG/p2p/onode" 35 "github.com/annchain/gcache" 36 ) 37 38 const ( 39 softResponseLimit = 4 * 1024 * 1024 // Target maximum size of returned blocks, headers or node Data. 40 estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header 41 42 // txChanSize is the size of channel listening to NewTxsEvent. 43 // The number is referenced from the size of tx pool. 44 txChanSize = 4096 45 DuplicateMsgPeerNum = 5 46 ) 47 48 var errIncompatibleConfig = errors.New("incompatible configuration") 49 50 // Hub is the middle layer between p2p and business layer 51 // When there is a general request coming from the upper layer, Hub will find the appropriate peer to handle. 52 // When there is a Message coming from p2p, Hub will unmarshall this Message and give it to Message router. 53 // Hub will also prevent duplicate requests/responses. 54 // If there is any failure, Hub is NOT responsible for changing a peer and retry. (maybe enhanced in the future.) 55 // DO NOT INVOLVE ANY BUSINESS LOGICS HERE. 56 type Hub struct { 57 outgoing chan *message_archive.types 58 incoming chan *message_archive.types 59 quit chan bool 60 //CallbackRegistry map[message.BinaryMessageType]func(*message.types) // All callbacks 61 //CallbackRegistryOG02 map[message.BinaryMessageType]func(*message.types) // All callbacks of OG02 62 StatusDataProvider NodeStatusDataProvider 63 peers *peerSet 64 SubProtocols []p2p.Protocol 65 66 wg sync.WaitGroup // wait group is used for graceful shutdowns during downloading and processing 67 68 messageCache gcache.Cache // cache for duplicate responses/msg to prevent storm 69 maxPeers int 70 newPeerCh chan *peer 71 noMorePeers chan struct{} 72 quitSync chan bool 73 74 // new peer event 75 OnNewPeerConnected []chan string 76 Downloader *downloader.Downloader 77 Fetcher *fetcher.Fetcher 78 79 NodeInfo func() *p2p.NodeInfo 80 IsReceivedHash func(hash types.Hash) bool 81 broadCastMode uint8 82 encryptionPrivKey *crypto.PrivateKey 83 encryptionPubKey *crypto.PublicKey 84 disableEncryptGossip bool 85 MessageUnmarshaller message_archive.typesUnmarshalManager 86 } 87 88 func (h *Hub) GetBenchmarks() map[string]interface{} { 89 m := map[string]interface{}{ 90 "outgoing": len(h.outgoing), 91 "incoming": len(h.incoming), 92 "newPeerCh": len(h.newPeerCh), 93 "messageCache": h.messageCache.Len(true), 94 } 95 peers := h.peers.Peers() 96 for _, p := range peers { 97 if p != nil { 98 key := "peer_" + p.id + "_knownMsg" 99 m[key] = p.knownMsg.Cardinality() 100 } 101 } 102 return m 103 } 104 105 type PeerProvider interface { 106 BestPeerInfo() (peerId string, hash types.Hash, seqId uint64, err error) 107 GetPeerHead(peerId string) (hash types.Hash, seqId uint64, err error) 108 } 109 110 type EncryptionLayer interface { 111 SetEncryptionKey(priv *crypto.PrivateKey) 112 } 113 114 type HubConfig struct { 115 OutgoingBufferSize int 116 IncomingBufferSize int 117 MessageCacheMaxSize int 118 MessageCacheExpirationSeconds int 119 MaxPeers int 120 BroadCastMode uint8 121 DisableEncryptGossip bool 122 } 123 124 const ( 125 NormalMode uint8 = iota 126 FeedBackMode 127 ) 128 129 func DefaultHubConfig() HubConfig { 130 config := HubConfig{ 131 OutgoingBufferSize: 40, 132 IncomingBufferSize: 40, 133 MessageCacheMaxSize: 60, 134 MessageCacheExpirationSeconds: 3000, 135 MaxPeers: 50, 136 BroadCastMode: NormalMode, 137 DisableEncryptGossip: false, 138 } 139 return config 140 } 141 142 func (h *Hub) Init(config *HubConfig) { 143 h.outgoing = make(chan *message_archive.types, config.OutgoingBufferSize) 144 h.incoming = make(chan *message_archive.types, config.IncomingBufferSize) 145 h.peers = newPeerSet() 146 h.newPeerCh = make(chan *peer) 147 h.noMorePeers = make(chan struct{}) 148 h.quit = make(chan bool) 149 h.maxPeers = config.MaxPeers 150 h.quitSync = make(chan bool) 151 h.messageCache = gcache.New(config.MessageCacheMaxSize).LRU(). 152 Expiration(time.Second * time.Duration(config.MessageCacheExpirationSeconds)).Build() 153 154 //h.CallbackRegistryOG02 = make(map[message.BinaryMessageType]func(*message.types)) 155 h.broadCastMode = config.BroadCastMode 156 h.disableEncryptGossip = config.DisableEncryptGossip 157 } 158 159 func NewHub(config *HubConfig) *Hub { 160 h := &Hub{} 161 h.Init(config) 162 163 h.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions)) 164 for _, version := range ProtocolVersions { 165 // Skip protocol Version if incompatible with the mode of operation 166 // h.mode == downloader.FastSync && 167 //if Version < OG32 { 168 // continue 169 //} 170 //Compatible; initialise the sub-protocol 171 version := version // Closure for the run 172 h.SubProtocols = append(h.SubProtocols, p2p.Protocol{ 173 Name: ProtocolName, 174 Version: version, 175 // TODO: fix 777 176 //Length: p2p.MsgCodeType(ProtocolLengths[i]), 177 Length: p2p.MsgCodeType(777), 178 Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 179 peer := h.newPeer(int(version), p, rw) 180 select { 181 case <-h.quitSync: 182 return p2p.DiscQuitting 183 default: 184 h.wg.Add(1) 185 defer h.wg.Done() 186 return h.handle(peer) 187 } 188 }, 189 NodeInfo: func() interface{} { 190 return h.NodeStatus() 191 }, 192 PeerInfo: func(id onode.ID) interface{} { 193 if p := h.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil { 194 return p.Info() 195 } 196 return nil 197 }, 198 }) 199 } 200 201 if len(h.SubProtocols) == 0 { 202 log.Error(errIncompatibleConfig) 203 return nil 204 } 205 206 return h 207 } 208 209 func (h *Hub) SetEncryptionKey(priv *crypto.PrivateKey) { 210 h.encryptionPrivKey = priv 211 h.encryptionPubKey = priv.PublicKey() 212 } 213 214 func (h *Hub) newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 215 return newPeer(version, p, rw) 216 } 217 218 // handle is the callback invoked to manage the life cycle of an eth peer. When 219 // this function terminates, the peer is disconnected. 220 func (h *Hub) handle(p *peer) error { 221 // Ignore maxPeers if this is a trusted peer 222 if h.peers.Len() >= h.maxPeers && !p.Peer.Info().Network.Trusted { 223 return p2p.DiscTooManyPeers 224 } 225 log.WithField("name", p.Name()).WithField("id", p.id).Info("OG peer connected") 226 // Execute the og handshake 227 statusData := h.StatusDataProvider.GetCurrentNodeStatus() 228 //if statusData.CurrentBlock == nil{ 229 // panic("Last sequencer is nil") 230 //} 231 232 if err := p.Handshake(statusData.NetworkId, statusData.CurrentBlock, 233 statusData.CurrentId, statusData.GenesisBlock); err != nil { 234 log.WithError(err).WithField("peer ", p.id).Debug("OG handshake failed") 235 return err 236 } 237 // Register the peer locally 238 if err := h.peers.Register(p); err != nil { 239 log.WithError(err).Error("og peer registration failed") 240 return err 241 } 242 243 log.Debug("register peer locally") 244 245 defer h.RemovePeer(p.id) 246 // Register the peer in the downloader. If the downloader considers it banned, we disconnect 247 if err := h.Downloader.RegisterPeer(p.id, p.version, p); err != nil { 248 return err 249 } 250 //announce new peer 251 h.newPeerCh <- p 252 // main loop. handle incoming messages. 253 for { 254 if err := h.handleMsg(p); err != nil { 255 log.WithError(err).Debug("og Message handling failed") 256 return err 257 } 258 } 259 } 260 261 262 // handleMsg is invoked whenever an inbound Message is received from a remote 263 // peer. The remote connection is torn down upon returning any error. 264 func (h *Hub) handleMsg(p *peer) error { 265 // Read the next Message from the remote peer, and ensure it's fully consumed 266 msg, err := p.rw.ReadMsg() 267 if err != nil { 268 return err 269 } 270 if msg.Size > ProtocolMaxMsgSize { 271 return message_archive.ErrResp(message_archive.ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) 272 } 273 defer msg.Discard() 274 // Handle the Message depending on its contents 275 data, err := msg.GetPayLoad() 276 m := message_archive.types{MessageType: message_archive.BinaryMessageType(msg.Code), Data: data, SourceID: p.id, Version: p.version} 277 //log.Debug("start handle p2p Message ",p2pMsg.MessageType) 278 switch m.MessageType { 279 case message_archive.StatusMsg: 280 // Handle the Message depending on its contents 281 282 // Status messages should never arrive after the handshake 283 return message_archive.ErrResp(message_archive.ErrExtraStatusMsg, "uncontrolled status Message") 284 // Block header query, collect the requested headers and reply 285 case message_archive.MessageTypeDuplicate: 286 msgLog.WithField("got msg", m.MessageType).WithField("peer ", p.String()).Trace("set path to false") 287 if !p.SetOutPath(false) { 288 msgLog.WithField("got msg again ", m.MessageType).WithField("peer ", p.String()).Warn("set path to false") 289 } 290 return nil 291 case message_archive.MessageTypeSecret: 292 if h.disableEncryptGossip { 293 m.DisableEncrypt = true 294 } 295 if !m.CheckRequiredSize() { 296 return fmt.Errorf("msg len error") 297 } 298 m.CalculateHash() 299 p.MarkMessage(m.MessageType, *m.Hash) 300 oldMsg := m 301 if duplicate := h.cacheMessage(&m); !duplicate { 302 var isForMe bool 303 if isForMe = m.MaybeIsforMe(h.encryptionPubKey); isForMe { 304 var e error 305 //if encryption gossip is disabled , just check the target 306 //else decrypt 307 if h.disableEncryptGossip { 308 e = m.RemoveGossipTarget() 309 } else { 310 e = m.Decrypt(h.encryptionPrivKey) 311 } 312 if e == nil { 313 err := h.MessageUnmarshaller.Unmarshal(&m) 314 //err = m.Unmarshal() 315 if err != nil { 316 // TODO delete 317 log.Errorf("unmarshal error msg: %x", m.Data) 318 log.WithField("type ", m.MessageType).WithError(err).Warn("handle msg error") 319 return err 320 } 321 msgLog.WithField("type", m.MessageType.String()).WithField("from", p.String()).WithField( 322 "Message", m.Message.String()).WithField("len ", len(m.Data)).Debug("received a Message") 323 h.incoming <- &m 324 } else { 325 log.WithError(e).Debug("this msg is not for me, will relay") 326 isForMe = false 327 } 328 } 329 log.Debug("this msg is not for me, will relay") 330 h.RelayMessage(&oldMsg) 331 332 } else { 333 out, in := p.CheckPath() 334 log.WithField("type", m.MessageType).WithField("size", len(m.Data)).WithField( 335 "Hash", m.Hash).WithField("from ", p.String()).WithField("out ", out).WithField( 336 "in ", in).Debug("duplicate msg ,discard") 337 338 } 339 return nil 340 default: 341 //for incoming msg 342 err := h.MessageUnmarshaller.Unmarshal(&m) 343 //err = m.Unmarshal() 344 if err != nil { 345 log.WithField("type ", m.MessageType).WithError(err).Warn("handle msg error") 346 return err 347 } 348 m.CalculateHash() 349 p.MarkMessage(m.MessageType, *m.Hash) 350 hashes := m.GetMarkHashes() 351 if len(hashes) != 0 { 352 msgLog.WithField("len hahses", len(hashes)).Trace("before mark msg") 353 for _, hash := range hashes { 354 p.MarkMessage(message_archive.MessageTypeNewTx, hash) 355 } 356 msgLog.WithField("len ", len(hashes)).Trace("after mark msg") 357 } 358 if duplicate := h.cacheMessage(&m); duplicate { 359 out, in := p.CheckPath() 360 log.WithField("type", m.MessageType).WithField("msg", m.Message.String()).WithField( 361 "Hash", m.Hash).WithField("from ", p.String()).WithField("out ", out).WithField( 362 "in ", in).Debug("duplicate msg ,discard") 363 if h.broadCastMode == FeedBackMode && m.AllowSendDuplicateMsg() { 364 if outNum, inNum := h.peers.ValidPathNum(); inNum <= 1 { 365 log.WithField("outNum ", outNum).WithField("inNum", inNum).Debug("not enough valid path") 366 //return nil 367 } 368 var dup p2p_message.MessageDuplicate 369 p.SetInPath(false) 370 return h.SendToPeer(message_archive.MessageTypeDuplicate, &dup, p.id) 371 } 372 return nil 373 } 374 } 375 376 msgLog.WithField("type", m.MessageType.String()).WithField("from", p.String()).WithField( 377 "Message", m.Message.String()).WithField("len ", len(m.Data)).Debug("received a Message") 378 379 h.incoming <- &m 380 return nil 381 } 382 383 func (h *Hub) RemovePeer(id string) { 384 // Short circuit if the peer was already removed 385 peer := h.peers.Peer(id) 386 if peer == nil { 387 log.Debug("peer not found id") 388 return 389 } 390 log.WithField("peer", id).Debug("Removing og peer") 391 392 // Unregister the peer from the downloader (should already done) and OG peer set 393 h.Downloader.UnregisterPeer(id) 394 if err := h.peers.Unregister(id); err != nil { 395 log.WithField("peer", "id").WithError(err). 396 Error("Sender removal failed") 397 } 398 // Hard disconnect at the networking layer 399 if peer != nil { 400 peer.Peer.Disconnect(p2p.DiscUselessPeer) 401 } 402 } 403 404 func (h *Hub) Start() { 405 h.Fetcher.Start() 406 goroutine.New(h.loopSend) 407 goroutine.New(h.loopReceive) 408 goroutine.New(h.loopNotify) 409 } 410 411 func (h *Hub) Stop() { 412 // Quit the sync loop. 413 // After this send has completed, no new peers will be accepted. 414 //h.noMorePeers <- struct{}{} 415 log.Info("quit notifying") 416 close(h.quitSync) 417 log.Info("quit notified") 418 h.peers.Close() 419 log.Info("peers closing") 420 h.wg.Wait() 421 log.Info("peers closed") 422 h.Fetcher.Stop() 423 log.Info("fetcher stopped") 424 log.Info("hub stopped") 425 } 426 427 func (h *Hub) Name() string { 428 return "Hub" 429 } 430 431 func (h *Hub) loopNotify() { 432 for { 433 select { 434 case p := <-h.newPeerCh: 435 for _, listener := range h.OnNewPeerConnected { 436 listener <- p.id 437 } 438 case <-h.quit: 439 log.Info("Hub-loopNotify received quit Message. Quitting...") 440 return 441 } 442 } 443 } 444 445 func (h *Hub) loopSend() { 446 for { 447 select { 448 case m := <-h.outgoing: 449 //bug fix , don't use go routine to send here 450 // start a new routine in order not to block other communications 451 switch m.SendingType { 452 case sendingTypeBroadcast: 453 h.broadcastMessage(m) 454 case sendingTypeMulticast: 455 h.multicastMessage(m) 456 case sendingTypeMulticastToSource: 457 h.multicastMessageToSource(m) 458 case sendingTypeBroacastWithFilter: 459 h.broadcastMessage(m) 460 case sendingTypeBroacastWithLink: 461 h.broadcastMessageWithLink(m) 462 463 default: 464 log.WithField("type ", m.SendingType).Error("unknown sending type") 465 panic(m) 466 } 467 case <-h.quit: 468 log.Info("Hub-loopSend received quit Message. Quitting...") 469 return 470 } 471 } 472 } 473 474 func (h *Hub) loopReceive() { 475 for { 476 select { 477 case m := <-h.incoming: 478 // start a new routine in order not to block other communications 479 // bug fix ; don't use go routine 480 h.receiveMessage(m) 481 case <-h.quit: 482 log.Info("Hub-loopReceive received quit Message. Quitting...") 483 return 484 } 485 } 486 } 487 488 //MulticastToSource multicast msg to source , for example , send tx request to the peer which Hash the tx 489 func (h *Hub) MulticastToSource(messageType message_archive.BinaryMessageType, msg p2p_message.Message, sourceMsgHash *types.Hash) { 490 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeMulticastToSource, SourceHash: sourceMsgHash} 491 err := msgOut.Marshal() 492 if err != nil { 493 msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err") 494 return 495 } 496 msgOut.CalculateHash() 497 msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("multicast msg to source") 498 h.outgoing <- msgOut 499 } 500 501 //BroadcastMessage broadcast to whole network 502 func (h *Hub) BroadcastMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message) { 503 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroadcast} 504 err := msgOut.Marshal() 505 if err != nil { 506 msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err") 507 return 508 } 509 msgOut.CalculateHash() 510 msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message") 511 h.outgoing <- msgOut 512 } 513 514 //BroadcastMessage broadcast to whole network 515 func (h *Hub) BroadcastMessageWithLink(messageType message_archive.BinaryMessageType, msg p2p_message.Message) { 516 if h.broadCastMode != FeedBackMode { 517 msgLog.WithField("type", messageType).Trace("broadcast withlink disabled") 518 h.BroadcastMessage(messageType, msg) 519 return 520 } 521 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroacastWithLink} 522 err := msgOut.Marshal() 523 if err != nil { 524 msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err") 525 return 526 } 527 msgOut.CalculateHash() 528 msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message") 529 h.outgoing <- msgOut 530 } 531 532 //BroadcastMessage broadcast to whole network 533 func (h *Hub) BroadcastMessageWithFilter(messageType message_archive.BinaryMessageType, msg p2p_message.Message) { 534 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroacastWithFilter} 535 err := msgOut.Marshal() 536 if err != nil { 537 msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err") 538 return 539 } 540 msgOut.CalculateHash() 541 msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message") 542 h.outgoing <- msgOut 543 } 544 545 //MulticastMessage multicast Message to some peer 546 func (h *Hub) MulticastMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message) { 547 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeMulticast} 548 err := msgOut.Marshal() 549 if err != nil { 550 msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err") 551 return 552 } 553 msgOut.CalculateHash() 554 msgLog.WithField("size", len(msgOut.Data)).WithField("type", messageType).Trace("multicast Message") 555 h.outgoing <- msgOut 556 } 557 558 // AnonymousSendMessage use a pubkey to encrypt the Message and then broadcast it 559 // Only the one who has the private key can decrypt the Message and become the receiver. 560 // the Message will append the target receiver pubkey to accelerate filtering on the target side. 561 // TODO: support multi encryption keys in one Message 562 // TODO: encrypt the Message whatever disableEncryptGossip is on or not 563 func (h *Hub) AnonymousSendMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message, encryptionKey *crypto.PublicKey) { 564 msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroadcast} 565 if h.disableEncryptGossip { 566 msgOut.DisableEncrypt = true 567 } 568 err := msgOut.Marshal() 569 if err != nil { 570 msgLog.WithError(err).WithField("type", messageType).Warn("AnonymousSendMessage Message init msg err") 571 return 572 } 573 beforeEncSize := len(msgOut.Data) 574 if h.disableEncryptGossip { 575 err = msgOut.AppendGossipTarget(encryptionKey) 576 } else { 577 err = msgOut.Encrypt(encryptionKey) 578 } 579 if err != nil { 580 msgLog.WithError(err).WithField("type", messageType).Warn("AnonymousSendMessage Message encrypt msg err") 581 return 582 } 583 msgOut.CalculateHash() 584 msgLog.WithField("before enc size ", beforeEncSize).WithField("size", len(msgOut.Data)).WithField("type", messageType).Trace("AnonymousSendMessage Message") 585 h.outgoing <- msgOut 586 587 } 588 589 func (h *Hub) RelayMessage(msgOut *message_archive.types) { 590 msgLog.WithField("size", len(msgOut.Data)).WithField("type", msgOut.MessageType).Trace("relay Message") 591 h.outgoing <- msgOut 592 } 593 594 func (h *Hub) SendToPeer(messageType message_archive.BinaryMessageType, msg p2p_message.Message, peerId string) error { 595 p := h.peers.Peer(peerId) 596 if p == nil { 597 return fmt.Errorf("peer not found") 598 } 599 return p.sendRequest(messageType, msg) 600 } 601 602 func (h *Hub) SendGetMsg(peerId string, msg *p2p_message.MessageGetMsg) error { 603 p := h.peers.Peer(peerId) 604 if p == nil { 605 ids := h.getMsgFromCache(message_archive.MessageTypeControl, *msg.Hash) 606 ps := h.peers.GetPeers(ids, 1) 607 if len(ps) != 0 { 608 p = ps[0] 609 } 610 } 611 if p == nil { 612 h.MulticastMessage(message_archive.MessageTypeGetMsg, msg) 613 return nil 614 } else { 615 p.SetInPath(true) 616 } 617 return p.sendRequest(message_archive.MessageTypeGetMsg, msg) 618 } 619 620 func (h *Hub) SendBytesToPeer(peerId string, messageType message_archive.BinaryMessageType, msg []byte) error { 621 p := h.peers.Peer(peerId) 622 if p == nil { 623 return fmt.Errorf("peer not found") 624 } 625 return p.sendRawMessage(messageType, msg) 626 } 627 628 // SetPeerHead is just a hack to set the latest seq number known of the peer 629 // This value ought not to be stored in peer, but an outside map. 630 // This has nothing related to p2p. 631 func (h *Hub) SetPeerHead(peerId string, hash types.Hash, number uint64) error { 632 p := h.peers.Peer(peerId) 633 if p == nil { 634 return fmt.Errorf("peer not found") 635 } 636 p.SetHead(hash, number) 637 return nil 638 } 639 640 func (h *Hub) BestPeerInfo() (peerId string, hash types.Hash, seqId uint64, err error) { 641 p := h.peers.BestPeer() 642 if p != nil { 643 peerId = p.id 644 hash, seqId = p.Head() 645 return 646 } 647 err = fmt.Errorf("no best peer") 648 return 649 } 650 651 func (h *Hub) GetPeerHead(peerId string) (hash types.Hash, seqId uint64, err error) { 652 p := h.peers.Peer(peerId) 653 if p != nil { 654 hash, seqId = p.Head() 655 return 656 } 657 err = fmt.Errorf("no such peer") 658 return 659 } 660 661 func (h *Hub) BestPeerId() (peerId string, err error) { 662 p := h.peers.BestPeer() 663 if p != nil { 664 peerId = p.id 665 return 666 } 667 err = fmt.Errorf("no best peer") 668 return 669 } 670 671 //broadcastMessage 672 func (h *Hub) broadcastMessage(msg *message_archive.types) { 673 var peers []*peer 674 // choose all peer and then send. 675 peers = h.peers.PeersWithoutMsg(*msg.Hash, msg.MessageType) 676 for _, peer := range peers { 677 peer.AsyncSendMessage(msg) 678 } 679 return 680 } 681 682 func (h *Hub) broadcastMessageWithLink(msg *message_archive.types) { 683 var peers []*peer 684 // choose all peer and then send. 685 var hash types.Hash 686 hash = *msg.Hash 687 c := p2p_message.MessageControl{Hash: &hash} 688 var pMsg = &message_archive.types{MessageType: message_archive.MessageTypeControl, Message: &c} 689 //outgoing msg 690 if err := pMsg.Marshal(); err != nil { 691 msgLog.Error(err) 692 } 693 pMsg.CalculateHash() 694 peers = h.peers.PeersWithoutMsg(*msg.Hash, msg.MessageType) 695 for _, peer := range peers { 696 //if len(peers) == 1 { 697 if out, _ := peer.CheckPath(); out { 698 msgLog.WithField("peer ", peer.String()).Debug("send original tx to peer") 699 peer.AsyncSendMessage(msg) 700 } else { 701 msgLog.WithField("to peer ", peer.String()).WithField("Hash ", hash).Debug("send MessageTypeControl") 702 peer.AsyncSendMessage(pMsg) 703 } 704 } 705 return 706 } 707 708 /* 709 func (h *Hub) broadcastMessageWithFilter(msg *message.types) { 710 newSeq := msg.Message.(*p2p_message.MessageNewSequencer) 711 if newSeq.Filter == nil { 712 newSeq.Filter = types.NewDefaultBloomFilter() 713 } else if len(newSeq.Filter.Data) != 0 { 714 err := newSeq.Filter.Decode() 715 if err != nil { 716 msgLog.WithError(err).Warn("encode bloom filter error") 717 return 718 } 719 } 720 var allpeers []*peer 721 var peers []*peer 722 allpeers = h.peers.PeersWithoutMsg(msg.Hash) 723 for _, peer := range allpeers { 724 ok, _ := newSeq.Filter.LookUpItem(peer.ID().KeyBytes()) 725 if ok { 726 msgLog.WithField("id ", peer.id).Debug("filtered ,don't send") 727 } else { 728 newSeq.Filter.AddItem(peer.ID().KeyBytes()) 729 peers = append(peers, peer) 730 msgLog.WithField("id ", peer.id).Debug("not filtered , send") 731 } 732 } 733 newSeq.Filter.Encode() 734 msg.Message = newSeq 735 msg.Data, _ = newSeq.MarshalMsg(nil) 736 for _, peer := range peers { 737 peer.AsyncSendMessage(msg) 738 } 739 } 740 741 */ 742 743 //multicastMessage 744 func (h *Hub) multicastMessage(msg *message_archive.types) error { 745 peers := h.peers.GetRandomPeers(3) 746 // choose random peer and then send. 747 for _, peer := range peers { 748 peer.AsyncSendMessage(msg) 749 } 750 return nil 751 } 752 753 //multicastMessageToSource 754 func (h *Hub) multicastMessageToSource(msg *message_archive.types) error { 755 if msg.SourceHash == nil { 756 msgLog.Warn("source msg Hash is nil , multicast to random") 757 return h.multicastMessage(msg) 758 } 759 ids := h.getMsgFromCache(message_archive.MessageTypeControl, *msg.SourceHash) 760 if len(ids) == 0 { 761 ids = h.getMsgFromCache(message_archive.MessageTypeNewTx, *msg.SourceHash) 762 } 763 //send to 2 peer , considering if one peer disconnect, 764 peers := h.peers.GetPeers(ids, 3) 765 if len(peers) == 0 { 766 msgLog.WithField("type ", msg.MessageType).WithField("peeers id ", ids).Warn( 767 "not found source peers, multicast to random") 768 return h.multicastMessage(msg) 769 } 770 // choose random peer and then send. 771 for _, peer := range peers { 772 if peer == nil { 773 continue 774 } 775 peer.AsyncSendMessage(msg) 776 } 777 return nil 778 } 779 780 //cacheMessge save msg to cache 781 func (h *Hub) cacheMessage(m *message_archive.types) (exists bool) { 782 if m.Hash == nil { 783 return false 784 } 785 var peers []string 786 key := m.MsgKey() 787 if a, err := h.messageCache.GetIFPresent(key); err == nil { 788 // already there 789 exists = true 790 //var peers []string 791 peers = a.([]string) 792 msgLog.WithField("from ", m.SourceID).WithField("Hash", m.Hash).WithField("peers", peers).WithField( 793 "type", m.MessageType).Trace("we have a duplicate Message. Discard") 794 if len(peers) == 0 { 795 msgLog.Error("peers is nil") 796 } else if len(peers) >= DuplicateMsgPeerNum { 797 return exists 798 } 799 } 800 peers = append(peers, m.SourceID) 801 h.messageCache.Set(key, peers) 802 return exists 803 } 804 805 //getMsgFromCache 806 func (h *Hub) getMsgFromCache(m message_archive.BinaryMessageType, hash types.Hash) []string { 807 key := message_archive.NewMsgKey(m, hash) 808 if a, err := h.messageCache.GetIFPresent(key); err == nil { 809 var peers []string 810 peers = a.([]string) 811 msgLog.WithField("peers", peers).Trace("get peers from cache") 812 return peers 813 } 814 return nil 815 } 816 817 func (h *Hub) receiveMessage(msg *message_archive.types) { 818 // route to specific callbacks according to the registry. 819 if msg.Version >= OG02 { 820 if v, ok := h.CallbackRegistryOG02[msg.MessageType]; ok { 821 log.WithField("from", msg.SourceID).WithField("type", msg.MessageType.String()).Trace("Received a Message") 822 v(msg) 823 return 824 } 825 } 826 if msg.MessageType == message_archive.MessageTypeGetMsg { 827 peer := h.peers.Peer(msg.SourceID) 828 if peer != nil { 829 msgLog.WithField("msg", msg.Message.String()).WithField("peer ", peer.String()).Trace("set path to true") 830 peer.SetOutPath(true) 831 } 832 } 833 834 if v, ok := h.CallbackRegistry[msg.MessageType]; ok { 835 msgLog.WithField("type", msg.MessageType).Debug("handle") 836 v(msg) 837 } else { 838 msgLog.WithField("from", msg.SourceID).WithField("type", msg.MessageType).Debug("Received an Unknown Message") 839 } 840 } 841 842 // NodeInfo retrieves some protocol metadata about the running host node. 843 func (h *Hub) PeersInfo() []*PeerInfo { 844 peers := h.peers.Peers() 845 // Gather all the generic and sub-protocol specific infos 846 infos := make([]*PeerInfo, 0, len(peers)) 847 for _, peer := range peers { 848 if peer != nil { 849 infos = append(infos, peer.Info()) 850 } 851 } 852 return infos 853 } 854 855 // NodeInfo represents a short summary of the OG sub-protocol metadata 856 // known about the host peer. 857 type NodeStatus struct { 858 Network uint64 `json:"network"` // OG network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4) 859 Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain 860 Genesis types.Hash `json:"genesis"` // SHA3 Hash of the host's genesis block 861 Head types.Hash `json:"head"` // SHA3 Hash of the host's best owned block 862 } 863 864 // NodeInfo retrieves some protocol metadata about the running host node. 865 func (h *Hub) NodeStatus() *NodeStatus { 866 statusData := h.StatusDataProvider.GetCurrentNodeStatus() 867 return &NodeStatus{ 868 Network: statusData.NetworkId, 869 Genesis: statusData.GenesisBlock, 870 Head: statusData.CurrentBlock, 871 } 872 }