github.com/ylsgit/go-ethereum@v1.6.5/whisper/whisperv5/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 whisperv5
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	crand "crypto/rand"
    23  	"crypto/sha256"
    24  	"fmt"
    25  	"runtime"
    26  	"sync"
    27  	"time"
    28  
    29  	"github.com/ethereum/go-ethereum/common"
    30  	"github.com/ethereum/go-ethereum/crypto"
    31  	"github.com/ethereum/go-ethereum/log"
    32  	"github.com/ethereum/go-ethereum/p2p"
    33  	"github.com/ethereum/go-ethereum/rpc"
    34  	"github.com/syndtr/goleveldb/leveldb/errors"
    35  	"golang.org/x/crypto/pbkdf2"
    36  	set "gopkg.in/fatih/set.v0"
    37  )
    38  
    39  type Statistics struct {
    40  	messagesCleared      int
    41  	memoryCleared        int
    42  	memoryUsed           int
    43  	cycles               int
    44  	totalMessagesCleared int
    45  }
    46  
    47  // Whisper represents a dark communication interface through the Ethereum
    48  // network, using its very own P2P communication layer.
    49  type Whisper struct {
    50  	protocol p2p.Protocol // Protocol description and parameters
    51  	filters  *Filters     // Message filters installed with Subscribe function
    52  
    53  	privateKeys map[string]*ecdsa.PrivateKey // Private key storage
    54  	symKeys     map[string][]byte            // Symmetric key storage
    55  	keyMu       sync.RWMutex                 // Mutex associated with key storages
    56  
    57  	envelopes   map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
    58  	expirations map[uint32]*set.SetNonTS  // Message expiration pool
    59  	poolMu      sync.RWMutex              // Mutex to sync the message and expiration pools
    60  
    61  	peers  map[*Peer]struct{} // Set of currently active peers
    62  	peerMu sync.RWMutex       // Mutex to sync the active peer set
    63  
    64  	messageQueue chan *Envelope // Message queue for normal whisper messages
    65  	p2pMsgQueue  chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further)
    66  	quit         chan struct{}  // Channel used for graceful exit
    67  
    68  	minPoW       float64 // Minimal PoW required by the whisper node
    69  	maxMsgLength int     // Maximal message length allowed by the whisper node
    70  	overflow     bool    // Indicator of message queue overflow
    71  
    72  	stats Statistics // Statistics of whisper node
    73  
    74  	mailServer MailServer // MailServer interface
    75  }
    76  
    77  // New creates a Whisper client ready to communicate through the Ethereum P2P network.
    78  func New() *Whisper {
    79  	whisper := &Whisper{
    80  		privateKeys:  make(map[string]*ecdsa.PrivateKey),
    81  		symKeys:      make(map[string][]byte),
    82  		envelopes:    make(map[common.Hash]*Envelope),
    83  		expirations:  make(map[uint32]*set.SetNonTS),
    84  		peers:        make(map[*Peer]struct{}),
    85  		messageQueue: make(chan *Envelope, messageQueueLimit),
    86  		p2pMsgQueue:  make(chan *Envelope, messageQueueLimit),
    87  		quit:         make(chan struct{}),
    88  		minPoW:       DefaultMinimumPoW,
    89  		maxMsgLength: DefaultMaxMessageLength,
    90  	}
    91  	whisper.filters = NewFilters(whisper)
    92  
    93  	// p2p whisper sub protocol handler
    94  	whisper.protocol = p2p.Protocol{
    95  		Name:    ProtocolName,
    96  		Version: uint(ProtocolVersion),
    97  		Length:  NumberOfMessageCodes,
    98  		Run:     whisper.HandlePeer,
    99  	}
   100  
   101  	return whisper
   102  }
   103  
   104  // APIs returns the RPC descriptors the Whisper implementation offers
   105  func (w *Whisper) APIs() []rpc.API {
   106  	return []rpc.API{
   107  		{
   108  			Namespace: ProtocolName,
   109  			Version:   ProtocolVersionStr,
   110  			Service:   NewPublicWhisperAPI(w),
   111  			Public:    true,
   112  		},
   113  	}
   114  }
   115  
   116  // RegisterServer registers MailServer interface.
   117  // MailServer will process all the incoming messages with p2pRequestCode.
   118  func (w *Whisper) RegisterServer(server MailServer) {
   119  	w.mailServer = server
   120  }
   121  
   122  // Protocols returns the whisper sub-protocols ran by this particular client.
   123  func (w *Whisper) Protocols() []p2p.Protocol {
   124  	return []p2p.Protocol{w.protocol}
   125  }
   126  
   127  // Version returns the whisper sub-protocols version number.
   128  func (w *Whisper) Version() uint {
   129  	return w.protocol.Version
   130  }
   131  
   132  // SetMaxMessageLength sets the maximal message length allowed by this node
   133  func (w *Whisper) SetMaxMessageLength(val int) error {
   134  	if val <= 0 {
   135  		return fmt.Errorf("invalid message length: %d", val)
   136  	}
   137  	w.maxMsgLength = val
   138  	return nil
   139  }
   140  
   141  // SetMinimumPoW sets the minimal PoW required by this node
   142  func (w *Whisper) SetMinimumPoW(val float64) error {
   143  	if val <= 0.0 {
   144  		return fmt.Errorf("invalid PoW: %f", val)
   145  	}
   146  	w.minPoW = val
   147  	return nil
   148  }
   149  
   150  // getPeer retrieves peer by ID
   151  func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
   152  	w.peerMu.Lock()
   153  	defer w.peerMu.Unlock()
   154  	for p := range w.peers {
   155  		id := p.peer.ID()
   156  		if bytes.Equal(peerID, id[:]) {
   157  			return p, nil
   158  		}
   159  	}
   160  	return nil, fmt.Errorf("Could not find peer with ID: %x", peerID)
   161  }
   162  
   163  // AllowP2PMessagesFromPeer marks specific peer trusted,
   164  // which will allow it to send historic (expired) messages.
   165  func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error {
   166  	p, err := w.getPeer(peerID)
   167  	if err != nil {
   168  		return err
   169  	}
   170  	p.trusted = true
   171  	return nil
   172  }
   173  
   174  // RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
   175  // which is known to implement MailServer interface, and is supposed to process this
   176  // request and respond with a number of peer-to-peer messages (possibly expired),
   177  // which are not supposed to be forwarded any further.
   178  // The whisper protocol is agnostic of the format and contents of envelope.
   179  func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error {
   180  	p, err := w.getPeer(peerID)
   181  	if err != nil {
   182  		return err
   183  	}
   184  	p.trusted = true
   185  	return p2p.Send(p.ws, p2pRequestCode, envelope)
   186  }
   187  
   188  // SendP2PMessage sends a peer-to-peer message to a specific peer.
   189  func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
   190  	p, err := w.getPeer(peerID)
   191  	if err != nil {
   192  		return err
   193  	}
   194  	return w.SendP2PDirect(p, envelope)
   195  }
   196  
   197  // SendP2PDirect sends a peer-to-peer message to a specific peer.
   198  func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
   199  	return p2p.Send(peer.ws, p2pCode, envelope)
   200  }
   201  
   202  // NewKeyPair generates a new cryptographic identity for the client, and injects
   203  // it into the known identities for message decryption. Returns ID of the new key pair.
   204  func (w *Whisper) NewKeyPair() (string, error) {
   205  	key, err := crypto.GenerateKey()
   206  	if err != nil || !validatePrivateKey(key) {
   207  		key, err = crypto.GenerateKey() // retry once
   208  	}
   209  	if err != nil {
   210  		return "", err
   211  	}
   212  	if !validatePrivateKey(key) {
   213  		return "", fmt.Errorf("failed to generate valid key")
   214  	}
   215  
   216  	id, err := GenerateRandomID()
   217  	if err != nil {
   218  		return "", fmt.Errorf("failed to generate ID: %s", err)
   219  	}
   220  
   221  	w.keyMu.Lock()
   222  	defer w.keyMu.Unlock()
   223  
   224  	if w.privateKeys[id] != nil {
   225  		return "", fmt.Errorf("failed to generate unique ID")
   226  	}
   227  	w.privateKeys[id] = key
   228  	return id, nil
   229  }
   230  
   231  // DeleteKeyPair deletes the specified key if it exists.
   232  func (w *Whisper) DeleteKeyPair(key string) bool {
   233  	w.keyMu.Lock()
   234  	defer w.keyMu.Unlock()
   235  
   236  	if w.privateKeys[key] != nil {
   237  		delete(w.privateKeys, key)
   238  		return true
   239  	}
   240  	return false
   241  }
   242  
   243  // HasKeyPair checks if the the whisper node is configured with the private key
   244  // of the specified public pair.
   245  func (w *Whisper) HasKeyPair(id string) bool {
   246  	w.keyMu.RLock()
   247  	defer w.keyMu.RUnlock()
   248  	return w.privateKeys[id] != nil
   249  }
   250  
   251  // GetPrivateKey retrieves the private key of the specified identity.
   252  func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
   253  	w.keyMu.RLock()
   254  	defer w.keyMu.RUnlock()
   255  	key := w.privateKeys[id]
   256  	if key == nil {
   257  		return nil, fmt.Errorf("invalid id")
   258  	}
   259  	return key, nil
   260  }
   261  
   262  // GenerateSymKey generates a random symmetric key and stores it under id,
   263  // which is then returned. Will be used in the future for session key exchange.
   264  func (w *Whisper) GenerateSymKey() (string, error) {
   265  	key := make([]byte, aesKeyLength)
   266  	_, err := crand.Read(key)
   267  	if err != nil {
   268  		return "", err
   269  	} else if !validateSymmetricKey(key) {
   270  		return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
   271  	}
   272  
   273  	id, err := GenerateRandomID()
   274  	if err != nil {
   275  		return "", fmt.Errorf("failed to generate ID: %s", err)
   276  	}
   277  
   278  	w.keyMu.Lock()
   279  	defer w.keyMu.Unlock()
   280  
   281  	if w.symKeys[id] != nil {
   282  		return "", fmt.Errorf("failed to generate unique ID")
   283  	}
   284  	w.symKeys[id] = key
   285  	return id, nil
   286  }
   287  
   288  // AddSymKeyDirect stores the key, and returns its id.
   289  func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
   290  	if len(key) != aesKeyLength {
   291  		return "", fmt.Errorf("wrong key size: %d", len(key))
   292  	}
   293  
   294  	id, err := GenerateRandomID()
   295  	if err != nil {
   296  		return "", fmt.Errorf("failed to generate ID: %s", err)
   297  	}
   298  
   299  	w.keyMu.Lock()
   300  	defer w.keyMu.Unlock()
   301  
   302  	if w.symKeys[id] != nil {
   303  		return "", fmt.Errorf("failed to generate unique ID")
   304  	}
   305  	w.symKeys[id] = key
   306  	return id, nil
   307  }
   308  
   309  // AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
   310  func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
   311  	id, err := GenerateRandomID()
   312  	if err != nil {
   313  		return "", fmt.Errorf("failed to generate ID: %s", err)
   314  	}
   315  	if w.HasSymKey(id) {
   316  		return "", fmt.Errorf("failed to generate unique ID")
   317  	}
   318  
   319  	derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
   320  	if err != nil {
   321  		return "", err
   322  	}
   323  
   324  	w.keyMu.Lock()
   325  	defer w.keyMu.Unlock()
   326  
   327  	// double check is necessary, because deriveKeyMaterial() is very slow
   328  	if w.symKeys[id] != nil {
   329  		return "", fmt.Errorf("critical error: failed to generate unique ID")
   330  	}
   331  	w.symKeys[id] = derived
   332  	return id, nil
   333  }
   334  
   335  // HasSymKey returns true if there is a key associated with the given id.
   336  // Otherwise returns false.
   337  func (w *Whisper) HasSymKey(id string) bool {
   338  	w.keyMu.RLock()
   339  	defer w.keyMu.RUnlock()
   340  	return w.symKeys[id] != nil
   341  }
   342  
   343  // DeleteSymKey deletes the key associated with the name string if it exists.
   344  func (w *Whisper) DeleteSymKey(id string) bool {
   345  	w.keyMu.Lock()
   346  	defer w.keyMu.Unlock()
   347  	if w.symKeys[id] != nil {
   348  		delete(w.symKeys, id)
   349  		return true
   350  	}
   351  	return false
   352  }
   353  
   354  // GetSymKey returns the symmetric key associated with the given id.
   355  func (w *Whisper) GetSymKey(id string) ([]byte, error) {
   356  	w.keyMu.RLock()
   357  	defer w.keyMu.RUnlock()
   358  	if w.symKeys[id] != nil {
   359  		return w.symKeys[id], nil
   360  	}
   361  	return nil, fmt.Errorf("non-existent key ID")
   362  }
   363  
   364  // Subscribe installs a new message handler used for filtering, decrypting
   365  // and subsequent storing of incoming messages.
   366  func (w *Whisper) Subscribe(f *Filter) (string, error) {
   367  	return w.filters.Install(f)
   368  }
   369  
   370  // GetFilter returns the filter by id.
   371  func (w *Whisper) GetFilter(id string) *Filter {
   372  	return w.filters.Get(id)
   373  }
   374  
   375  // Unsubscribe removes an installed message handler.
   376  func (w *Whisper) Unsubscribe(id string) error {
   377  	ok := w.filters.Uninstall(id)
   378  	if !ok {
   379  		return fmt.Errorf("Unsubscribe: Invalid ID")
   380  	}
   381  	return nil
   382  }
   383  
   384  // Send injects a message into the whisper send queue, to be distributed in the
   385  // network in the coming cycles.
   386  func (w *Whisper) Send(envelope *Envelope) error {
   387  	ok, err := w.add(envelope)
   388  	if err != nil {
   389  		return err
   390  	}
   391  	if !ok {
   392  		return fmt.Errorf("failed to add envelope")
   393  	}
   394  	return err
   395  }
   396  
   397  // Start implements node.Service, starting the background data propagation thread
   398  // of the Whisper protocol.
   399  func (w *Whisper) Start(*p2p.Server) error {
   400  	log.Info("started whisper v." + ProtocolVersionStr)
   401  	go w.update()
   402  
   403  	numCPU := runtime.NumCPU()
   404  	for i := 0; i < numCPU; i++ {
   405  		go w.processQueue()
   406  	}
   407  
   408  	return nil
   409  }
   410  
   411  // Stop implements node.Service, stopping the background data propagation thread
   412  // of the Whisper protocol.
   413  func (w *Whisper) Stop() error {
   414  	close(w.quit)
   415  	log.Info("whisper stopped")
   416  	return nil
   417  }
   418  
   419  // HandlePeer is called by the underlying P2P layer when the whisper sub-protocol
   420  // connection is negotiated.
   421  func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
   422  	// Create the new peer and start tracking it
   423  	whisperPeer := newPeer(wh, peer, rw)
   424  
   425  	wh.peerMu.Lock()
   426  	wh.peers[whisperPeer] = struct{}{}
   427  	wh.peerMu.Unlock()
   428  
   429  	defer func() {
   430  		wh.peerMu.Lock()
   431  		delete(wh.peers, whisperPeer)
   432  		wh.peerMu.Unlock()
   433  	}()
   434  
   435  	// Run the peer handshake and state updates
   436  	if err := whisperPeer.handshake(); err != nil {
   437  		return err
   438  	}
   439  	whisperPeer.start()
   440  	defer whisperPeer.stop()
   441  
   442  	return wh.runMessageLoop(whisperPeer, rw)
   443  }
   444  
   445  // runMessageLoop reads and processes inbound messages directly to merge into client-global state.
   446  func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
   447  	for {
   448  		// fetch the next packet
   449  		packet, err := rw.ReadMsg()
   450  		if err != nil {
   451  			log.Warn("message loop", "peer", p.peer.ID(), "err", err)
   452  			return err
   453  		}
   454  		if packet.Size > uint32(wh.maxMsgLength) {
   455  			log.Warn("oversized message received", "peer", p.peer.ID())
   456  			return errors.New("oversized message received")
   457  		}
   458  
   459  		switch packet.Code {
   460  		case statusCode:
   461  			// this should not happen, but no need to panic; just ignore this message.
   462  			log.Warn("unxepected status message received", "peer", p.peer.ID())
   463  		case messagesCode:
   464  			// decode the contained envelopes
   465  			var envelope Envelope
   466  			if err := packet.Decode(&envelope); err != nil {
   467  				log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   468  				return errors.New("invalid envelope")
   469  			}
   470  			cached, err := wh.add(&envelope)
   471  			if err != nil {
   472  				log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   473  				return errors.New("invalid envelope")
   474  			}
   475  			if cached {
   476  				p.mark(&envelope)
   477  			}
   478  		case p2pCode:
   479  			// peer-to-peer message, sent directly to peer bypassing PoW checks, etc.
   480  			// this message is not supposed to be forwarded to other peers, and
   481  			// therefore might not satisfy the PoW, expiry and other requirements.
   482  			// these messages are only accepted from the trusted peer.
   483  			if p.trusted {
   484  				var envelope Envelope
   485  				if err := packet.Decode(&envelope); err != nil {
   486  					log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   487  					return errors.New("invalid direct message")
   488  				}
   489  				wh.postEvent(&envelope, true)
   490  			}
   491  		case p2pRequestCode:
   492  			// Must be processed if mail server is implemented. Otherwise ignore.
   493  			if wh.mailServer != nil {
   494  				var request Envelope
   495  				if err := packet.Decode(&request); err != nil {
   496  					log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   497  					return errors.New("invalid p2p request")
   498  				}
   499  				wh.mailServer.DeliverMail(p, &request)
   500  			}
   501  		default:
   502  			// New message types might be implemented in the future versions of Whisper.
   503  			// For forward compatibility, just ignore.
   504  		}
   505  
   506  		packet.Discard()
   507  	}
   508  }
   509  
   510  // add inserts a new envelope into the message pool to be distributed within the
   511  // whisper network. It also inserts the envelope into the expiration pool at the
   512  // appropriate time-stamp. In case of error, connection should be dropped.
   513  func (wh *Whisper) add(envelope *Envelope) (bool, error) {
   514  	now := uint32(time.Now().Unix())
   515  	sent := envelope.Expiry - envelope.TTL
   516  
   517  	if sent > now {
   518  		if sent-SynchAllowance > now {
   519  			return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash())
   520  		} else {
   521  			// recalculate PoW, adjusted for the time difference, plus one second for latency
   522  			envelope.calculatePoW(sent - now + 1)
   523  		}
   524  	}
   525  
   526  	if envelope.Expiry < now {
   527  		if envelope.Expiry+SynchAllowance*2 < now {
   528  			return false, fmt.Errorf("very old message")
   529  		} else {
   530  			log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
   531  			return false, nil // drop envelope without error
   532  		}
   533  	}
   534  
   535  	if envelope.size() > wh.maxMsgLength {
   536  		return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
   537  	}
   538  
   539  	if len(envelope.Version) > 4 {
   540  		return false, fmt.Errorf("oversized version [%x]", envelope.Hash())
   541  	}
   542  
   543  	aesNonceSize := len(envelope.AESNonce)
   544  	if aesNonceSize != 0 && aesNonceSize != AESNonceLength {
   545  		// the standard AES GCM nonce size is 12 bytes,
   546  		// but constant gcmStandardNonceSize cannot be accessed (not exported)
   547  		return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash())
   548  	}
   549  
   550  	if envelope.PoW() < wh.minPoW {
   551  		log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
   552  		return false, nil // drop envelope without error
   553  	}
   554  
   555  	hash := envelope.Hash()
   556  
   557  	wh.poolMu.Lock()
   558  	_, alreadyCached := wh.envelopes[hash]
   559  	if !alreadyCached {
   560  		wh.envelopes[hash] = envelope
   561  		if wh.expirations[envelope.Expiry] == nil {
   562  			wh.expirations[envelope.Expiry] = set.NewNonTS()
   563  		}
   564  		if !wh.expirations[envelope.Expiry].Has(hash) {
   565  			wh.expirations[envelope.Expiry].Add(hash)
   566  		}
   567  	}
   568  	wh.poolMu.Unlock()
   569  
   570  	if alreadyCached {
   571  		log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
   572  	} else {
   573  		log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex())
   574  		wh.stats.memoryUsed += envelope.size()
   575  		wh.postEvent(envelope, false) // notify the local node about the new message
   576  		if wh.mailServer != nil {
   577  			wh.mailServer.Archive(envelope)
   578  		}
   579  	}
   580  	return true, nil
   581  }
   582  
   583  // postEvent queues the message for further processing.
   584  func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
   585  	// if the version of incoming message is higher than
   586  	// currently supported version, we can not decrypt it,
   587  	// and therefore just ignore this message
   588  	if envelope.Ver() <= EnvelopeVersion {
   589  		if isP2P {
   590  			w.p2pMsgQueue <- envelope
   591  		} else {
   592  			w.checkOverflow()
   593  			w.messageQueue <- envelope
   594  		}
   595  	}
   596  }
   597  
   598  // checkOverflow checks if message queue overflow occurs and reports it if necessary.
   599  func (w *Whisper) checkOverflow() {
   600  	queueSize := len(w.messageQueue)
   601  
   602  	if queueSize == messageQueueLimit {
   603  		if !w.overflow {
   604  			w.overflow = true
   605  			log.Warn("message queue overflow")
   606  		}
   607  	} else if queueSize <= messageQueueLimit/2 {
   608  		if w.overflow {
   609  			w.overflow = false
   610  			log.Warn("message queue overflow fixed (back to normal)")
   611  		}
   612  	}
   613  }
   614  
   615  // processQueue delivers the messages to the watchers during the lifetime of the whisper node.
   616  func (w *Whisper) processQueue() {
   617  	var e *Envelope
   618  	for {
   619  		select {
   620  		case <-w.quit:
   621  			return
   622  
   623  		case e = <-w.messageQueue:
   624  			w.filters.NotifyWatchers(e, false)
   625  
   626  		case e = <-w.p2pMsgQueue:
   627  			w.filters.NotifyWatchers(e, true)
   628  		}
   629  	}
   630  }
   631  
   632  // update loops until the lifetime of the whisper node, updating its internal
   633  // state by expiring stale messages from the pool.
   634  func (w *Whisper) update() {
   635  	// Start a ticker to check for expirations
   636  	expire := time.NewTicker(expirationCycle)
   637  
   638  	// Repeat updates until termination is requested
   639  	for {
   640  		select {
   641  		case <-expire.C:
   642  			w.expire()
   643  
   644  		case <-w.quit:
   645  			return
   646  		}
   647  	}
   648  }
   649  
   650  // expire iterates over all the expiration timestamps, removing all stale
   651  // messages from the pools.
   652  func (w *Whisper) expire() {
   653  	w.poolMu.Lock()
   654  	defer w.poolMu.Unlock()
   655  
   656  	w.stats.reset()
   657  	now := uint32(time.Now().Unix())
   658  	for expiry, hashSet := range w.expirations {
   659  		if expiry < now {
   660  			// Dump all expired messages and remove timestamp
   661  			hashSet.Each(func(v interface{}) bool {
   662  				sz := w.envelopes[v.(common.Hash)].size()
   663  				delete(w.envelopes, v.(common.Hash))
   664  				w.stats.messagesCleared++
   665  				w.stats.memoryCleared += sz
   666  				w.stats.memoryUsed -= sz
   667  				return true
   668  			})
   669  			w.expirations[expiry].Clear()
   670  			delete(w.expirations, expiry)
   671  		}
   672  	}
   673  }
   674  
   675  // Stats returns the whisper node statistics.
   676  func (w *Whisper) Stats() string {
   677  	result := fmt.Sprintf("Memory usage: %d bytes. Average messages cleared per expiry cycle: %d. Total messages cleared: %d.",
   678  		w.stats.memoryUsed, w.stats.totalMessagesCleared/w.stats.cycles, w.stats.totalMessagesCleared)
   679  	if w.stats.messagesCleared > 0 {
   680  		result += fmt.Sprintf(" Latest expiry cycle cleared %d messages (%d bytes).",
   681  			w.stats.messagesCleared, w.stats.memoryCleared)
   682  	}
   683  	if w.overflow {
   684  		result += " Message queue state: overflow."
   685  	}
   686  	return result
   687  }
   688  
   689  // Envelopes retrieves all the messages currently pooled by the node.
   690  func (w *Whisper) Envelopes() []*Envelope {
   691  	w.poolMu.RLock()
   692  	defer w.poolMu.RUnlock()
   693  
   694  	all := make([]*Envelope, 0, len(w.envelopes))
   695  	for _, envelope := range w.envelopes {
   696  		all = append(all, envelope)
   697  	}
   698  	return all
   699  }
   700  
   701  // Messages iterates through all currently floating envelopes
   702  // and retrieves all the messages, that this filter could decrypt.
   703  func (w *Whisper) Messages(id string) []*ReceivedMessage {
   704  	result := make([]*ReceivedMessage, 0)
   705  	w.poolMu.RLock()
   706  	defer w.poolMu.RUnlock()
   707  
   708  	if filter := w.filters.Get(id); filter != nil {
   709  		for _, env := range w.envelopes {
   710  			msg := filter.processEnvelope(env)
   711  			if msg != nil {
   712  				result = append(result, msg)
   713  			}
   714  		}
   715  	}
   716  	return result
   717  }
   718  
   719  // isEnvelopeCached checks if envelope with specific hash has already been received and cached.
   720  func (w *Whisper) isEnvelopeCached(hash common.Hash) bool {
   721  	w.poolMu.Lock()
   722  	defer w.poolMu.Unlock()
   723  
   724  	_, exist := w.envelopes[hash]
   725  	return exist
   726  }
   727  
   728  // reset resets the node's statistics after each expiry cycle.
   729  func (s *Statistics) reset() {
   730  	s.cycles++
   731  	s.totalMessagesCleared += s.messagesCleared
   732  
   733  	s.memoryCleared = 0
   734  	s.messagesCleared = 0
   735  }
   736  
   737  // ValidateKeyID checks the format of key id.
   738  func ValidateKeyID(id string) error {
   739  	const target = keyIdSize * 2
   740  	if len(id) != target {
   741  		return fmt.Errorf("wrong size of key ID (expected %d bytes, got %d)", target, len(id))
   742  	}
   743  	return nil
   744  }
   745  
   746  // ValidatePublicKey checks the format of the given public key.
   747  func ValidatePublicKey(k *ecdsa.PublicKey) bool {
   748  	return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0
   749  }
   750  
   751  // validatePrivateKey checks the format of the given private key.
   752  func validatePrivateKey(k *ecdsa.PrivateKey) bool {
   753  	if k == nil || k.D == nil || k.D.Sign() == 0 {
   754  		return false
   755  	}
   756  	return ValidatePublicKey(&k.PublicKey)
   757  }
   758  
   759  // validateSymmetricKey returns false if the key contains all zeros
   760  func validateSymmetricKey(k []byte) bool {
   761  	return len(k) > 0 && !containsOnlyZeros(k)
   762  }
   763  
   764  // containsOnlyZeros checks if the data contain only zeros.
   765  func containsOnlyZeros(data []byte) bool {
   766  	for _, b := range data {
   767  		if b != 0 {
   768  			return false
   769  		}
   770  	}
   771  	return true
   772  }
   773  
   774  // bytesToUintLittleEndian converts the slice to 64-bit unsigned integer.
   775  func bytesToUintLittleEndian(b []byte) (res uint64) {
   776  	mul := uint64(1)
   777  	for i := 0; i < len(b); i++ {
   778  		res += uint64(b[i]) * mul
   779  		mul *= 256
   780  	}
   781  	return res
   782  }
   783  
   784  // BytesToUintBigEndian converts the slice to 64-bit unsigned integer.
   785  func BytesToUintBigEndian(b []byte) (res uint64) {
   786  	for i := 0; i < len(b); i++ {
   787  		res *= 256
   788  		res += uint64(b[i])
   789  	}
   790  	return res
   791  }
   792  
   793  // deriveKeyMaterial derives symmetric key material from the key or password.
   794  // pbkdf2 is used for security, in case people use password instead of randomly generated keys.
   795  func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) {
   796  	if version == 0 {
   797  		// kdf should run no less than 0.1 seconds on average compute,
   798  		// because it's a once in a session experience
   799  		derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New)
   800  		return derivedKey, nil
   801  	} else {
   802  		return nil, unknownVersionError(version)
   803  	}
   804  }
   805  
   806  // GenerateRandomID generates a random string, which is then returned to be used as a key id
   807  func GenerateRandomID() (id string, err error) {
   808  	buf := make([]byte, keyIdSize)
   809  	_, err = crand.Read(buf)
   810  	if err != nil {
   811  		return "", err
   812  	}
   813  	if !validateSymmetricKey(buf) {
   814  		return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
   815  	}
   816  	id = common.Bytes2Hex(buf)
   817  	return id, err
   818  }