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