github.com/annchain/OG@v0.0.9/og/message_handler.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 "fmt" 18 "github.com/annchain/OG/arefactor/common/goroutine" 19 types2 "github.com/annchain/OG/arefactor/og/types" 20 "github.com/annchain/OG/common" 21 "github.com/annchain/OG/consensus/campaign" 22 "github.com/annchain/OG/og/protocol/ogmessage/archive" 23 "github.com/annchain/OG/og/types" 24 "sort" 25 "sync/atomic" 26 27 // "github.com/annchain/OG/ffchan" 28 "sync" 29 "time" 30 31 "github.com/annchain/OG/og/downloader" 32 ) 33 34 // IncomingMessageHandler is the default handler of all incoming messages for OG 35 type IncomingMessageHandler struct { 36 Og *Og 37 Hub *Hub 38 controlMsgCache *ControlMsgCache 39 requestCache *RequestCache 40 TxEnable func() bool 41 quit chan struct{} 42 } 43 44 type hashAndSourceId struct { 45 hash types2.Hash 46 sourceId string 47 } 48 49 //msg request cache ,don't send duplicate Message 50 type ControlMsgCache struct { 51 cache map[types2.Hash]*controlItem 52 mu sync.RWMutex 53 size int 54 queue chan *hashAndSourceId 55 ExpireTime time.Duration 56 } 57 58 type controlItem struct { 59 sourceId string 60 receivedAt *time.Time 61 requested bool 62 } 63 64 type RequestCache struct { 65 cache map[uint64]bool 66 mu sync.RWMutex 67 } 68 69 //NewIncomingMessageHandler 70 func NewIncomingMessageHandler(og *Og, hub *Hub, cacheSize int, expireTime time.Duration) *IncomingMessageHandler { 71 return &IncomingMessageHandler{ 72 Og: og, 73 Hub: hub, 74 controlMsgCache: &ControlMsgCache{ 75 cache: make(map[types2.Hash]*controlItem), 76 size: cacheSize, 77 ExpireTime: expireTime, 78 queue: make(chan *hashAndSourceId, 1), 79 }, 80 requestCache: &RequestCache{ 81 cache: make(map[uint64]bool), 82 }, 83 84 quit: make(chan struct{}), 85 } 86 } 87 88 func (h *IncomingMessageHandler) HandleFetchByHashRequest(syncRequest *p2p_message.MessageSyncRequest, peerId string) { 89 var txs types.TxisMarshaler 90 //var index []uint32 91 //encode bloom filter , send txs that the peer dose't have 92 if syncRequest.Filter != nil && len(syncRequest.Filter.Data) > 0 { 93 err := syncRequest.Filter.Decode() 94 if err != nil { 95 message_archive.msgLog.WithError(err).Warn("encode bloom filter error") 96 return 97 } 98 if syncRequest.Height == nil { 99 message_archive.msgLog.WithError(err).Warn("param error, height is nil") 100 return 101 } 102 height := *syncRequest.Height 103 ourHeight := h.Og.Dag.LatestSequencer().Number() 104 if height < ourHeight { 105 message_archive.msgLog.WithField("ourHeight ", ourHeight).WithField("height", height).Warn("our height is smaller") 106 return 107 } else { 108 var filterHashes types2.Hashes 109 if height == ourHeight { 110 filterHashes = h.Og.TxPool.GetHashOrder() 111 } else if height < ourHeight { 112 dagHashes := h.Og.Dag.GetTxsHashesByNumber(height + 1) 113 if dagHashes != nil { 114 filterHashes = *dagHashes 115 } 116 filterHashes = append(filterHashes, h.Og.Dag.LatestSequencer().GetHash()) 117 } 118 message_archive.msgLog.WithField("len ", len(filterHashes)).Trace("get hashes") 119 for _, hash := range filterHashes { 120 ok, err := syncRequest.Filter.LookUpItem(hash.Bytes[:]) 121 if err != nil { 122 message_archive.msgLog.WithError(err).Warn("lookup bloom filter error") 123 continue 124 } 125 //if peer miss this tx ,send it 126 if !ok { 127 txi := h.Og.TxPool.Get(hash) 128 if txi == nil { 129 txi = h.Og.Dag.GetTx(hash) 130 } 131 txs.Append(txi) 132 } 133 } 134 135 // uint64(0) -2 >0 136 if height+2 <= ourHeight { 137 dagTxs := h.Og.Dag.GetTxisByNumber(height + 2) 138 rtxs := types.NewTxisMarshaler(dagTxs) 139 if rtxs != nil && len(rtxs) != 0 { 140 txs = append(txs, rtxs...) 141 } 142 //index = append(index, uint32(len(txs))) 143 seq := h.Og.Dag.GetSequencerByHeight(height + 2) 144 txs.Append(seq) 145 } 146 message_archive.msgLog.WithField("to ", peerId).WithField("to request ", syncRequest.RequestId).WithField("len txs ", len(txs)).Debug("will send txs after bloom filter") 147 } 148 } else if syncRequest.Hashes != nil && len(*syncRequest.Hashes) > 0 { 149 for _, hash := range *syncRequest.Hashes { 150 txi := h.Og.TxPool.Get(hash) 151 if txi == nil { 152 txi = h.Og.Dag.GetTx(hash) 153 } 154 if txi == nil { 155 continue 156 } 157 txs.Append(txi) 158 } 159 } else if syncRequest.HashTerminats != nil { 160 hashMap := make(map[p2p_message.HashTerminat]int) 161 allhashs := h.Og.TxPool.GetOrder() 162 if len(*syncRequest.HashTerminats) > 0 { 163 //var hashTerminates p2p_message.HashTerminats 164 for i, hash := range allhashs { 165 var hashTerminate p2p_message.HashTerminat 166 copy(hashTerminate[:], hash.Bytes[:4]) 167 //hashTerminates = append(hashTerminates, hashTerminate) 168 hashMap[hashTerminate] = i 169 } 170 for _, hash := range *syncRequest.HashTerminats { 171 if _, ok := hashMap[hash]; ok { 172 delete(hashMap, hash) 173 } 174 } 175 for _, v := range hashMap { 176 hash := allhashs[v] 177 //if peer miss this tx ,send it 178 txi := h.Og.TxPool.Get(hash) 179 if txi == nil { 180 txi = h.Og.Dag.GetTx(hash) 181 } 182 txs.Append(txi) 183 } 184 message_archive.msgLog.WithField("your tx num", len(*syncRequest.HashTerminats)).WithField( 185 "our tx num ", len(allhashs)).WithField("response tx len", len(txs)).WithField( 186 "to ", peerId).Debug("response to hashList") 187 } else { 188 for _, hash := range allhashs { 189 //if peer miss this tx ,send it 190 txi := h.Og.TxPool.Get(hash) 191 if txi == nil { 192 txi = h.Og.Dag.GetTx(hash) 193 } 194 txs.Append(txi) 195 } 196 } 197 } else { 198 message_archive.msgLog.Debug("empty MessageBatchSyncRequest") 199 return 200 } 201 if len(txs) > 0 { 202 msgRes := p2p_message.MessageSyncResponse{ 203 RawTxs: &txs, 204 //SequencerIndex: index, 205 RequestedId: syncRequest.RequestId, 206 } 207 if txs != nil && len(txs) != 0 { 208 msgRes.RawTxs = &txs 209 } 210 h.Hub.SendToPeer(peerId, message_archive.MessageTypeFetchByHashResponse, &msgRes) 211 } else { 212 message_archive.msgLog.Debug("empty Data , did't send") 213 } 214 return 215 } 216 217 func (h *IncomingMessageHandler) HandleHeaderResponse(headerMsg *p2p_message.MessageHeaderResponse, peerId string) { 218 219 // Filter out any explicitly requested headers, deliver the rest to the downloader 220 if headerMsg.Headers == nil { 221 message_archive.msgLog.Warn("nil MessageHeaderResponse headers") 222 return 223 } 224 225 seqHeaders := *headerMsg.Headers 226 filter := len(seqHeaders) == 1 227 228 // TODO: verify fetcher 229 if filter { 230 // Irrelevant of the fork checks, send the header to the fetcher just in case 231 seqHeaders = h.Hub.Fetcher.FilterHeaders(peerId, seqHeaders, time.Now()) 232 } 233 if len(seqHeaders) > 0 || !filter { 234 err := h.Hub.Downloader.DeliverHeaders(peerId, seqHeaders) 235 if err != nil { 236 message_archive.msgLog.WithError(err).Debug("Failed to deliver headers") 237 } 238 } 239 message_archive.msgLog.WithField("headers", headerMsg).WithField("header lens", len(seqHeaders)).Debug("handle p2p_message.MessageTypeHeaderResponse") 240 } 241 242 func (h *IncomingMessageHandler) HandleHeaderRequest(query *p2p_message.MessageHeaderRequest, peerId string) { 243 hashMode := query.Origin.Hash != nil 244 if query.Origin.Number == nil { 245 i := uint64(0) 246 query.Origin.Number = &i 247 } 248 first := true 249 message_archive.msgLog.WithField("Hash", query.Origin.Hash).WithField("number", query.Origin.Number).WithField( 250 "hashmode", hashMode).WithField("amount", query.Amount).WithField("skip", query.Skip).Trace("requests") 251 // Gather headers until the fetch or network limits is reached 252 var ( 253 bytes common.StorageSize 254 headers archive.Sequencers 255 unknown bool 256 ) 257 for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit && len(headers) < downloader.MaxHeaderFetch { 258 // Retrieve the next header satisfying the query 259 var origin *types.Sequencer 260 if hashMode { 261 if first { 262 first = false 263 origin = h.Og.Dag.GetSequencerByHash(*query.Origin.Hash) 264 if origin != nil { 265 numBer := origin.Number() 266 query.Origin.Number = &numBer 267 } 268 } else { 269 origin = h.Og.Dag.GetSequencer(*query.Origin.Hash, *query.Origin.Number) 270 } 271 } else { 272 origin = h.Og.Dag.GetSequencerByHeight(*query.Origin.Number) 273 } 274 if origin == nil { 275 break 276 } 277 headers = append(headers, origin) 278 bytes += estHeaderRlpSize 279 280 // Advance to the next header of the query 281 switch { 282 case hashMode && query.Reverse: 283 // Hash based traversal towards the genesis block 284 ancestor := query.Skip + 1 285 if ancestor == 0 { 286 unknown = true 287 } else { 288 seq := h.Og.Dag.GetSequencerByHeight(*query.Origin.Number - ancestor) 289 hash := seq.GetHash() 290 num := seq.Number() 291 query.Origin.Hash, query.Origin.Number = &hash, &num 292 unknown = query.Origin.Hash == nil 293 } 294 case hashMode && !query.Reverse: 295 // Hash based traversal towards the leaf block 296 var ( 297 current = origin.Number() 298 next = current + query.Skip + 1 299 ) 300 if next <= current { 301 message_archive.msgLog.Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", peerId) 302 unknown = true 303 } else { 304 if header := h.Og.Dag.GetSequencerByHeight(next); header != nil { 305 nextHash := header.GetHash() 306 oldSeq := h.Og.Dag.GetSequencerByHeight(next - (query.Skip + 1)) 307 expOldHash := oldSeq.GetHash() 308 if expOldHash == *query.Origin.Hash { 309 num := next 310 query.Origin.Hash, query.Origin.Number = &nextHash, &num 311 } else { 312 unknown = true 313 } 314 } else { 315 unknown = true 316 } 317 } 318 case query.Reverse: 319 // Number based traversal towards the genesis block 320 if *query.Origin.Number >= query.Skip+1 { 321 *query.Origin.Number -= query.Skip + 1 322 } else { 323 unknown = true 324 } 325 326 case !query.Reverse: 327 // Number based traversal towards the leaf block 328 *query.Origin.Number += query.Skip + 1 329 } 330 } 331 headres := headers.ToHeaders() 332 msgRes := p2p_message.MessageHeaderResponse{ 333 Headers: &headres, 334 RequestedId: query.RequestId, 335 } 336 h.Hub.SendToPeer(peerId, message_archive.MessageTypeHeaderResponse, &msgRes) 337 } 338 339 func (h *IncomingMessageHandler) HandleTxsResponse(request *p2p_message.MessageTxsResponse) { 340 var rawTxs types.TxisMarshaler 341 var txis types.Txis 342 if request.RawTxs != nil { 343 rawTxs = *request.RawTxs 344 } 345 if request.RawSequencer != nil { 346 message_archive.msgLog.WithField("len rawTx", len(rawTxs)).WithField("seq height", request.RawSequencer.Height).Trace( 347 "got response txs") 348 } else { 349 message_archive.msgLog.Warn("got nil sequencer") 350 return 351 } 352 seq := request.RawSequencer.Sequencer() 353 lseq := h.Og.Dag.LatestSequencer() 354 //todo need more condition 355 if lseq.Number() < seq.Number() { 356 h.Og.TxBuffer.ReceivedNewTxChan <- seq 357 // <-ffchan.NewTimeoutSenderShort(h.Og.TxBuffer.ReceivedNewTxChan, seq, "HandleTxsResponse").C 358 txis = rawTxs.Txis() 359 sort.Sort(txis) 360 for _, tx := range txis { 361 //todo add to txcache first 362 h.Og.TxBuffer.ReceivedNewTxChan <- tx 363 // <-ffchan.NewTimeoutSenderShort(h.Og.TxBuffer.ReceivedNewTxChan, tx, "HandleTxsResponse").C 364 } 365 } 366 return 367 } 368 369 func (h *IncomingMessageHandler) HandleTxsRequest(msgReq *p2p_message.MessageTxsRequest, peerId string) { 370 var msgRes p2p_message.MessageTxsResponse 371 var seq *types.Sequencer 372 if msgReq.Id == nil { 373 i := uint64(0) 374 msgReq.Id = &i 375 } 376 if msgReq.SeqHash != nil && *msgReq.Id != 0 { 377 seq = h.Og.Dag.GetSequencer(*msgReq.SeqHash, *msgReq.Id) 378 } else { 379 seq = h.Og.Dag.GetSequencerByHeight(*msgReq.Id) 380 } 381 msgRes.RawSequencer = seq.RawSequencer() 382 if seq != nil { 383 txs := h.Og.Dag.GetTxisByNumber(seq.Height) 384 rtxs := types.NewTxisMarshaler(txs) 385 if rtxs != nil && len(rtxs) != 0 { 386 msgRes.RawTxs = &rtxs 387 } 388 389 } else { 390 message_archive.msgLog.WithField("id", msgReq.Id).WithField("Hash", msgReq.SeqHash).Warn("seq was not found for request") 391 } 392 h.Hub.SendToPeer(peerId, message_archive.MessageTypeTxsResponse, &msgRes) 393 } 394 395 func (h *IncomingMessageHandler) HandleBodiesResponse(request *p2p_message.MessageBodiesResponse, peerId string) { 396 // Deliver them all to the downloader for queuing 397 transactions := make([]types.Txis, len(request.Bodies)) 398 sequencers := make([]*types.Sequencer, len(request.Bodies)) 399 for i, bodyData := range request.Bodies { 400 var body p2p_message.MessageBodyData 401 _, err := body.UnmarshalMsg(bodyData) 402 if err != nil { 403 message_archive.msgLog.WithError(err).Warn("decode error") 404 break 405 } 406 if body.RawSequencer == nil { 407 message_archive.msgLog.Warn(" body.Sequencer is nil") 408 break 409 } 410 txis := body.ToTxis() 411 sort.Sort(txis) 412 transactions[i] = txis 413 sequencers[i] = body.RawSequencer.Sequencer() 414 } 415 message_archive.msgLog.WithField("bodies len", len(request.Bodies)).Trace("got bodies") 416 417 // Filter out any explicitly requested bodies, deliver the rest to the downloader 418 filter := len(transactions) > 0 || len(sequencers) > 0 419 // TODO: verify fetcher 420 if filter { 421 transactions = h.Hub.Fetcher.FilterBodies(peerId, transactions, sequencers, time.Now()) 422 } 423 if len(transactions) > 0 || len(sequencers) > 0 || !filter { 424 message_archive.msgLog.WithField("txs len", len(transactions)).WithField("seq len", len(sequencers)).Trace("deliver bodies") 425 err := h.Hub.Downloader.DeliverBodies(peerId, transactions, sequencers) 426 if err != nil { 427 message_archive.msgLog.Debug("Failed to deliver bodies", "err", err) 428 } 429 } 430 message_archive.msgLog.Debug("handle MessageTypeBodiesResponse") 431 return 432 } 433 434 func (h *IncomingMessageHandler) HandleBodiesRequest(msgReq *p2p_message.MessageBodiesRequest, peerId string) { 435 var msgRes p2p_message.MessageBodiesResponse 436 var bytes int 437 438 for i := 0; i < len(msgReq.SeqHashes); i++ { 439 seq := h.Og.Dag.GetSequencerByHash(msgReq.SeqHashes[i]) 440 if seq == nil { 441 message_archive.msgLog.WithField("Hash", msgReq.SeqHashes[i]).Warn("seq is nil") 442 break 443 } 444 if bytes >= softResponseLimit { 445 message_archive.msgLog.Debug("reached softResponseLimit") 446 break 447 } 448 if len(msgRes.Bodies) >= downloader.MaxBlockFetch { 449 message_archive.msgLog.Debug("reached MaxBlockFetch 128") 450 break 451 } 452 var body p2p_message.MessageBodyData 453 body.RawSequencer = seq.RawSequencer() 454 txs := h.Og.Dag.GetTxisByNumber(seq.Height) 455 rtxs := types.NewTxisMarshaler(txs) 456 if rtxs != nil && len(rtxs) != 0 { 457 body.RawTxs = &rtxs 458 } 459 bodyData, _ := body.MarshalMsg(nil) 460 bytes += len(bodyData) 461 msgRes.Bodies = append(msgRes.Bodies, p2p_message.RawData(bodyData)) 462 } 463 msgRes.RequestedId = msgReq.RequestId 464 h.Hub.SendToPeer(peerId, message_archive.MessageTypeBodiesResponse, &msgRes) 465 } 466 467 func (h *IncomingMessageHandler) HandleSequencerHeader(msgHeader *p2p_message.MessageSequencerHeader, peerId string) { 468 if msgHeader.Hash == nil { 469 return 470 } 471 if msgHeader.Number == nil { 472 i := uint64(0) 473 msgHeader.Number = &i 474 } 475 number := *msgHeader.Number 476 //no need to broadcast again ,just all our peers need know this ,not all network 477 //set peer's head 478 h.Hub.SetPeerHead(peerId, *msgHeader.Hash, *msgHeader.Number) 479 480 //if h.SyncManager.Status != syncer.SyncStatusIncremental{ 481 // return 482 //} 483 return 484 // TODO: 485 lseq := h.Og.Dag.LatestSequencer() 486 if number > lseq.Number() { 487 if !h.requestCache.get(number) { 488 h.Hub.Fetcher.Notify(peerId, *msgHeader.Hash, number, time.Now(), h.Hub.RequestOneHeader, h.Hub.RequestBodies) 489 h.requestCache.set(number) 490 message_archive.msgLog.WithField("header ", msgHeader.String()).Info("notify to header to fetcher") 491 } 492 h.requestCache.clean(lseq.Number()) 493 } 494 495 return 496 } 497 498 func (c *RequestCache) set(id uint64) { 499 c.mu.Lock() 500 defer c.mu.Unlock() 501 c.cache[id] = true 502 } 503 504 func (c *RequestCache) get(id uint64) bool { 505 c.mu.Lock() 506 defer c.mu.Unlock() 507 return c.cache[id] 508 } 509 510 func (c *RequestCache) remove(id uint64) { 511 c.mu.Lock() 512 defer c.mu.Unlock() 513 delete(c.cache, id) 514 } 515 516 func (c *RequestCache) clean(lseqId uint64) { 517 c.mu.Lock() 518 defer c.mu.Unlock() 519 for k := range c.cache { 520 if k <= lseqId { 521 delete(c.cache, k) 522 } 523 } 524 } 525 526 func (c *ControlMsgCache) set(hash types2.Hash, sourceId string) { 527 c.queue <- &hashAndSourceId{hash: hash, sourceId: sourceId} 528 } 529 530 func (c *ControlMsgCache) get(hash types2.Hash) *controlItem { 531 c.mu.RLock() 532 defer c.mu.RUnlock() 533 if v, ok := c.cache[hash]; ok { 534 return v 535 } 536 return nil 537 } 538 539 func (c *ControlMsgCache) getALlKey() types2.Hashes { 540 c.mu.RLock() 541 defer c.mu.RUnlock() 542 var hashes types2.Hashes 543 for k := range c.cache { 544 hashes = append(hashes, k) 545 } 546 return hashes 547 } 548 549 func (c *ControlMsgCache) Len() int { 550 //c.mu.RLock() 551 //defer c.mu.RUnlock() 552 return len(c.cache) 553 } 554 555 func (c *ControlMsgCache) remove(hash types2.Hash) { 556 c.mu.Lock() 557 defer c.mu.Unlock() 558 delete(c.cache, hash) 559 } 560 561 func (h *IncomingMessageHandler) RemoveControlMsgFromCache(hash types2.Hash) { 562 h.controlMsgCache.remove(hash) 563 } 564 565 func (h *IncomingMessageHandler) loop() { 566 if h.Hub.broadCastMode != FeedBackMode { 567 //TODO 568 //return 569 } 570 c := h.controlMsgCache 571 var handling uint32 572 for { 573 select { 574 case h := <-c.queue: 575 c.mu.Lock() 576 if len(c.cache) > c.size { 577 //todo 578 } 579 now := time.Now() 580 item := controlItem{ 581 receivedAt: &now, 582 sourceId: h.sourceId, 583 } 584 c.cache[h.hash] = &item 585 c.mu.Unlock() 586 //todo optimize the time after 587 case <-time.After(10 * time.Millisecond): 588 if atomic.LoadUint32(&handling) == 1 { 589 continue 590 } 591 atomic.StoreUint32(&handling, 1) 592 h.processControlMsg() 593 atomic.StoreUint32(&handling, 0) 594 595 case <-h.quit: 596 message_archive.msgLog.Info(" incoming msg handler got quit signal ,quiting...") 597 return 598 } 599 600 } 601 } 602 603 func (h *IncomingMessageHandler) processControlMsg() { 604 c := h.controlMsgCache 605 keys := c.getALlKey() 606 for _, k := range keys { 607 item := c.get(k) 608 if item == nil { 609 continue 610 } 611 txkey := message_archive.NewMsgKey(message_archive.MessageTypeNewTx, k) 612 if _, err := h.Hub.messageCache.GetIFPresent(txkey); err == nil { 613 message_archive.msgLog.WithField("Hash ", k).Trace("already received tx of this control msg") 614 c.remove(k) 615 continue 616 } 617 if item.receivedAt.Add(2 * time.Millisecond).Before(time.Now()) { 618 if h.Hub.IsReceivedHash(k) { 619 message_archive.msgLog.WithField("Hash ", k).Trace("already received tx of this control msg") 620 c.remove(k) 621 continue 622 } 623 if item.receivedAt.Add(c.ExpireTime).Before(time.Now()) { 624 hash := k 625 msg := &p2p_message.MessageGetMsg{Hash: &hash} 626 message_archive.msgLog.WithField("Hash ", k).Debug("send GetTx msg") 627 goroutine.New(func() { 628 h.Hub.SendGetMsg(item.sourceId, msg) 629 }) 630 c.remove(k) 631 } 632 } 633 } 634 } 635 636 func (h *IncomingMessageHandler) HandlePing(peerId string) { 637 message_archive.msgLog.Debug("received your ping. Respond you a pong") 638 h.Hub.SendBytesToPeer(peerId, message_archive.MessageTypePong, []byte{1}) 639 } 640 641 func (h *IncomingMessageHandler) HandlePong() { 642 message_archive.msgLog.Debug("received your pong.") 643 } 644 645 func (h *IncomingMessageHandler) HandleGetMsg(msg *p2p_message.MessageGetMsg, sourcePeerId string) { 646 if msg == nil || msg.Hash == nil { 647 message_archive.msgLog.Warn("msg is nil") 648 return 649 } 650 txi := h.Og.TxPool.Get(*msg.Hash) 651 if txi == nil { 652 txi = h.Og.Dag.GetTx(*msg.Hash) 653 } 654 if txi == nil { 655 message_archive.msgLog.WithField("for Hash ", *msg.Hash).Warn("txi not found") 656 return 657 } 658 switch txi.GetType() { 659 case types.TxBaseTypeTx: 660 tx := txi.(*types.Tx) 661 response := p2p_message.MessageNewTx{RawTx: tx.RawTx()} 662 h.Hub.SendToPeer(sourcePeerId, message_archive.MessageTypeNewTx, &response) 663 case types.TxBaseTypeTermChange: 664 tx := txi.(*campaign.TermChange) 665 response := p2p_message.MessageTermChange{RawTermChange: tx.RawTermChange()} 666 h.Hub.SendToPeer(sourcePeerId, message_archive.MessageTypeNewTx, &response) 667 case types.TxBaseTypeCampaign: 668 tx := txi.(*campaign.Campaign) 669 response := p2p_message.MessageCampaign{RawCampaign: tx.RawCampaign()} 670 h.Hub.SendToPeer(sourcePeerId, message_archive.MessageTypeNewTx, &response) 671 case types.TxBaseTypeSequencer: 672 tx := txi.(*types.Sequencer) 673 response := p2p_message.MessageNewSequencer{RawSequencer: tx.RawSequencer()} 674 h.Hub.SendToPeer(sourcePeerId, message_archive.MessageTypeNewSequencer, &response) 675 case types.TxBaseAction: 676 tx := txi.(*archive.ActionTx) 677 response := p2p_message.MessageNewActionTx{ActionTx: tx} 678 h.Hub.SendToPeer(sourcePeerId, message_archive.MessageTypeNewSequencer, &response) 679 } 680 return 681 } 682 683 func (h *IncomingMessageHandler) HandleControlMsg(req *p2p_message.MessageControl, sourceId string) { 684 if req.Hash == nil { 685 message_archive.msgLog.WithError(fmt.Errorf("miss Hash")).Debug("control msg request err") 686 return 687 } 688 689 if !h.TxEnable() { 690 message_archive.msgLog.Debug("incremental received p2p_message.MessageTypeControl but receiveTx disabled") 691 return 692 } 693 hash := *req.Hash 694 txkey := message_archive.NewMsgKey(message_archive.MessageTypeNewTx, hash) 695 if _, err := h.Hub.messageCache.GetIFPresent(txkey); err == nil { 696 message_archive.msgLog.WithField("Hash ", hash).Trace("already got tx of this control msg") 697 return 698 } 699 if item := h.controlMsgCache.get(hash); item != nil { 700 message_archive.msgLog.WithField("Hash ", hash).Trace("duplicated control msg") 701 return 702 } 703 if h.Hub.IsReceivedHash(hash) { 704 message_archive.msgLog.WithField("Hash ", hash).Trace("already received tx of this control msg") 705 } 706 h.controlMsgCache.set(hash, sourceId) 707 message_archive.msgLog.WithField("Hash ", hash).Trace("already received tx of this control msg") 708 } 709 710 func (m *IncomingMessageHandler) Start() { 711 goroutine.New(m.loop) 712 message_archive.msgLog.Info("Message handler started") 713 } 714 715 func (m *IncomingMessageHandler) Stop() { 716 close(m.quit) 717 message_archive.msgLog.Info("Message handler stopped") 718 } 719 720 func (m *IncomingMessageHandler) Name() string { 721 return "IncomingMessageHandler" 722 } 723 724 func (m *IncomingMessageHandler) GetBenchmarks() map[string]interface{} { 725 return map[string]interface{}{ 726 "controlMsgCache": m.controlMsgCache.Len(), 727 } 728 }