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