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