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