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