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 }