github.com/status-im/status-go@v1.1.0/waku/v1/peer.go (about) 1 package v1 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "math" 10 "net" 11 "sync" 12 "time" 13 14 "go.uber.org/zap" 15 16 mapset "github.com/deckarep/golang-set" 17 18 gethcommon "github.com/ethereum/go-ethereum/common" 19 "github.com/ethereum/go-ethereum/crypto" 20 "github.com/ethereum/go-ethereum/p2p" 21 "github.com/ethereum/go-ethereum/p2p/enode" 22 "github.com/ethereum/go-ethereum/rlp" 23 24 "github.com/status-im/status-go/eth-node/types" 25 "github.com/status-im/status-go/waku/common" 26 ) 27 28 type Peer struct { 29 host common.WakuHost 30 rw p2p.MsgReadWriter 31 p2pPeer *p2p.Peer 32 logger *zap.Logger 33 34 quit chan struct{} 35 36 trusted bool 37 powRequirement float64 38 // bloomMu is to allow thread safe access to 39 // the bloom filter 40 bloomMu sync.Mutex 41 bloomFilter []byte 42 // topicInterestMu is to allow thread safe access to 43 // the map of topic interests 44 topicInterestMu sync.Mutex 45 topicInterest map[common.TopicType]bool 46 // fullNode is used to indicate that the node will be accepting any 47 // envelope. The opposite is an "empty node" , which is when 48 // a bloom filter is all 0s or topic interest is an empty map (not nil). 49 // In that case no envelope is accepted. 50 fullNode bool 51 confirmationsEnabled bool 52 packetRateLimitsMu sync.Mutex 53 packetRateLimits common.RateLimits 54 bytesRateLimitsMu sync.Mutex 55 bytesRateLimits common.RateLimits 56 57 stats *common.StatsTracker 58 59 known mapset.Set // Messages already known by the peer to avoid wasting bandwidth 60 } 61 62 func NewPeer(host common.WakuHost, p2pPeer *p2p.Peer, rw p2p.MsgReadWriter, logger *zap.Logger, stats *common.StatsTracker) common.Peer { 63 if logger == nil { 64 logger = zap.NewNop() 65 } 66 67 return &Peer{ 68 host: host, 69 p2pPeer: p2pPeer, 70 logger: logger, 71 rw: rw, 72 trusted: false, 73 powRequirement: 0.0, 74 known: mapset.NewSet(), 75 quit: make(chan struct{}), 76 bloomFilter: common.MakeFullNodeBloom(), 77 fullNode: true, 78 stats: stats, 79 } 80 } 81 82 func (p *Peer) Start() error { 83 if err := p.handshake(); err != nil { 84 return err 85 } 86 go p.update() 87 p.logger.Debug("starting peer", zap.String("peerID", types.EncodeHex(p.ID()))) 88 return nil 89 } 90 91 func (p *Peer) Stop() { 92 close(p.quit) 93 p.logger.Debug("stopping peer", zap.String("peerID", types.EncodeHex(p.ID()))) 94 } 95 96 func (p *Peer) NotifyAboutPowRequirementChange(pow float64) (err error) { 97 i := math.Float64bits(pow) 98 data := StatusOptions{PoWRequirement: &i} 99 err = p2p.Send(p.rw, statusUpdateCode, data) 100 if err != nil { 101 p.stats.AddUpload(data) 102 } 103 return 104 } 105 106 func (p *Peer) NotifyAboutBloomFilterChange(bloom []byte) (err error) { 107 data := StatusOptions{BloomFilter: bloom} 108 err = p2p.Send(p.rw, statusUpdateCode, data) 109 if err != nil { 110 p.stats.AddUpload(data) 111 } 112 return 113 } 114 115 func (p *Peer) NotifyAboutTopicInterestChange(topics []common.TopicType) (err error) { 116 data := StatusOptions{TopicInterest: topics} 117 err = p2p.Send(p.rw, statusUpdateCode, data) 118 if err != nil { 119 p.stats.AddUpload(data) 120 } 121 return 122 } 123 124 func (p *Peer) SetPeerTrusted(trusted bool) { 125 p.trusted = trusted 126 } 127 128 func (p *Peer) RequestHistoricMessages(envelope *common.Envelope) (err error) { 129 err = p2p.Send(p.rw, p2pRequestCode, envelope) 130 if err != nil { 131 p.stats.AddUpload(envelope) 132 } 133 return 134 } 135 136 func (p *Peer) SendHistoricMessageResponse(payload []byte) (err error) { 137 size, r, err := rlp.EncodeToReader(payload) 138 if err != nil { 139 return err 140 } 141 142 err = p.rw.WriteMsg(p2p.Msg{Code: p2pRequestCompleteCode, Size: uint32(size), Payload: r}) 143 if err != nil { 144 p.stats.AddUpload(payload) 145 } 146 return 147 } 148 149 func (p *Peer) SendP2PMessages(envelopes []*common.Envelope) (err error) { 150 err = p2p.Send(p.rw, p2pMessageCode, envelopes) 151 if err != nil { 152 p.stats.AddUpload(envelopes) 153 } 154 return 155 } 156 157 func (p *Peer) SendRawP2PDirect(envelopes []rlp.RawValue) (err error) { 158 err = p2p.Send(p.rw, p2pMessageCode, envelopes) 159 if err != nil { 160 p.stats.AddUpload(envelopes) 161 } 162 return 163 } 164 165 func (p *Peer) SetRWWriter(rw p2p.MsgReadWriter) { 166 p.rw = rw 167 } 168 169 // Mark marks an envelope known to the peer so that it won't be sent back. 170 func (p *Peer) Mark(envelope *common.Envelope) { 171 p.known.Add(envelope.Hash()) 172 } 173 174 // Marked checks if an envelope is already known to the remote peer. 175 func (p *Peer) Marked(envelope *common.Envelope) bool { 176 return p.known.Contains(envelope.Hash()) 177 } 178 179 func (p *Peer) BloomFilter() []byte { 180 p.bloomMu.Lock() 181 defer p.bloomMu.Unlock() 182 183 bloomFilterCopy := make([]byte, len(p.bloomFilter)) 184 copy(bloomFilterCopy, p.bloomFilter) 185 return bloomFilterCopy 186 } 187 188 func (p *Peer) PoWRequirement() float64 { 189 return p.powRequirement 190 } 191 192 func (p *Peer) ConfirmationsEnabled() bool { 193 return p.confirmationsEnabled 194 } 195 196 // ID returns a peer's id 197 func (p *Peer) ID() []byte { 198 id := p.p2pPeer.ID() 199 return id[:] 200 } 201 202 func (p *Peer) EnodeID() enode.ID { 203 return p.p2pPeer.ID() 204 } 205 206 func (p *Peer) IP() net.IP { 207 return p.p2pPeer.Node().IP() 208 } 209 210 func (p *Peer) Run() error { 211 logger := p.logger.Named("Run") 212 213 for { 214 // fetch the next packet 215 packet, err := p.rw.ReadMsg() 216 if err != nil { 217 logger.Info("failed to read a message", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 218 return err 219 } 220 221 p.stats.AddDownloadBytes(uint64(packet.Size)) 222 223 if packet.Size > p.host.MaxMessageSize() { 224 logger.Warn("oversize message received", zap.String("peerID", types.EncodeHex(p.ID())), zap.Uint32("size", packet.Size)) 225 return errors.New("oversize message received") 226 } 227 228 if err := p.handlePacket(packet); err != nil { 229 logger.Warn("failed to handle packet message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 230 } 231 _ = packet.Discard() 232 } 233 } 234 235 func (p *Peer) handlePacket(packet p2p.Msg) error { 236 switch packet.Code { 237 case messagesCode: 238 if err := p.handleMessagesCode(packet); err != nil { 239 p.logger.Warn("failed to handle messagesCode message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 240 return err 241 } 242 case messageResponseCode: 243 if err := p.handleMessageResponseCode(packet); err != nil { 244 p.logger.Warn("failed to handle messageResponseCode message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 245 return err 246 } 247 case batchAcknowledgedCode: 248 if err := p.handleBatchAcknowledgeCode(packet); err != nil { 249 p.logger.Warn("failed to handle batchAcknowledgedCode message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 250 return err 251 } 252 case statusUpdateCode: 253 if err := p.handleStatusUpdateCode(packet); err != nil { 254 p.logger.Warn("failed to decode status update message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 255 return err 256 } 257 case p2pMessageCode: 258 if err := p.handleP2PMessageCode(packet); err != nil { 259 p.logger.Warn("failed to decode direct message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 260 return err 261 } 262 case p2pRequestCode: 263 if err := p.handleP2PRequestCode(packet); err != nil { 264 p.logger.Warn("failed to decode p2p request message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 265 return err 266 } 267 case p2pRequestCompleteCode: 268 if err := p.handleP2PRequestCompleteCode(packet); err != nil { 269 p.logger.Warn("failed to decode p2p request complete message, peer will be disconnected", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 270 return err 271 } 272 default: 273 // New message common might be implemented in the future versions of Waku. 274 // For forward compatibility, just ignore. 275 p.logger.Debug("ignored packet with message code", zap.Uint64("code", packet.Code)) 276 } 277 278 return nil 279 } 280 281 func (p *Peer) handleMessagesCode(packet p2p.Msg) error { 282 // decode the contained envelopes 283 data, err := ioutil.ReadAll(packet.Payload) 284 if err != nil { 285 common.EnvelopesRejectedCounter.WithLabelValues("failed_read").Inc() 286 return fmt.Errorf("failed to read packet payload: %v", err) 287 } 288 289 var envelopes []*common.Envelope 290 if err := rlp.DecodeBytes(data, &envelopes); err != nil { 291 common.EnvelopesRejectedCounter.WithLabelValues("invalid_data").Inc() 292 return fmt.Errorf("invalid payload: %v", err) 293 } 294 295 envelopeErrors, err := p.host.OnNewEnvelopes(envelopes, p) 296 297 if p.host.ConfirmationsEnabled() { 298 go p.sendConfirmation(data, envelopeErrors) // nolint: errcheck 299 } 300 301 return err 302 } 303 304 func (p *Peer) handleMessageResponseCode(packet p2p.Msg) error { 305 var resp MultiVersionResponse 306 if err := packet.Decode(&resp); err != nil { 307 common.EnvelopesRejectedCounter.WithLabelValues("failed_read").Inc() 308 return fmt.Errorf("invalid response message: %v", err) 309 } 310 if resp.Version != 1 { 311 p.logger.Info("received unsupported version of MultiVersionResponse for messageResponseCode packet", zap.Uint("version", resp.Version)) 312 return nil 313 } 314 315 response, err := resp.DecodeResponse1() 316 if err != nil { 317 common.EnvelopesRejectedCounter.WithLabelValues("invalid_data").Inc() 318 return fmt.Errorf("failed to decode response message: %v", err) 319 } 320 321 return p.host.OnMessagesResponse(response, p) 322 } 323 324 func (p *Peer) handleP2PRequestCode(packet p2p.Msg) error { 325 // Must be processed if mail server is implemented. Otherwise ignore. 326 if !p.host.Mailserver() { 327 return nil 328 } 329 330 // Read all data as we will try to decode it possibly twice. 331 data, err := ioutil.ReadAll(packet.Payload) 332 if err != nil { 333 return fmt.Errorf("invalid p2p request messages: %v", err) 334 } 335 r := bytes.NewReader(data) 336 packet.Payload = r 337 338 var requestDeprecated common.Envelope 339 errDepReq := packet.Decode(&requestDeprecated) 340 if errDepReq == nil { 341 return p.host.OnDeprecatedMessagesRequest(&requestDeprecated, p) 342 } 343 p.logger.Info("failed to decode p2p request message (deprecated)", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(errDepReq)) 344 345 // As we failed to decode the request, let's set the offset 346 // to the beginning and try decode it again. 347 if _, err := r.Seek(0, io.SeekStart); err != nil { 348 return fmt.Errorf("invalid p2p request message: %v", err) 349 } 350 351 var request common.MessagesRequest 352 errReq := packet.Decode(&request) 353 if errReq == nil { 354 return p.host.OnMessagesRequest(request, p) 355 } 356 p.logger.Info("failed to decode p2p request message", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(errReq)) 357 358 return errors.New("invalid p2p request message") 359 } 360 361 func (p *Peer) handleBatchAcknowledgeCode(packet p2p.Msg) error { 362 var batchHash gethcommon.Hash 363 if err := packet.Decode(&batchHash); err != nil { 364 return fmt.Errorf("invalid batch ack message: %v", err) 365 } 366 return p.host.OnBatchAcknowledged(batchHash, p) 367 } 368 369 func (p *Peer) handleStatusUpdateCode(packet p2p.Msg) error { 370 var StatusOptions StatusOptions 371 err := packet.Decode(&StatusOptions) 372 if err != nil { 373 p.logger.Error("failed to decode status-options", zap.Error(err)) 374 common.EnvelopesRejectedCounter.WithLabelValues("invalid_settings_changed").Inc() 375 return err 376 } 377 378 return p.setOptions(StatusOptions) 379 380 } 381 382 func (p *Peer) handleP2PMessageCode(packet p2p.Msg) error { 383 // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. 384 // this message is not supposed to be forwarded to other peers, and 385 // therefore might not satisfy the PoW, expiry and other requirements. 386 // these messages are only accepted from the trusted peer. 387 if !p.trusted { 388 return nil 389 } 390 391 var ( 392 envelopes []*common.Envelope 393 err error 394 ) 395 396 if err = packet.Decode(&envelopes); err != nil { 397 return fmt.Errorf("invalid direct message payload: %v", err) 398 } 399 400 return p.host.OnNewP2PEnvelopes(envelopes) 401 } 402 403 func (p *Peer) handleP2PRequestCompleteCode(packet p2p.Msg) error { 404 if !p.trusted { 405 return nil 406 } 407 408 var payload []byte 409 if err := packet.Decode(&payload); err != nil { 410 return fmt.Errorf("invalid p2p request complete message: %v", err) 411 } 412 return p.host.OnP2PRequestCompleted(payload, p) 413 } 414 415 // sendConfirmation sends messageResponseCode and batchAcknowledgedCode messages. 416 func (p *Peer) sendConfirmation(data []byte, envelopeErrors []common.EnvelopeError) (err error) { 417 batchHash := crypto.Keccak256Hash(data) 418 msg := NewMessagesResponse(batchHash, envelopeErrors) 419 err = p2p.Send(p.rw, messageResponseCode, msg) 420 if err != nil { 421 p.stats.AddUpload(msg) 422 return 423 } 424 425 err = p2p.Send(p.rw, batchAcknowledgedCode, batchHash) // DEPRECATED 426 if err != nil { 427 p.stats.AddUpload(batchHash) 428 } 429 430 return 431 } 432 433 // handshake sends the protocol initiation status message to the remote peer and 434 // verifies the remote status too. 435 func (p *Peer) handshake() error { 436 // Send the handshake status message asynchronously 437 errc := make(chan error, 1) 438 opts := StatusOptionsFromHost(p.host) 439 go func() { 440 err := p2p.Send(p.rw, statusCode, opts) 441 if err != nil { 442 p.stats.AddUpload(statusCode) 443 } 444 errc <- err 445 }() 446 447 // Fetch the remote status packet and verify protocol match 448 packet, err := p.rw.ReadMsg() 449 if err != nil { 450 return err 451 } 452 453 p.stats.AddDownloadBytes(uint64(packet.Size)) 454 455 if packet.Code != statusCode { 456 return fmt.Errorf("p [%x] sent packet %x before status packet", p.ID(), packet.Code) 457 } 458 459 var peerOptions StatusOptions 460 s := rlp.NewStream(packet.Payload, uint64(packet.Size)) 461 462 // Decode and validate other status packet options. 463 if err := s.Decode(&peerOptions); err != nil { 464 return fmt.Errorf("p [%x]: failed to decode status options: %v", p.ID(), err) 465 } 466 467 if err := p.setOptions(peerOptions.WithDefaults()); err != nil { 468 return fmt.Errorf("p [%x]: failed to set options: %v", p.ID(), err) 469 } 470 if err := <-errc; err != nil { 471 return fmt.Errorf("p [%x] failed to send status packet: %v", p.ID(), err) 472 } 473 474 _ = packet.Discard() 475 return nil 476 } 477 478 // update executes periodic operations on the peer, including message transmission 479 // and expiration. 480 func (p *Peer) update() { 481 // Start the tickers for the updates 482 expire := time.NewTicker(common.ExpirationCycle) 483 transmit := time.NewTicker(common.TransmissionCycle) 484 485 // Loop and transmit until termination is requested 486 for { 487 select { 488 case <-expire.C: 489 p.expire() 490 491 case <-transmit.C: 492 if err := p.broadcast(); err != nil { 493 p.logger.Debug("broadcasting failed", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 494 return 495 } 496 497 case <-p.quit: 498 return 499 } 500 } 501 } 502 503 func (p *Peer) setOptions(peerOptions StatusOptions) error { 504 505 p.logger.Debug("settings options", zap.String("peerID", types.EncodeHex(p.ID())), zap.Any("Options", peerOptions)) 506 507 if err := peerOptions.Validate(); err != nil { 508 return fmt.Errorf("p [%x]: sent invalid options: %v", p.ID(), err) 509 } 510 // Validate and save peer's PoW. 511 pow := peerOptions.PoWRequirementF() 512 if pow != nil { 513 if math.IsInf(*pow, 0) || math.IsNaN(*pow) || *pow < 0.0 { 514 return fmt.Errorf("p [%x]: sent bad status message: invalid pow", p.ID()) 515 } 516 p.powRequirement = *pow 517 } 518 519 if peerOptions.TopicInterest != nil { 520 p.setTopicInterest(peerOptions.TopicInterest) 521 } else if peerOptions.BloomFilter != nil { 522 // Validate and save peer's bloom filters. 523 bloom := peerOptions.BloomFilter 524 bloomSize := len(bloom) 525 if bloomSize != 0 && bloomSize != common.BloomFilterSize { 526 return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), bloomSize) 527 } 528 p.setBloomFilter(bloom) 529 } 530 531 if peerOptions.LightNodeEnabled != nil { 532 // Validate and save other peer's options. 533 if *peerOptions.LightNodeEnabled && p.host.LightClientMode() && p.host.LightClientModeConnectionRestricted() { 534 return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID()) 535 } 536 } 537 if peerOptions.ConfirmationsEnabled != nil { 538 p.confirmationsEnabled = *peerOptions.ConfirmationsEnabled 539 } 540 if peerOptions.PacketRateLimits != nil { 541 p.setPacketRateLimits(*peerOptions.PacketRateLimits) 542 } 543 if peerOptions.BytesRateLimits != nil { 544 p.setBytesRateLimits(*peerOptions.BytesRateLimits) 545 } 546 547 return nil 548 } 549 550 // expire iterates over all the known envelopes in the host and removes all 551 // expired (unknown) ones from the known list. 552 func (p *Peer) expire() { 553 unmark := make(map[gethcommon.Hash]struct{}) 554 p.known.Each(func(v interface{}) bool { 555 if !p.host.IsEnvelopeCached(v.(gethcommon.Hash)) { 556 unmark[v.(gethcommon.Hash)] = struct{}{} 557 } 558 return true 559 }) 560 // Dump all known but no longer cached 561 for hash := range unmark { 562 p.known.Remove(hash) 563 } 564 } 565 566 // broadcast iterates over the collection of envelopes and transmits yet unknown 567 // ones over the network. 568 func (p *Peer) broadcast() error { 569 envelopes := p.host.Envelopes() 570 bundle := make([]*common.Envelope, 0, len(envelopes)) 571 for _, envelope := range envelopes { 572 if !p.Marked(envelope) && envelope.PoW() >= p.powRequirement && p.topicOrBloomMatch(envelope) { 573 bundle = append(bundle, envelope) 574 } 575 } 576 577 if len(bundle) == 0 { 578 return nil 579 } 580 581 batchHash, err := p.SendBundle(bundle) 582 if err != nil { 583 p.logger.Debug("failed to deliver envelopes", zap.String("peerID", types.EncodeHex(p.ID())), zap.Error(err)) 584 return err 585 } 586 587 // mark envelopes only if they were successfully sent 588 for _, e := range bundle { 589 p.Mark(e) 590 event := common.EnvelopeEvent{ 591 Event: common.EventEnvelopeSent, 592 Hash: e.Hash(), 593 Peer: p.EnodeID(), 594 } 595 if p.confirmationsEnabled { 596 event.Batch = batchHash 597 } 598 p.host.SendEnvelopeEvent(event) 599 } 600 p.logger.Debug("broadcasted bundles successfully", zap.String("peerID", types.EncodeHex(p.ID())), zap.Int("count", len(bundle))) 601 return nil 602 } 603 604 func (p *Peer) SendBundle(bundle []*common.Envelope) (rst gethcommon.Hash, err error) { 605 data, err := rlp.EncodeToBytes(bundle) 606 if err != nil { 607 return 608 } 609 610 msg := p2p.Msg{ 611 Code: messagesCode, 612 Size: uint32(len(data)), 613 Payload: bytes.NewBuffer(data), 614 } 615 616 err = p.rw.WriteMsg(msg) 617 if err != nil { 618 return 619 } 620 621 p.stats.AddUpload(bundle) 622 623 return crypto.Keccak256Hash(data), nil 624 } 625 626 func (p *Peer) setBloomFilter(bloom []byte) { 627 p.bloomMu.Lock() 628 defer p.bloomMu.Unlock() 629 p.bloomFilter = bloom 630 p.fullNode = common.IsFullNode(bloom) 631 if p.fullNode && p.bloomFilter == nil { 632 p.bloomFilter = common.MakeFullNodeBloom() 633 } 634 p.topicInterest = nil 635 } 636 637 func (p *Peer) setTopicInterest(topicInterest []common.TopicType) { 638 p.topicInterestMu.Lock() 639 defer p.topicInterestMu.Unlock() 640 if topicInterest == nil { 641 p.topicInterest = nil 642 return 643 } 644 p.topicInterest = make(map[common.TopicType]bool) 645 for _, topic := range topicInterest { 646 p.topicInterest[topic] = true 647 } 648 p.fullNode = false 649 p.bloomFilter = nil 650 } 651 652 func (p *Peer) setPacketRateLimits(r common.RateLimits) { 653 p.packetRateLimitsMu.Lock() 654 p.packetRateLimits = r 655 p.packetRateLimitsMu.Unlock() 656 } 657 658 func (p *Peer) setBytesRateLimits(r common.RateLimits) { 659 p.bytesRateLimitsMu.Lock() 660 p.bytesRateLimits = r 661 p.bytesRateLimitsMu.Unlock() 662 } 663 664 // topicOrBloomMatch matches against topic-interest if topic interest 665 // is not nil. Otherwise it will match against the bloom-filter. 666 // If the bloom-filter is nil, or full, the node is considered a full-node 667 // and any envelope will be accepted. An empty topic-interest (but not nil) 668 // signals that we are not interested in any envelope. 669 func (p *Peer) topicOrBloomMatch(env *common.Envelope) bool { 670 p.topicInterestMu.Lock() 671 topicInterestMode := p.topicInterest != nil 672 p.topicInterestMu.Unlock() 673 674 if topicInterestMode { 675 return p.topicInterestMatch(env) 676 } 677 return p.bloomMatch(env) 678 } 679 680 func (p *Peer) topicInterestMatch(env *common.Envelope) bool { 681 p.topicInterestMu.Lock() 682 defer p.topicInterestMu.Unlock() 683 684 if p.topicInterest == nil { 685 return false 686 } 687 688 return p.topicInterest[env.Topic] 689 } 690 691 func (p *Peer) bloomMatch(env *common.Envelope) bool { 692 p.bloomMu.Lock() 693 defer p.bloomMu.Unlock() 694 return p.fullNode || common.BloomFilterMatch(p.bloomFilter, env.Bloom()) 695 }