github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/whisperv5/whisper.go (about)

     1  // Copyright 2016 The Spectrum Authors
     2  // This file is part of the Spectrum library.
     3  //
     4  // The Spectrum 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 Spectrum 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 Spectrum 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/SmartMeshFoundation/Spectrum/common"
    30  	"github.com/SmartMeshFoundation/Spectrum/crypto"
    31  	"github.com/SmartMeshFoundation/Spectrum/log"
    32  	"github.com/SmartMeshFoundation/Spectrum/p2p"
    33  	"github.com/SmartMeshFoundation/Spectrum/rpc"
    34  	"github.com/syndtr/goleveldb/leveldb/errors"
    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 Ethereum
    55  // network, using its very own P2P communication layer.
    56  type Whisper struct {
    57  	protocol p2p.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 Ethereum 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 = p2p.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() []p2p.Protocol {
   161  	return []p2p.Protocol{w.protocol}
   162  }
   163  
   164  // Version returns the whisper sub-protocols version number.
   165  func (w *Whisper) Version() uint {
   166  	return w.protocol.Version
   167  }
   168  
   169  // SetMaxMessageSize sets the maximal message size allowed by this node
   170  func (w *Whisper) SetMaxMessageSize(size uint32) error {
   171  	if size > MaxMessageSize {
   172  		return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize)
   173  	}
   174  	w.settings.Store(maxMsgSizeIdx, size)
   175  	return nil
   176  }
   177  
   178  // SetMinimumPoW sets the minimal PoW required by this node
   179  func (w *Whisper) SetMinimumPoW(val float64) error {
   180  	if val <= 0.0 {
   181  		return fmt.Errorf("invalid PoW: %f", val)
   182  	}
   183  	w.settings.Store(minPowIdx, val)
   184  	return nil
   185  }
   186  
   187  // getPeer retrieves peer by ID
   188  func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
   189  	w.peerMu.Lock()
   190  	defer w.peerMu.Unlock()
   191  	for p := range w.peers {
   192  		id := p.peer.ID()
   193  		if bytes.Equal(peerID, id[:]) {
   194  			return p, nil
   195  		}
   196  	}
   197  	return nil, fmt.Errorf("Could not find peer with ID: %x", peerID)
   198  }
   199  
   200  // AllowP2PMessagesFromPeer marks specific peer trusted,
   201  // which will allow it to send historic (expired) messages.
   202  func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error {
   203  	p, err := w.getPeer(peerID)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	p.trusted = true
   208  	return nil
   209  }
   210  
   211  // RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
   212  // which is known to implement MailServer interface, and is supposed to process this
   213  // request and respond with a number of peer-to-peer messages (possibly expired),
   214  // which are not supposed to be forwarded any further.
   215  // The whisper protocol is agnostic of the format and contents of envelope.
   216  func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error {
   217  	p, err := w.getPeer(peerID)
   218  	if err != nil {
   219  		return err
   220  	}
   221  	p.trusted = true
   222  	return p2p.Send(p.ws, p2pRequestCode, envelope)
   223  }
   224  
   225  // SendP2PMessage sends a peer-to-peer message to a specific peer.
   226  func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
   227  	p, err := w.getPeer(peerID)
   228  	if err != nil {
   229  		return err
   230  	}
   231  	return w.SendP2PDirect(p, envelope)
   232  }
   233  
   234  // SendP2PDirect sends a peer-to-peer message to a specific peer.
   235  func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
   236  	return p2p.Send(peer.ws, p2pCode, envelope)
   237  }
   238  
   239  // NewKeyPair generates a new cryptographic identity for the client, and injects
   240  // it into the known identities for message decryption. Returns ID of the new key pair.
   241  func (w *Whisper) NewKeyPair() (string, error) {
   242  	key, err := crypto.GenerateKey()
   243  	if err != nil || !validatePrivateKey(key) {
   244  		key, err = crypto.GenerateKey() // retry once
   245  	}
   246  	if err != nil {
   247  		return "", err
   248  	}
   249  	if !validatePrivateKey(key) {
   250  		return "", fmt.Errorf("failed to generate valid key")
   251  	}
   252  
   253  	id, err := GenerateRandomID()
   254  	if err != nil {
   255  		return "", fmt.Errorf("failed to generate ID: %s", err)
   256  	}
   257  
   258  	w.keyMu.Lock()
   259  	defer w.keyMu.Unlock()
   260  
   261  	if w.privateKeys[id] != nil {
   262  		return "", fmt.Errorf("failed to generate unique ID")
   263  	}
   264  	w.privateKeys[id] = key
   265  	return id, nil
   266  }
   267  
   268  // DeleteKeyPair deletes the specified key if it exists.
   269  func (w *Whisper) DeleteKeyPair(key string) bool {
   270  	w.keyMu.Lock()
   271  	defer w.keyMu.Unlock()
   272  
   273  	if w.privateKeys[key] != nil {
   274  		delete(w.privateKeys, key)
   275  		return true
   276  	}
   277  	return false
   278  }
   279  
   280  // AddKeyPair imports a asymmetric private key and returns it identifier.
   281  func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
   282  	id, err := GenerateRandomID()
   283  	if err != nil {
   284  		return "", fmt.Errorf("failed to generate ID: %s", err)
   285  	}
   286  
   287  	w.keyMu.Lock()
   288  	w.privateKeys[id] = key
   289  	w.keyMu.Unlock()
   290  
   291  	return id, nil
   292  }
   293  
   294  // HasKeyPair checks if the the whisper node is configured with the private key
   295  // of the specified public pair.
   296  func (w *Whisper) HasKeyPair(id string) bool {
   297  	w.keyMu.RLock()
   298  	defer w.keyMu.RUnlock()
   299  	return w.privateKeys[id] != nil
   300  }
   301  
   302  // GetPrivateKey retrieves the private key of the specified identity.
   303  func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
   304  	w.keyMu.RLock()
   305  	defer w.keyMu.RUnlock()
   306  	key := w.privateKeys[id]
   307  	if key == nil {
   308  		return nil, fmt.Errorf("invalid id")
   309  	}
   310  	return key, nil
   311  }
   312  
   313  // GenerateSymKey generates a random symmetric key and stores it under id,
   314  // which is then returned. Will be used in the future for session key exchange.
   315  func (w *Whisper) GenerateSymKey() (string, error) {
   316  	key := make([]byte, aesKeyLength)
   317  	_, err := crand.Read(key)
   318  	if err != nil {
   319  		return "", err
   320  	} else if !validateSymmetricKey(key) {
   321  		return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
   322  	}
   323  
   324  	id, err := GenerateRandomID()
   325  	if err != nil {
   326  		return "", fmt.Errorf("failed to generate ID: %s", err)
   327  	}
   328  
   329  	w.keyMu.Lock()
   330  	defer w.keyMu.Unlock()
   331  
   332  	if w.symKeys[id] != nil {
   333  		return "", fmt.Errorf("failed to generate unique ID")
   334  	}
   335  	w.symKeys[id] = key
   336  	return id, nil
   337  }
   338  
   339  // AddSymKeyDirect stores the key, and returns its id.
   340  func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
   341  	if len(key) != aesKeyLength {
   342  		return "", fmt.Errorf("wrong key size: %d", len(key))
   343  	}
   344  
   345  	id, err := GenerateRandomID()
   346  	if err != nil {
   347  		return "", fmt.Errorf("failed to generate ID: %s", err)
   348  	}
   349  
   350  	w.keyMu.Lock()
   351  	defer w.keyMu.Unlock()
   352  
   353  	if w.symKeys[id] != nil {
   354  		return "", fmt.Errorf("failed to generate unique ID")
   355  	}
   356  	w.symKeys[id] = key
   357  	return id, nil
   358  }
   359  
   360  // AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
   361  func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
   362  	id, err := GenerateRandomID()
   363  	if err != nil {
   364  		return "", fmt.Errorf("failed to generate ID: %s", err)
   365  	}
   366  	if w.HasSymKey(id) {
   367  		return "", fmt.Errorf("failed to generate unique ID")
   368  	}
   369  
   370  	derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
   371  	if err != nil {
   372  		return "", err
   373  	}
   374  
   375  	w.keyMu.Lock()
   376  	defer w.keyMu.Unlock()
   377  
   378  	// double check is necessary, because deriveKeyMaterial() is very slow
   379  	if w.symKeys[id] != nil {
   380  		return "", fmt.Errorf("critical error: failed to generate unique ID")
   381  	}
   382  	w.symKeys[id] = derived
   383  	return id, nil
   384  }
   385  
   386  // HasSymKey returns true if there is a key associated with the given id.
   387  // Otherwise returns false.
   388  func (w *Whisper) HasSymKey(id string) bool {
   389  	w.keyMu.RLock()
   390  	defer w.keyMu.RUnlock()
   391  	return w.symKeys[id] != nil
   392  }
   393  
   394  // DeleteSymKey deletes the key associated with the name string if it exists.
   395  func (w *Whisper) DeleteSymKey(id string) bool {
   396  	w.keyMu.Lock()
   397  	defer w.keyMu.Unlock()
   398  	if w.symKeys[id] != nil {
   399  		delete(w.symKeys, id)
   400  		return true
   401  	}
   402  	return false
   403  }
   404  
   405  // GetSymKey returns the symmetric key associated with the given id.
   406  func (w *Whisper) GetSymKey(id string) ([]byte, error) {
   407  	w.keyMu.RLock()
   408  	defer w.keyMu.RUnlock()
   409  	if w.symKeys[id] != nil {
   410  		return w.symKeys[id], nil
   411  	}
   412  	return nil, fmt.Errorf("non-existent key ID")
   413  }
   414  
   415  // Subscribe installs a new message handler used for filtering, decrypting
   416  // and subsequent storing of incoming messages.
   417  func (w *Whisper) Subscribe(f *Filter) (string, error) {
   418  	return w.filters.Install(f)
   419  }
   420  
   421  // GetFilter returns the filter by id.
   422  func (w *Whisper) GetFilter(id string) *Filter {
   423  	return w.filters.Get(id)
   424  }
   425  
   426  // Unsubscribe removes an installed message handler.
   427  func (w *Whisper) Unsubscribe(id string) error {
   428  	ok := w.filters.Uninstall(id)
   429  	if !ok {
   430  		return fmt.Errorf("Unsubscribe: Invalid ID")
   431  	}
   432  	return nil
   433  }
   434  
   435  // Send injects a message into the whisper send queue, to be distributed in the
   436  // network in the coming cycles.
   437  func (w *Whisper) Send(envelope *Envelope) error {
   438  	ok, err := w.add(envelope)
   439  	if err != nil {
   440  		return err
   441  	}
   442  	if !ok {
   443  		return fmt.Errorf("failed to add envelope")
   444  	}
   445  	return err
   446  }
   447  
   448  // Start implements node.Service, starting the background data propagation thread
   449  // of the Whisper protocol.
   450  func (w *Whisper) Start(*p2p.Server) error {
   451  	log.Info("started whisper v." + ProtocolVersionStr)
   452  	go w.update()
   453  
   454  	numCPU := runtime.NumCPU()
   455  	for i := 0; i < numCPU; i++ {
   456  		go w.processQueue()
   457  	}
   458  
   459  	return nil
   460  }
   461  
   462  // Stop implements node.Service, stopping the background data propagation thread
   463  // of the Whisper protocol.
   464  func (w *Whisper) Stop() error {
   465  	close(w.quit)
   466  	log.Info("whisper stopped")
   467  	return nil
   468  }
   469  
   470  // HandlePeer is called by the underlying P2P layer when the whisper sub-protocol
   471  // connection is negotiated.
   472  func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
   473  	// Create the new peer and start tracking it
   474  	whisperPeer := newPeer(wh, peer, rw)
   475  
   476  	wh.peerMu.Lock()
   477  	wh.peers[whisperPeer] = struct{}{}
   478  	wh.peerMu.Unlock()
   479  
   480  	defer func() {
   481  		wh.peerMu.Lock()
   482  		delete(wh.peers, whisperPeer)
   483  		wh.peerMu.Unlock()
   484  	}()
   485  
   486  	// Run the peer handshake and state updates
   487  	if err := whisperPeer.handshake(); err != nil {
   488  		return err
   489  	}
   490  	whisperPeer.start()
   491  	defer whisperPeer.stop()
   492  
   493  	return wh.runMessageLoop(whisperPeer, rw)
   494  }
   495  
   496  // runMessageLoop reads and processes inbound messages directly to merge into client-global state.
   497  func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
   498  	for {
   499  		// fetch the next packet
   500  		packet, err := rw.ReadMsg()
   501  		if err != nil {
   502  			log.Warn("message loop", "peer", p.peer.ID(), "err", err)
   503  			return err
   504  		}
   505  		if packet.Size > wh.MaxMessageSize() {
   506  			log.Warn("oversized message received", "peer", p.peer.ID())
   507  			return errors.New("oversized message received")
   508  		}
   509  
   510  		switch packet.Code {
   511  		case statusCode:
   512  			// this should not happen, but no need to panic; just ignore this message.
   513  			log.Warn("unxepected status message received", "peer", p.peer.ID())
   514  		case messagesCode:
   515  			// decode the contained envelopes
   516  			var envelope Envelope
   517  			if err := packet.Decode(&envelope); err != nil {
   518  				log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   519  				return errors.New("invalid envelope")
   520  			}
   521  			cached, err := wh.add(&envelope)
   522  			if err != nil {
   523  				log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   524  				return errors.New("invalid envelope")
   525  			}
   526  			if cached {
   527  				p.mark(&envelope)
   528  			}
   529  		case p2pCode:
   530  			// peer-to-peer message, sent directly to peer bypassing PoW checks, etc.
   531  			// this message is not supposed to be forwarded to other peers, and
   532  			// therefore might not satisfy the PoW, expiry and other requirements.
   533  			// these messages are only accepted from the trusted peer.
   534  			if p.trusted {
   535  				var envelope Envelope
   536  				if err := packet.Decode(&envelope); err != nil {
   537  					log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   538  					return errors.New("invalid direct message")
   539  				}
   540  				wh.postEvent(&envelope, true)
   541  			}
   542  		case p2pRequestCode:
   543  			// Must be processed if mail server is implemented. Otherwise ignore.
   544  			if wh.mailServer != nil {
   545  				var request Envelope
   546  				if err := packet.Decode(&request); err != nil {
   547  					log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
   548  					return errors.New("invalid p2p request")
   549  				}
   550  				wh.mailServer.DeliverMail(p, &request)
   551  			}
   552  		default:
   553  			// New message types might be implemented in the future versions of Whisper.
   554  			// For forward compatibility, just ignore.
   555  		}
   556  
   557  		packet.Discard()
   558  	}
   559  }
   560  
   561  // add inserts a new envelope into the message pool to be distributed within the
   562  // whisper network. It also inserts the envelope into the expiration pool at the
   563  // appropriate time-stamp. In case of error, connection should be dropped.
   564  func (wh *Whisper) add(envelope *Envelope) (bool, error) {
   565  	now := uint32(time.Now().Unix())
   566  	sent := envelope.Expiry - envelope.TTL
   567  
   568  	if sent > now {
   569  		if sent-SynchAllowance > now {
   570  			return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash())
   571  		} else {
   572  			// recalculate PoW, adjusted for the time difference, plus one second for latency
   573  			envelope.calculatePoW(sent - now + 1)
   574  		}
   575  	}
   576  
   577  	if envelope.Expiry < now {
   578  		if envelope.Expiry+SynchAllowance*2 < now {
   579  			return false, fmt.Errorf("very old message")
   580  		} else {
   581  			log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
   582  			return false, nil // drop envelope without error
   583  		}
   584  	}
   585  
   586  	if uint32(envelope.size()) > wh.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() < wh.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  	wh.poolMu.Lock()
   609  	_, alreadyCached := wh.envelopes[hash]
   610  	if !alreadyCached {
   611  		wh.envelopes[hash] = envelope
   612  		if wh.expirations[envelope.Expiry] == nil {
   613  			//wh.expirations[envelope.Expiry] = set.NewNonTS()
   614  		}
   615  		if !wh.expirations[envelope.Expiry].Has(hash) {
   616  			wh.expirations[envelope.Expiry].Add(hash)
   617  		}
   618  	}
   619  	wh.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  		wh.statsMu.Lock()
   626  		wh.stats.memoryUsed += envelope.size()
   627  		wh.statsMu.Unlock()
   628  		wh.postEvent(envelope, false) // notify the local node about the new message
   629  		if wh.mailServer != nil {
   630  			wh.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  	} else {
   842  		return nil, unknownVersionError(version)
   843  	}
   844  }
   845  
   846  // GenerateRandomID generates a random string, which is then returned to be used as a key id
   847  func GenerateRandomID() (id string, err error) {
   848  	buf := make([]byte, keyIdSize)
   849  	_, err = crand.Read(buf)
   850  	if err != nil {
   851  		return "", err
   852  	}
   853  	if !validateSymmetricKey(buf) {
   854  		return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
   855  	}
   856  	id = common.Bytes2Hex(buf)
   857  	return id, err
   858  }