github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/whisper/whisperv5/whisper.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:51</date> 10 //</624342689604702208> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 package whisperv5 29 30 import ( 31 "bytes" 32 "crypto/ecdsa" 33 crand "crypto/rand" 34 "crypto/sha256" 35 "fmt" 36 "runtime" 37 "sync" 38 "time" 39 40 mapset "github.com/deckarep/golang-set" 41 "github.com/ethereum/go-ethereum/common" 42 "github.com/ethereum/go-ethereum/crypto" 43 "github.com/ethereum/go-ethereum/log" 44 "github.com/ethereum/go-ethereum/p2p" 45 "github.com/ethereum/go-ethereum/rpc" 46 "github.com/syndtr/goleveldb/leveldb/errors" 47 "golang.org/x/crypto/pbkdf2" 48 "golang.org/x/sync/syncmap" 49 ) 50 51 type Statistics struct { 52 messagesCleared int 53 memoryCleared int 54 memoryUsed int 55 cycles int 56 totalMessagesCleared int 57 } 58 59 const ( 60 minPowIdx = iota // 61 maxMsgSizeIdx = iota // 62 overflowIdx = iota // 63 ) 64 65 // 66 // 67 type Whisper struct { 68 protocol p2p.Protocol // 69 filters *Filters // 70 71 privateKeys map[string]*ecdsa.PrivateKey // 72 symKeys map[string][]byte // 73 keyMu sync.RWMutex // 74 75 poolMu sync.RWMutex // 76 envelopes map[common.Hash]*Envelope // 77 expirations map[uint32]mapset.Set // 78 79 peerMu sync.RWMutex // 80 peers map[*Peer]struct{} // 81 82 messageQueue chan *Envelope // 83 p2pMsgQueue chan *Envelope // 84 quit chan struct{} // 85 86 settings syncmap.Map // 87 88 statsMu sync.Mutex // 89 stats Statistics // 90 91 mailServer MailServer // 92 } 93 94 // 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 } 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 // 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 func (w *Whisper) MinPow() float64 { 136 val, _ := w.settings.Load(minPowIdx) 137 return val.(float64) 138 } 139 140 // 141 func (w *Whisper) MaxMessageSize() uint32 { 142 val, _ := w.settings.Load(maxMsgSizeIdx) 143 return val.(uint32) 144 } 145 146 // 147 func (w *Whisper) Overflow() bool { 148 val, _ := w.settings.Load(overflowIdx) 149 return val.(bool) 150 } 151 152 // 153 func (w *Whisper) APIs() []rpc.API { 154 return []rpc.API{ 155 { 156 Namespace: ProtocolName, 157 Version: ProtocolVersionStr, 158 Service: NewPublicWhisperAPI(w), 159 Public: true, 160 }, 161 } 162 } 163 164 // 165 // 166 func (w *Whisper) RegisterServer(server MailServer) { 167 w.mailServer = server 168 } 169 170 // 171 func (w *Whisper) Protocols() []p2p.Protocol { 172 return []p2p.Protocol{w.protocol} 173 } 174 175 // 176 func (w *Whisper) Version() uint { 177 return w.protocol.Version 178 } 179 180 // 181 func (w *Whisper) SetMaxMessageSize(size uint32) error { 182 if size > MaxMessageSize { 183 return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) 184 } 185 w.settings.Store(maxMsgSizeIdx, size) 186 return nil 187 } 188 189 // 190 func (w *Whisper) SetMinimumPoW(val float64) error { 191 if val <= 0.0 { 192 return fmt.Errorf("invalid PoW: %f", val) 193 } 194 w.settings.Store(minPowIdx, val) 195 return nil 196 } 197 198 // 199 func (w *Whisper) getPeer(peerID []byte) (*Peer, error) { 200 w.peerMu.Lock() 201 defer w.peerMu.Unlock() 202 for p := range w.peers { 203 id := p.peer.ID() 204 if bytes.Equal(peerID, id[:]) { 205 return p, nil 206 } 207 } 208 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 209 } 210 211 // 212 // 213 func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error { 214 p, err := w.getPeer(peerID) 215 if err != nil { 216 return err 217 } 218 p.trusted = true 219 return nil 220 } 221 222 // 223 // 224 // 225 // 226 // 227 func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { 228 p, err := w.getPeer(peerID) 229 if err != nil { 230 return err 231 } 232 p.trusted = true 233 return p2p.Send(p.ws, p2pRequestCode, envelope) 234 } 235 236 // 237 func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { 238 p, err := w.getPeer(peerID) 239 if err != nil { 240 return err 241 } 242 return w.SendP2PDirect(p, envelope) 243 } 244 245 // 246 func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 247 return p2p.Send(peer.ws, p2pCode, envelope) 248 } 249 250 // 251 // 252 func (w *Whisper) NewKeyPair() (string, error) { 253 key, err := crypto.GenerateKey() 254 if err != nil || !validatePrivateKey(key) { 255 key, err = crypto.GenerateKey() // 256 } 257 if err != nil { 258 return "", err 259 } 260 if !validatePrivateKey(key) { 261 return "", fmt.Errorf("failed to generate valid key") 262 } 263 264 id, err := GenerateRandomID() 265 if err != nil { 266 return "", fmt.Errorf("failed to generate ID: %s", err) 267 } 268 269 w.keyMu.Lock() 270 defer w.keyMu.Unlock() 271 272 if w.privateKeys[id] != nil { 273 return "", fmt.Errorf("failed to generate unique ID") 274 } 275 w.privateKeys[id] = key 276 return id, nil 277 } 278 279 // 280 func (w *Whisper) DeleteKeyPair(key string) bool { 281 w.keyMu.Lock() 282 defer w.keyMu.Unlock() 283 284 if w.privateKeys[key] != nil { 285 delete(w.privateKeys, key) 286 return true 287 } 288 return false 289 } 290 291 // 292 func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 293 id, err := GenerateRandomID() 294 if err != nil { 295 return "", fmt.Errorf("failed to generate ID: %s", err) 296 } 297 298 w.keyMu.Lock() 299 w.privateKeys[id] = key 300 w.keyMu.Unlock() 301 302 return id, nil 303 } 304 305 // 306 // 307 func (w *Whisper) HasKeyPair(id string) bool { 308 w.keyMu.RLock() 309 defer w.keyMu.RUnlock() 310 return w.privateKeys[id] != nil 311 } 312 313 // 314 func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 315 w.keyMu.RLock() 316 defer w.keyMu.RUnlock() 317 key := w.privateKeys[id] 318 if key == nil { 319 return nil, fmt.Errorf("invalid id") 320 } 321 return key, nil 322 } 323 324 // 325 // 326 func (w *Whisper) GenerateSymKey() (string, error) { 327 key := make([]byte, aesKeyLength) 328 _, err := crand.Read(key) 329 if err != nil { 330 return "", err 331 } else if !validateSymmetricKey(key) { 332 return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 333 } 334 335 id, err := GenerateRandomID() 336 if err != nil { 337 return "", fmt.Errorf("failed to generate ID: %s", err) 338 } 339 340 w.keyMu.Lock() 341 defer w.keyMu.Unlock() 342 343 if w.symKeys[id] != nil { 344 return "", fmt.Errorf("failed to generate unique ID") 345 } 346 w.symKeys[id] = key 347 return id, nil 348 } 349 350 // 351 func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) { 352 if len(key) != aesKeyLength { 353 return "", fmt.Errorf("wrong key size: %d", len(key)) 354 } 355 356 id, err := GenerateRandomID() 357 if err != nil { 358 return "", fmt.Errorf("failed to generate ID: %s", err) 359 } 360 361 w.keyMu.Lock() 362 defer w.keyMu.Unlock() 363 364 if w.symKeys[id] != nil { 365 return "", fmt.Errorf("failed to generate unique ID") 366 } 367 w.symKeys[id] = key 368 return id, nil 369 } 370 371 // 372 func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) { 373 id, err := GenerateRandomID() 374 if err != nil { 375 return "", fmt.Errorf("failed to generate ID: %s", err) 376 } 377 if w.HasSymKey(id) { 378 return "", fmt.Errorf("failed to generate unique ID") 379 } 380 381 derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion) 382 if err != nil { 383 return "", err 384 } 385 386 w.keyMu.Lock() 387 defer w.keyMu.Unlock() 388 389 // 390 if w.symKeys[id] != nil { 391 return "", fmt.Errorf("critical error: failed to generate unique ID") 392 } 393 w.symKeys[id] = derived 394 return id, nil 395 } 396 397 // 398 // 399 func (w *Whisper) HasSymKey(id string) bool { 400 w.keyMu.RLock() 401 defer w.keyMu.RUnlock() 402 return w.symKeys[id] != nil 403 } 404 405 // 406 func (w *Whisper) DeleteSymKey(id string) bool { 407 w.keyMu.Lock() 408 defer w.keyMu.Unlock() 409 if w.symKeys[id] != nil { 410 delete(w.symKeys, id) 411 return true 412 } 413 return false 414 } 415 416 // 417 func (w *Whisper) GetSymKey(id string) ([]byte, error) { 418 w.keyMu.RLock() 419 defer w.keyMu.RUnlock() 420 if w.symKeys[id] != nil { 421 return w.symKeys[id], nil 422 } 423 return nil, fmt.Errorf("non-existent key ID") 424 } 425 426 // 427 // 428 func (w *Whisper) Subscribe(f *Filter) (string, error) { 429 return w.filters.Install(f) 430 } 431 432 // 433 func (w *Whisper) GetFilter(id string) *Filter { 434 return w.filters.Get(id) 435 } 436 437 // 438 func (w *Whisper) Unsubscribe(id string) error { 439 ok := w.filters.Uninstall(id) 440 if !ok { 441 return fmt.Errorf("Unsubscribe: Invalid ID") 442 } 443 return nil 444 } 445 446 // 447 // 448 func (w *Whisper) Send(envelope *Envelope) error { 449 ok, err := w.add(envelope) 450 if err != nil { 451 return err 452 } 453 if !ok { 454 return fmt.Errorf("failed to add envelope") 455 } 456 return err 457 } 458 459 // 460 // 461 func (w *Whisper) Start(*p2p.Server) error { 462 log.Info("started whisper v." + ProtocolVersionStr) 463 go w.update() 464 465 numCPU := runtime.NumCPU() 466 for i := 0; i < numCPU; i++ { 467 go w.processQueue() 468 } 469 470 return nil 471 } 472 473 // 474 // 475 func (w *Whisper) Stop() error { 476 close(w.quit) 477 log.Info("whisper stopped") 478 return nil 479 } 480 481 // 482 // 483 func (w *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 484 // 485 whisperPeer := newPeer(w, peer, rw) 486 487 w.peerMu.Lock() 488 w.peers[whisperPeer] = struct{}{} 489 w.peerMu.Unlock() 490 491 defer func() { 492 w.peerMu.Lock() 493 delete(w.peers, whisperPeer) 494 w.peerMu.Unlock() 495 }() 496 497 // 498 if err := whisperPeer.handshake(); err != nil { 499 return err 500 } 501 whisperPeer.start() 502 defer whisperPeer.stop() 503 504 return w.runMessageLoop(whisperPeer, rw) 505 } 506 507 // 508 func (w *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { 509 for { 510 // 511 packet, err := rw.ReadMsg() 512 if err != nil { 513 log.Info("message loop", "peer", p.peer.ID(), "err", err) 514 return err 515 } 516 if packet.Size > w.MaxMessageSize() { 517 log.Warn("oversized message received", "peer", p.peer.ID()) 518 return errors.New("oversized message received") 519 } 520 521 switch packet.Code { 522 case statusCode: 523 // 524 log.Warn("unxepected status message received", "peer", p.peer.ID()) 525 case messagesCode: 526 // 527 var envelope Envelope 528 if err := packet.Decode(&envelope); err != nil { 529 log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err) 530 return errors.New("invalid envelope") 531 } 532 cached, err := w.add(&envelope) 533 if err != nil { 534 log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) 535 return errors.New("invalid envelope") 536 } 537 if cached { 538 p.mark(&envelope) 539 } 540 case p2pCode: 541 // 542 // 543 // 544 // 545 if p.trusted { 546 var envelope Envelope 547 if err := packet.Decode(&envelope); err != nil { 548 log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 549 return errors.New("invalid direct message") 550 } 551 w.postEvent(&envelope, true) 552 } 553 case p2pRequestCode: 554 // 555 if w.mailServer != nil { 556 var request Envelope 557 if err := packet.Decode(&request); err != nil { 558 log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 559 return errors.New("invalid p2p request") 560 } 561 w.mailServer.DeliverMail(p, &request) 562 } 563 default: 564 // 565 // 566 } 567 568 packet.Discard() 569 } 570 } 571 572 // 573 // 574 // 575 func (w *Whisper) add(envelope *Envelope) (bool, error) { 576 now := uint32(time.Now().Unix()) 577 sent := envelope.Expiry - envelope.TTL 578 579 if sent > now { 580 if sent-SynchAllowance > now { 581 return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 582 } 583 // 584 envelope.calculatePoW(sent - now + 1) 585 } 586 587 if envelope.Expiry < now { 588 if envelope.Expiry+SynchAllowance*2 < now { 589 return false, fmt.Errorf("very old message") 590 } 591 log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) 592 return false, nil // 593 } 594 595 if uint32(envelope.size()) > w.MaxMessageSize() { 596 return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 597 } 598 599 if len(envelope.Version) > 4 { 600 return false, fmt.Errorf("oversized version [%x]", envelope.Hash()) 601 } 602 603 aesNonceSize := len(envelope.AESNonce) 604 if aesNonceSize != 0 && aesNonceSize != AESNonceLength { 605 // 606 // 607 return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash()) 608 } 609 610 if envelope.PoW() < w.MinPow() { 611 log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex()) 612 return false, nil // 613 } 614 615 hash := envelope.Hash() 616 617 w.poolMu.Lock() 618 _, alreadyCached := w.envelopes[hash] 619 if !alreadyCached { 620 w.envelopes[hash] = envelope 621 if w.expirations[envelope.Expiry] == nil { 622 w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() 623 } 624 if !w.expirations[envelope.Expiry].Contains(hash) { 625 w.expirations[envelope.Expiry].Add(hash) 626 } 627 } 628 w.poolMu.Unlock() 629 630 if alreadyCached { 631 log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) 632 } else { 633 log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) 634 w.statsMu.Lock() 635 w.stats.memoryUsed += envelope.size() 636 w.statsMu.Unlock() 637 w.postEvent(envelope, false) // 638 if w.mailServer != nil { 639 w.mailServer.Archive(envelope) 640 } 641 } 642 return true, nil 643 } 644 645 // 646 func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) { 647 // 648 // 649 // 650 if envelope.Ver() <= EnvelopeVersion { 651 if isP2P { 652 w.p2pMsgQueue <- envelope 653 } else { 654 w.checkOverflow() 655 w.messageQueue <- envelope 656 } 657 } 658 } 659 660 // 661 func (w *Whisper) checkOverflow() { 662 queueSize := len(w.messageQueue) 663 664 if queueSize == messageQueueLimit { 665 if !w.Overflow() { 666 w.settings.Store(overflowIdx, true) 667 log.Warn("message queue overflow") 668 } 669 } else if queueSize <= messageQueueLimit/2 { 670 if w.Overflow() { 671 w.settings.Store(overflowIdx, false) 672 log.Warn("message queue overflow fixed (back to normal)") 673 } 674 } 675 } 676 677 // 678 func (w *Whisper) processQueue() { 679 var e *Envelope 680 for { 681 select { 682 case <-w.quit: 683 return 684 685 case e = <-w.messageQueue: 686 w.filters.NotifyWatchers(e, false) 687 688 case e = <-w.p2pMsgQueue: 689 w.filters.NotifyWatchers(e, true) 690 } 691 } 692 } 693 694 // 695 // 696 func (w *Whisper) update() { 697 // 698 expire := time.NewTicker(expirationCycle) 699 700 // 701 for { 702 select { 703 case <-expire.C: 704 w.expire() 705 706 case <-w.quit: 707 return 708 } 709 } 710 } 711 712 // 713 // 714 func (w *Whisper) expire() { 715 w.poolMu.Lock() 716 defer w.poolMu.Unlock() 717 718 w.statsMu.Lock() 719 defer w.statsMu.Unlock() 720 w.stats.reset() 721 now := uint32(time.Now().Unix()) 722 for expiry, hashSet := range w.expirations { 723 if expiry < now { 724 // 725 hashSet.Each(func(v interface{}) bool { 726 sz := w.envelopes[v.(common.Hash)].size() 727 delete(w.envelopes, v.(common.Hash)) 728 w.stats.messagesCleared++ 729 w.stats.memoryCleared += sz 730 w.stats.memoryUsed -= sz 731 return true 732 }) 733 w.expirations[expiry].Clear() 734 delete(w.expirations, expiry) 735 } 736 } 737 } 738 739 // 740 func (w *Whisper) Stats() Statistics { 741 w.statsMu.Lock() 742 defer w.statsMu.Unlock() 743 744 return w.stats 745 } 746 747 // 748 func (w *Whisper) Envelopes() []*Envelope { 749 w.poolMu.RLock() 750 defer w.poolMu.RUnlock() 751 752 all := make([]*Envelope, 0, len(w.envelopes)) 753 for _, envelope := range w.envelopes { 754 all = append(all, envelope) 755 } 756 return all 757 } 758 759 // 760 // 761 func (w *Whisper) Messages(id string) []*ReceivedMessage { 762 result := make([]*ReceivedMessage, 0) 763 w.poolMu.RLock() 764 defer w.poolMu.RUnlock() 765 766 if filter := w.filters.Get(id); filter != nil { 767 for _, env := range w.envelopes { 768 msg := filter.processEnvelope(env) 769 if msg != nil { 770 result = append(result, msg) 771 } 772 } 773 } 774 return result 775 } 776 777 // 778 func (w *Whisper) isEnvelopeCached(hash common.Hash) bool { 779 w.poolMu.Lock() 780 defer w.poolMu.Unlock() 781 782 _, exist := w.envelopes[hash] 783 return exist 784 } 785 786 // 787 func (s *Statistics) reset() { 788 s.cycles++ 789 s.totalMessagesCleared += s.messagesCleared 790 791 s.memoryCleared = 0 792 s.messagesCleared = 0 793 } 794 795 // 796 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 797 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 798 } 799 800 // 801 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 802 if k == nil || k.D == nil || k.D.Sign() == 0 { 803 return false 804 } 805 return ValidatePublicKey(&k.PublicKey) 806 } 807 808 // 809 func validateSymmetricKey(k []byte) bool { 810 return len(k) > 0 && !containsOnlyZeros(k) 811 } 812 813 // 814 func containsOnlyZeros(data []byte) bool { 815 for _, b := range data { 816 if b != 0 { 817 return false 818 } 819 } 820 return true 821 } 822 823 // 824 func bytesToUintLittleEndian(b []byte) (res uint64) { 825 mul := uint64(1) 826 for i := 0; i < len(b); i++ { 827 res += uint64(b[i]) * mul 828 mul *= 256 829 } 830 return res 831 } 832 833 // 834 func BytesToUintBigEndian(b []byte) (res uint64) { 835 for i := 0; i < len(b); i++ { 836 res *= 256 837 res += uint64(b[i]) 838 } 839 return res 840 } 841 842 // 843 // 844 func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) { 845 if version == 0 { 846 // 847 // 848 derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New) 849 return derivedKey, nil 850 } 851 return nil, unknownVersionError(version) 852 } 853 854 // 855 func GenerateRandomID() (id string, err error) { 856 buf := make([]byte, keyIdSize) 857 _, err = crand.Read(buf) 858 if err != nil { 859 return "", err 860 } 861 if !validateSymmetricKey(buf) { 862 return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") 863 } 864 id = common.Bytes2Hex(buf) 865 return id, err 866 } 867