github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/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 "crypto/ecdsa" 21 "crypto/sha256" 22 "fmt" 23 "math" 24 "runtime" 25 "sync" 26 "time" 27 28 libp2p "github.com/libp2p/go-libp2p-peer" 29 "github.com/syndtr/goleveldb/leveldb/errors" 30 "github.com/vntchain/go-vnt/common" 31 "github.com/vntchain/go-vnt/crypto" 32 "github.com/vntchain/go-vnt/log" 33 "github.com/vntchain/go-vnt/rlp" 34 "github.com/vntchain/go-vnt/rpc" 35 "github.com/vntchain/go-vnt/vntp2p" 36 "golang.org/x/crypto/pbkdf2" 37 "golang.org/x/sync/syncmap" 38 set "gopkg.in/fatih/set.v0" 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 VNT 61 // network, using its very own P2P communication layer. 62 type Whisper struct { 63 protocol vntp2p.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]*set.SetNonTS // 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 VNT 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]*set.SetNonTS), 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 = vntp2p.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() []vntp2p.Protocol { 216 return []vntp2p.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 //return 0 223 } 224 225 // SetMaxMessageSize sets the maximal message size allowed by this node 226 func (whisper *Whisper) SetMaxMessageSize(size uint32) error { 227 if size > MaxMessageSize { 228 return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) 229 } 230 whisper.settings.Store(maxMsgSizeIdx, size) 231 return nil 232 } 233 234 // SetBloomFilter sets the new bloom filter 235 func (whisper *Whisper) SetBloomFilter(bloom []byte) error { 236 if len(bloom) != BloomFilterSize { 237 return fmt.Errorf("invalid bloom filter size: %d", len(bloom)) 238 } 239 240 b := make([]byte, BloomFilterSize) 241 copy(b, bloom) 242 243 whisper.settings.Store(bloomFilterIdx, b) 244 whisper.notifyPeersAboutBloomFilterChange(b) 245 246 go func() { 247 // allow some time before all the peers have processed the notification 248 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 249 whisper.settings.Store(bloomFilterToleranceIdx, b) 250 }() 251 252 return nil 253 } 254 255 // SetMinimumPoW sets the minimal PoW required by this node 256 func (whisper *Whisper) SetMinimumPoW(val float64) error { 257 if val < 0.0 { 258 return fmt.Errorf("invalid PoW: %f", val) 259 } 260 261 whisper.settings.Store(minPowIdx, val) 262 whisper.notifyPeersAboutPowRequirementChange(val) 263 264 go func() { 265 // allow some time before all the peers have processed the notification 266 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 267 whisper.settings.Store(minPowToleranceIdx, val) 268 }() 269 270 return nil 271 } 272 273 // SetMinimumPowTest sets the minimal PoW in test environment 274 func (whisper *Whisper) SetMinimumPowTest(val float64) { 275 whisper.settings.Store(minPowIdx, val) 276 whisper.notifyPeersAboutPowRequirementChange(val) 277 whisper.settings.Store(minPowToleranceIdx, val) 278 } 279 280 func (whisper *Whisper) notifyPeersAboutPowRequirementChange(pow float64) { 281 arr := whisper.getPeers() 282 for _, p := range arr { 283 err := p.notifyAboutPowRequirementChange(pow) 284 if err != nil { 285 // allow one retry 286 err = p.notifyAboutPowRequirementChange(pow) 287 } 288 if err != nil { 289 log.Warn("failed to notify peer about new pow requirement", "peer", p.ID(), "error", err) 290 } 291 } 292 } 293 294 func (whisper *Whisper) notifyPeersAboutBloomFilterChange(bloom []byte) { 295 arr := whisper.getPeers() 296 for _, p := range arr { 297 err := p.notifyAboutBloomFilterChange(bloom) 298 if err != nil { 299 // allow one retry 300 err = p.notifyAboutBloomFilterChange(bloom) 301 } 302 if err != nil { 303 log.Warn("failed to notify peer about new bloom filter", "peer", p.ID(), "error", err) 304 } 305 } 306 } 307 308 func (whisper *Whisper) getPeers() []*Peer { 309 arr := make([]*Peer, len(whisper.peers)) 310 i := 0 311 whisper.peerMu.Lock() 312 for p := range whisper.peers { 313 arr[i] = p 314 i++ 315 } 316 whisper.peerMu.Unlock() 317 return arr 318 } 319 320 // getPeer retrieves peer by ID 321 func (whisper *Whisper) getPeer(peerID libp2p.ID) (*Peer, error) { 322 whisper.peerMu.Lock() 323 defer whisper.peerMu.Unlock() 324 for p := range whisper.peers { 325 id := p.peer.RemoteID() 326 if peerID == id { 327 return p, nil 328 } 329 } 330 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 331 } 332 333 // AllowP2PMessagesFromPeer marks specific peer trusted, 334 // which will allow it to send historic (expired) messages. 335 func (whisper *Whisper) AllowP2PMessagesFromPeer(peerID libp2p.ID) error { 336 p, err := whisper.getPeer(peerID) 337 if err != nil { 338 return err 339 } 340 p.trusted = true 341 return nil 342 } 343 344 // RequestHistoricMessages sends a message with p2pRequestCode to a specific peer, 345 // which is known to implement MailServer interface, and is supposed to process this 346 // request and respond with a number of peer-to-peer messages (possibly expired), 347 // which are not supposed to be forwarded any further. 348 // The whisper protocol is agnostic of the format and contents of envelope. 349 func (whisper *Whisper) RequestHistoricMessages(peerID libp2p.ID, envelope *Envelope) error { 350 p, err := whisper.getPeer(peerID) 351 if err != nil { 352 return err 353 } 354 p.trusted = true 355 return vntp2p.Send(p.ws, ProtocolName, p2pRequestCode, envelope) 356 } 357 358 // SendP2PMessage sends a peer-to-peer message to a specific peer. 359 func (whisper *Whisper) SendP2PMessage(peerID libp2p.ID, envelope *Envelope) error { 360 p, err := whisper.getPeer(peerID) 361 if err != nil { 362 return err 363 } 364 return whisper.SendP2PDirect(p, envelope) 365 } 366 367 // SendP2PDirect sends a peer-to-peer message to a specific peer. 368 func (whisper *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 369 return vntp2p.Send(peer.ws, ProtocolName, p2pMessageCode, envelope) 370 } 371 372 // NewKeyPair generates a new cryptographic identity for the client, and injects 373 // it into the known identities for message decryption. Returns ID of the new key pair. 374 func (whisper *Whisper) NewKeyPair() (string, error) { 375 key, err := crypto.GenerateKey() 376 if err != nil || !validatePrivateKey(key) { 377 key, err = crypto.GenerateKey() // retry once 378 } 379 if err != nil { 380 return "", err 381 } 382 if !validatePrivateKey(key) { 383 return "", fmt.Errorf("failed to generate valid key") 384 } 385 386 id, err := GenerateRandomID() 387 if err != nil { 388 return "", fmt.Errorf("failed to generate ID: %s", err) 389 } 390 391 whisper.keyMu.Lock() 392 defer whisper.keyMu.Unlock() 393 394 if whisper.privateKeys[id] != nil { 395 return "", fmt.Errorf("failed to generate unique ID") 396 } 397 whisper.privateKeys[id] = key 398 return id, nil 399 } 400 401 // DeleteKeyPair deletes the specified key if it exists. 402 func (whisper *Whisper) DeleteKeyPair(key string) bool { 403 whisper.keyMu.Lock() 404 defer whisper.keyMu.Unlock() 405 406 if whisper.privateKeys[key] != nil { 407 delete(whisper.privateKeys, key) 408 return true 409 } 410 return false 411 } 412 413 // AddKeyPair imports a asymmetric private key and returns it identifier. 414 func (whisper *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 415 id, err := GenerateRandomID() 416 if err != nil { 417 return "", fmt.Errorf("failed to generate ID: %s", err) 418 } 419 420 whisper.keyMu.Lock() 421 whisper.privateKeys[id] = key 422 whisper.keyMu.Unlock() 423 424 return id, nil 425 } 426 427 // HasKeyPair checks if the the whisper node is configured with the private key 428 // of the specified public pair. 429 func (whisper *Whisper) HasKeyPair(id string) bool { 430 whisper.keyMu.RLock() 431 defer whisper.keyMu.RUnlock() 432 return whisper.privateKeys[id] != nil 433 } 434 435 // GetPrivateKey retrieves the private key of the specified identity. 436 func (whisper *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 437 whisper.keyMu.RLock() 438 defer whisper.keyMu.RUnlock() 439 key := whisper.privateKeys[id] 440 if key == nil { 441 return nil, fmt.Errorf("invalid id") 442 } 443 return key, nil 444 } 445 446 // GenerateSymKey generates a random symmetric key and stores it under id, 447 // which is then returned. Will be used in the future for session key exchange. 448 func (whisper *Whisper) GenerateSymKey() (string, error) { 449 key, err := generateSecureRandomData(aesKeyLength) 450 if err != nil { 451 return "", err 452 } else if !validateDataIntegrity(key, aesKeyLength) { 453 return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 454 } 455 456 id, err := GenerateRandomID() 457 if err != nil { 458 return "", fmt.Errorf("failed to generate ID: %s", err) 459 } 460 461 whisper.keyMu.Lock() 462 defer whisper.keyMu.Unlock() 463 464 if whisper.symKeys[id] != nil { 465 return "", fmt.Errorf("failed to generate unique ID") 466 } 467 whisper.symKeys[id] = key 468 return id, nil 469 } 470 471 // AddSymKeyDirect stores the key, and returns its id. 472 func (whisper *Whisper) AddSymKeyDirect(key []byte) (string, error) { 473 if len(key) != aesKeyLength { 474 return "", fmt.Errorf("wrong key size: %d", len(key)) 475 } 476 477 id, err := GenerateRandomID() 478 if err != nil { 479 return "", fmt.Errorf("failed to generate ID: %s", err) 480 } 481 482 whisper.keyMu.Lock() 483 defer whisper.keyMu.Unlock() 484 485 if whisper.symKeys[id] != nil { 486 return "", fmt.Errorf("failed to generate unique ID") 487 } 488 whisper.symKeys[id] = key 489 return id, nil 490 } 491 492 // AddSymKeyFromPassword generates the key from password, stores it, and returns its id. 493 func (whisper *Whisper) AddSymKeyFromPassword(password string) (string, error) { 494 id, err := GenerateRandomID() 495 if err != nil { 496 return "", fmt.Errorf("failed to generate ID: %s", err) 497 } 498 if whisper.HasSymKey(id) { 499 return "", fmt.Errorf("failed to generate unique ID") 500 } 501 502 // kdf should run no less than 0.1 seconds on an average computer, 503 // because it's an once in a session experience 504 derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New) 505 if err != nil { 506 return "", err 507 } 508 509 whisper.keyMu.Lock() 510 defer whisper.keyMu.Unlock() 511 512 // double check is necessary, because deriveKeyMaterial() is very slow 513 if whisper.symKeys[id] != nil { 514 return "", fmt.Errorf("critical error: failed to generate unique ID") 515 } 516 whisper.symKeys[id] = derived 517 return id, nil 518 } 519 520 // HasSymKey returns true if there is a key associated with the given id. 521 // Otherwise returns false. 522 func (whisper *Whisper) HasSymKey(id string) bool { 523 whisper.keyMu.RLock() 524 defer whisper.keyMu.RUnlock() 525 return whisper.symKeys[id] != nil 526 } 527 528 // DeleteSymKey deletes the key associated with the name string if it exists. 529 func (whisper *Whisper) DeleteSymKey(id string) bool { 530 whisper.keyMu.Lock() 531 defer whisper.keyMu.Unlock() 532 if whisper.symKeys[id] != nil { 533 delete(whisper.symKeys, id) 534 return true 535 } 536 return false 537 } 538 539 // GetSymKey returns the symmetric key associated with the given id. 540 func (whisper *Whisper) GetSymKey(id string) ([]byte, error) { 541 whisper.keyMu.RLock() 542 defer whisper.keyMu.RUnlock() 543 if whisper.symKeys[id] != nil { 544 return whisper.symKeys[id], nil 545 } 546 return nil, fmt.Errorf("non-existent key ID") 547 } 548 549 // Subscribe installs a new message handler used for filtering, decrypting 550 // and subsequent storing of incoming messages. 551 func (whisper *Whisper) Subscribe(f *Filter) (string, error) { 552 s, err := whisper.filters.Install(f) 553 if err == nil { 554 whisper.updateBloomFilter(f) 555 } 556 return s, err 557 } 558 559 // updateBloomFilter recalculates the new value of bloom filter, 560 // and informs the peers if necessary. 561 func (whisper *Whisper) updateBloomFilter(f *Filter) { 562 aggregate := make([]byte, BloomFilterSize) 563 for _, t := range f.Topics { 564 top := BytesToTopic(t) 565 b := TopicToBloom(top) 566 aggregate = addBloom(aggregate, b) 567 } 568 569 if !BloomFilterMatch(whisper.BloomFilter(), aggregate) { 570 // existing bloom filter must be updated 571 aggregate = addBloom(whisper.BloomFilter(), aggregate) 572 whisper.SetBloomFilter(aggregate) 573 } 574 } 575 576 // GetFilter returns the filter by id. 577 func (whisper *Whisper) GetFilter(id string) *Filter { 578 return whisper.filters.Get(id) 579 } 580 581 // Unsubscribe removes an installed message handler. 582 func (whisper *Whisper) Unsubscribe(id string) error { 583 ok := whisper.filters.Uninstall(id) 584 if !ok { 585 return fmt.Errorf("Unsubscribe: Invalid ID") 586 } 587 return nil 588 } 589 590 // Send injects a message into the whisper send queue, to be distributed in the 591 // network in the coming cycles. 592 func (whisper *Whisper) Send(envelope *Envelope) error { 593 ok, err := whisper.add(envelope, false) 594 if err == nil && !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 (whisper *Whisper) Start(*vntp2p.Server) error { 603 log.Info("started whisper v." + ProtocolVersionStr) 604 go whisper.update() 605 606 numCPU := runtime.NumCPU() 607 for i := 0; i < numCPU; i++ { 608 go whisper.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 (whisper *Whisper) Stop() error { 617 close(whisper.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 (whisper *Whisper) HandlePeer(peer *vntp2p.Peer, rw vntp2p.MsgReadWriter) error { 625 // Create the new peer and start tracking it 626 whisperPeer := newPeer(whisper, peer, rw) 627 628 whisper.peerMu.Lock() 629 whisper.peers[whisperPeer] = struct{}{} 630 whisper.peerMu.Unlock() 631 632 defer func() { 633 whisper.peerMu.Lock() 634 delete(whisper.peers, whisperPeer) 635 whisper.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 whisper.runMessageLoop(whisperPeer, rw) 646 } 647 648 // runMessageLoop reads and processes inbound messages directly to merge into client-global state. 649 func (whisper *Whisper) runMessageLoop(p *Peer, rw vntp2p.MsgReadWriter) error { 650 for { 651 // fetch the next packet 652 packet, err := rw.ReadMsg() 653 if err != nil { 654 log.Warn("Whisper6 message loop", "peer", p.peer.RemoteID(), "err", err) 655 return err 656 } 657 if packet.GetBodySize() > whisper.MaxMessageSize() { 658 log.Warn("oversized message received", "peer", p.peer.RemoteID()) 659 return errors.New("oversized message received") 660 } 661 662 switch packet.Body.Type { 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.RemoteID()) 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.RemoteID(), "err", err) 671 return errors.New("invalid envelopes") 672 } 673 674 trouble := false 675 for _, env := range envelopes { 676 cached, err := whisper.add(env, whisper.lightClient) 677 if err != nil { 678 trouble = true 679 log.Error("bad envelope received, peer will be disconnected", "peer", p.peer.RemoteID(), "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.Body.Payload, uint64(packet.Body.PayloadSize)) 691 i, err := s.Uint() 692 if err != nil { 693 log.Warn("failed to decode powRequirementCode message, peer will be disconnected", "peer", p.peer.RemoteID(), "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.RemoteID(), "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.RemoteID(), "err", err) 711 return errors.New("invalid bloom filter exchange message") 712 } 713 p.setBloomFilter(bloom) 714 case p2pMessageCode: 715 // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. 716 // this message is not supposed to be forwarded to other peers, and 717 // therefore might not satisfy the PoW, expiry and other requirements. 718 // these messages are only accepted from the trusted peer. 719 if p.trusted { 720 var envelope Envelope 721 if err := packet.Decode(&envelope); err != nil { 722 log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.RemoteID(), "err", err) 723 return errors.New("invalid direct message") 724 } 725 whisper.postEvent(&envelope, true) 726 } 727 case p2pRequestCode: 728 // Must be processed if mail server is implemented. Otherwise ignore. 729 if whisper.mailServer != nil { 730 var request Envelope 731 if err := packet.Decode(&request); err != nil { 732 log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.RemoteID(), "err", err) 733 return errors.New("invalid p2p request") 734 } 735 whisper.mailServer.DeliverMail(p, &request) 736 } 737 default: 738 // New message types might be implemented in the future versions of Whisper. 739 // For forward compatibility, just ignore. 740 } 741 742 //packet.Discard() 743 } 744 } 745 746 // add inserts a new envelope into the message pool to be distributed within the 747 // whisper network. It also inserts the envelope into the expiration pool at the 748 // appropriate time-stamp. In case of error, connection should be dropped. 749 // param isP2P indicates whether the message is peer-to-peer (should not be forwarded). 750 func (whisper *Whisper) add(envelope *Envelope, isP2P bool) (bool, error) { 751 now := uint32(time.Now().Unix()) 752 sent := envelope.Expiry - envelope.TTL 753 754 if sent > now { 755 if sent-DefaultSyncAllowance > now { 756 return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 757 } 758 // recalculate PoW, adjusted for the time difference, plus one second for latency 759 envelope.calculatePoW(sent - now + 1) 760 } 761 762 if envelope.Expiry < now { 763 if envelope.Expiry+DefaultSyncAllowance*2 < now { 764 return false, fmt.Errorf("very old message") 765 } 766 log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) 767 return false, nil // drop envelope without error 768 } 769 770 if uint32(envelope.size()) > whisper.MaxMessageSize() { 771 return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 772 } 773 774 if envelope.PoW() < whisper.MinPow() { 775 // maybe the value was recently changed, and the peers did not adjust yet. 776 // in this case the previous value is retrieved by MinPowTolerance() 777 // for a short period of peer synchronization. 778 if envelope.PoW() < whisper.MinPowTolerance() { 779 return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%v]", envelope.PoW(), envelope.Hash().Hex()) 780 } 781 } 782 783 if !BloomFilterMatch(whisper.BloomFilter(), envelope.Bloom()) { 784 // maybe the value was recently changed, and the peers did not adjust yet. 785 // in this case the previous value is retrieved by BloomFilterTolerance() 786 // for a short period of peer synchronization. 787 if !BloomFilterMatch(whisper.BloomFilterTolerance(), envelope.Bloom()) { 788 return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", 789 envelope.Hash().Hex(), whisper.BloomFilter(), envelope.Bloom(), envelope.Topic) 790 } 791 } 792 793 hash := envelope.Hash() 794 795 whisper.poolMu.Lock() 796 _, alreadyCached := whisper.envelopes[hash] 797 if !alreadyCached { 798 whisper.envelopes[hash] = envelope 799 if whisper.expirations[envelope.Expiry] == nil { 800 whisper.expirations[envelope.Expiry] = set.NewNonTS() 801 } 802 if !whisper.expirations[envelope.Expiry].Has(hash) { 803 whisper.expirations[envelope.Expiry].Add(hash) 804 } 805 } 806 whisper.poolMu.Unlock() 807 808 if alreadyCached { 809 log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) 810 } else { 811 log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) 812 whisper.statsMu.Lock() 813 whisper.stats.memoryUsed += envelope.size() 814 whisper.statsMu.Unlock() 815 whisper.postEvent(envelope, isP2P) // notify the local node about the new message 816 if whisper.mailServer != nil { 817 whisper.mailServer.Archive(envelope) 818 } 819 } 820 return true, nil 821 } 822 823 // postEvent queues the message for further processing. 824 func (whisper *Whisper) postEvent(envelope *Envelope, isP2P bool) { 825 if isP2P { 826 whisper.p2pMsgQueue <- envelope 827 } else { 828 whisper.checkOverflow() 829 whisper.messageQueue <- envelope 830 } 831 } 832 833 // checkOverflow checks if message queue overflow occurs and reports it if necessary. 834 func (whisper *Whisper) checkOverflow() { 835 queueSize := len(whisper.messageQueue) 836 837 if queueSize == messageQueueLimit { 838 if !whisper.Overflow() { 839 whisper.settings.Store(overflowIdx, true) 840 log.Warn("message queue overflow") 841 } 842 } else if queueSize <= messageQueueLimit/2 { 843 if whisper.Overflow() { 844 whisper.settings.Store(overflowIdx, false) 845 log.Warn("message queue overflow fixed (back to normal)") 846 } 847 } 848 } 849 850 // processQueue delivers the messages to the watchers during the lifetime of the whisper node. 851 func (whisper *Whisper) processQueue() { 852 var e *Envelope 853 for { 854 select { 855 case <-whisper.quit: 856 return 857 858 case e = <-whisper.messageQueue: 859 whisper.filters.NotifyWatchers(e, false) 860 861 case e = <-whisper.p2pMsgQueue: 862 whisper.filters.NotifyWatchers(e, true) 863 } 864 } 865 } 866 867 // update loops until the lifetime of the whisper node, updating its internal 868 // state by expiring stale messages from the pool. 869 func (whisper *Whisper) update() { 870 // Start a ticker to check for expirations 871 expire := time.NewTicker(expirationCycle) 872 873 // Repeat updates until termination is requested 874 for { 875 select { 876 case <-expire.C: 877 whisper.expire() 878 879 case <-whisper.quit: 880 return 881 } 882 } 883 } 884 885 // expire iterates over all the expiration timestamps, removing all stale 886 // messages from the pools. 887 func (whisper *Whisper) expire() { 888 whisper.poolMu.Lock() 889 defer whisper.poolMu.Unlock() 890 891 whisper.statsMu.Lock() 892 defer whisper.statsMu.Unlock() 893 whisper.stats.reset() 894 now := uint32(time.Now().Unix()) 895 for expiry, hashSet := range whisper.expirations { 896 if expiry < now { 897 // Dump all expired messages and remove timestamp 898 hashSet.Each(func(v interface{}) bool { 899 sz := whisper.envelopes[v.(common.Hash)].size() 900 delete(whisper.envelopes, v.(common.Hash)) 901 whisper.stats.messagesCleared++ 902 whisper.stats.memoryCleared += sz 903 whisper.stats.memoryUsed -= sz 904 return true 905 }) 906 whisper.expirations[expiry].Clear() 907 delete(whisper.expirations, expiry) 908 } 909 } 910 } 911 912 // Stats returns the whisper node statistics. 913 func (whisper *Whisper) Stats() Statistics { 914 whisper.statsMu.Lock() 915 defer whisper.statsMu.Unlock() 916 917 return whisper.stats 918 } 919 920 // Envelopes retrieves all the messages currently pooled by the node. 921 func (whisper *Whisper) Envelopes() []*Envelope { 922 whisper.poolMu.RLock() 923 defer whisper.poolMu.RUnlock() 924 925 all := make([]*Envelope, 0, len(whisper.envelopes)) 926 for _, envelope := range whisper.envelopes { 927 all = append(all, envelope) 928 } 929 return all 930 } 931 932 // isEnvelopeCached checks if envelope with specific hash has already been received and cached. 933 func (whisper *Whisper) isEnvelopeCached(hash common.Hash) bool { 934 whisper.poolMu.Lock() 935 defer whisper.poolMu.Unlock() 936 937 _, exist := whisper.envelopes[hash] 938 return exist 939 } 940 941 // reset resets the node's statistics after each expiry cycle. 942 func (s *Statistics) reset() { 943 s.cycles++ 944 s.totalMessagesCleared += s.messagesCleared 945 946 s.memoryCleared = 0 947 s.messagesCleared = 0 948 } 949 950 // ValidatePublicKey checks the format of the given public key. 951 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 952 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 953 } 954 955 // validatePrivateKey checks the format of the given private key. 956 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 957 if k == nil || k.D == nil || k.D.Sign() == 0 { 958 return false 959 } 960 return ValidatePublicKey(&k.PublicKey) 961 } 962 963 // validateDataIntegrity returns false if the data have the wrong or contains all zeros, 964 // which is the simplest and the most common bug. 965 func validateDataIntegrity(k []byte, expectedSize int) bool { 966 if len(k) != expectedSize { 967 return false 968 } 969 if expectedSize > 3 && containsOnlyZeros(k) { 970 return false 971 } 972 return true 973 } 974 975 // containsOnlyZeros checks if the data contain only zeros. 976 func containsOnlyZeros(data []byte) bool { 977 for _, b := range data { 978 if b != 0 { 979 return false 980 } 981 } 982 return true 983 } 984 985 // bytesToUintLittleEndian converts the slice to 64-bit unsigned integer. 986 func bytesToUintLittleEndian(b []byte) (res uint64) { 987 mul := uint64(1) 988 for i := 0; i < len(b); i++ { 989 res += uint64(b[i]) * mul 990 mul *= 256 991 } 992 return res 993 } 994 995 // BytesToUintBigEndian converts the slice to 64-bit unsigned integer. 996 func BytesToUintBigEndian(b []byte) (res uint64) { 997 for i := 0; i < len(b); i++ { 998 res *= 256 999 res += uint64(b[i]) 1000 } 1001 return res 1002 } 1003 1004 // GenerateRandomID generates a random string, which is then returned to be used as a key id 1005 func GenerateRandomID() (id string, err error) { 1006 buf, err := generateSecureRandomData(keyIDSize) 1007 if err != nil { 1008 return "", err 1009 } 1010 if !validateDataIntegrity(buf, keyIDSize) { 1011 return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") 1012 } 1013 id = common.Bytes2Hex(buf) 1014 return id, err 1015 } 1016 1017 func isFullNode(bloom []byte) bool { 1018 if bloom == nil { 1019 return true 1020 } 1021 for _, b := range bloom { 1022 if b != 255 { 1023 return false 1024 } 1025 } 1026 return true 1027 } 1028 1029 func BloomFilterMatch(filter, sample []byte) bool { 1030 if filter == nil { 1031 return true 1032 } 1033 1034 for i := 0; i < BloomFilterSize; i++ { 1035 f := filter[i] 1036 s := sample[i] 1037 if (f | s) != f { 1038 return false 1039 } 1040 } 1041 1042 return true 1043 } 1044 1045 func addBloom(a, b []byte) []byte { 1046 c := make([]byte, BloomFilterSize) 1047 for i := 0; i < BloomFilterSize; i++ { 1048 c[i] = a[i] | b[i] 1049 } 1050 return c 1051 }