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