github.com/status-im/status-go@v1.1.0/waku/waku.go (about)

     1  // Copyright 2019 The Waku Library Authors.
     2  //
     3  // The Waku library is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Lesser General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // (at your option) any later version.
     7  //
     8  // The Waku library is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty off
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    11  // GNU Lesser General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Lesser General Public License
    14  // along with the Waku library. If not, see <http://www.gnu.org/licenses/>.
    15  //
    16  // This software uses the go-ethereum library, which is licensed
    17  // under the GNU Lesser General Public Library, version 3 or any later.
    18  
    19  package waku
    20  
    21  import (
    22  	"bytes"
    23  	"crypto/ecdsa"
    24  	"crypto/sha256"
    25  	"errors"
    26  	"fmt"
    27  	"runtime"
    28  	"sync"
    29  	"time"
    30  
    31  	"github.com/libp2p/go-libp2p/core/peer"
    32  
    33  	"github.com/ethereum/go-ethereum/common/hexutil"
    34  
    35  	"go.uber.org/zap"
    36  
    37  	mapset "github.com/deckarep/golang-set"
    38  	"golang.org/x/crypto/pbkdf2"
    39  
    40  	gethcommon "github.com/ethereum/go-ethereum/common"
    41  	"github.com/ethereum/go-ethereum/crypto"
    42  	"github.com/ethereum/go-ethereum/event"
    43  	"github.com/ethereum/go-ethereum/p2p"
    44  	"github.com/ethereum/go-ethereum/rlp"
    45  	"github.com/ethereum/go-ethereum/rpc"
    46  
    47  	"github.com/status-im/status-go/eth-node/types"
    48  	"github.com/status-im/status-go/logutils"
    49  	"github.com/status-im/status-go/waku/common"
    50  	v0 "github.com/status-im/status-go/waku/v0"
    51  	v1 "github.com/status-im/status-go/waku/v1"
    52  )
    53  
    54  const messageQueueLimit = 1024
    55  
    56  type Bridge interface {
    57  	Pipe() (<-chan *common.Envelope, chan<- *common.Envelope)
    58  }
    59  
    60  type settings struct {
    61  	MaxMsgSize               uint32                    // Maximal message length allowed by the waku node
    62  	EnableConfirmations      bool                      // Enable sending message confirmations
    63  	MinPow                   float64                   // Minimal PoW required by the waku node
    64  	MinPowTolerance          float64                   // Minimal PoW tolerated by the waku node for a limited time
    65  	BloomFilter              []byte                    // Bloom filter for topics of interest for this node
    66  	BloomFilterTolerance     []byte                    // Bloom filter tolerated by the waku node for a limited time
    67  	TopicInterest            map[common.TopicType]bool // Topic interest for this node
    68  	TopicInterestTolerance   map[common.TopicType]bool // Topic interest tolerated by the waku node for a limited time
    69  	SoftBlacklistedPeerIDs   map[string]bool           // SoftBlacklistedPeerIDs is a list of peer ids that we want to keep connected but silently drop any envelope from
    70  	BloomFilterMode          bool                      // Whether we should match against bloom-filter only
    71  	LightClient              bool                      // Light client mode enabled does not forward messages
    72  	RestrictLightClientsConn bool                      // Restrict connection between two light clients
    73  	SyncAllowance            int                       // Maximum time in seconds allowed to process the waku-related messages
    74  	FullNode                 bool                      // Whether this is to be run in FullNode settings
    75  }
    76  
    77  // Waku represents a dark communication interface through the Ethereum
    78  // network, using its very own P2P communication layer.
    79  type Waku struct {
    80  	protocols []p2p.Protocol  // Peer description and parameters
    81  	filters   *common.Filters // Message filters installed with Subscribe function
    82  
    83  	privateKeys map[string]*ecdsa.PrivateKey // Private key storage
    84  	symKeys     map[string][]byte            // Symmetric key storage
    85  	keyMu       sync.RWMutex                 // Mutex associated with key stores
    86  
    87  	envelopes   map[gethcommon.Hash]*common.Envelope // Pool of envelopes currently tracked by this node
    88  	expirations map[uint32]mapset.Set                // Message expiration pool
    89  	poolMu      sync.RWMutex                         // Mutex to sync the message and expiration pools
    90  
    91  	stats  *common.StatsTracker
    92  	peers  map[common.Peer]struct{} // Set of currently active peers
    93  	peerMu sync.RWMutex             // Mutex to sync the active peer set
    94  
    95  	msgQueue    chan *common.Envelope    // Message queue for normal waku messages
    96  	p2pMsgQueue chan interface{}         // Message queue for peer-to-peer messages (not to be forwarded any further) and history delivery confirmations.
    97  	p2pMsgIDs   map[gethcommon.Hash]bool // Map of the currently processing ids
    98  	p2pMsgIDsMu sync.RWMutex
    99  
   100  	quit chan struct{} // Channel used for graceful exit
   101  
   102  	settings   settings     // Holds configuration settings that can be dynamically changed
   103  	settingsMu sync.RWMutex // Mutex to sync the settings access
   104  
   105  	mailServer MailServer
   106  
   107  	rateLimiter *common.PeerRateLimiter
   108  
   109  	envelopeFeed event.Feed
   110  
   111  	timeSource func() time.Time // source of time for waku
   112  
   113  	bridge       Bridge
   114  	bridgeWg     sync.WaitGroup
   115  	cancelBridge chan struct{}
   116  
   117  	logger *zap.Logger
   118  }
   119  
   120  // New creates a Waku client ready to communicate through the Ethereum P2P network.
   121  func New(cfg *Config, logger *zap.Logger) *Waku {
   122  	if logger == nil {
   123  		logger = logutils.ZapLogger()
   124  	}
   125  
   126  	logger.Debug("starting waku with config", zap.Any("config", cfg))
   127  	if cfg == nil {
   128  		c := DefaultConfig
   129  		cfg = &c
   130  	}
   131  
   132  	waku := &Waku{
   133  		privateKeys: make(map[string]*ecdsa.PrivateKey),
   134  		symKeys:     make(map[string][]byte),
   135  		envelopes:   make(map[gethcommon.Hash]*common.Envelope),
   136  		expirations: make(map[uint32]mapset.Set),
   137  		peers:       make(map[common.Peer]struct{}),
   138  		msgQueue:    make(chan *common.Envelope, messageQueueLimit),
   139  		p2pMsgQueue: make(chan interface{}, messageQueueLimit),
   140  		p2pMsgIDs:   make(map[gethcommon.Hash]bool),
   141  		quit:        make(chan struct{}),
   142  		timeSource:  time.Now,
   143  		logger:      logger,
   144  	}
   145  
   146  	waku.settings = settings{
   147  		MaxMsgSize:               cfg.MaxMessageSize,
   148  		MinPow:                   cfg.MinimumAcceptedPoW,
   149  		MinPowTolerance:          cfg.MinimumAcceptedPoW,
   150  		EnableConfirmations:      cfg.EnableConfirmations,
   151  		LightClient:              cfg.LightClient,
   152  		FullNode:                 cfg.FullNode,
   153  		BloomFilterMode:          cfg.BloomFilterMode,
   154  		SoftBlacklistedPeerIDs:   make(map[string]bool),
   155  		RestrictLightClientsConn: cfg.RestrictLightClientsConn,
   156  		SyncAllowance:            common.DefaultSyncAllowance,
   157  	}
   158  
   159  	for _, peerID := range cfg.SoftBlacklistedPeerIDs {
   160  		waku.settings.SoftBlacklistedPeerIDs[peerID] = true
   161  	}
   162  
   163  	if cfg.FullNode {
   164  		waku.settings.BloomFilter = common.MakeFullNodeBloom()
   165  		waku.settings.BloomFilterTolerance = common.MakeFullNodeBloom()
   166  	}
   167  
   168  	waku.filters = common.NewFilters()
   169  	waku.stats = &common.StatsTracker{}
   170  
   171  	// p2p waku sub-protocol handler
   172  	waku.protocols = []p2p.Protocol{{
   173  		Name:    v0.Name,
   174  		Version: uint(v0.Version),
   175  		Length:  v0.NumberOfMessageCodes,
   176  		Run:     waku.handlePeerV0,
   177  		NodeInfo: func() interface{} {
   178  			return map[string]interface{}{
   179  				"version":        v0.VersionStr,
   180  				"maxMessageSize": waku.MaxMessageSize(),
   181  				"minimumPoW":     waku.MinPow(),
   182  			}
   183  		},
   184  	},
   185  		{
   186  			Name:    v1.Name,
   187  			Version: uint(v1.Version),
   188  			Length:  v1.NumberOfMessageCodes,
   189  			Run:     waku.handlePeerV1,
   190  			NodeInfo: func() interface{} {
   191  				return map[string]interface{}{
   192  					"version":        v1.VersionStr,
   193  					"maxMessageSize": waku.MaxMessageSize(),
   194  					"minimumPoW":     waku.MinPow(),
   195  				}
   196  			},
   197  		},
   198  	}
   199  
   200  	return waku
   201  }
   202  
   203  func (w *Waku) GetStats() types.StatsSummary {
   204  	return w.stats.GetStats()
   205  }
   206  
   207  // MinPow returns the PoW value required by this node.
   208  func (w *Waku) MinPow() float64 {
   209  	w.settingsMu.RLock()
   210  	defer w.settingsMu.RUnlock()
   211  	return w.settings.MinPow
   212  }
   213  
   214  // SetMinimumPoW sets the minimal PoW required by this node
   215  func (w *Waku) SetMinimumPoW(val float64, tolerate bool) error {
   216  	if val < 0.0 {
   217  		return fmt.Errorf("invalid PoW: %f", val)
   218  	}
   219  
   220  	w.settingsMu.Lock()
   221  	w.settings.MinPow = val
   222  	w.settingsMu.Unlock()
   223  
   224  	w.notifyPeersAboutPowRequirementChange(val)
   225  
   226  	if tolerate {
   227  		go func() {
   228  			// allow some time before all the peers have processed the notification
   229  			select {
   230  			case <-w.quit:
   231  				return
   232  			case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second):
   233  				w.settingsMu.Lock()
   234  				w.settings.MinPowTolerance = val
   235  				w.settingsMu.Unlock()
   236  			}
   237  		}()
   238  	}
   239  
   240  	return nil
   241  }
   242  
   243  // MinPowTolerance returns the value of minimum PoW which is tolerated for a limited
   244  // time after PoW was changed. If sufficient time have elapsed or no change of PoW
   245  // have ever occurred, the return value will be the same as return value of MinPow().
   246  func (w *Waku) MinPowTolerance() float64 {
   247  	w.settingsMu.RLock()
   248  	defer w.settingsMu.RUnlock()
   249  	return w.settings.MinPowTolerance
   250  }
   251  
   252  // BloomFilter returns the aggregated bloom filter for all the topics of interest.
   253  // The nodes are required to send only messages that match the advertised bloom filter.
   254  // If a message does not match the bloom, it will tantamount to spam, and the peer will
   255  // be disconnected.
   256  func (w *Waku) BloomFilter() []byte {
   257  	if w.FullNode() {
   258  		return common.MakeFullNodeBloom()
   259  	}
   260  
   261  	w.settingsMu.RLock()
   262  	defer w.settingsMu.RUnlock()
   263  	return w.settings.BloomFilter
   264  }
   265  
   266  // BloomFilterTolerance returns the bloom filter which is tolerated for a limited
   267  // time after new bloom was advertised to the peers. If sufficient time have elapsed
   268  // or no change of bloom filter have ever occurred, the return value will be the same
   269  // as return value of BloomFilter().
   270  func (w *Waku) BloomFilterTolerance() []byte {
   271  	if w.FullNode() {
   272  		return common.MakeFullNodeBloom()
   273  	}
   274  
   275  	w.settingsMu.RLock()
   276  	defer w.settingsMu.RUnlock()
   277  	return w.settings.BloomFilterTolerance
   278  }
   279  
   280  // BloomFilterMode returns whether the node is running in bloom filter mode
   281  func (w *Waku) BloomFilterMode() bool {
   282  	if w.FullNode() {
   283  		return true
   284  	}
   285  
   286  	w.settingsMu.RLock()
   287  	defer w.settingsMu.RUnlock()
   288  	return w.settings.BloomFilterMode
   289  }
   290  
   291  // SetBloomFilter sets the new bloom filter
   292  func (w *Waku) SetBloomFilter(bloom []byte) error {
   293  	if len(bloom) != common.BloomFilterSize {
   294  		return fmt.Errorf("invalid bloom filter size: %d", len(bloom))
   295  	}
   296  
   297  	b := make([]byte, common.BloomFilterSize)
   298  	copy(b, bloom)
   299  
   300  	w.settingsMu.Lock()
   301  	w.settings.BloomFilter = b
   302  	// Setting bloom filter reset topic interest
   303  	w.settings.TopicInterest = nil
   304  	w.settingsMu.Unlock()
   305  	w.notifyPeersAboutBloomFilterChange(b)
   306  
   307  	go func() {
   308  		// allow some time before all the peers have processed the notification
   309  		select {
   310  		case <-w.quit:
   311  			return
   312  		case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second):
   313  			w.settingsMu.Lock()
   314  			w.settings.BloomFilterTolerance = b
   315  			w.settingsMu.Unlock()
   316  		}
   317  
   318  	}()
   319  
   320  	return nil
   321  }
   322  
   323  // TopicInterest returns the all the topics of interest.
   324  // The nodes are required to send only messages that match the advertised topics.
   325  // If a message does not match the topic-interest, it will tantamount to spam, and the peer will
   326  // be disconnected.
   327  func (w *Waku) TopicInterest() []common.TopicType {
   328  	w.settingsMu.RLock()
   329  	defer w.settingsMu.RUnlock()
   330  	// Return nil if FullNode as otherwise topic interest will have precedence
   331  	if w.settings.FullNode || w.settings.TopicInterest == nil {
   332  		return nil
   333  	}
   334  	topicInterest := make([]common.TopicType, len(w.settings.TopicInterest))
   335  
   336  	i := 0
   337  	for topic := range w.settings.TopicInterest {
   338  		topicInterest[i] = topic
   339  		i++
   340  	}
   341  	return topicInterest
   342  }
   343  
   344  // updateTopicInterest adds a new topic interest
   345  // and informs the peers
   346  func (w *Waku) updateTopicInterest(f *common.Filter) error {
   347  	newTopicInterest := w.TopicInterest()
   348  	for _, t := range f.Topics {
   349  		top := common.BytesToTopic(t)
   350  		newTopicInterest = append(newTopicInterest, top)
   351  	}
   352  
   353  	return w.SetTopicInterest(newTopicInterest)
   354  }
   355  
   356  // SetTopicInterest sets the new topicInterest
   357  func (w *Waku) SetTopicInterest(topicInterest []common.TopicType) error {
   358  	var topicInterestMap map[common.TopicType]bool
   359  	if len(topicInterest) > common.MaxTopicInterest {
   360  		return fmt.Errorf("invalid topic interest: %d", len(topicInterest))
   361  	}
   362  
   363  	if topicInterest != nil {
   364  		topicInterestMap = make(map[common.TopicType]bool, len(topicInterest))
   365  		for _, topic := range topicInterest {
   366  			topicInterestMap[topic] = true
   367  		}
   368  	}
   369  
   370  	w.settingsMu.Lock()
   371  	w.settings.TopicInterest = topicInterestMap
   372  	// Setting topic interest resets bloom filter
   373  	w.settings.BloomFilter = nil
   374  	w.settingsMu.Unlock()
   375  	w.notifyPeersAboutTopicInterestChange(topicInterest)
   376  
   377  	go func() {
   378  		// allow some time before all the peers have processed the notification
   379  		select {
   380  		case <-w.quit:
   381  			return
   382  		case <-time.After(time.Duration(w.settings.SyncAllowance) * time.Second):
   383  			w.settingsMu.Lock()
   384  			w.settings.TopicInterestTolerance = topicInterestMap
   385  			w.settingsMu.Unlock()
   386  		}
   387  	}()
   388  
   389  	return nil
   390  }
   391  
   392  // MaxMessageSize returns the maximum accepted message size.
   393  func (w *Waku) MaxMessageSize() uint32 {
   394  	w.settingsMu.RLock()
   395  	defer w.settingsMu.RUnlock()
   396  	return w.settings.MaxMsgSize
   397  }
   398  
   399  // SetMaxMessageSize sets the maximal message size allowed by this node
   400  func (w *Waku) SetMaxMessageSize(size uint32) error {
   401  	if size > common.MaxMessageSize {
   402  		return fmt.Errorf("message size too large [%d>%d]", size, common.MaxMessageSize)
   403  	}
   404  	w.settingsMu.Lock()
   405  	w.settings.MaxMsgSize = size
   406  	w.settingsMu.Unlock()
   407  	return nil
   408  }
   409  
   410  // LightClientMode indicates is this node is light client (does not forward any messages)
   411  func (w *Waku) LightClientMode() bool {
   412  	w.settingsMu.RLock()
   413  	defer w.settingsMu.RUnlock()
   414  	return w.settings.LightClient
   415  }
   416  
   417  // SetLightClientMode makes node light client (does not forward any messages)
   418  func (w *Waku) SetLightClientMode(v bool) {
   419  	w.settingsMu.Lock()
   420  	w.settings.LightClient = v
   421  	w.settingsMu.Unlock()
   422  }
   423  
   424  // LightClientModeConnectionRestricted indicates that connection to light client in light client mode not allowed
   425  func (w *Waku) LightClientModeConnectionRestricted() bool {
   426  	w.settingsMu.RLock()
   427  	defer w.settingsMu.RUnlock()
   428  	return w.settings.RestrictLightClientsConn
   429  }
   430  
   431  // PacketRateLimiting returns RateLimits information for packets
   432  func (w *Waku) PacketRateLimits() common.RateLimits {
   433  	if w.rateLimiter == nil {
   434  		return common.RateLimits{}
   435  	}
   436  	return common.RateLimits{
   437  		IPLimits:     uint64(w.rateLimiter.PacketLimitPerSecIP),
   438  		PeerIDLimits: uint64(w.rateLimiter.PacketLimitPerSecPeerID),
   439  	}
   440  }
   441  
   442  // BytesRateLimiting returns RateLimits information for bytes
   443  func (w *Waku) BytesRateLimits() common.RateLimits {
   444  	if w.rateLimiter == nil {
   445  		return common.RateLimits{}
   446  	}
   447  	return common.RateLimits{
   448  		IPLimits:     uint64(w.rateLimiter.BytesLimitPerSecIP),
   449  		PeerIDLimits: uint64(w.rateLimiter.BytesLimitPerSecPeerID),
   450  	}
   451  }
   452  
   453  // ConfirmationsEnabled returns true if message confirmations are enabled.
   454  func (w *Waku) ConfirmationsEnabled() bool {
   455  	w.settingsMu.RLock()
   456  	defer w.settingsMu.RUnlock()
   457  	return w.settings.EnableConfirmations
   458  }
   459  
   460  // CurrentTime returns current time.
   461  func (w *Waku) CurrentTime() time.Time {
   462  	return w.timeSource()
   463  }
   464  
   465  // SetTimeSource assigns a particular source of time to a waku object.
   466  func (w *Waku) SetTimeSource(timesource func() time.Time) {
   467  	w.timeSource = timesource
   468  }
   469  
   470  // APIs returns the RPC descriptors the Waku implementation offers
   471  func (w *Waku) APIs() []rpc.API {
   472  	return []rpc.API{
   473  		{
   474  			Namespace: v0.Name,
   475  			Version:   v0.VersionStr,
   476  			Service:   NewPublicWakuAPI(w),
   477  			Public:    false,
   478  		},
   479  	}
   480  }
   481  
   482  // Protocols returns the waku sub-protocols ran by this particular client.
   483  func (w *Waku) Protocols() []p2p.Protocol {
   484  	return w.protocols
   485  }
   486  
   487  // RegisterMailServer registers MailServer interface.
   488  // MailServer will process all the incoming messages with p2pRequestCode.
   489  func (w *Waku) RegisterMailServer(server MailServer) {
   490  	w.mailServer = server
   491  }
   492  
   493  // SetRateLimiter registers a rate limiter.
   494  func (w *Waku) RegisterRateLimiter(r *common.PeerRateLimiter) {
   495  	w.rateLimiter = r
   496  }
   497  
   498  // RegisterBridge registers a new Bridge that moves envelopes
   499  // between different subprotocols.
   500  // It's important that a bridge is registered before the service
   501  // is started, otherwise, it won't read and propagate envelopes.
   502  func (w *Waku) RegisterBridge(b Bridge) {
   503  	if w.cancelBridge != nil {
   504  		close(w.cancelBridge)
   505  	}
   506  	w.bridge = b
   507  	w.cancelBridge = make(chan struct{})
   508  	w.bridgeWg.Add(1)
   509  	go w.readBridgeLoop()
   510  }
   511  
   512  func (w *Waku) readBridgeLoop() {
   513  	defer w.bridgeWg.Done()
   514  	out, _ := w.bridge.Pipe()
   515  	for {
   516  		select {
   517  		case <-w.cancelBridge:
   518  			return
   519  		case env := <-out:
   520  			_, err := w.addAndBridge(env, false, true)
   521  			if err != nil {
   522  				common.BridgeReceivedFailed.Inc()
   523  				w.logger.Warn(
   524  					"failed to add a bridged envelope",
   525  					zap.Binary("ID", env.Hash().Bytes()),
   526  					zap.Error(err),
   527  				)
   528  			} else {
   529  				common.BridgeReceivedSucceed.Inc()
   530  				w.logger.Debug("bridged envelope successfully", zap.Binary("ID", env.Hash().Bytes()))
   531  				w.envelopeFeed.Send(common.EnvelopeEvent{
   532  					Event: common.EventEnvelopeReceived,
   533  					Topic: env.Topic,
   534  					Hash:  env.Hash(),
   535  				})
   536  			}
   537  		}
   538  	}
   539  }
   540  
   541  func (w *Waku) SendEnvelopeEvent(event common.EnvelopeEvent) int {
   542  	return w.envelopeFeed.Send(event)
   543  }
   544  
   545  // SubscribeEnvelopeEvents subscribes to envelopes feed.
   546  // In order to prevent blocking waku producers events must be amply buffered.
   547  func (w *Waku) SubscribeEnvelopeEvents(events chan<- common.EnvelopeEvent) event.Subscription {
   548  	return w.envelopeFeed.Subscribe(events)
   549  }
   550  
   551  func (w *Waku) notifyPeersAboutPowRequirementChange(pow float64) {
   552  	arr := w.getPeers()
   553  	for _, p := range arr {
   554  		err := p.NotifyAboutPowRequirementChange(pow)
   555  		if err != nil {
   556  			// allow one retry
   557  			err = p.NotifyAboutPowRequirementChange(pow)
   558  		}
   559  		if err != nil {
   560  			w.logger.Warn("failed to notify peer about new pow requirement", zap.Binary("peer", p.ID()), zap.Error(err))
   561  		}
   562  	}
   563  }
   564  
   565  func (w *Waku) FullNode() bool {
   566  	w.settingsMu.RLock()
   567  	// If full node, nothing to do
   568  	fullNode := w.settings.FullNode
   569  	w.settingsMu.RUnlock()
   570  	return fullNode
   571  }
   572  
   573  func (w *Waku) notifyPeersAboutBloomFilterChange(bloom []byte) {
   574  
   575  	if w.FullNode() {
   576  		return
   577  	}
   578  	arr := w.getPeers()
   579  	for _, p := range arr {
   580  		err := p.NotifyAboutBloomFilterChange(bloom)
   581  		if err != nil {
   582  			// allow one retry
   583  			err = p.NotifyAboutBloomFilterChange(bloom)
   584  		}
   585  		if err != nil {
   586  			w.logger.Warn("failed to notify peer about new bloom filter change", zap.Binary("peer", p.ID()), zap.Error(err))
   587  		}
   588  	}
   589  }
   590  
   591  func (w *Waku) notifyPeersAboutTopicInterestChange(topicInterest []common.TopicType) {
   592  	if w.FullNode() {
   593  		return
   594  	}
   595  	arr := w.getPeers()
   596  	for _, p := range arr {
   597  		err := p.NotifyAboutTopicInterestChange(topicInterest)
   598  		if err != nil {
   599  			// allow one retry
   600  			err = p.NotifyAboutTopicInterestChange(topicInterest)
   601  		}
   602  		if err != nil {
   603  			w.logger.Warn("failed to notify peer about new topic interest", zap.Binary("peer", p.ID()), zap.Error(err))
   604  		}
   605  	}
   606  }
   607  
   608  func (w *Waku) getPeers() []common.Peer {
   609  	w.peerMu.Lock()
   610  	arr := make([]common.Peer, len(w.peers))
   611  	i := 0
   612  	for p := range w.peers {
   613  		arr[i] = p
   614  		i++
   615  	}
   616  	w.peerMu.Unlock()
   617  	return arr
   618  }
   619  
   620  // getPeer retrieves peer by ID
   621  func (w *Waku) getPeer(peerID []byte) (common.Peer, error) {
   622  	w.peerMu.Lock()
   623  	defer w.peerMu.Unlock()
   624  	for p := range w.peers {
   625  		if bytes.Equal(peerID, p.ID()) {
   626  			return p, nil
   627  		}
   628  	}
   629  	return nil, fmt.Errorf("could not find peer with ID: %x", peerID)
   630  }
   631  
   632  // AllowP2PMessagesFromPeer marks specific peer trusted,
   633  // which will allow it to send historic (expired) messages.
   634  func (w *Waku) AllowP2PMessagesFromPeer(peerID []byte) error {
   635  	p, err := w.getPeer(peerID)
   636  	if err != nil {
   637  		return err
   638  	}
   639  	p.SetPeerTrusted(true)
   640  	return nil
   641  }
   642  
   643  func (w *Waku) SendHistoricMessageResponse(peerID []byte, payload []byte) error {
   644  	peer, err := w.getPeer(peerID)
   645  	if err != nil {
   646  		return err
   647  	}
   648  	return peer.SendHistoricMessageResponse(payload)
   649  }
   650  
   651  // SendP2PMessage sends a peer-to-peer message to a specific peer.
   652  // It sends one or more envelopes in a single batch.
   653  func (w *Waku) SendP2PMessages(peerID []byte, envelopes ...*common.Envelope) error {
   654  	p, err := w.getPeer(peerID)
   655  	if err != nil {
   656  		return err
   657  	}
   658  	return p.SendP2PMessages(envelopes)
   659  }
   660  
   661  // SendRawP2PDirect sends a peer-to-peer message to a specific peer.
   662  // It sends one or more envelopes in a single batch.
   663  func (w *Waku) SendRawP2PDirect(peerID []byte, envelopes ...rlp.RawValue) error {
   664  	p, err := w.getPeer(peerID)
   665  	if err != nil {
   666  		return err
   667  	}
   668  	return p.SendRawP2PDirect(envelopes)
   669  }
   670  
   671  // NewKeyPair generates a new cryptographic identity for the client, and injects
   672  // it into the known identities for message decryption. Returns ID of the new key pair.
   673  func (w *Waku) NewKeyPair() (string, error) {
   674  	key, err := crypto.GenerateKey()
   675  	if err != nil || !validatePrivateKey(key) {
   676  		key, err = crypto.GenerateKey() // retry once
   677  	}
   678  	if err != nil {
   679  		return "", err
   680  	}
   681  	if !validatePrivateKey(key) {
   682  		return "", fmt.Errorf("failed to generate valid key")
   683  	}
   684  
   685  	id, err := toDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), common.KeyIDSize)
   686  	if err != nil {
   687  		return "", err
   688  	}
   689  
   690  	w.keyMu.Lock()
   691  	defer w.keyMu.Unlock()
   692  
   693  	if w.privateKeys[id] != nil {
   694  		return "", fmt.Errorf("failed to generate unique ID")
   695  	}
   696  	w.privateKeys[id] = key
   697  	return id, nil
   698  }
   699  
   700  // DeleteKeyPair deletes the specified key if it exists.
   701  func (w *Waku) DeleteKeyPair(key string) bool {
   702  	deterministicID, err := toDeterministicID(key, common.KeyIDSize)
   703  	if err != nil {
   704  		return false
   705  	}
   706  
   707  	w.keyMu.Lock()
   708  	defer w.keyMu.Unlock()
   709  
   710  	if w.privateKeys[deterministicID] != nil {
   711  		delete(w.privateKeys, deterministicID)
   712  		return true
   713  	}
   714  	return false
   715  }
   716  
   717  // AddKeyPair imports a asymmetric private key and returns it identifier.
   718  func (w *Waku) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
   719  	id, err := makeDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), common.KeyIDSize)
   720  	if err != nil {
   721  		return "", err
   722  	}
   723  	if w.HasKeyPair(id) {
   724  		return id, nil // no need to re-inject
   725  	}
   726  
   727  	w.keyMu.Lock()
   728  	w.privateKeys[id] = key
   729  	w.keyMu.Unlock()
   730  
   731  	return id, nil
   732  }
   733  
   734  // SelectKeyPair adds cryptographic identity, and makes sure
   735  // that it is the only private key known to the node.
   736  func (w *Waku) SelectKeyPair(key *ecdsa.PrivateKey) error {
   737  	id, err := makeDeterministicID(hexutil.Encode(crypto.FromECDSAPub(&key.PublicKey)), common.KeyIDSize)
   738  	if err != nil {
   739  		return err
   740  	}
   741  
   742  	w.keyMu.Lock()
   743  	defer w.keyMu.Unlock()
   744  
   745  	w.privateKeys = make(map[string]*ecdsa.PrivateKey) // reset key store
   746  	w.privateKeys[id] = key
   747  
   748  	return nil
   749  }
   750  
   751  // DeleteKeyPairs removes all cryptographic identities known to the node
   752  func (w *Waku) DeleteKeyPairs() error {
   753  	w.keyMu.Lock()
   754  	defer w.keyMu.Unlock()
   755  
   756  	w.privateKeys = make(map[string]*ecdsa.PrivateKey)
   757  
   758  	return nil
   759  }
   760  
   761  // HasKeyPair checks if the waku node is configured with the private key
   762  // of the specified public pair.
   763  func (w *Waku) HasKeyPair(id string) bool {
   764  	deterministicID, err := toDeterministicID(id, common.KeyIDSize)
   765  	if err != nil {
   766  		return false
   767  	}
   768  
   769  	w.keyMu.RLock()
   770  	defer w.keyMu.RUnlock()
   771  	return w.privateKeys[deterministicID] != nil
   772  }
   773  
   774  // GetPrivateKey retrieves the private key of the specified identity.
   775  func (w *Waku) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
   776  	deterministicID, err := toDeterministicID(id, common.KeyIDSize)
   777  	if err != nil {
   778  		return nil, err
   779  	}
   780  
   781  	w.keyMu.RLock()
   782  	defer w.keyMu.RUnlock()
   783  	key := w.privateKeys[deterministicID]
   784  	if key == nil {
   785  		return nil, fmt.Errorf("invalid id")
   786  	}
   787  	return key, nil
   788  }
   789  
   790  // GenerateSymKey generates a random symmetric key and stores it under id,
   791  // which is then returned. Will be used in the future for session key exchange.
   792  func (w *Waku) GenerateSymKey() (string, error) {
   793  	key, err := common.GenerateSecureRandomData(common.AESKeyLength)
   794  	if err != nil {
   795  		return "", err
   796  	} else if !common.ValidateDataIntegrity(key, common.AESKeyLength) {
   797  		return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
   798  	}
   799  
   800  	id, err := common.GenerateRandomID()
   801  	if err != nil {
   802  		return "", fmt.Errorf("failed to generate ID: %s", err)
   803  	}
   804  
   805  	w.keyMu.Lock()
   806  	defer w.keyMu.Unlock()
   807  
   808  	if w.symKeys[id] != nil {
   809  		return "", fmt.Errorf("failed to generate unique ID")
   810  	}
   811  	w.symKeys[id] = key
   812  	return id, nil
   813  }
   814  
   815  // AddSymKey stores the key with a given id.
   816  func (w *Waku) AddSymKey(id string, key []byte) (string, error) {
   817  	deterministicID, err := toDeterministicID(id, common.KeyIDSize)
   818  	if err != nil {
   819  		return "", err
   820  	}
   821  
   822  	w.keyMu.Lock()
   823  	defer w.keyMu.Unlock()
   824  
   825  	if w.symKeys[deterministicID] != nil {
   826  		return "", fmt.Errorf("key already exists: %v", id)
   827  	}
   828  	w.symKeys[deterministicID] = key
   829  	return deterministicID, nil
   830  }
   831  
   832  // AddSymKeyDirect stores the key, and returns its id.
   833  func (w *Waku) AddSymKeyDirect(key []byte) (string, error) {
   834  	if len(key) != common.AESKeyLength {
   835  		return "", fmt.Errorf("wrong key size: %d", len(key))
   836  	}
   837  
   838  	id, err := common.GenerateRandomID()
   839  	if err != nil {
   840  		return "", fmt.Errorf("failed to generate ID: %s", err)
   841  	}
   842  
   843  	w.keyMu.Lock()
   844  	defer w.keyMu.Unlock()
   845  
   846  	if w.symKeys[id] != nil {
   847  		return "", fmt.Errorf("failed to generate unique ID")
   848  	}
   849  	w.symKeys[id] = key
   850  	return id, nil
   851  }
   852  
   853  // AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
   854  func (w *Waku) AddSymKeyFromPassword(password string) (string, error) {
   855  	id, err := common.GenerateRandomID()
   856  	if err != nil {
   857  		return "", fmt.Errorf("failed to generate ID: %s", err)
   858  	}
   859  	if w.HasSymKey(id) {
   860  		return "", fmt.Errorf("failed to generate unique ID")
   861  	}
   862  
   863  	// kdf should run no less than 0.1 seconds on an average computer,
   864  	// because it's an once in a session experience
   865  	derived := pbkdf2.Key([]byte(password), nil, 65356, common.AESKeyLength, sha256.New)
   866  
   867  	w.keyMu.Lock()
   868  	defer w.keyMu.Unlock()
   869  
   870  	// double check is necessary, because deriveKeyMaterial() is very slow
   871  	if w.symKeys[id] != nil {
   872  		return "", fmt.Errorf("critical error: failed to generate unique ID")
   873  	}
   874  	w.symKeys[id] = derived
   875  	return id, nil
   876  }
   877  
   878  // HasSymKey returns true if there is a key associated with the given id.
   879  // Otherwise returns false.
   880  func (w *Waku) HasSymKey(id string) bool {
   881  	w.keyMu.RLock()
   882  	defer w.keyMu.RUnlock()
   883  	return w.symKeys[id] != nil
   884  }
   885  
   886  // DeleteSymKey deletes the key associated with the name string if it exists.
   887  func (w *Waku) DeleteSymKey(id string) bool {
   888  	w.keyMu.Lock()
   889  	defer w.keyMu.Unlock()
   890  	if w.symKeys[id] != nil {
   891  		delete(w.symKeys, id)
   892  		return true
   893  	}
   894  	return false
   895  }
   896  
   897  // GetSymKey returns the symmetric key associated with the given id.
   898  func (w *Waku) GetSymKey(id string) ([]byte, error) {
   899  	w.keyMu.RLock()
   900  	defer w.keyMu.RUnlock()
   901  	if w.symKeys[id] != nil {
   902  		return w.symKeys[id], nil
   903  	}
   904  	return nil, fmt.Errorf("non-existent key ID")
   905  }
   906  
   907  // Subscribe installs a new message handler used for filtering, decrypting
   908  // and subsequent storing of incoming messages.
   909  func (w *Waku) Subscribe(f *common.Filter) (string, error) {
   910  	s, err := w.filters.Install(f)
   911  	if err != nil {
   912  		return s, err
   913  	}
   914  
   915  	err = w.updateSettingsForFilter(f)
   916  	if err != nil {
   917  		w.filters.Uninstall(s)
   918  		return s, err
   919  	}
   920  	return s, nil
   921  }
   922  
   923  func (w *Waku) updateSettingsForFilter(f *common.Filter) error {
   924  	w.settingsMu.RLock()
   925  	topicInterestMode := !w.settings.BloomFilterMode
   926  	w.settingsMu.RUnlock()
   927  
   928  	if topicInterestMode {
   929  		err := w.updateTopicInterest(f)
   930  		if err != nil {
   931  			return err
   932  		}
   933  	} else {
   934  		err := w.updateBloomFilter(f)
   935  		if err != nil {
   936  			return err
   937  		}
   938  	}
   939  	return nil
   940  }
   941  
   942  // updateBloomFilter recalculates the new value of bloom filter,
   943  // and informs the peers if necessary.
   944  func (w *Waku) updateBloomFilter(f *common.Filter) error {
   945  	aggregate := make([]byte, common.BloomFilterSize)
   946  	for _, t := range f.Topics {
   947  		top := common.BytesToTopic(t)
   948  		b := top.ToBloom()
   949  		aggregate = addBloom(aggregate, b)
   950  	}
   951  
   952  	if !common.BloomFilterMatch(w.BloomFilter(), aggregate) {
   953  		// existing bloom filter must be updated
   954  		aggregate = addBloom(w.BloomFilter(), aggregate)
   955  		return w.SetBloomFilter(aggregate)
   956  	}
   957  	return nil
   958  }
   959  
   960  // GetFilter returns the filter by id.
   961  func (w *Waku) GetFilter(id string) *common.Filter {
   962  	return w.filters.Get(id)
   963  }
   964  
   965  // Unsubscribe removes an installed message handler.
   966  // TODO: This does not update the bloom filter, but does update
   967  // the topic interest map
   968  func (w *Waku) Unsubscribe(id string) error {
   969  	ok := w.filters.Uninstall(id)
   970  	if !ok {
   971  		return fmt.Errorf("failed to unsubscribe: invalid ID '%s'", id)
   972  	}
   973  	if !w.settings.BloomFilterMode {
   974  		return w.SetTopicInterest(w.filters.AllTopics())
   975  	}
   976  	return nil
   977  }
   978  
   979  // Unsubscribe removes an installed message handler.
   980  // TODO: This does not update the bloom filter, but does update
   981  // the topic interest map
   982  func (w *Waku) UnsubscribeMany(ids []string) error {
   983  	for _, id := range ids {
   984  		w.logger.Debug("cleaning up filter", zap.String("id", id))
   985  		ok := w.filters.Uninstall(id)
   986  		if !ok {
   987  			w.logger.Warn("could not remove filter with id", zap.String("id", id))
   988  		}
   989  	}
   990  	if !w.settings.BloomFilterMode {
   991  		return w.SetTopicInterest(w.filters.AllTopics())
   992  	}
   993  	return nil
   994  }
   995  
   996  // Send injects a message into the waku send queue, to be distributed in the
   997  // network in the coming cycles.
   998  func (w *Waku) Send(envelope *common.Envelope) error {
   999  	w.logger.Debug("send: sending envelope", zap.String("hash", envelope.Hash().String()))
  1000  	ok, err := w.add(envelope, false)
  1001  	if err == nil && !ok {
  1002  		return fmt.Errorf("failed to add envelope")
  1003  	}
  1004  	return err
  1005  }
  1006  
  1007  // Start implements node.Service, starting the background data propagation thread
  1008  // of the Waku protocol.
  1009  func (w *Waku) Start() error {
  1010  	go w.update()
  1011  
  1012  	numCPU := runtime.NumCPU()
  1013  	for i := 0; i < numCPU; i++ {
  1014  		go w.processQueue()
  1015  	}
  1016  	go w.processP2P()
  1017  
  1018  	return nil
  1019  }
  1020  
  1021  // Stop implements node.Service, stopping the background data propagation thread
  1022  // of the Waku protocol.
  1023  func (w *Waku) Stop() error {
  1024  	if w.cancelBridge != nil {
  1025  		close(w.cancelBridge)
  1026  		w.cancelBridge = nil
  1027  		w.bridgeWg.Wait()
  1028  	}
  1029  	close(w.quit)
  1030  	return nil
  1031  }
  1032  
  1033  func (w *Waku) handlePeerV0(p2pPeer *p2p.Peer, rw p2p.MsgReadWriter) error {
  1034  	return w.HandlePeer(v0.NewPeer(w, p2pPeer, rw, w.logger.Named("waku/peerv0"), w.stats), rw)
  1035  }
  1036  
  1037  func (w *Waku) handlePeerV1(p2pPeer *p2p.Peer, rw p2p.MsgReadWriter) error {
  1038  	return w.HandlePeer(v1.NewPeer(w, p2pPeer, rw, w.logger.Named("waku/peerv1"), w.stats), rw)
  1039  }
  1040  
  1041  // HandlePeer is called by the underlying P2P layer when the waku sub-protocol
  1042  // connection is negotiated.
  1043  func (w *Waku) HandlePeer(peer common.Peer, rw p2p.MsgReadWriter) error {
  1044  	w.peerMu.Lock()
  1045  	w.peers[peer] = struct{}{}
  1046  	w.peerMu.Unlock()
  1047  
  1048  	w.logger.Info("handling peer", zap.String("peerID", types.EncodeHex(peer.ID())))
  1049  
  1050  	defer func() {
  1051  		w.peerMu.Lock()
  1052  		delete(w.peers, peer)
  1053  		w.peerMu.Unlock()
  1054  	}()
  1055  
  1056  	if err := peer.Start(); err != nil {
  1057  		return err
  1058  	}
  1059  	defer peer.Stop()
  1060  
  1061  	if w.rateLimiter != nil {
  1062  		runLoop := func(out p2p.MsgReadWriter) error {
  1063  			peer.SetRWWriter(out)
  1064  			err := peer.Run()
  1065  			w.logger.Info("handled peer", zap.String("peerID", types.EncodeHex(peer.ID())), zap.Error(err))
  1066  			return err
  1067  		}
  1068  		return w.rateLimiter.Decorate(peer, rw, runLoop)
  1069  	}
  1070  
  1071  	err := peer.Run()
  1072  	w.logger.Info("handled peer", zap.String("peerID", types.EncodeHex(peer.ID())), zap.Error(err))
  1073  	return err
  1074  }
  1075  
  1076  func (w *Waku) softBlacklisted(peerID string) bool {
  1077  	w.settingsMu.RLock()
  1078  	defer w.settingsMu.RUnlock()
  1079  	return w.settings.SoftBlacklistedPeerIDs[peerID]
  1080  }
  1081  
  1082  func (w *Waku) OnNewEnvelopes(envelopes []*common.Envelope, peer common.Peer) ([]common.EnvelopeError, error) {
  1083  	envelopeErrors := make([]common.EnvelopeError, 0)
  1084  	peerID := types.EncodeHex(peer.ID())
  1085  	w.logger.Debug("received new envelopes", zap.Int("count", len(envelopes)), zap.String("peer", peerID))
  1086  	trouble := false
  1087  
  1088  	if w.softBlacklisted(peerID) {
  1089  		w.logger.Debug("peer is soft blacklisted", zap.String("peer", peerID))
  1090  		return nil, nil
  1091  	}
  1092  
  1093  	for _, env := range envelopes {
  1094  		w.logger.Debug("received new envelope", zap.String("peer", peerID), zap.String("hash", env.Hash().Hex()))
  1095  		cached, err := w.add(env, w.LightClientMode())
  1096  		if err != nil {
  1097  			_, isTimeSyncError := err.(common.TimeSyncError)
  1098  			if !isTimeSyncError {
  1099  				trouble = true
  1100  				w.logger.Info("invalid envelope received", zap.String("peer", types.EncodeHex(peer.ID())), zap.Error(err))
  1101  			}
  1102  			envelopeErrors = append(envelopeErrors, common.ErrorToEnvelopeError(env.Hash(), err))
  1103  		} else if cached {
  1104  			peer.Mark(env)
  1105  		}
  1106  
  1107  		w.envelopeFeed.Send(common.EnvelopeEvent{
  1108  			Event: common.EventEnvelopeReceived,
  1109  			Topic: env.Topic,
  1110  			Hash:  env.Hash(),
  1111  			Peer:  peer.EnodeID(),
  1112  		})
  1113  		common.EnvelopesValidatedCounter.Inc()
  1114  	}
  1115  
  1116  	if trouble {
  1117  		return envelopeErrors, errors.New("received invalid envelope")
  1118  	}
  1119  	return envelopeErrors, nil
  1120  }
  1121  
  1122  func (w *Waku) OnNewP2PEnvelopes(envelopes []*common.Envelope) error {
  1123  	for _, envelope := range envelopes {
  1124  		w.postP2P(envelope)
  1125  	}
  1126  	return nil
  1127  }
  1128  
  1129  func (w *Waku) Mailserver() bool {
  1130  	return w.mailServer != nil
  1131  }
  1132  
  1133  func (w *Waku) OnMessagesRequest(request common.MessagesRequest, p common.Peer) error {
  1134  	w.mailServer.Deliver(p.ID(), request)
  1135  	return nil
  1136  }
  1137  
  1138  func (w *Waku) OnDeprecatedMessagesRequest(request *common.Envelope, p common.Peer) error {
  1139  	w.mailServer.DeliverMail(p.ID(), request)
  1140  	return nil
  1141  }
  1142  
  1143  func (w *Waku) OnP2PRequestCompleted(payload []byte, p common.Peer) error {
  1144  	msEvent, err := CreateMailServerEvent(p.EnodeID(), payload)
  1145  	if err != nil {
  1146  		return fmt.Errorf("invalid p2p request complete payload: %v", err)
  1147  	}
  1148  
  1149  	w.postP2P(*msEvent)
  1150  	return nil
  1151  }
  1152  
  1153  func (w *Waku) OnMessagesResponse(response common.MessagesResponse, p common.Peer) error {
  1154  	w.envelopeFeed.Send(common.EnvelopeEvent{
  1155  		Batch: response.Hash,
  1156  		Event: common.EventBatchAcknowledged,
  1157  		Peer:  p.EnodeID(),
  1158  		Data:  response.Errors,
  1159  	})
  1160  
  1161  	return nil
  1162  }
  1163  
  1164  func (w *Waku) OnBatchAcknowledged(batchHash gethcommon.Hash, p common.Peer) error {
  1165  	w.envelopeFeed.Send(common.EnvelopeEvent{
  1166  		Batch: batchHash,
  1167  		Event: common.EventBatchAcknowledged,
  1168  		Peer:  p.EnodeID(),
  1169  	})
  1170  	return nil
  1171  }
  1172  
  1173  func (w *Waku) add(envelope *common.Envelope, isP2P bool) (bool, error) {
  1174  	return w.addAndBridge(envelope, isP2P, false)
  1175  }
  1176  
  1177  func (w *Waku) bloomMatch(envelope *common.Envelope) (bool, error) {
  1178  	if !common.BloomFilterMatch(w.BloomFilter(), envelope.Bloom()) {
  1179  		// maybe the value was recently changed, and the peers did not adjust yet.
  1180  		// in this case the previous value is retrieved by BloomFilterTolerance()
  1181  		// for a short period of peer synchronization.
  1182  		if !common.BloomFilterMatch(w.BloomFilterTolerance(), envelope.Bloom()) {
  1183  			common.EnvelopesCacheFailedCounter.WithLabelValues("no_bloom_match").Inc()
  1184  			return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x",
  1185  				envelope.Hash().Hex(), w.BloomFilter(), envelope.Bloom(), envelope.Topic)
  1186  		}
  1187  	}
  1188  	return true, nil
  1189  }
  1190  
  1191  func (w *Waku) topicInterestMatch(envelope *common.Envelope) (bool, error) {
  1192  	w.settingsMu.RLock()
  1193  	defer w.settingsMu.RUnlock()
  1194  	if w.settings.TopicInterest == nil {
  1195  		return false, nil
  1196  	}
  1197  	if !w.settings.TopicInterest[envelope.Topic] {
  1198  		if !w.settings.TopicInterestTolerance[envelope.Topic] {
  1199  			common.EnvelopesCacheFailedCounter.WithLabelValues("no_topic_interest_match").Inc()
  1200  			return false, fmt.Errorf("envelope does not match topic interest, hash=[%v], bloom: \n%x \n%x",
  1201  				envelope.Hash().Hex(), envelope.Bloom(), envelope.Topic)
  1202  
  1203  		}
  1204  	}
  1205  
  1206  	return true, nil
  1207  }
  1208  
  1209  func (w *Waku) topicInterestOrBloomMatch(envelope *common.Envelope) (bool, error) {
  1210  	if w.FullNode() {
  1211  		return true, nil
  1212  	}
  1213  	w.settingsMu.RLock()
  1214  	topicInterestMode := !w.settings.BloomFilterMode
  1215  	w.settingsMu.RUnlock()
  1216  
  1217  	if topicInterestMode {
  1218  		match, err := w.topicInterestMatch(envelope)
  1219  		if err != nil {
  1220  			return false, err
  1221  		}
  1222  		if match {
  1223  			return true, nil
  1224  		}
  1225  	}
  1226  	return w.bloomMatch(envelope)
  1227  }
  1228  
  1229  func (w *Waku) SetBloomFilterMode(mode bool) {
  1230  	w.settingsMu.Lock()
  1231  	w.settings.BloomFilterMode = mode
  1232  	w.settingsMu.Unlock()
  1233  	// Recalculate and notify topic interest or bloom, currently not implemented
  1234  }
  1235  
  1236  func (w *Waku) SetFullNode(set bool) {
  1237  	w.settingsMu.Lock()
  1238  	w.settings.FullNode = set
  1239  	w.settingsMu.Unlock()
  1240  
  1241  	// We advertise the topic interest if full node has been disabled
  1242  	// or bloom filter if enabled, as that's how we indicate to a peer we are a full node or not
  1243  	if set {
  1244  		w.notifyPeersAboutBloomFilterChange(w.BloomFilter())
  1245  	} else {
  1246  		w.notifyPeersAboutTopicInterestChange(w.TopicInterest())
  1247  	}
  1248  }
  1249  
  1250  // addEnvelope adds an envelope to the envelope map, used for sending
  1251  func (w *Waku) addEnvelope(envelope *common.Envelope) {
  1252  
  1253  	hash := envelope.Hash()
  1254  
  1255  	w.poolMu.Lock()
  1256  	w.envelopes[hash] = envelope
  1257  	if w.expirations[envelope.Expiry] == nil {
  1258  		w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet()
  1259  	}
  1260  	if !w.expirations[envelope.Expiry].Contains(hash) {
  1261  		w.expirations[envelope.Expiry].Add(hash)
  1262  	}
  1263  	w.poolMu.Unlock()
  1264  }
  1265  
  1266  // addAndBridge inserts a new envelope into the message pool to be distributed within the
  1267  // waku network. It also inserts the envelope into the expiration pool at the
  1268  // appropriate time-stamp. In case of error, connection should be dropped.
  1269  // param isP2P indicates whether the message is peer-to-peer (should not be forwarded).
  1270  func (w *Waku) addAndBridge(envelope *common.Envelope, isP2P bool, bridged bool) (bool, error) {
  1271  	now := uint32(w.timeSource().Unix())
  1272  	sent := envelope.Expiry - envelope.TTL
  1273  	logger := w.logger.With(zap.String("hash", envelope.Hash().String()), zap.String("site", "addAndBridge"), zap.String("topic", envelope.Topic.String()), zap.Bool("isP2P", isP2P))
  1274  
  1275  	logger.Debug("addAndBridge: processing envelope")
  1276  
  1277  	common.EnvelopesReceivedCounter.Inc()
  1278  	if sent > now {
  1279  		if sent-common.DefaultSyncAllowance > now {
  1280  			common.EnvelopesCacheFailedCounter.WithLabelValues("in_future").Inc()
  1281  			logger.Warn("envelope created in the future")
  1282  			return false, common.TimeSyncError(errors.New("envelope from future"))
  1283  		}
  1284  		// recalculate PoW, adjusted for the time difference, plus one second for latency
  1285  		envelope.CalculatePoW(sent - now + 1)
  1286  	}
  1287  
  1288  	if envelope.Expiry < now {
  1289  		if envelope.Expiry+common.DefaultSyncAllowance*2 < now {
  1290  			common.EnvelopesCacheFailedCounter.WithLabelValues("very_old").Inc()
  1291  			logger.Warn("very old envelope")
  1292  			return false, common.TimeSyncError(errors.New("very old envelope"))
  1293  		}
  1294  		logger.Debug("expired envelope dropped")
  1295  		common.EnvelopesCacheFailedCounter.WithLabelValues("expired").Inc()
  1296  		return false, nil // drop envelope without error
  1297  	}
  1298  
  1299  	if uint32(envelope.Size()) > w.MaxMessageSize() {
  1300  		common.EnvelopesCacheFailedCounter.WithLabelValues("oversized").Inc()
  1301  		return false, fmt.Errorf("huge messages are not allowed [%s][%d][%d]", envelope.Hash().String(), envelope.Size(), w.MaxMessageSize())
  1302  	}
  1303  
  1304  	if envelope.PoW() < w.MinPow() {
  1305  		// maybe the value was recently changed, and the peers did not adjust yet.
  1306  		// in this case the previous value is retrieved by MinPowTolerance()
  1307  		// for a short period of peer synchronization.
  1308  		if envelope.PoW() < w.MinPowTolerance() {
  1309  			common.EnvelopesCacheFailedCounter.WithLabelValues("low_pow").Inc()
  1310  			return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%s]", envelope.PoW(), envelope.Hash().String())
  1311  		}
  1312  	}
  1313  
  1314  	match, err := w.topicInterestOrBloomMatch(envelope)
  1315  	if err != nil {
  1316  		return false, err
  1317  	}
  1318  
  1319  	if !match {
  1320  		logger.Debug("addAndBridge: no matches for envelope")
  1321  		return false, nil
  1322  	}
  1323  
  1324  	hash := envelope.Hash()
  1325  
  1326  	w.poolMu.Lock()
  1327  	_, alreadyCached := w.envelopes[hash]
  1328  	w.poolMu.Unlock()
  1329  	if !alreadyCached {
  1330  		logger.Debug("addAndBridge: adding envelope")
  1331  		w.addEnvelope(envelope)
  1332  	}
  1333  
  1334  	if alreadyCached {
  1335  		logger.Debug("addAndBridge: already cached")
  1336  		common.EnvelopesCachedCounter.WithLabelValues("hit").Inc()
  1337  	} else {
  1338  		common.EnvelopesCachedCounter.WithLabelValues("miss").Inc()
  1339  		common.EnvelopesSizeMeter.Observe(float64(envelope.Size()))
  1340  		w.postEvent(envelope, isP2P) // notify the local node about the new message
  1341  		if w.mailServer != nil {
  1342  			w.mailServer.Archive(envelope)
  1343  			w.envelopeFeed.Send(common.EnvelopeEvent{
  1344  				Topic: envelope.Topic,
  1345  				Hash:  envelope.Hash(),
  1346  				Event: common.EventMailServerEnvelopeArchived,
  1347  			})
  1348  		}
  1349  		// Bridge only envelopes that are not p2p messages.
  1350  		// In particular, if a node is a lightweight node,
  1351  		// it should not bridge any envelopes.
  1352  		if !isP2P && !bridged && w.bridge != nil {
  1353  			logger.Debug("bridging envelope from Waku")
  1354  			_, in := w.bridge.Pipe()
  1355  			in <- envelope
  1356  			common.BridgeSent.Inc()
  1357  		}
  1358  	}
  1359  	return true, nil
  1360  }
  1361  
  1362  func (w *Waku) postP2P(event interface{}) {
  1363  	w.p2pMsgQueue <- event
  1364  }
  1365  
  1366  // postEvent queues the message for further processing.
  1367  func (w *Waku) postEvent(envelope *common.Envelope, isP2P bool) {
  1368  	if isP2P {
  1369  		w.postP2P(envelope)
  1370  	} else {
  1371  		w.msgQueue <- envelope
  1372  	}
  1373  }
  1374  
  1375  // processQueue delivers the messages to the watchers during the lifetime of the waku node.
  1376  func (w *Waku) processQueue() {
  1377  	for {
  1378  		select {
  1379  		case <-w.quit:
  1380  			return
  1381  		case e := <-w.msgQueue:
  1382  			w.filters.NotifyWatchers(e, false)
  1383  			w.envelopeFeed.Send(common.EnvelopeEvent{
  1384  				Topic: e.Topic,
  1385  				Hash:  e.Hash(),
  1386  				Event: common.EventEnvelopeAvailable,
  1387  			})
  1388  		}
  1389  	}
  1390  }
  1391  
  1392  func (w *Waku) processP2P() {
  1393  	for {
  1394  		select {
  1395  		case <-w.quit:
  1396  			return
  1397  		case e := <-w.p2pMsgQueue:
  1398  			switch evn := e.(type) {
  1399  			case *common.Envelope:
  1400  				// We need to insert it first, and then remove it if not matched,
  1401  				// as messages are processed asynchronously
  1402  				w.p2pMsgIDsMu.Lock()
  1403  				w.p2pMsgIDs[evn.Hash()] = true
  1404  				w.p2pMsgIDsMu.Unlock()
  1405  
  1406  				matched := w.filters.NotifyWatchers(evn, true)
  1407  
  1408  				// If not matched we remove it
  1409  				if !matched {
  1410  					w.p2pMsgIDsMu.Lock()
  1411  					delete(w.p2pMsgIDs, evn.Hash())
  1412  					w.p2pMsgIDsMu.Unlock()
  1413  				}
  1414  
  1415  				w.envelopeFeed.Send(common.EnvelopeEvent{
  1416  					Topic: evn.Topic,
  1417  					Hash:  evn.Hash(),
  1418  					Event: common.EventEnvelopeAvailable,
  1419  				})
  1420  			case common.EnvelopeEvent:
  1421  				w.envelopeFeed.Send(evn)
  1422  			}
  1423  		}
  1424  	}
  1425  }
  1426  
  1427  // update loops until the lifetime of the waku node, updating its internal
  1428  // state by expiring stale messages from the pool.
  1429  func (w *Waku) update() {
  1430  	// Start a ticker to check for expirations
  1431  	expire := time.NewTicker(common.ExpirationCycle)
  1432  
  1433  	// Repeat updates until termination is requested
  1434  	for {
  1435  		select {
  1436  		case <-expire.C:
  1437  			w.expire()
  1438  
  1439  		case <-w.quit:
  1440  			return
  1441  		}
  1442  	}
  1443  }
  1444  
  1445  // expire iterates over all the expiration timestamps, removing all stale
  1446  // messages from the pools.
  1447  func (w *Waku) expire() {
  1448  	w.poolMu.Lock()
  1449  	defer w.poolMu.Unlock()
  1450  	logger := w.logger.With(zap.String("site", "expire"))
  1451  
  1452  	now := uint32(w.timeSource().Unix())
  1453  	for expiry, hashSet := range w.expirations {
  1454  		if expiry < now {
  1455  			// Dump all expired messages and remove timestamp
  1456  			hashSet.Each(func(v interface{}) bool {
  1457  				logger.Debug("expiring envelope", zap.String("hash", v.(gethcommon.Hash).String()))
  1458  				delete(w.envelopes, v.(gethcommon.Hash))
  1459  				common.EnvelopesCachedCounter.WithLabelValues("clear").Inc()
  1460  				w.envelopeFeed.Send(common.EnvelopeEvent{
  1461  					Hash:  v.(gethcommon.Hash),
  1462  					Event: common.EventEnvelopeExpired,
  1463  				})
  1464  				return false
  1465  			})
  1466  			w.expirations[expiry].Clear()
  1467  			delete(w.expirations, expiry)
  1468  		}
  1469  	}
  1470  }
  1471  
  1472  // Envelopes retrieves all the messages currently pooled by the node.
  1473  func (w *Waku) Envelopes() []*common.Envelope {
  1474  	w.poolMu.RLock()
  1475  	defer w.poolMu.RUnlock()
  1476  
  1477  	all := make([]*common.Envelope, 0, len(w.envelopes))
  1478  	for _, envelope := range w.envelopes {
  1479  		all = append(all, envelope)
  1480  	}
  1481  	return all
  1482  }
  1483  
  1484  // GetEnvelope retrieves an envelope from the message queue by its hash.
  1485  // It returns nil if the envelope can not be found.
  1486  func (w *Waku) GetEnvelope(hash gethcommon.Hash) *common.Envelope {
  1487  	w.poolMu.RLock()
  1488  	defer w.poolMu.RUnlock()
  1489  	return w.envelopes[hash]
  1490  }
  1491  
  1492  func (w *Waku) Version() uint {
  1493  	return 1
  1494  }
  1495  
  1496  // isEnvelopeCached checks if envelope with specific hash has already been received and cached.
  1497  func (w *Waku) IsEnvelopeCached(hash gethcommon.Hash) bool {
  1498  	w.poolMu.Lock()
  1499  	defer w.poolMu.Unlock()
  1500  
  1501  	_, exist := w.envelopes[hash]
  1502  	return exist
  1503  }
  1504  
  1505  func (w *Waku) ProcessingP2PMessages() bool {
  1506  	w.p2pMsgIDsMu.Lock()
  1507  	defer w.p2pMsgIDsMu.Unlock()
  1508  	return len(w.p2pMsgIDs) != 0
  1509  }
  1510  
  1511  func (w *Waku) MarkP2PMessageAsProcessed(hash gethcommon.Hash) {
  1512  	w.p2pMsgIDsMu.Lock()
  1513  	defer w.p2pMsgIDsMu.Unlock()
  1514  	delete(w.p2pMsgIDs, hash)
  1515  }
  1516  
  1517  func (w *Waku) ClearEnvelopesCache() {
  1518  	w.poolMu.Lock()
  1519  	defer w.poolMu.Unlock()
  1520  	w.envelopes = make(map[gethcommon.Hash]*common.Envelope)
  1521  }
  1522  
  1523  func (w *Waku) Clean() error {
  1524  	w.poolMu.Lock()
  1525  	defer w.poolMu.Unlock()
  1526  	w.envelopes = make(map[gethcommon.Hash]*common.Envelope)
  1527  	for _, f := range w.filters.All() {
  1528  		f.Messages = common.NewMemoryMessageStore()
  1529  	}
  1530  
  1531  	return nil
  1532  }
  1533  
  1534  func (w *Waku) PeerID() peer.ID {
  1535  	panic("not implemented")
  1536  }
  1537  
  1538  // validatePrivateKey checks the format of the given private key.
  1539  func validatePrivateKey(k *ecdsa.PrivateKey) bool {
  1540  	if k == nil || k.D == nil || k.D.Sign() == 0 {
  1541  		return false
  1542  	}
  1543  	return common.ValidatePublicKey(&k.PublicKey)
  1544  }
  1545  
  1546  // makeDeterministicID generates a deterministic ID, based on a given input
  1547  func makeDeterministicID(input string, keyLen int) (id string, err error) {
  1548  	buf := pbkdf2.Key([]byte(input), nil, 4096, keyLen, sha256.New)
  1549  	if !common.ValidateDataIntegrity(buf, common.KeyIDSize) {
  1550  		return "", fmt.Errorf("error in GenerateDeterministicID: failed to generate key")
  1551  	}
  1552  	id = gethcommon.Bytes2Hex(buf)
  1553  	return id, err
  1554  }
  1555  
  1556  // toDeterministicID reviews incoming id, and transforms it to format
  1557  // expected internally be private key store. Originally, public keys
  1558  // were used as keys, now random keys are being used. And in order to
  1559  // make it easier to consume, we now allow both random IDs and public
  1560  // keys to be passed.
  1561  func toDeterministicID(id string, expectedLen int) (string, error) {
  1562  	if len(id) != (expectedLen * 2) { // we received hex key, so number of chars in id is doubled
  1563  		var err error
  1564  		id, err = makeDeterministicID(id, expectedLen)
  1565  		if err != nil {
  1566  			return "", err
  1567  		}
  1568  	}
  1569  
  1570  	return id, nil
  1571  }
  1572  
  1573  func addBloom(a, b []byte) []byte {
  1574  	c := make([]byte, common.BloomFilterSize)
  1575  	for i := 0; i < common.BloomFilterSize; i++ {
  1576  		c[i] = a[i] | b[i]
  1577  	}
  1578  	return c
  1579  }