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