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