github.hscsec.cn/scroll-tech/go-ethereum@v1.9.7/whisper/whisperv6/whisper.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package whisperv6 18 19 import ( 20 "bytes" 21 "crypto/ecdsa" 22 "crypto/sha256" 23 "fmt" 24 "math" 25 "runtime" 26 "sync" 27 "time" 28 29 mapset "github.com/deckarep/golang-set" 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/crypto" 32 "github.com/ethereum/go-ethereum/log" 33 "github.com/ethereum/go-ethereum/p2p" 34 "github.com/ethereum/go-ethereum/rlp" 35 "github.com/ethereum/go-ethereum/rpc" 36 "github.com/syndtr/goleveldb/leveldb/errors" 37 "golang.org/x/crypto/pbkdf2" 38 "golang.org/x/sync/syncmap" 39 ) 40 41 // Statistics holds several message-related counter for analytics 42 // purposes. 43 type Statistics struct { 44 messagesCleared int 45 memoryCleared int 46 memoryUsed int 47 cycles int 48 totalMessagesCleared int 49 } 50 51 const ( 52 maxMsgSizeIdx = iota // Maximal message length allowed by the whisper node 53 overflowIdx // Indicator of message queue overflow 54 minPowIdx // Minimal PoW required by the whisper node 55 minPowToleranceIdx // Minimal PoW tolerated by the whisper node for a limited time 56 bloomFilterIdx // Bloom filter for topics of interest for this node 57 bloomFilterToleranceIdx // Bloom filter tolerated by the whisper node for a limited time 58 lightClientModeIdx // Light client mode. (does not forward any messages) 59 restrictConnectionBetweenLightClientsIdx // Restrict connection between two light clients 60 ) 61 62 // Whisper represents a dark communication interface through the Ethereum 63 // network, using its very own P2P communication layer. 64 type Whisper struct { 65 protocol p2p.Protocol // Protocol description and parameters 66 filters *Filters // Message filters installed with Subscribe function 67 68 privateKeys map[string]*ecdsa.PrivateKey // Private key storage 69 symKeys map[string][]byte // Symmetric key storage 70 keyMu sync.RWMutex // Mutex associated with key storages 71 72 poolMu sync.RWMutex // Mutex to sync the message and expiration pools 73 envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node 74 expirations map[uint32]mapset.Set // Message expiration pool 75 76 peerMu sync.RWMutex // Mutex to sync the active peer set 77 peers map[*Peer]struct{} // Set of currently active peers 78 79 messageQueue chan *Envelope // Message queue for normal whisper messages 80 p2pMsgQueue chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further) 81 quit chan struct{} // Channel used for graceful exit 82 83 settings syncmap.Map // holds configuration settings that can be dynamically changed 84 85 syncAllowance int // maximum time in seconds allowed to process the whisper-related messages 86 87 statsMu sync.Mutex // guard stats 88 stats Statistics // Statistics of whisper node 89 90 mailServer MailServer // MailServer interface 91 } 92 93 // New creates a Whisper client ready to communicate through the Ethereum P2P network. 94 func New(cfg *Config) *Whisper { 95 if cfg == nil { 96 cfg = &DefaultConfig 97 } 98 99 whisper := &Whisper{ 100 privateKeys: make(map[string]*ecdsa.PrivateKey), 101 symKeys: make(map[string][]byte), 102 envelopes: make(map[common.Hash]*Envelope), 103 expirations: make(map[uint32]mapset.Set), 104 peers: make(map[*Peer]struct{}), 105 messageQueue: make(chan *Envelope, messageQueueLimit), 106 p2pMsgQueue: make(chan *Envelope, messageQueueLimit), 107 quit: make(chan struct{}), 108 syncAllowance: DefaultSyncAllowance, 109 } 110 111 whisper.filters = NewFilters(whisper) 112 113 whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW) 114 whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize) 115 whisper.settings.Store(overflowIdx, false) 116 whisper.settings.Store(restrictConnectionBetweenLightClientsIdx, cfg.RestrictConnectionBetweenLightClients) 117 118 // p2p whisper sub protocol handler 119 whisper.protocol = p2p.Protocol{ 120 Name: ProtocolName, 121 Version: uint(ProtocolVersion), 122 Length: NumberOfMessageCodes, 123 Run: whisper.HandlePeer, 124 NodeInfo: func() interface{} { 125 return map[string]interface{}{ 126 "version": ProtocolVersionStr, 127 "maxMessageSize": whisper.MaxMessageSize(), 128 "minimumPoW": whisper.MinPow(), 129 } 130 }, 131 } 132 133 return whisper 134 } 135 136 // MinPow returns the PoW value required by this node. 137 func (whisper *Whisper) MinPow() float64 { 138 val, exist := whisper.settings.Load(minPowIdx) 139 if !exist || val == nil { 140 return DefaultMinimumPoW 141 } 142 v, ok := val.(float64) 143 if !ok { 144 log.Error("Error loading minPowIdx, using default") 145 return DefaultMinimumPoW 146 } 147 return v 148 } 149 150 // MinPowTolerance returns the value of minimum PoW which is tolerated for a limited 151 // time after PoW was changed. If sufficient time have elapsed or no change of PoW 152 // have ever occurred, the return value will be the same as return value of MinPow(). 153 func (whisper *Whisper) MinPowTolerance() float64 { 154 val, exist := whisper.settings.Load(minPowToleranceIdx) 155 if !exist || val == nil { 156 return DefaultMinimumPoW 157 } 158 return val.(float64) 159 } 160 161 // BloomFilter returns the aggregated bloom filter for all the topics of interest. 162 // The nodes are required to send only messages that match the advertised bloom filter. 163 // If a message does not match the bloom, it will tantamount to spam, and the peer will 164 // be disconnected. 165 func (whisper *Whisper) BloomFilter() []byte { 166 val, exist := whisper.settings.Load(bloomFilterIdx) 167 if !exist || val == nil { 168 return nil 169 } 170 return val.([]byte) 171 } 172 173 // BloomFilterTolerance returns the bloom filter which is tolerated for a limited 174 // time after new bloom was advertised to the peers. If sufficient time have elapsed 175 // or no change of bloom filter have ever occurred, the return value will be the same 176 // as return value of BloomFilter(). 177 func (whisper *Whisper) BloomFilterTolerance() []byte { 178 val, exist := whisper.settings.Load(bloomFilterToleranceIdx) 179 if !exist || val == nil { 180 return nil 181 } 182 return val.([]byte) 183 } 184 185 // MaxMessageSize returns the maximum accepted message size. 186 func (whisper *Whisper) MaxMessageSize() uint32 { 187 val, _ := whisper.settings.Load(maxMsgSizeIdx) 188 return val.(uint32) 189 } 190 191 // Overflow returns an indication if the message queue is full. 192 func (whisper *Whisper) Overflow() bool { 193 val, _ := whisper.settings.Load(overflowIdx) 194 return val.(bool) 195 } 196 197 // APIs returns the RPC descriptors the Whisper implementation offers 198 func (whisper *Whisper) APIs() []rpc.API { 199 return []rpc.API{ 200 { 201 Namespace: ProtocolName, 202 Version: ProtocolVersionStr, 203 Service: NewPublicWhisperAPI(whisper), 204 Public: true, 205 }, 206 } 207 } 208 209 // RegisterServer registers MailServer interface. 210 // MailServer will process all the incoming messages with p2pRequestCode. 211 func (whisper *Whisper) RegisterServer(server MailServer) { 212 whisper.mailServer = server 213 } 214 215 // Protocols returns the whisper sub-protocols ran by this particular client. 216 func (whisper *Whisper) Protocols() []p2p.Protocol { 217 return []p2p.Protocol{whisper.protocol} 218 } 219 220 // Version returns the whisper sub-protocols version number. 221 func (whisper *Whisper) Version() uint { 222 return whisper.protocol.Version 223 } 224 225 // SetMaxMessageSize sets the maximal message size allowed by this node 226 func (whisper *Whisper) SetMaxMessageSize(size uint32) error { 227 if size > MaxMessageSize { 228 return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) 229 } 230 whisper.settings.Store(maxMsgSizeIdx, size) 231 return nil 232 } 233 234 // SetBloomFilter sets the new bloom filter 235 func (whisper *Whisper) SetBloomFilter(bloom []byte) error { 236 if len(bloom) != BloomFilterSize { 237 return fmt.Errorf("invalid bloom filter size: %d", len(bloom)) 238 } 239 240 b := make([]byte, BloomFilterSize) 241 copy(b, bloom) 242 243 whisper.settings.Store(bloomFilterIdx, b) 244 whisper.notifyPeersAboutBloomFilterChange(b) 245 246 go func() { 247 // allow some time before all the peers have processed the notification 248 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 249 whisper.settings.Store(bloomFilterToleranceIdx, b) 250 }() 251 252 return nil 253 } 254 255 // SetMinimumPoW sets the minimal PoW required by this node 256 func (whisper *Whisper) SetMinimumPoW(val float64) error { 257 if val < 0.0 { 258 return fmt.Errorf("invalid PoW: %f", val) 259 } 260 261 whisper.settings.Store(minPowIdx, val) 262 whisper.notifyPeersAboutPowRequirementChange(val) 263 264 go func() { 265 // allow some time before all the peers have processed the notification 266 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 267 whisper.settings.Store(minPowToleranceIdx, val) 268 }() 269 270 return nil 271 } 272 273 // SetMinimumPowTest sets the minimal PoW in test environment 274 func (whisper *Whisper) SetMinimumPowTest(val float64) { 275 whisper.settings.Store(minPowIdx, val) 276 whisper.notifyPeersAboutPowRequirementChange(val) 277 whisper.settings.Store(minPowToleranceIdx, val) 278 } 279 280 //SetLightClientMode makes node light client (does not forward any messages) 281 func (whisper *Whisper) SetLightClientMode(v bool) { 282 whisper.settings.Store(lightClientModeIdx, v) 283 } 284 285 //LightClientMode indicates is this node is light client (does not forward any messages) 286 func (whisper *Whisper) LightClientMode() bool { 287 val, exist := whisper.settings.Load(lightClientModeIdx) 288 if !exist || val == nil { 289 return false 290 } 291 v, ok := val.(bool) 292 return v && ok 293 } 294 295 //LightClientModeConnectionRestricted indicates that connection to light client in light client mode not allowed 296 func (whisper *Whisper) LightClientModeConnectionRestricted() bool { 297 val, exist := whisper.settings.Load(restrictConnectionBetweenLightClientsIdx) 298 if !exist || val == nil { 299 return false 300 } 301 v, ok := val.(bool) 302 return v && ok 303 } 304 305 func (whisper *Whisper) notifyPeersAboutPowRequirementChange(pow float64) { 306 arr := whisper.getPeers() 307 for _, p := range arr { 308 err := p.notifyAboutPowRequirementChange(pow) 309 if err != nil { 310 // allow one retry 311 err = p.notifyAboutPowRequirementChange(pow) 312 } 313 if err != nil { 314 log.Warn("failed to notify peer about new pow requirement", "peer", p.ID(), "error", err) 315 } 316 } 317 } 318 319 func (whisper *Whisper) notifyPeersAboutBloomFilterChange(bloom []byte) { 320 arr := whisper.getPeers() 321 for _, p := range arr { 322 err := p.notifyAboutBloomFilterChange(bloom) 323 if err != nil { 324 // allow one retry 325 err = p.notifyAboutBloomFilterChange(bloom) 326 } 327 if err != nil { 328 log.Warn("failed to notify peer about new bloom filter", "peer", p.ID(), "error", err) 329 } 330 } 331 } 332 333 func (whisper *Whisper) getPeers() []*Peer { 334 arr := make([]*Peer, len(whisper.peers)) 335 i := 0 336 whisper.peerMu.Lock() 337 for p := range whisper.peers { 338 arr[i] = p 339 i++ 340 } 341 whisper.peerMu.Unlock() 342 return arr 343 } 344 345 // getPeer retrieves peer by ID 346 func (whisper *Whisper) getPeer(peerID []byte) (*Peer, error) { 347 whisper.peerMu.Lock() 348 defer whisper.peerMu.Unlock() 349 for p := range whisper.peers { 350 id := p.peer.ID() 351 if bytes.Equal(peerID, id[:]) { 352 return p, nil 353 } 354 } 355 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 356 } 357 358 // AllowP2PMessagesFromPeer marks specific peer trusted, 359 // which will allow it to send historic (expired) messages. 360 func (whisper *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error { 361 p, err := whisper.getPeer(peerID) 362 if err != nil { 363 return err 364 } 365 p.trusted = true 366 return nil 367 } 368 369 // RequestHistoricMessages sends a message with p2pRequestCode to a specific peer, 370 // which is known to implement MailServer interface, and is supposed to process this 371 // request and respond with a number of peer-to-peer messages (possibly expired), 372 // which are not supposed to be forwarded any further. 373 // The whisper protocol is agnostic of the format and contents of envelope. 374 func (whisper *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { 375 p, err := whisper.getPeer(peerID) 376 if err != nil { 377 return err 378 } 379 p.trusted = true 380 return p2p.Send(p.ws, p2pRequestCode, envelope) 381 } 382 383 // SendP2PMessage sends a peer-to-peer message to a specific peer. 384 func (whisper *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { 385 p, err := whisper.getPeer(peerID) 386 if err != nil { 387 return err 388 } 389 return whisper.SendP2PDirect(p, envelope) 390 } 391 392 // SendP2PDirect sends a peer-to-peer message to a specific peer. 393 func (whisper *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 394 return p2p.Send(peer.ws, p2pMessageCode, envelope) 395 } 396 397 // NewKeyPair generates a new cryptographic identity for the client, and injects 398 // it into the known identities for message decryption. Returns ID of the new key pair. 399 func (whisper *Whisper) NewKeyPair() (string, error) { 400 key, err := crypto.GenerateKey() 401 if err != nil || !validatePrivateKey(key) { 402 key, err = crypto.GenerateKey() // retry once 403 } 404 if err != nil { 405 return "", err 406 } 407 if !validatePrivateKey(key) { 408 return "", fmt.Errorf("failed to generate valid key") 409 } 410 411 id, err := GenerateRandomID() 412 if err != nil { 413 return "", fmt.Errorf("failed to generate ID: %s", err) 414 } 415 416 whisper.keyMu.Lock() 417 defer whisper.keyMu.Unlock() 418 419 if whisper.privateKeys[id] != nil { 420 return "", fmt.Errorf("failed to generate unique ID") 421 } 422 whisper.privateKeys[id] = key 423 return id, nil 424 } 425 426 // DeleteKeyPair deletes the specified key if it exists. 427 func (whisper *Whisper) DeleteKeyPair(key string) bool { 428 whisper.keyMu.Lock() 429 defer whisper.keyMu.Unlock() 430 431 if whisper.privateKeys[key] != nil { 432 delete(whisper.privateKeys, key) 433 return true 434 } 435 return false 436 } 437 438 // AddKeyPair imports a asymmetric private key and returns it identifier. 439 func (whisper *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 440 id, err := GenerateRandomID() 441 if err != nil { 442 return "", fmt.Errorf("failed to generate ID: %s", err) 443 } 444 445 whisper.keyMu.Lock() 446 whisper.privateKeys[id] = key 447 whisper.keyMu.Unlock() 448 449 return id, nil 450 } 451 452 // HasKeyPair checks if the whisper node is configured with the private key 453 // of the specified public pair. 454 func (whisper *Whisper) HasKeyPair(id string) bool { 455 whisper.keyMu.RLock() 456 defer whisper.keyMu.RUnlock() 457 return whisper.privateKeys[id] != nil 458 } 459 460 // GetPrivateKey retrieves the private key of the specified identity. 461 func (whisper *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 462 whisper.keyMu.RLock() 463 defer whisper.keyMu.RUnlock() 464 key := whisper.privateKeys[id] 465 if key == nil { 466 return nil, fmt.Errorf("invalid id") 467 } 468 return key, nil 469 } 470 471 // GenerateSymKey generates a random symmetric key and stores it under id, 472 // which is then returned. Will be used in the future for session key exchange. 473 func (whisper *Whisper) GenerateSymKey() (string, error) { 474 key, err := generateSecureRandomData(aesKeyLength) 475 if err != nil { 476 return "", err 477 } else if !validateDataIntegrity(key, aesKeyLength) { 478 return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 479 } 480 481 id, err := GenerateRandomID() 482 if err != nil { 483 return "", fmt.Errorf("failed to generate ID: %s", err) 484 } 485 486 whisper.keyMu.Lock() 487 defer whisper.keyMu.Unlock() 488 489 if whisper.symKeys[id] != nil { 490 return "", fmt.Errorf("failed to generate unique ID") 491 } 492 whisper.symKeys[id] = key 493 return id, nil 494 } 495 496 // AddSymKeyDirect stores the key, and returns its id. 497 func (whisper *Whisper) AddSymKeyDirect(key []byte) (string, error) { 498 if len(key) != aesKeyLength { 499 return "", fmt.Errorf("wrong key size: %d", len(key)) 500 } 501 502 id, err := GenerateRandomID() 503 if err != nil { 504 return "", fmt.Errorf("failed to generate ID: %s", err) 505 } 506 507 whisper.keyMu.Lock() 508 defer whisper.keyMu.Unlock() 509 510 if whisper.symKeys[id] != nil { 511 return "", fmt.Errorf("failed to generate unique ID") 512 } 513 whisper.symKeys[id] = key 514 return id, nil 515 } 516 517 // AddSymKeyFromPassword generates the key from password, stores it, and returns its id. 518 func (whisper *Whisper) AddSymKeyFromPassword(password string) (string, error) { 519 id, err := GenerateRandomID() 520 if err != nil { 521 return "", fmt.Errorf("failed to generate ID: %s", err) 522 } 523 if whisper.HasSymKey(id) { 524 return "", fmt.Errorf("failed to generate unique ID") 525 } 526 527 // kdf should run no less than 0.1 seconds on an average computer, 528 // because it's an once in a session experience 529 derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New) 530 if err != nil { 531 return "", err 532 } 533 534 whisper.keyMu.Lock() 535 defer whisper.keyMu.Unlock() 536 537 // double check is necessary, because deriveKeyMaterial() is very slow 538 if whisper.symKeys[id] != nil { 539 return "", fmt.Errorf("critical error: failed to generate unique ID") 540 } 541 whisper.symKeys[id] = derived 542 return id, nil 543 } 544 545 // HasSymKey returns true if there is a key associated with the given id. 546 // Otherwise returns false. 547 func (whisper *Whisper) HasSymKey(id string) bool { 548 whisper.keyMu.RLock() 549 defer whisper.keyMu.RUnlock() 550 return whisper.symKeys[id] != nil 551 } 552 553 // DeleteSymKey deletes the key associated with the name string if it exists. 554 func (whisper *Whisper) DeleteSymKey(id string) bool { 555 whisper.keyMu.Lock() 556 defer whisper.keyMu.Unlock() 557 if whisper.symKeys[id] != nil { 558 delete(whisper.symKeys, id) 559 return true 560 } 561 return false 562 } 563 564 // GetSymKey returns the symmetric key associated with the given id. 565 func (whisper *Whisper) GetSymKey(id string) ([]byte, error) { 566 whisper.keyMu.RLock() 567 defer whisper.keyMu.RUnlock() 568 if whisper.symKeys[id] != nil { 569 return whisper.symKeys[id], nil 570 } 571 return nil, fmt.Errorf("non-existent key ID") 572 } 573 574 // Subscribe installs a new message handler used for filtering, decrypting 575 // and subsequent storing of incoming messages. 576 func (whisper *Whisper) Subscribe(f *Filter) (string, error) { 577 s, err := whisper.filters.Install(f) 578 if err == nil { 579 whisper.updateBloomFilter(f) 580 } 581 return s, err 582 } 583 584 // updateBloomFilter recalculates the new value of bloom filter, 585 // and informs the peers if necessary. 586 func (whisper *Whisper) updateBloomFilter(f *Filter) { 587 aggregate := make([]byte, BloomFilterSize) 588 for _, t := range f.Topics { 589 top := BytesToTopic(t) 590 b := TopicToBloom(top) 591 aggregate = addBloom(aggregate, b) 592 } 593 594 if !BloomFilterMatch(whisper.BloomFilter(), aggregate) { 595 // existing bloom filter must be updated 596 aggregate = addBloom(whisper.BloomFilter(), aggregate) 597 whisper.SetBloomFilter(aggregate) 598 } 599 } 600 601 // GetFilter returns the filter by id. 602 func (whisper *Whisper) GetFilter(id string) *Filter { 603 return whisper.filters.Get(id) 604 } 605 606 // Unsubscribe removes an installed message handler. 607 func (whisper *Whisper) Unsubscribe(id string) error { 608 ok := whisper.filters.Uninstall(id) 609 if !ok { 610 return fmt.Errorf("Unsubscribe: Invalid ID") 611 } 612 return nil 613 } 614 615 // Send injects a message into the whisper send queue, to be distributed in the 616 // network in the coming cycles. 617 func (whisper *Whisper) Send(envelope *Envelope) error { 618 ok, err := whisper.add(envelope, false) 619 if err == nil && !ok { 620 return fmt.Errorf("failed to add envelope") 621 } 622 return err 623 } 624 625 // Start implements node.Service, starting the background data propagation thread 626 // of the Whisper protocol. 627 func (whisper *Whisper) Start(*p2p.Server) error { 628 log.Info("started whisper v." + ProtocolVersionStr) 629 go whisper.update() 630 631 numCPU := runtime.NumCPU() 632 for i := 0; i < numCPU; i++ { 633 go whisper.processQueue() 634 } 635 636 return nil 637 } 638 639 // Stop implements node.Service, stopping the background data propagation thread 640 // of the Whisper protocol. 641 func (whisper *Whisper) Stop() error { 642 close(whisper.quit) 643 log.Info("whisper stopped") 644 return nil 645 } 646 647 // HandlePeer is called by the underlying P2P layer when the whisper sub-protocol 648 // connection is negotiated. 649 func (whisper *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 650 // Create the new peer and start tracking it 651 whisperPeer := newPeer(whisper, peer, rw) 652 653 whisper.peerMu.Lock() 654 whisper.peers[whisperPeer] = struct{}{} 655 whisper.peerMu.Unlock() 656 657 defer func() { 658 whisper.peerMu.Lock() 659 delete(whisper.peers, whisperPeer) 660 whisper.peerMu.Unlock() 661 }() 662 663 // Run the peer handshake and state updates 664 if err := whisperPeer.handshake(); err != nil { 665 return err 666 } 667 whisperPeer.start() 668 defer whisperPeer.stop() 669 670 return whisper.runMessageLoop(whisperPeer, rw) 671 } 672 673 // runMessageLoop reads and processes inbound messages directly to merge into client-global state. 674 func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { 675 for { 676 // fetch the next packet 677 packet, err := rw.ReadMsg() 678 if err != nil { 679 log.Info("message loop", "peer", p.peer.ID(), "err", err) 680 return err 681 } 682 if packet.Size > whisper.MaxMessageSize() { 683 log.Warn("oversized message received", "peer", p.peer.ID()) 684 return errors.New("oversized message received") 685 } 686 687 switch packet.Code { 688 case statusCode: 689 // this should not happen, but no need to panic; just ignore this message. 690 log.Warn("unxepected status message received", "peer", p.peer.ID()) 691 case messagesCode: 692 // decode the contained envelopes 693 var envelopes []*Envelope 694 if err := packet.Decode(&envelopes); err != nil { 695 log.Warn("failed to decode envelopes, peer will be disconnected", "peer", p.peer.ID(), "err", err) 696 return errors.New("invalid envelopes") 697 } 698 699 trouble := false 700 for _, env := range envelopes { 701 cached, err := whisper.add(env, whisper.LightClientMode()) 702 if err != nil { 703 trouble = true 704 log.Error("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) 705 } 706 if cached { 707 p.mark(env) 708 } 709 } 710 711 if trouble { 712 return errors.New("invalid envelope") 713 } 714 case powRequirementCode: 715 s := rlp.NewStream(packet.Payload, uint64(packet.Size)) 716 i, err := s.Uint() 717 if err != nil { 718 log.Warn("failed to decode powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 719 return errors.New("invalid powRequirementCode message") 720 } 721 f := math.Float64frombits(i) 722 if math.IsInf(f, 0) || math.IsNaN(f) || f < 0.0 { 723 log.Warn("invalid value in powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 724 return errors.New("invalid value in powRequirementCode message") 725 } 726 p.powRequirement = f 727 case bloomFilterExCode: 728 var bloom []byte 729 err := packet.Decode(&bloom) 730 if err == nil && len(bloom) != BloomFilterSize { 731 err = fmt.Errorf("wrong bloom filter size %d", len(bloom)) 732 } 733 734 if err != nil { 735 log.Warn("failed to decode bloom filter exchange message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 736 return errors.New("invalid bloom filter exchange message") 737 } 738 p.setBloomFilter(bloom) 739 case p2pMessageCode: 740 // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. 741 // this message is not supposed to be forwarded to other peers, and 742 // therefore might not satisfy the PoW, expiry and other requirements. 743 // these messages are only accepted from the trusted peer. 744 if p.trusted { 745 var envelope Envelope 746 if err := packet.Decode(&envelope); err != nil { 747 log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 748 return errors.New("invalid direct message") 749 } 750 whisper.postEvent(&envelope, true) 751 } 752 case p2pRequestCode: 753 // Must be processed if mail server is implemented. Otherwise ignore. 754 if whisper.mailServer != nil { 755 var request Envelope 756 if err := packet.Decode(&request); err != nil { 757 log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 758 return errors.New("invalid p2p request") 759 } 760 whisper.mailServer.DeliverMail(p, &request) 761 } 762 default: 763 // New message types might be implemented in the future versions of Whisper. 764 // For forward compatibility, just ignore. 765 } 766 767 packet.Discard() 768 } 769 } 770 771 // add inserts a new envelope into the message pool to be distributed within the 772 // whisper network. It also inserts the envelope into the expiration pool at the 773 // appropriate time-stamp. In case of error, connection should be dropped. 774 // param isP2P indicates whether the message is peer-to-peer (should not be forwarded). 775 func (whisper *Whisper) add(envelope *Envelope, isP2P bool) (bool, error) { 776 now := uint32(time.Now().Unix()) 777 sent := envelope.Expiry - envelope.TTL 778 779 if sent > now { 780 if sent-DefaultSyncAllowance > now { 781 return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 782 } 783 // recalculate PoW, adjusted for the time difference, plus one second for latency 784 envelope.calculatePoW(sent - now + 1) 785 } 786 787 if envelope.Expiry < now { 788 if envelope.Expiry+DefaultSyncAllowance*2 < now { 789 return false, fmt.Errorf("very old message") 790 } 791 log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) 792 return false, nil // drop envelope without error 793 } 794 795 if uint32(envelope.size()) > whisper.MaxMessageSize() { 796 return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 797 } 798 799 if envelope.PoW() < whisper.MinPow() { 800 // maybe the value was recently changed, and the peers did not adjust yet. 801 // in this case the previous value is retrieved by MinPowTolerance() 802 // for a short period of peer synchronization. 803 if envelope.PoW() < whisper.MinPowTolerance() { 804 return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%v]", envelope.PoW(), envelope.Hash().Hex()) 805 } 806 } 807 808 if !BloomFilterMatch(whisper.BloomFilter(), envelope.Bloom()) { 809 // maybe the value was recently changed, and the peers did not adjust yet. 810 // in this case the previous value is retrieved by BloomFilterTolerance() 811 // for a short period of peer synchronization. 812 if !BloomFilterMatch(whisper.BloomFilterTolerance(), envelope.Bloom()) { 813 return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", 814 envelope.Hash().Hex(), whisper.BloomFilter(), envelope.Bloom(), envelope.Topic) 815 } 816 } 817 818 hash := envelope.Hash() 819 820 whisper.poolMu.Lock() 821 _, alreadyCached := whisper.envelopes[hash] 822 if !alreadyCached { 823 whisper.envelopes[hash] = envelope 824 if whisper.expirations[envelope.Expiry] == nil { 825 whisper.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() 826 } 827 if !whisper.expirations[envelope.Expiry].Contains(hash) { 828 whisper.expirations[envelope.Expiry].Add(hash) 829 } 830 } 831 whisper.poolMu.Unlock() 832 833 if alreadyCached { 834 log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) 835 } else { 836 log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) 837 whisper.statsMu.Lock() 838 whisper.stats.memoryUsed += envelope.size() 839 whisper.statsMu.Unlock() 840 whisper.postEvent(envelope, isP2P) // notify the local node about the new message 841 if whisper.mailServer != nil { 842 whisper.mailServer.Archive(envelope) 843 } 844 } 845 return true, nil 846 } 847 848 // postEvent queues the message for further processing. 849 func (whisper *Whisper) postEvent(envelope *Envelope, isP2P bool) { 850 if isP2P { 851 whisper.p2pMsgQueue <- envelope 852 } else { 853 whisper.checkOverflow() 854 whisper.messageQueue <- envelope 855 } 856 } 857 858 // checkOverflow checks if message queue overflow occurs and reports it if necessary. 859 func (whisper *Whisper) checkOverflow() { 860 queueSize := len(whisper.messageQueue) 861 862 if queueSize == messageQueueLimit { 863 if !whisper.Overflow() { 864 whisper.settings.Store(overflowIdx, true) 865 log.Warn("message queue overflow") 866 } 867 } else if queueSize <= messageQueueLimit/2 { 868 if whisper.Overflow() { 869 whisper.settings.Store(overflowIdx, false) 870 log.Warn("message queue overflow fixed (back to normal)") 871 } 872 } 873 } 874 875 // processQueue delivers the messages to the watchers during the lifetime of the whisper node. 876 func (whisper *Whisper) processQueue() { 877 var e *Envelope 878 for { 879 select { 880 case <-whisper.quit: 881 return 882 883 case e = <-whisper.messageQueue: 884 whisper.filters.NotifyWatchers(e, false) 885 886 case e = <-whisper.p2pMsgQueue: 887 whisper.filters.NotifyWatchers(e, true) 888 } 889 } 890 } 891 892 // update loops until the lifetime of the whisper node, updating its internal 893 // state by expiring stale messages from the pool. 894 func (whisper *Whisper) update() { 895 // Start a ticker to check for expirations 896 expire := time.NewTicker(expirationCycle) 897 898 // Repeat updates until termination is requested 899 for { 900 select { 901 case <-expire.C: 902 whisper.expire() 903 904 case <-whisper.quit: 905 return 906 } 907 } 908 } 909 910 // expire iterates over all the expiration timestamps, removing all stale 911 // messages from the pools. 912 func (whisper *Whisper) expire() { 913 whisper.poolMu.Lock() 914 defer whisper.poolMu.Unlock() 915 916 whisper.statsMu.Lock() 917 defer whisper.statsMu.Unlock() 918 whisper.stats.reset() 919 now := uint32(time.Now().Unix()) 920 for expiry, hashSet := range whisper.expirations { 921 if expiry < now { 922 // Dump all expired messages and remove timestamp 923 hashSet.Each(func(v interface{}) bool { 924 sz := whisper.envelopes[v.(common.Hash)].size() 925 delete(whisper.envelopes, v.(common.Hash)) 926 whisper.stats.messagesCleared++ 927 whisper.stats.memoryCleared += sz 928 whisper.stats.memoryUsed -= sz 929 return false 930 }) 931 whisper.expirations[expiry].Clear() 932 delete(whisper.expirations, expiry) 933 } 934 } 935 } 936 937 // Stats returns the whisper node statistics. 938 func (whisper *Whisper) Stats() Statistics { 939 whisper.statsMu.Lock() 940 defer whisper.statsMu.Unlock() 941 942 return whisper.stats 943 } 944 945 // Envelopes retrieves all the messages currently pooled by the node. 946 func (whisper *Whisper) Envelopes() []*Envelope { 947 whisper.poolMu.RLock() 948 defer whisper.poolMu.RUnlock() 949 950 all := make([]*Envelope, 0, len(whisper.envelopes)) 951 for _, envelope := range whisper.envelopes { 952 all = append(all, envelope) 953 } 954 return all 955 } 956 957 // isEnvelopeCached checks if envelope with specific hash has already been received and cached. 958 func (whisper *Whisper) isEnvelopeCached(hash common.Hash) bool { 959 whisper.poolMu.Lock() 960 defer whisper.poolMu.Unlock() 961 962 _, exist := whisper.envelopes[hash] 963 return exist 964 } 965 966 // reset resets the node's statistics after each expiry cycle. 967 func (s *Statistics) reset() { 968 s.cycles++ 969 s.totalMessagesCleared += s.messagesCleared 970 971 s.memoryCleared = 0 972 s.messagesCleared = 0 973 } 974 975 // ValidatePublicKey checks the format of the given public key. 976 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 977 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 978 } 979 980 // validatePrivateKey checks the format of the given private key. 981 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 982 if k == nil || k.D == nil || k.D.Sign() == 0 { 983 return false 984 } 985 return ValidatePublicKey(&k.PublicKey) 986 } 987 988 // validateDataIntegrity returns false if the data have the wrong or contains all zeros, 989 // which is the simplest and the most common bug. 990 func validateDataIntegrity(k []byte, expectedSize int) bool { 991 if len(k) != expectedSize { 992 return false 993 } 994 if expectedSize > 3 && containsOnlyZeros(k) { 995 return false 996 } 997 return true 998 } 999 1000 // containsOnlyZeros checks if the data contain only zeros. 1001 func containsOnlyZeros(data []byte) bool { 1002 for _, b := range data { 1003 if b != 0 { 1004 return false 1005 } 1006 } 1007 return true 1008 } 1009 1010 // bytesToUintLittleEndian converts the slice to 64-bit unsigned integer. 1011 func bytesToUintLittleEndian(b []byte) (res uint64) { 1012 mul := uint64(1) 1013 for i := 0; i < len(b); i++ { 1014 res += uint64(b[i]) * mul 1015 mul *= 256 1016 } 1017 return res 1018 } 1019 1020 // BytesToUintBigEndian converts the slice to 64-bit unsigned integer. 1021 func BytesToUintBigEndian(b []byte) (res uint64) { 1022 for i := 0; i < len(b); i++ { 1023 res *= 256 1024 res += uint64(b[i]) 1025 } 1026 return res 1027 } 1028 1029 // GenerateRandomID generates a random string, which is then returned to be used as a key id 1030 func GenerateRandomID() (id string, err error) { 1031 buf, err := generateSecureRandomData(keyIDSize) 1032 if err != nil { 1033 return "", err 1034 } 1035 if !validateDataIntegrity(buf, keyIDSize) { 1036 return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") 1037 } 1038 id = common.Bytes2Hex(buf) 1039 return id, err 1040 } 1041 1042 func isFullNode(bloom []byte) bool { 1043 if bloom == nil { 1044 return true 1045 } 1046 for _, b := range bloom { 1047 if b != 255 { 1048 return false 1049 } 1050 } 1051 return true 1052 } 1053 1054 func BloomFilterMatch(filter, sample []byte) bool { 1055 if filter == nil { 1056 return true 1057 } 1058 1059 for i := 0; i < BloomFilterSize; i++ { 1060 f := filter[i] 1061 s := sample[i] 1062 if (f | s) != f { 1063 return false 1064 } 1065 } 1066 1067 return true 1068 } 1069 1070 func addBloom(a, b []byte) []byte { 1071 c := make([]byte, BloomFilterSize) 1072 for i := 0; i < BloomFilterSize; i++ { 1073 c[i] = a[i] | b[i] 1074 } 1075 return c 1076 }