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

     1  package node
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"database/sql"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"os"
    10  	"reflect"
    11  	"time"
    12  
    13  	"github.com/status-im/status-go/protocol/common/shard"
    14  	"github.com/status-im/status-go/server"
    15  	"github.com/status-im/status-go/signal"
    16  	"github.com/status-im/status-go/transactions"
    17  
    18  	"github.com/ethereum/go-ethereum/common/hexutil"
    19  	"github.com/ethereum/go-ethereum/event"
    20  	"github.com/ethereum/go-ethereum/p2p/enode"
    21  	gethrpc "github.com/ethereum/go-ethereum/rpc"
    22  
    23  	"github.com/status-im/status-go/appmetrics"
    24  	"github.com/status-im/status-go/common"
    25  	gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
    26  	"github.com/status-im/status-go/eth-node/crypto"
    27  	"github.com/status-im/status-go/eth-node/types"
    28  	"github.com/status-im/status-go/logutils"
    29  	"github.com/status-im/status-go/mailserver"
    30  	"github.com/status-im/status-go/multiaccounts/accounts"
    31  	"github.com/status-im/status-go/multiaccounts/settings"
    32  	"github.com/status-im/status-go/params"
    33  	"github.com/status-im/status-go/rpc"
    34  	accountssvc "github.com/status-im/status-go/services/accounts"
    35  	"github.com/status-im/status-go/services/accounts/settingsevent"
    36  	appgeneral "github.com/status-im/status-go/services/app-general"
    37  	appmetricsservice "github.com/status-im/status-go/services/appmetrics"
    38  	"github.com/status-im/status-go/services/browsers"
    39  	"github.com/status-im/status-go/services/chat"
    40  	"github.com/status-im/status-go/services/communitytokens"
    41  	"github.com/status-im/status-go/services/connector"
    42  	"github.com/status-im/status-go/services/ens"
    43  	"github.com/status-im/status-go/services/ext"
    44  	"github.com/status-im/status-go/services/gif"
    45  	localnotifications "github.com/status-im/status-go/services/local-notifications"
    46  	"github.com/status-im/status-go/services/mailservers"
    47  	"github.com/status-im/status-go/services/peer"
    48  	"github.com/status-im/status-go/services/permissions"
    49  	"github.com/status-im/status-go/services/personal"
    50  	"github.com/status-im/status-go/services/rpcfilters"
    51  	"github.com/status-im/status-go/services/rpcstats"
    52  	"github.com/status-im/status-go/services/status"
    53  	"github.com/status-im/status-go/services/stickers"
    54  	"github.com/status-im/status-go/services/subscriptions"
    55  	"github.com/status-im/status-go/services/updates"
    56  	"github.com/status-im/status-go/services/wakuext"
    57  	"github.com/status-im/status-go/services/wakuv2ext"
    58  	"github.com/status-im/status-go/services/wallet"
    59  	"github.com/status-im/status-go/services/wallet/thirdparty"
    60  	"github.com/status-im/status-go/services/wallet/transfer"
    61  	"github.com/status-im/status-go/services/web3provider"
    62  	"github.com/status-im/status-go/timesource"
    63  	"github.com/status-im/status-go/waku"
    64  	wakucommon "github.com/status-im/status-go/waku/common"
    65  	"github.com/status-im/status-go/wakuv2"
    66  )
    67  
    68  var (
    69  	// ErrWakuClearIdentitiesFailure clearing whisper identities has failed.
    70  	ErrWakuClearIdentitiesFailure = errors.New("failed to clear waku identities")
    71  	// ErrRPCClientUnavailable is returned if an RPC client can't be retrieved.
    72  	// This is a normal situation when a node is stopped.
    73  	ErrRPCClientUnavailable = errors.New("JSON-RPC client is unavailable")
    74  )
    75  
    76  func (b *StatusNode) initServices(config *params.NodeConfig, mediaServer *server.MediaServer) error {
    77  	settingsFeed := &event.Feed{}
    78  	accDB, err := accounts.NewDB(b.appDB)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	setSettingsNotifier(accDB, settingsFeed)
    84  
    85  	services := []common.StatusService{}
    86  	services = appendIf(config.UpstreamConfig.Enabled, services, b.rpcFiltersService())
    87  	services = append(services, b.subscriptionService())
    88  	services = append(services, b.rpcStatsService())
    89  	services = append(services, b.appmetricsService())
    90  	services = append(services, b.appgeneralService())
    91  	services = append(services, b.peerService())
    92  	services = append(services, b.personalService())
    93  	services = append(services, b.statusPublicService())
    94  	services = append(services, b.pendingTrackerService(&b.walletFeed))
    95  	services = append(services, b.ensService(b.timeSourceNow()))
    96  	services = append(services, b.CommunityTokensService())
    97  	services = append(services, b.stickersService(accDB))
    98  	services = append(services, b.updatesService())
    99  	services = appendIf(b.appDB != nil && b.multiaccountsDB != nil, services, b.accountsService(&b.accountsFeed, accDB, mediaServer))
   100  	services = appendIf(config.BrowsersConfig.Enabled, services, b.browsersService())
   101  	services = appendIf(config.PermissionsConfig.Enabled, services, b.permissionsService())
   102  	services = appendIf(config.MailserversConfig.Enabled, services, b.mailserversService())
   103  	services = appendIf(config.Web3ProviderConfig.Enabled, services, b.providerService(accDB))
   104  	services = appendIf(config.ConnectorConfig.Enabled, services, b.connectorService())
   105  	services = append(services, b.gifService(accDB))
   106  	services = append(services, b.ChatService(accDB))
   107  
   108  	// Wallet Service is used by wakuExtSrvc/wakuV2ExtSrvc
   109  	// Keep this initialization before the other two
   110  	if config.WalletConfig.Enabled {
   111  		walletService := b.walletService(accDB, b.appDB, &b.accountsFeed, settingsFeed, &b.walletFeed, config.WalletConfig.StatusProxyStageName)
   112  		services = append(services, walletService)
   113  	}
   114  
   115  	// CollectiblesManager needs the WakuExt service to get metadata for
   116  	// Community collectibles.
   117  	// Messenger needs the CollectiblesManager to get the list of collectibles owned
   118  	// by a certain account and check community entry permissions.
   119  	// We handle circular dependency between the two by delaying ininitalization of the CommunityCollectibleInfoProvider
   120  	// in the CollectiblesManager.
   121  	if config.WakuConfig.Enabled {
   122  		wakuService, err := b.wakuService(&config.WakuConfig, &config.ClusterConfig)
   123  		if err != nil {
   124  			return err
   125  		}
   126  
   127  		services = append(services, wakuService)
   128  
   129  		wakuext, err := b.wakuExtService(config)
   130  		if err != nil {
   131  			return err
   132  		}
   133  
   134  		b.wakuExtSrvc = wakuext
   135  
   136  		services = append(services, wakuext)
   137  
   138  		b.SetWalletCommunityInfoProvider(wakuext)
   139  	}
   140  
   141  	if config.WakuV2Config.Enabled {
   142  		telemetryServerURL := ""
   143  		if accDB.DB() != nil {
   144  			telemetryServerURL, err = accDB.GetTelemetryServerURL()
   145  			if err != nil {
   146  				return err
   147  			}
   148  			if telemetryServerURL != "" {
   149  				config.WakuV2Config.TelemetryServerURL = telemetryServerURL
   150  			}
   151  		}
   152  		waku2Service, err := b.wakuV2Service(config)
   153  		if err != nil {
   154  			return err
   155  		}
   156  		services = append(services, waku2Service)
   157  
   158  		wakuext, err := b.wakuV2ExtService(config)
   159  		if err != nil {
   160  			return err
   161  		}
   162  
   163  		b.wakuV2ExtSrvc = wakuext
   164  
   165  		services = append(services, wakuext)
   166  
   167  		b.SetWalletCommunityInfoProvider(wakuext)
   168  	}
   169  
   170  	// We ignore for now local notifications flag as users who are upgrading have no mean to enable it
   171  	lns, err := b.localNotificationsService(config.NetworkID)
   172  	if err != nil {
   173  		return err
   174  	}
   175  	services = append(services, lns)
   176  
   177  	b.peerSrvc.SetDiscoverer(b)
   178  
   179  	for i := range services {
   180  		b.RegisterLifecycle(services[i])
   181  	}
   182  
   183  	b.services = services
   184  
   185  	return nil
   186  }
   187  
   188  func (b *StatusNode) RegisterLifecycle(s common.StatusService) {
   189  	b.addPublicMethods(s.APIs())
   190  	b.gethNode.RegisterAPIs(s.APIs())
   191  	b.gethNode.RegisterProtocols(s.Protocols())
   192  	b.gethNode.RegisterLifecycle(s)
   193  }
   194  
   195  // Add through reflection a list of public methods so we can check when the
   196  // user makes a call if they are allowed
   197  func (b *StatusNode) addPublicMethods(apis []gethrpc.API) {
   198  	for _, api := range apis {
   199  		if api.Public {
   200  			addSuitableCallbacks(reflect.ValueOf(api.Service), api.Namespace, b.publicMethods)
   201  		}
   202  	}
   203  }
   204  
   205  func (b *StatusNode) nodeBridge() types.Node {
   206  	return gethbridge.NewNodeBridge(b.gethNode, b.wakuSrvc, b.wakuV2Srvc)
   207  }
   208  
   209  func (b *StatusNode) wakuExtService(config *params.NodeConfig) (*wakuext.Service, error) {
   210  	if b.gethNode == nil {
   211  		return nil, errors.New("geth node not initialized")
   212  	}
   213  
   214  	if b.wakuExtSrvc == nil {
   215  		b.wakuExtSrvc = wakuext.New(*config, b.nodeBridge(), b.rpcClient, ext.EnvelopeSignalHandler{}, b.db)
   216  	}
   217  
   218  	b.wakuExtSrvc.SetP2PServer(b.gethNode.Server())
   219  	return b.wakuExtSrvc, nil
   220  }
   221  
   222  func (b *StatusNode) wakuV2ExtService(config *params.NodeConfig) (*wakuv2ext.Service, error) {
   223  	if b.gethNode == nil {
   224  		return nil, errors.New("geth node not initialized")
   225  	}
   226  	if b.wakuV2ExtSrvc == nil {
   227  		b.wakuV2ExtSrvc = wakuv2ext.New(*config, b.nodeBridge(), b.rpcClient, ext.EnvelopeSignalHandler{}, b.db)
   228  	}
   229  
   230  	b.wakuV2ExtSrvc.SetP2PServer(b.gethNode.Server())
   231  	return b.wakuV2ExtSrvc, nil
   232  }
   233  
   234  func (b *StatusNode) statusPublicService() *status.Service {
   235  	if b.statusPublicSrvc == nil {
   236  		b.statusPublicSrvc = status.New()
   237  	}
   238  	return b.statusPublicSrvc
   239  }
   240  
   241  func (b *StatusNode) StatusPublicService() *status.Service {
   242  	return b.statusPublicSrvc
   243  }
   244  
   245  func (b *StatusNode) AccountService() *accountssvc.Service {
   246  	return b.accountsSrvc
   247  }
   248  
   249  func (b *StatusNode) BrowserService() *browsers.Service {
   250  	return b.browsersSrvc
   251  }
   252  
   253  func (b *StatusNode) EnsService() *ens.Service {
   254  	return b.ensSrvc
   255  }
   256  
   257  func (b *StatusNode) WakuService() *waku.Waku {
   258  	return b.wakuSrvc
   259  }
   260  
   261  func (b *StatusNode) WakuExtService() *wakuext.Service {
   262  	return b.wakuExtSrvc
   263  }
   264  
   265  func (b *StatusNode) WakuV2ExtService() *wakuv2ext.Service {
   266  	return b.wakuV2ExtSrvc
   267  }
   268  func (b *StatusNode) WakuV2Service() *wakuv2.Waku {
   269  	return b.wakuV2Srvc
   270  }
   271  
   272  func (b *StatusNode) wakuService(wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) (*waku.Waku, error) {
   273  	if b.wakuSrvc == nil {
   274  		cfg := &waku.Config{
   275  			MaxMessageSize:         wakucommon.DefaultMaxMessageSize,
   276  			BloomFilterMode:        wakuCfg.BloomFilterMode,
   277  			FullNode:               wakuCfg.FullNode,
   278  			SoftBlacklistedPeerIDs: wakuCfg.SoftBlacklistedPeerIDs,
   279  			MinimumAcceptedPoW:     params.WakuMinimumPoW,
   280  			EnableConfirmations:    wakuCfg.EnableConfirmations,
   281  		}
   282  
   283  		if wakuCfg.MaxMessageSize > 0 {
   284  			cfg.MaxMessageSize = wakuCfg.MaxMessageSize
   285  		}
   286  		if wakuCfg.MinimumPoW > 0 {
   287  			cfg.MinimumAcceptedPoW = wakuCfg.MinimumPoW
   288  		}
   289  
   290  		w := waku.New(cfg, logutils.ZapLogger())
   291  
   292  		if wakuCfg.EnableRateLimiter {
   293  			r := wakuRateLimiter(wakuCfg, clusterCfg)
   294  			w.RegisterRateLimiter(r)
   295  		}
   296  
   297  		if timesource := b.timeSource(); timesource != nil {
   298  			w.SetTimeSource(timesource.Now)
   299  		}
   300  
   301  		// enable mail service
   302  		if wakuCfg.EnableMailServer {
   303  			if err := registerWakuMailServer(w, wakuCfg); err != nil {
   304  				return nil, fmt.Errorf("failed to register WakuMailServer: %v", err)
   305  			}
   306  		}
   307  
   308  		if wakuCfg.LightClient {
   309  			emptyBloomFilter := make([]byte, 64)
   310  			if err := w.SetBloomFilter(emptyBloomFilter); err != nil {
   311  				return nil, err
   312  			}
   313  		}
   314  		b.wakuSrvc = w
   315  	}
   316  	return b.wakuSrvc, nil
   317  
   318  }
   319  
   320  func (b *StatusNode) wakuV2Service(nodeConfig *params.NodeConfig) (*wakuv2.Waku, error) {
   321  	if b.wakuV2Srvc == nil {
   322  		cfg := &wakuv2.Config{
   323  			MaxMessageSize:                         wakucommon.DefaultMaxMessageSize,
   324  			Host:                                   nodeConfig.WakuV2Config.Host,
   325  			Port:                                   nodeConfig.WakuV2Config.Port,
   326  			LightClient:                            nodeConfig.WakuV2Config.LightClient,
   327  			WakuNodes:                              nodeConfig.ClusterConfig.WakuNodes,
   328  			EnableStore:                            nodeConfig.WakuV2Config.EnableStore,
   329  			StoreCapacity:                          nodeConfig.WakuV2Config.StoreCapacity,
   330  			StoreSeconds:                           nodeConfig.WakuV2Config.StoreSeconds,
   331  			DiscoveryLimit:                         nodeConfig.WakuV2Config.DiscoveryLimit,
   332  			DiscV5BootstrapNodes:                   nodeConfig.ClusterConfig.DiscV5BootstrapNodes,
   333  			Nameserver:                             nodeConfig.WakuV2Config.Nameserver,
   334  			UDPPort:                                nodeConfig.WakuV2Config.UDPPort,
   335  			AutoUpdate:                             nodeConfig.WakuV2Config.AutoUpdate,
   336  			DefaultShardPubsubTopic:                shard.DefaultShardPubsubTopic(),
   337  			TelemetryServerURL:                     nodeConfig.WakuV2Config.TelemetryServerURL,
   338  			ClusterID:                              nodeConfig.ClusterConfig.ClusterID,
   339  			EnableMissingMessageVerification:       nodeConfig.WakuV2Config.EnableMissingMessageVerification,
   340  			EnableStoreConfirmationForMessagesSent: nodeConfig.WakuV2Config.EnableStoreConfirmationForMessagesSent,
   341  			UseThrottledPublish:                    true,
   342  		}
   343  
   344  		// Configure peer exchange and discv5 settings based on node type
   345  		if cfg.LightClient {
   346  			cfg.EnablePeerExchangeServer = false
   347  			cfg.EnablePeerExchangeClient = true
   348  			cfg.EnableDiscV5 = false
   349  		} else {
   350  			cfg.EnablePeerExchangeServer = true
   351  			cfg.EnablePeerExchangeClient = false
   352  			cfg.EnableDiscV5 = true
   353  		}
   354  
   355  		if nodeConfig.WakuV2Config.MaxMessageSize > 0 {
   356  			cfg.MaxMessageSize = nodeConfig.WakuV2Config.MaxMessageSize
   357  		}
   358  
   359  		var nodeKey *ecdsa.PrivateKey
   360  		var err error
   361  		if nodeConfig.NodeKey != "" {
   362  			nodeKey, err = crypto.HexToECDSA(nodeConfig.NodeKey)
   363  			if err != nil {
   364  				return nil, fmt.Errorf("could not convert nodekey into a valid private key: %v", err)
   365  			}
   366  		} else {
   367  			nodeKeyStr := os.Getenv("WAKUV2_NODE_KEY")
   368  			if nodeKeyStr != "" {
   369  				nodeKeyBytes, err := hexutil.Decode(nodeKeyStr)
   370  				if err != nil {
   371  					return nil, fmt.Errorf("failed to decode the go-waku private key: %v", err)
   372  				}
   373  
   374  				nodeKey, err = crypto.ToECDSA(nodeKeyBytes)
   375  				if err != nil {
   376  					return nil, fmt.Errorf("could not convert nodekey into a valid private key: %v", err)
   377  				}
   378  			}
   379  		}
   380  
   381  		w, err := wakuv2.New(nodeKey, nodeConfig.ClusterConfig.Fleet, cfg, logutils.ZapLogger(), b.appDB, b.timeSource(), signal.SendHistoricMessagesRequestFailed, signal.SendPeerStats)
   382  
   383  		if err != nil {
   384  			return nil, err
   385  		}
   386  		b.wakuV2Srvc = w
   387  	}
   388  
   389  	return b.wakuV2Srvc, nil
   390  }
   391  
   392  func setSettingsNotifier(db *accounts.Database, feed *event.Feed) {
   393  	db.SetSettingsNotifier(func(setting settings.SettingField, val interface{}) {
   394  		feed.Send(settingsevent.Event{
   395  			Type:    settingsevent.EventTypeChanged,
   396  			Setting: setting,
   397  			Value:   val,
   398  		})
   399  	})
   400  }
   401  
   402  func wakuRateLimiter(wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) *wakucommon.PeerRateLimiter {
   403  	enodes := append(
   404  		parseNodes(clusterCfg.StaticNodes),
   405  		parseNodes(clusterCfg.TrustedMailServers)...,
   406  	)
   407  	var (
   408  		ips     []string
   409  		peerIDs []enode.ID
   410  	)
   411  	for _, item := range enodes {
   412  		ips = append(ips, item.IP().String())
   413  		peerIDs = append(peerIDs, item.ID())
   414  	}
   415  	return wakucommon.NewPeerRateLimiter(
   416  		&wakucommon.PeerRateLimiterConfig{
   417  			PacketLimitPerSecIP:     wakuCfg.PacketRateLimitIP,
   418  			PacketLimitPerSecPeerID: wakuCfg.PacketRateLimitPeerID,
   419  			BytesLimitPerSecIP:      wakuCfg.BytesRateLimitIP,
   420  			BytesLimitPerSecPeerID:  wakuCfg.BytesRateLimitPeerID,
   421  			WhitelistedIPs:          ips,
   422  			WhitelistedPeerIDs:      peerIDs,
   423  		},
   424  		&wakucommon.MetricsRateLimiterHandler{},
   425  		&wakucommon.DropPeerRateLimiterHandler{
   426  			Tolerance: wakuCfg.RateLimitTolerance,
   427  		},
   428  	)
   429  }
   430  
   431  func (b *StatusNode) connectorService() *connector.Service {
   432  	if b.connectorSrvc == nil {
   433  		b.connectorSrvc = connector.NewService(b.walletDB, b.rpcClient, b.rpcClient.NetworkManager)
   434  	}
   435  	return b.connectorSrvc
   436  }
   437  
   438  func (b *StatusNode) rpcFiltersService() *rpcfilters.Service {
   439  	if b.rpcFiltersSrvc == nil {
   440  		b.rpcFiltersSrvc = rpcfilters.New(b)
   441  	}
   442  	return b.rpcFiltersSrvc
   443  }
   444  
   445  func (b *StatusNode) subscriptionService() *subscriptions.Service {
   446  	if b.subscriptionsSrvc == nil {
   447  
   448  		b.subscriptionsSrvc = subscriptions.New(func() *rpc.Client { return b.RPCClient() })
   449  	}
   450  	return b.subscriptionsSrvc
   451  }
   452  
   453  func (b *StatusNode) rpcStatsService() *rpcstats.Service {
   454  	if b.rpcStatsSrvc == nil {
   455  		b.rpcStatsSrvc = rpcstats.New()
   456  	}
   457  
   458  	return b.rpcStatsSrvc
   459  }
   460  
   461  func (b *StatusNode) accountsService(accountsFeed *event.Feed, accDB *accounts.Database, mediaServer *server.MediaServer) *accountssvc.Service {
   462  	if b.accountsSrvc == nil {
   463  		b.accountsSrvc = accountssvc.NewService(
   464  			accDB,
   465  			b.multiaccountsDB,
   466  			b.gethAccountManager,
   467  			b.config,
   468  			accountsFeed,
   469  			mediaServer,
   470  		)
   471  	}
   472  
   473  	return b.accountsSrvc
   474  }
   475  
   476  func (b *StatusNode) browsersService() *browsers.Service {
   477  	if b.browsersSrvc == nil {
   478  		b.browsersSrvc = browsers.NewService(browsers.NewDB(b.appDB))
   479  	}
   480  	return b.browsersSrvc
   481  }
   482  
   483  func (b *StatusNode) ensService(timesource func() time.Time) *ens.Service {
   484  	if b.ensSrvc == nil {
   485  		b.ensSrvc = ens.NewService(b.rpcClient, b.gethAccountManager, b.pendingTracker, b.config, b.appDB, timesource)
   486  	}
   487  	return b.ensSrvc
   488  }
   489  
   490  func (b *StatusNode) pendingTrackerService(walletFeed *event.Feed) *transactions.PendingTxTracker {
   491  	if b.pendingTracker == nil {
   492  		b.pendingTracker = transactions.NewPendingTxTracker(b.walletDB, b.rpcClient, b.rpcFiltersSrvc, walletFeed, transactions.PendingCheckInterval)
   493  		if b.transactor != nil {
   494  			b.transactor.SetPendingTracker(b.pendingTracker)
   495  		}
   496  	}
   497  	return b.pendingTracker
   498  }
   499  
   500  func (b *StatusNode) CommunityTokensService() *communitytokens.Service {
   501  	if b.communityTokensSrvc == nil {
   502  		b.communityTokensSrvc = communitytokens.NewService(b.rpcClient, b.gethAccountManager, b.pendingTracker, b.config, b.appDB, &b.walletFeed, b.transactor)
   503  	}
   504  	return b.communityTokensSrvc
   505  }
   506  
   507  func (b *StatusNode) stickersService(accountDB *accounts.Database) *stickers.Service {
   508  	if b.stickersSrvc == nil {
   509  		b.stickersSrvc = stickers.NewService(accountDB, b.rpcClient, b.gethAccountManager, b.config, b.downloader, b.httpServer, b.pendingTracker)
   510  	}
   511  	return b.stickersSrvc
   512  }
   513  
   514  func (b *StatusNode) updatesService() *updates.Service {
   515  	if b.updatesSrvc == nil {
   516  		b.updatesSrvc = updates.NewService(b.ensService(b.timeSourceNow()))
   517  	}
   518  
   519  	return b.updatesSrvc
   520  }
   521  
   522  func (b *StatusNode) gifService(accountsDB *accounts.Database) *gif.Service {
   523  	if b.gifSrvc == nil {
   524  		b.gifSrvc = gif.NewService(accountsDB)
   525  	}
   526  	return b.gifSrvc
   527  }
   528  
   529  func (b *StatusNode) ChatService(accountsDB *accounts.Database) *chat.Service {
   530  	if b.chatSrvc == nil {
   531  		b.chatSrvc = chat.NewService(accountsDB)
   532  	}
   533  	return b.chatSrvc
   534  }
   535  
   536  func (b *StatusNode) permissionsService() *permissions.Service {
   537  	if b.permissionsSrvc == nil {
   538  		b.permissionsSrvc = permissions.NewService(permissions.NewDB(b.appDB))
   539  	}
   540  	return b.permissionsSrvc
   541  }
   542  
   543  func (b *StatusNode) mailserversService() *mailservers.Service {
   544  	if b.mailserversSrvc == nil {
   545  
   546  		b.mailserversSrvc = mailservers.NewService(mailservers.NewDB(b.appDB))
   547  	}
   548  	return b.mailserversSrvc
   549  }
   550  
   551  func (b *StatusNode) providerService(accountsDB *accounts.Database) *web3provider.Service {
   552  	web3S := web3provider.NewService(b.appDB, accountsDB, b.rpcClient, b.config, b.gethAccountManager, b.rpcFiltersSrvc, b.transactor)
   553  	if b.providerSrvc == nil {
   554  		b.providerSrvc = web3S
   555  	}
   556  	return b.providerSrvc
   557  }
   558  
   559  func (b *StatusNode) appmetricsService() common.StatusService {
   560  	if b.appMetricsSrvc == nil {
   561  		b.appMetricsSrvc = appmetricsservice.NewService(appmetrics.NewDB(b.appDB))
   562  	}
   563  	return b.appMetricsSrvc
   564  }
   565  
   566  func (b *StatusNode) appgeneralService() *appgeneral.Service {
   567  	if b.appGeneralSrvc == nil {
   568  		b.appGeneralSrvc = appgeneral.New()
   569  	}
   570  	return b.appGeneralSrvc
   571  }
   572  
   573  func (b *StatusNode) WalletService() *wallet.Service {
   574  	return b.walletSrvc
   575  }
   576  
   577  func (b *StatusNode) AccountsFeed() *event.Feed {
   578  	return &b.accountsFeed
   579  }
   580  
   581  func (b *StatusNode) SetWalletCommunityInfoProvider(provider thirdparty.CommunityInfoProvider) {
   582  	if b.walletSrvc != nil {
   583  		b.walletSrvc.SetWalletCommunityInfoProvider(provider)
   584  	}
   585  }
   586  
   587  func (b *StatusNode) walletService(accountsDB *accounts.Database, appDB *sql.DB, accountsFeed *event.Feed, settingsFeed *event.Feed, walletFeed *event.Feed, statusProxyStageName string) *wallet.Service {
   588  	if b.walletSrvc == nil {
   589  		b.walletSrvc = wallet.NewService(
   590  			b.walletDB, accountsDB, appDB, b.rpcClient, accountsFeed, settingsFeed, b.gethAccountManager, b.transactor, b.config,
   591  			b.ensService(b.timeSourceNow()),
   592  			b.stickersService(accountsDB),
   593  			b.pendingTracker,
   594  			walletFeed,
   595  			b.httpServer,
   596  			statusProxyStageName,
   597  		)
   598  	}
   599  	return b.walletSrvc
   600  }
   601  
   602  func (b *StatusNode) localNotificationsService(network uint64) (*localnotifications.Service, error) {
   603  	var err error
   604  	if b.localNotificationsSrvc == nil {
   605  		b.localNotificationsSrvc, err = localnotifications.NewService(b.appDB, transfer.NewDB(b.walletDB), network)
   606  		if err != nil {
   607  			return nil, err
   608  		}
   609  	}
   610  	return b.localNotificationsSrvc, nil
   611  }
   612  
   613  func (b *StatusNode) peerService() *peer.Service {
   614  	if b.peerSrvc == nil {
   615  		b.peerSrvc = peer.New()
   616  	}
   617  	return b.peerSrvc
   618  }
   619  
   620  func registerWakuMailServer(wakuService *waku.Waku, config *params.WakuConfig) (err error) {
   621  	var mailServer mailserver.WakuMailServer
   622  	wakuService.RegisterMailServer(&mailServer)
   623  
   624  	return mailServer.Init(wakuService, config)
   625  }
   626  
   627  func appendIf(condition bool, services []common.StatusService, service common.StatusService) []common.StatusService {
   628  	if !condition {
   629  		return services
   630  	}
   631  	return append(services, service)
   632  }
   633  
   634  func (b *StatusNode) RPCFiltersService() *rpcfilters.Service {
   635  	return b.rpcFiltersSrvc
   636  }
   637  
   638  func (b *StatusNode) PendingTracker() *transactions.PendingTxTracker {
   639  	return b.pendingTracker
   640  }
   641  
   642  func (b *StatusNode) StopLocalNotifications() error {
   643  	if b.localNotificationsSrvc == nil {
   644  		return nil
   645  	}
   646  
   647  	if b.localNotificationsSrvc.IsStarted() {
   648  		err := b.localNotificationsSrvc.Stop()
   649  		if err != nil {
   650  			b.log.Error("LocalNotifications service stop failed on StopLocalNotifications", "error", err)
   651  			return nil
   652  		}
   653  	}
   654  
   655  	return nil
   656  }
   657  
   658  func (b *StatusNode) StartLocalNotifications() error {
   659  	if b.localNotificationsSrvc == nil {
   660  		return nil
   661  	}
   662  
   663  	if b.walletSrvc == nil {
   664  		return nil
   665  	}
   666  
   667  	if !b.localNotificationsSrvc.IsStarted() {
   668  		err := b.localNotificationsSrvc.Start()
   669  
   670  		if err != nil {
   671  			b.log.Error("LocalNotifications service start failed on StartLocalNotifications", "error", err)
   672  			return nil
   673  		}
   674  	}
   675  
   676  	err := b.localNotificationsSrvc.SubscribeWallet(&b.walletFeed)
   677  
   678  	if err != nil {
   679  		b.log.Error("LocalNotifications service could not subscribe to wallet on StartLocalNotifications", "error", err)
   680  		return nil
   681  	}
   682  
   683  	return nil
   684  }
   685  
   686  // `personal_sign` and `personal_ecRecover` methods are important to
   687  // keep DApps working.
   688  // Usually, they are provided by an ETH or a LES service, but when using
   689  // upstream, we don't start any of these, so we need to start our own
   690  // implementation.
   691  
   692  func (b *StatusNode) personalService() *personal.Service {
   693  	if b.personalSrvc == nil {
   694  		b.personalSrvc = personal.New(b.accountsManager)
   695  	}
   696  	return b.personalSrvc
   697  }
   698  
   699  func (b *StatusNode) timeSource() *timesource.NTPTimeSource {
   700  
   701  	if b.timeSourceSrvc == nil {
   702  		b.timeSourceSrvc = timesource.Default()
   703  	}
   704  	return b.timeSourceSrvc
   705  }
   706  
   707  func (b *StatusNode) timeSourceNow() func() time.Time {
   708  	return b.timeSource().Now
   709  }
   710  
   711  func (b *StatusNode) Cleanup() error {
   712  	if b.wakuSrvc != nil {
   713  		if err := b.wakuSrvc.DeleteKeyPairs(); err != nil {
   714  			return fmt.Errorf("%s: %v", ErrWakuClearIdentitiesFailure, err)
   715  		}
   716  	}
   717  
   718  	if b.Config() != nil && b.Config().WalletConfig.Enabled {
   719  		if b.walletSrvc != nil {
   720  			if b.walletSrvc.IsStarted() {
   721  				err := b.walletSrvc.Stop()
   722  				if err != nil {
   723  					return err
   724  				}
   725  			}
   726  		}
   727  	}
   728  
   729  	if b.ensSrvc != nil {
   730  		err := b.ensSrvc.Stop()
   731  		if err != nil {
   732  			return err
   733  		}
   734  	}
   735  
   736  	if b.pendingTracker != nil {
   737  		err := b.pendingTracker.Stop()
   738  		if err != nil {
   739  			return err
   740  		}
   741  	}
   742  
   743  	return nil
   744  }
   745  
   746  type RPCCall struct {
   747  	Method string `json:"method"`
   748  }
   749  
   750  func (b *StatusNode) CallPrivateRPC(inputJSON string) (string, error) {
   751  	b.mu.Lock()
   752  	defer b.mu.Unlock()
   753  	if b.rpcClient == nil {
   754  		return "", ErrRPCClientUnavailable
   755  	}
   756  
   757  	return b.rpcClient.CallRaw(inputJSON), nil
   758  }
   759  
   760  // CallRPC calls public methods on the node, we register public methods
   761  // in a map and check if they can be called in this function
   762  func (b *StatusNode) CallRPC(inputJSON string) (string, error) {
   763  	b.mu.Lock()
   764  	defer b.mu.Unlock()
   765  	if b.rpcClient == nil {
   766  		return "", ErrRPCClientUnavailable
   767  	}
   768  
   769  	rpcCall := &RPCCall{}
   770  	err := json.Unmarshal([]byte(inputJSON), rpcCall)
   771  	if err != nil {
   772  		return "", err
   773  	}
   774  
   775  	if rpcCall.Method == "" || !b.publicMethods[rpcCall.Method] {
   776  		return ErrRPCMethodUnavailable, nil
   777  	}
   778  
   779  	return b.rpcClient.CallRaw(inputJSON), nil
   780  }