github.com/oskarth/go-ethereum@v1.6.8-0.20191013093314-dac24a9d3494/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  	mapset "github.com/deckarep/golang-set"
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/crypto"
    32  	"github.com/ethereum/go-ethereum/log"
    33  	"github.com/ethereum/go-ethereum/p2p"
    34  	"github.com/ethereum/go-ethereum/rpc"
    35  	"github.com/syndtr/goleveldb/leveldb/errors"
    36  	"golang.org/x/crypto/pbkdf2"
    37  	"golang.org/x/sync/syncmap"
    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]mapset.Set     // 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]mapset.Set),
    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 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 (w *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
   473  	// Create the new peer and start tracking it
   474  	whisperPeer := newPeer(w, peer, rw)
   475  
   476  	w.peerMu.Lock()
   477  	w.peers[whisperPeer] = struct{}{}
   478  	w.peerMu.Unlock()
   479  
   480  	defer func() {
   481  		w.peerMu.Lock()
   482  		delete(w.peers, whisperPeer)
   483  		w.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 w.runMessageLoop(whisperPeer, rw)
   494  }
   495  
   496  // runMessageLoop reads and processes inbound messages directly to merge into client-global state.
   497  func (w *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.Info("message loop", "peer", p.peer.ID(), "err", err)
   503  			return err
   504  		}
   505  		if packet.Size > w.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 := w.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  				w.postEvent(&envelope, true)
   541  			}
   542  		case p2pRequestCode:
   543  			// Must be processed if mail server is implemented. Otherwise ignore.
   544  			if w.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  				w.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 (w *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  		}
   572  		// recalculate PoW, adjusted for the time difference, plus one second for latency
   573  		envelope.calculatePoW(sent - now + 1)
   574  	}
   575  
   576  	if envelope.Expiry < now {
   577  		if envelope.Expiry+SynchAllowance*2 < now {
   578  			return false, fmt.Errorf("very old message")
   579  		}
   580  		log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
   581  		return false, nil // drop envelope without error
   582  	}
   583  
   584  	if uint32(envelope.size()) > w.MaxMessageSize() {
   585  		return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
   586  	}
   587  
   588  	if len(envelope.Version) > 4 {
   589  		return false, fmt.Errorf("oversized version [%x]", envelope.Hash())
   590  	}
   591  
   592  	aesNonceSize := len(envelope.AESNonce)
   593  	if aesNonceSize != 0 && aesNonceSize != AESNonceLength {
   594  		// the standard AES GCM nonce size is 12 bytes,
   595  		// but constant gcmStandardNonceSize cannot be accessed (not exported)
   596  		return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash())
   597  	}
   598  
   599  	if envelope.PoW() < w.MinPow() {
   600  		log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
   601  		return false, nil // drop envelope without error
   602  	}
   603  
   604  	hash := envelope.Hash()
   605  
   606  	w.poolMu.Lock()
   607  	_, alreadyCached := w.envelopes[hash]
   608  	if !alreadyCached {
   609  		w.envelopes[hash] = envelope
   610  		if w.expirations[envelope.Expiry] == nil {
   611  			w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet()
   612  		}
   613  		if !w.expirations[envelope.Expiry].Contains(hash) {
   614  			w.expirations[envelope.Expiry].Add(hash)
   615  		}
   616  	}
   617  	w.poolMu.Unlock()
   618  
   619  	if alreadyCached {
   620  		log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
   621  	} else {
   622  		log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex())
   623  		w.statsMu.Lock()
   624  		w.stats.memoryUsed += envelope.size()
   625  		w.statsMu.Unlock()
   626  		w.postEvent(envelope, false) // notify the local node about the new message
   627  		if w.mailServer != nil {
   628  			w.mailServer.Archive(envelope)
   629  		}
   630  	}
   631  	return true, nil
   632  }
   633  
   634  // postEvent queues the message for further processing.
   635  func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
   636  	// if the version of incoming message is higher than
   637  	// currently supported version, we can not decrypt it,
   638  	// and therefore just ignore this message
   639  	if envelope.Ver() <= EnvelopeVersion {
   640  		if isP2P {
   641  			w.p2pMsgQueue <- envelope
   642  		} else {
   643  			w.checkOverflow()
   644  			w.messageQueue <- envelope
   645  		}
   646  	}
   647  }
   648  
   649  // checkOverflow checks if message queue overflow occurs and reports it if necessary.
   650  func (w *Whisper) checkOverflow() {
   651  	queueSize := len(w.messageQueue)
   652  
   653  	if queueSize == messageQueueLimit {
   654  		if !w.Overflow() {
   655  			w.settings.Store(overflowIdx, true)
   656  			log.Warn("message queue overflow")
   657  		}
   658  	} else if queueSize <= messageQueueLimit/2 {
   659  		if w.Overflow() {
   660  			w.settings.Store(overflowIdx, false)
   661  			log.Warn("message queue overflow fixed (back to normal)")
   662  		}
   663  	}
   664  }
   665  
   666  // processQueue delivers the messages to the watchers during the lifetime of the whisper node.
   667  func (w *Whisper) processQueue() {
   668  	var e *Envelope
   669  	for {
   670  		select {
   671  		case <-w.quit:
   672  			return
   673  
   674  		case e = <-w.messageQueue:
   675  			w.filters.NotifyWatchers(e, false)
   676  
   677  		case e = <-w.p2pMsgQueue:
   678  			w.filters.NotifyWatchers(e, true)
   679  		}
   680  	}
   681  }
   682  
   683  // update loops until the lifetime of the whisper node, updating its internal
   684  // state by expiring stale messages from the pool.
   685  func (w *Whisper) update() {
   686  	// Start a ticker to check for expirations
   687  	expire := time.NewTicker(expirationCycle)
   688  
   689  	// Repeat updates until termination is requested
   690  	for {
   691  		select {
   692  		case <-expire.C:
   693  			w.expire()
   694  
   695  		case <-w.quit:
   696  			return
   697  		}
   698  	}
   699  }
   700  
   701  // expire iterates over all the expiration timestamps, removing all stale
   702  // messages from the pools.
   703  func (w *Whisper) expire() {
   704  	w.poolMu.Lock()
   705  	defer w.poolMu.Unlock()
   706  
   707  	w.statsMu.Lock()
   708  	defer w.statsMu.Unlock()
   709  	w.stats.reset()
   710  	now := uint32(time.Now().Unix())
   711  	for expiry, hashSet := range w.expirations {
   712  		if expiry < now {
   713  			// Dump all expired messages and remove timestamp
   714  			hashSet.Each(func(v interface{}) bool {
   715  				sz := w.envelopes[v.(common.Hash)].size()
   716  				delete(w.envelopes, v.(common.Hash))
   717  				w.stats.messagesCleared++
   718  				w.stats.memoryCleared += sz
   719  				w.stats.memoryUsed -= sz
   720  				return false
   721  			})
   722  			w.expirations[expiry].Clear()
   723  			delete(w.expirations, expiry)
   724  		}
   725  	}
   726  }
   727  
   728  // Stats returns the whisper node statistics.
   729  func (w *Whisper) Stats() Statistics {
   730  	w.statsMu.Lock()
   731  	defer w.statsMu.Unlock()
   732  
   733  	return w.stats
   734  }
   735  
   736  // Envelopes retrieves all the messages currently pooled by the node.
   737  func (w *Whisper) Envelopes() []*Envelope {
   738  	w.poolMu.RLock()
   739  	defer w.poolMu.RUnlock()
   740  
   741  	all := make([]*Envelope, 0, len(w.envelopes))
   742  	for _, envelope := range w.envelopes {
   743  		all = append(all, envelope)
   744  	}
   745  	return all
   746  }
   747  
   748  // Messages iterates through all currently floating envelopes
   749  // and retrieves all the messages, that this filter could decrypt.
   750  func (w *Whisper) Messages(id string) []*ReceivedMessage {
   751  	result := make([]*ReceivedMessage, 0)
   752  	w.poolMu.RLock()
   753  	defer w.poolMu.RUnlock()
   754  
   755  	if filter := w.filters.Get(id); filter != nil {
   756  		for _, env := range w.envelopes {
   757  			msg := filter.processEnvelope(env)
   758  			if msg != nil {
   759  				result = append(result, msg)
   760  			}
   761  		}
   762  	}
   763  	return result
   764  }
   765  
   766  // isEnvelopeCached checks if envelope with specific hash has already been received and cached.
   767  func (w *Whisper) isEnvelopeCached(hash common.Hash) bool {
   768  	w.poolMu.Lock()
   769  	defer w.poolMu.Unlock()
   770  
   771  	_, exist := w.envelopes[hash]
   772  	return exist
   773  }
   774  
   775  // reset resets the node's statistics after each expiry cycle.
   776  func (s *Statistics) reset() {
   777  	s.cycles++
   778  	s.totalMessagesCleared += s.messagesCleared
   779  
   780  	s.memoryCleared = 0
   781  	s.messagesCleared = 0
   782  }
   783  
   784  // ValidatePublicKey checks the format of the given public key.
   785  func ValidatePublicKey(k *ecdsa.PublicKey) bool {
   786  	return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0
   787  }
   788  
   789  // validatePrivateKey checks the format of the given private key.
   790  func validatePrivateKey(k *ecdsa.PrivateKey) bool {
   791  	if k == nil || k.D == nil || k.D.Sign() == 0 {
   792  		return false
   793  	}
   794  	return ValidatePublicKey(&k.PublicKey)
   795  }
   796  
   797  // validateSymmetricKey returns false if the key contains all zeros
   798  func validateSymmetricKey(k []byte) bool {
   799  	return len(k) > 0 && !containsOnlyZeros(k)
   800  }
   801  
   802  // containsOnlyZeros checks if the data contain only zeros.
   803  func containsOnlyZeros(data []byte) bool {
   804  	for _, b := range data {
   805  		if b != 0 {
   806  			return false
   807  		}
   808  	}
   809  	return true
   810  }
   811  
   812  // bytesToUintLittleEndian converts the slice to 64-bit unsigned integer.
   813  func bytesToUintLittleEndian(b []byte) (res uint64) {
   814  	mul := uint64(1)
   815  	for i := 0; i < len(b); i++ {
   816  		res += uint64(b[i]) * mul
   817  		mul *= 256
   818  	}
   819  	return res
   820  }
   821  
   822  // BytesToUintBigEndian converts the slice to 64-bit unsigned integer.
   823  func BytesToUintBigEndian(b []byte) (res uint64) {
   824  	for i := 0; i < len(b); i++ {
   825  		res *= 256
   826  		res += uint64(b[i])
   827  	}
   828  	return res
   829  }
   830  
   831  // deriveKeyMaterial derives symmetric key material from the key or password.
   832  // pbkdf2 is used for security, in case people use password instead of randomly generated keys.
   833  func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) {
   834  	if version == 0 {
   835  		// kdf should run no less than 0.1 seconds on average compute,
   836  		// because it's a once in a session experience
   837  		derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New)
   838  		return derivedKey, nil
   839  	}
   840  	return nil, unknownVersionError(version)
   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  }