From 0a8a5c4795ca2aa360dc6971593e0a90c9881918 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Wed, 24 Nov 2021 13:09:15 +0100 Subject: [PATCH] refactor(node-configuration-service): node configuration added added as a new service --- src/app/boot/app_controller.nim | 10 +- .../node_configuration/dto/node_config.nim | 508 ++++++++++++++++++ .../service/node_configuration/service.nim | 138 +++++ .../node_configuration/service_interface.nim | 37 ++ .../service/settings/dto/settings.nim | 5 + src/app_service/service/settings/service.nim | 14 + .../service/settings/service_interface.nim | 7 + 7 files changed, 717 insertions(+), 2 deletions(-) create mode 100644 src/app_service/service/node_configuration/dto/node_config.nim create mode 100644 src/app_service/service/node_configuration/service.nim create mode 100644 src/app_service/service/node_configuration/service_interface.nim diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index c23843f559..e0e538a316 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -21,6 +21,7 @@ import ../../app_service/service/ens/service as ens_service import ../../app_service/service/profile/service as profile_service import ../../app_service/service/settings/service as settings_service import ../../app_service/service/about/service as about_service +import ../../app_service/service/node_configuration/service as node_configuration_service import ../modules/startup/module as startup_module import ../modules/main/module as main_module @@ -100,6 +101,7 @@ type languageService: language_service.Service mnemonicService: mnemonic_service.Service privacyService: privacy_service.Service + nodeConfigurationService: node_configuration_service.Service # Modules startupModule: startup_module.AccessInterface @@ -162,9 +164,11 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = result.userProfileVariant = newQVariant(singletonInstance.userProfile) # Services + result.settingsService = settings_service.newService() + result.nodeConfigurationService = node_configuration_service.newService(statusFoundation.fleetConfiguration, + result.settingsService) result.osNotificationService = os_notification_service.newService(statusFoundation.status.events) result.keychainService = keychain_service.newService(statusFoundation.status.events) - result.settingsService = settings_service.newService() result.accountsService = accounts_service.newService(statusFoundation.fleetConfiguration) result.contactsService = contacts_service.newService(statusFoundation.status.events, statusFoundation.threadpool) result.chatService = chat_service.newService(result.contactsService) @@ -261,12 +265,13 @@ proc delete*(self: AppController) = self.tokenService.delete self.transactionService.delete self.collectibleService.delete - self.settingsService.delete self.walletAccountService.delete self.aboutService.delete self.dappPermissionsService.delete self.providerService.delete self.ensService.delete + self.nodeConfigurationService.delete + self.settingsService.delete proc startupDidLoad*(self: AppController) = ################################################# @@ -306,6 +311,7 @@ proc start*(self: AppController) = proc load(self: AppController) = self.settingsService.init() + self.nodeConfigurationService.init() self.contactsService.init() self.chatService.init() self.communityService.init() diff --git a/src/app_service/service/node_configuration/dto/node_config.nim b/src/app_service/service/node_configuration/dto/node_config.nim new file mode 100644 index 0000000000..2053e16f7f --- /dev/null +++ b/src/app_service/service/node_configuration/dto/node_config.nim @@ -0,0 +1,508 @@ +import json, marshal + +include ../../../common/json_utils + +################################################# +# Important note: +# +# Uppercase letters are used in properties in object types deliberately, cause +# we're following "keys" which are received from `status-lib` (`status-go`) +# +# Why do we do that? +# Cause we're storing node configuration to the settings as JsonNode, and in order to +# convert `NodeConfigDto` to JsonNode we're using `marshal` Nim's module, which actually +# follows property names inside object types and convert them to "keys" of json object. +# That further means if we want to have parsing methods from this file reusable we have +# to store "keys" as they are received. +################################################# + +type + UpstreamConfig* = object + Enabled*: bool + URL*: string + + Network* = object + chainId*: int + chainName*: string + rpcUrl*: string + blockExplorerUrl*: string + nativeCurrencyName*: string + nativeCurrencySymbol*: string + nativeCurrencyDecimals*: int + isTest*: bool + layer*: int + enabled*: bool + + ClusterConfig* = object + Enabled*: bool + Fleet*: string + StaticNodes*: seq[string] + BootNodes*: seq[string] + TrustedMailServers*: seq[string] + PushNotificationsServers*: seq[string] + RendezvousNodes*: seq[string] + RelayNodes*: seq[string] + StoreNodes*: seq[string] + FilterNodes*: seq[string] + LightpushNodes*: seq[string] + WakuRendezvousNodes*: seq[string] + + LightEthConfig* = object + Enabled*: bool + DatabaseCache*: int + TrustedNodes*: seq[string] + MinTrustedFraction*: int + + PGConfig* = object + Enabled*: bool + URI*: string + + DatabaseConfig* = object + PgConfig*: PGConfig + + WakuConfig* = object + Enabled*: bool + LightClient*: bool + FullNode*: bool + EnableMailServer*: bool + DataDir*: string + MinimumPoW*: float + MailServerPassword*: string + MailServerRateLimit*: int + MailServerDataRetention*: int + TTL: int64 + MaxMessageSize*: int + DatabaseConfig*: DatabaseConfig + EnableRateLimiter*: bool + PacketRateLimitIP*: int + PacketRateLimitPeerID*: int + BytesRateLimitIP*: int + BytesRateLimitPeerID*: int + RateLimitTolerance*: int + BloomFilterMode*: bool + SoftBlacklistedPeerIDs*: seq[string] + EnableConfirmations*: bool + DiscoveryLimit*: int + Rendezvous*: bool + + ShhextConfig* = object + PFSEnabled*: bool + BackupDisabledDataDir*: string + InstallationID*: string + MailServerConfirmations*: bool + EnableConnectionManager*: bool + EnableLastUsedMonitor*: bool + ConnectionTarget*: int + RequestsDelay*: int + MaxServerFailures*: int + MaxMessageDeliveryAttempts*: int + WhisperCacheDir*: string + DisableGenericDiscoveryTopic*: bool + SendV1Messages*: bool + DataSyncEnabled*: bool + VerifyTransactionURL*: string + VerifyENSURL*: string + VerifyENSContractAddress*: string + VerifyTransactionChainID*: int + DefaultPushNotificationsServers*: seq[string] # not sure about the type, but we don't use it, so doesn't matter + AnonMetricsSendID*: string + AnonMetricsServerEnabled*: bool + AnonMetricsServerPostgresURI*: string + BandwidthStatsEnabled*: bool + + BridgeConfig* = object + Enabled*: bool + + WalletConfig* = object + Enabled*: bool + + LocalNotificationsConfig* = object + Enabled*: bool + + BrowsersConfig* = object + Enabled*: bool + + PermissionsConfig* = object + Enabled*: bool + + MailserversConfig* = object + Enabled*: bool + + SwarmConfig* = object + Enabled*: bool + + Whisper* = object + Min*: int + Max*: int + + RequireTopics* = object + whisper*: Whisper + + PushNotificationServerConfig* = object + Enabled*: bool + Identity*: seq[string] # not sure about the type, but we don't use it, so doesn't matter + GorushURL*: string + Logger*: seq[string] # not sure about the type, but we don't use it, so doesn't matter + +type + NodeConfigDto* = object + NetworkId*: int + DataDir*: string + KeyStoreDir*: string + NodeKey*: string + NoDiscovery*: bool + Rendezvous*: bool + ListenAddr*: string + AdvertiseAddr*: string + Name*: string + Version*: string + APIModules*: string + HTTPEnabled*: bool + HTTPHost*: string + HTTPPort*: int + HTTPVirtualHosts*: string + HTTPCors*: string + IPCEnabled*: bool + IPCFile*: string + TLSenabled*: bool + MaxPeers*: int + MaxPendingPeers*: int + LogEnabled*: bool + LogMobileSystem*: bool + LogDir*: string + LogFile*: string + LogLevel*: string + LogMaxBackups*: int + LogMaxSize*: int + LogCompressRotated*: bool + LogToStderr*: bool + EnableStatusService*: bool + EnableNTPSync*: bool + UpstreamConfig*: UpstreamConfig + Networks*: seq[Network] + ClusterConfig*: ClusterConfig + LightEthConfig*: LightEthConfig + WakuConfig*: WakuConfig + WakuV2Config*: WakuConfig + BridgeConfig*: BridgeConfig + ShhextConfig*: ShhextConfig + WalletConfig*: WalletConfig + LocalNotificationsConfig*: LocalNotificationsConfig + BrowsersConfig*: BrowsersConfig + PermissionsConfig*: PermissionsConfig + MailserversConfig*: MailserversConfig + SwarmConfig*: SwarmConfig + RegisterTopics*: seq[string] + RequireTopics*: RequireTopics + MailServerRegistryAddress*: string + PushNotificationServerConfig*: PushNotificationServerConfig # not used in the app yet + +proc toUpstreamConfig*(jsonObj: JsonNode): UpstreamConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("URL", result.URL) + +proc toNetwork*(jsonObj: JsonNode): Network = + discard jsonObj.getProp("chainId", result.chainId) + discard jsonObj.getProp("chainName", result.chainName) + discard jsonObj.getProp("rpcUrl", result.rpcUrl) + discard jsonObj.getProp("blockExplorerUrl", result.blockExplorerUrl) + discard jsonObj.getProp("nativeCurrencyName", result.nativeCurrencyName) + discard jsonObj.getProp("nativeCurrencySymbol", result.nativeCurrencySymbol) + discard jsonObj.getProp("nativeCurrencyDecimals", result.nativeCurrencyDecimals) + discard jsonObj.getProp("isTest", result.isTest) + discard jsonObj.getProp("layer", result.layer) + discard jsonObj.getProp("enabled", result.enabled) + +proc toClusterConfig*(jsonObj: JsonNode): ClusterConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("Fleet", result.Fleet) + + var arr: JsonNode + if(jsonObj.getProp("StaticNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.StaticNodes.add(valueObj.getStr) + + if(jsonObj.getProp("BootNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.BootNodes.add(valueObj.getStr) + + if(jsonObj.getProp("TrustedMailServers", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.TrustedMailServers.add(valueObj.getStr) + + if(jsonObj.getProp("PushNotificationsServers", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.PushNotificationsServers.add(valueObj.getStr) + + if(jsonObj.getProp("RendezvousNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.RendezvousNodes.add(valueObj.getStr) + + if(jsonObj.getProp("RelayNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.RelayNodes.add(valueObj.getStr) + + if(jsonObj.getProp("StoreNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.StoreNodes.add(valueObj.getStr) + + if(jsonObj.getProp("FilterNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.FilterNodes.add(valueObj.getStr) + + if(jsonObj.getProp("LightpushNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.LightpushNodes.add(valueObj.getStr) + + if(jsonObj.getProp("WakuRendezvousNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.WakuRendezvousNodes.add(valueObj.getStr) + +proc toLightEthConfig*(jsonObj: JsonNode): LightEthConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("DatabaseCache", result.DatabaseCache) + discard jsonObj.getProp("MinTrustedFraction", result.MinTrustedFraction) + + var arr: JsonNode + if(jsonObj.getProp("TrustedNodes", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.TrustedNodes.add(valueObj.getStr) + +proc toPGConfig*(jsonObj: JsonNode): PGConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("URI", result.URI) + +proc toDatabaseConfig*(jsonObj: JsonNode): DatabaseConfig = + var pgConfigObj: JsonNode + if(jsonObj.getProp("PGConfig", pgConfigObj)): + result.PGConfig = toPGConfig(pgConfigObj) + +proc toWakuConfig*(jsonObj: JsonNode): WakuConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("LightClient", result.LightClient) + discard jsonObj.getProp("FullNode", result.FullNode) + discard jsonObj.getProp("EnableMailServer", result.EnableMailServer) + discard jsonObj.getProp("DataDir", result.DataDir) + discard jsonObj.getProp("MinimumPoW", result.MinimumPoW) + discard jsonObj.getProp("MailServerPassword", result.MailServerPassword) + discard jsonObj.getProp("MailServerRateLimit", result.MailServerRateLimit) + discard jsonObj.getProp("MailServerDataRetention", result.MailServerDataRetention) + discard jsonObj.getProp("TTL", result.TTL) + discard jsonObj.getProp("MaxMessageSize", result.MaxMessageSize) + discard jsonObj.getProp("EnableRateLimiter", result.EnableRateLimiter) + discard jsonObj.getProp("PacketRateLimitIP", result.PacketRateLimitIP) + discard jsonObj.getProp("PacketRateLimitPeerID", result.PacketRateLimitPeerID) + discard jsonObj.getProp("BytesRateLimitIP", result.BytesRateLimitIP) + discard jsonObj.getProp("BytesRateLimitPeerID", result.BytesRateLimitPeerID) + discard jsonObj.getProp("RateLimitTolerance", result.RateLimitTolerance) + discard jsonObj.getProp("BloomFilterMode", result.BloomFilterMode) + discard jsonObj.getProp("EnableConfirmations", result.EnableConfirmations) + discard jsonObj.getProp("DiscoveryLimit", result.DiscoveryLimit) + discard jsonObj.getProp("Rendezvous", result.Rendezvous) + + var databaseConfigObj: JsonNode + if(jsonObj.getProp("DatabaseConfig", databaseConfigObj)): + result.DatabaseConfig = toDatabaseConfig(databaseConfigObj) + + var arr: JsonNode + if(jsonObj.getProp("SoftBlacklistedPeerIDs", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.SoftBlacklistedPeerIDs.add(valueObj.getStr) + +proc toShhextConfig*(jsonObj: JsonNode): ShhextConfig = + discard jsonObj.getProp("PFSEnabled", result.PFSEnabled) + discard jsonObj.getProp("BackupDisabledDataDir", result.BackupDisabledDataDir) + discard jsonObj.getProp("InstallationID", result.InstallationID) + discard jsonObj.getProp("MailServerConfirmations", result.MailServerConfirmations) + discard jsonObj.getProp("EnableConnectionManager", result.EnableConnectionManager) + discard jsonObj.getProp("EnableLastUsedMonitor", result.EnableLastUsedMonitor) + discard jsonObj.getProp("ConnectionTarget", result.ConnectionTarget) + discard jsonObj.getProp("RequestsDelay", result.RequestsDelay) + discard jsonObj.getProp("MaxServerFailures", result.MaxServerFailures) + discard jsonObj.getProp("MaxMessageDeliveryAttempts", result.MaxMessageDeliveryAttempts) + discard jsonObj.getProp("WhisperCacheDir", result.WhisperCacheDir) + discard jsonObj.getProp("DisableGenericDiscoveryTopic", result.DisableGenericDiscoveryTopic) + discard jsonObj.getProp("SendV1Messages", result.SendV1Messages) + discard jsonObj.getProp("DataSyncEnabled", result.DataSyncEnabled) + discard jsonObj.getProp("VerifyTransactionURL", result.VerifyTransactionURL) + discard jsonObj.getProp("VerifyENSURL", result.VerifyENSURL) + discard jsonObj.getProp("VerifyENSContractAddress", result.VerifyENSContractAddress) + discard jsonObj.getProp("VerifyTransactionChainID", result.VerifyTransactionChainID) + discard jsonObj.getProp("AnonMetricsSendID", result.AnonMetricsSendID) + discard jsonObj.getProp("AnonMetricsServerEnabled", result.AnonMetricsServerEnabled) + discard jsonObj.getProp("AnonMetricsServerPostgresURI", result.AnonMetricsServerPostgresURI) + discard jsonObj.getProp("BandwidthStatsEnabled", result.BandwidthStatsEnabled) + + var arr: JsonNode + if(jsonObj.getProp("DefaultPushNotificationsServers", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.DefaultPushNotificationsServers.add(valueObj.getStr) + +proc toBridgeConfig*(jsonObj: JsonNode): BridgeConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toWalletConfig*(jsonObj: JsonNode): WalletConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toLocalNotificationsConfig*(jsonObj: JsonNode): LocalNotificationsConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toBrowsersConfig*(jsonObj: JsonNode): BrowsersConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toPermissionsConfig*(jsonObj: JsonNode): PermissionsConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toMailserversConfig*(jsonObj: JsonNode): MailserversConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toSwarmConfig*(jsonObj: JsonNode): SwarmConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + +proc toWhisper*(jsonObj: JsonNode): Whisper = + discard jsonObj.getProp("Min", result.Min) + discard jsonObj.getProp("Max", result.Max) + +proc toRequireTopics*(jsonObj: JsonNode): RequireTopics = + var whisperObj: JsonNode + if(jsonObj.getProp("whisper", whisperObj)): + result.whisper = toWhisper(whisperObj) + +proc toPushNotificationServerConfig*(jsonObj: JsonNode): PushNotificationServerConfig = + discard jsonObj.getProp("Enabled", result.Enabled) + discard jsonObj.getProp("GorushURL", result.GorushURL) + + var arr: JsonNode + if(jsonObj.getProp("Identity", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.Identity.add(valueObj.getStr) + + if(jsonObj.getProp("Logger", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.Logger.add(valueObj.getStr) + +proc toNodeConfigDto*(jsonObj: JsonNode): NodeConfigDto = + discard jsonObj.getProp("NetworkId", result.NetworkId) + discard jsonObj.getProp("DataDir", result.DataDir) + discard jsonObj.getProp("KeyStoreDir", result.KeyStoreDir) + discard jsonObj.getProp("NodeKey", result.NodeKey) + discard jsonObj.getProp("NoDiscovery", result.NoDiscovery) + discard jsonObj.getProp("Rendezvous", result.Rendezvous) + discard jsonObj.getProp("ListenAddr", result.ListenAddr) + discard jsonObj.getProp("AdvertiseAddr", result.AdvertiseAddr) + discard jsonObj.getProp("Name", result.Name) + discard jsonObj.getProp("Version", result.Version) + discard jsonObj.getProp("APIModules", result.APIModules) + discard jsonObj.getProp("HTTPEnabled", result.HTTPEnabled) + discard jsonObj.getProp("HTTPHost", result.HTTPHost) + discard jsonObj.getProp("HTTPPort", result.HTTPPort) + discard jsonObj.getProp("HTTPVirtualHosts", result.HTTPVirtualHosts) + discard jsonObj.getProp("HTTPCors", result.HTTPCors) + discard jsonObj.getProp("IPCEnabled", result.IPCEnabled) + discard jsonObj.getProp("IPCFile", result.IPCFile) + discard jsonObj.getProp("TLSEnabled", result.TLSEnabled) + discard jsonObj.getProp("MaxPeers", result.MaxPeers) + discard jsonObj.getProp("MaxPendingPeers", result.MaxPendingPeers) + discard jsonObj.getProp("LogEnabled", result.LogEnabled) + discard jsonObj.getProp("LogMobileSystem", result.LogMobileSystem) + discard jsonObj.getProp("LogDir", result.LogDir) + discard jsonObj.getProp("LogFile", result.LogFile) + discard jsonObj.getProp("LogLevel", result.LogLevel) + discard jsonObj.getProp("LogMaxBackups", result.LogMaxBackups) + discard jsonObj.getProp("LogMaxSize", result.LogMaxSize) + discard jsonObj.getProp("LogCompressRotated", result.LogCompressRotated) + discard jsonObj.getProp("LogToStderr", result.LogToStderr) + discard jsonObj.getProp("EnableStatusService", result.EnableStatusService) + discard jsonObj.getProp("EnableNTPSync", result.EnableNTPSync) + discard jsonObj.getProp("MailServerRegistryAddress", result.MailServerRegistryAddress) + + var upstreamConfigObj: JsonNode + if(jsonObj.getProp("UpstreamConfig", upstreamConfigObj)): + result.UpstreamConfig = toUpstreamConfig(upstreamConfigObj) + + var networksArr: JsonNode + if(jsonObj.getProp("Networks", networksArr)): + if(networksArr.kind == JArray): + for networkObj in networksArr: + result.Networks.add(toNetwork(networkObj)) + + var clusterConfigObj: JsonNode + if(jsonObj.getProp("ClusterConfig", clusterConfigObj)): + result.ClusterConfig = toClusterConfig(clusterConfigObj) + + var lightEthConfigObj: JsonNode + if(jsonObj.getProp("ClusterConfig", lightEthConfigObj)): + result.LightEthConfig = toLightEthConfig(lightEthConfigObj) + + var wakuConfigObj: JsonNode + if(jsonObj.getProp("WakuConfig", wakuConfigObj)): + result.WakuConfig = toWakuConfig(wakuConfigObj) + + var wakuV2ConfigObj: JsonNode + if(jsonObj.getProp("WakuV2Config", wakuV2ConfigObj)): + result.WakuV2Config = toWakuConfig(wakuV2ConfigObj) + + var shhextConfigObj: JsonNode + if(jsonObj.getProp("ShhextConfig", shhextConfigObj)): + result.ShhextConfig = toShhextConfig(shhextConfigObj) + + var bridgeConfigObj: JsonNode + if(jsonObj.getProp("BridgeConfig", bridgeConfigObj)): + result.BridgeConfig = toBridgeConfig(bridgeConfigObj) + + var walletConfigObj: JsonNode + if(jsonObj.getProp("WalletConfig", walletConfigObj)): + result.WalletConfig = toWalletConfig(walletConfigObj) + + var localNotificationsConfigObj: JsonNode + if(jsonObj.getProp("LocalNotificationsConfig", localNotificationsConfigObj)): + result.LocalNotificationsConfig = toLocalNotificationsConfig(localNotificationsConfigObj) + + var browsersConfigObj: JsonNode + if(jsonObj.getProp("BrowsersConfig", browsersConfigObj)): + result.BrowsersConfig = toBrowsersConfig(browsersConfigObj) + + var permissionsConfigObj: JsonNode + if(jsonObj.getProp("PermissionsConfig", permissionsConfigObj)): + result.PermissionsConfig = toPermissionsConfig(permissionsConfigObj) + + var mailserversConfigObj: JsonNode + if(jsonObj.getProp("MailserversConfig", mailserversConfigObj)): + result.MailserversConfig = toMailserversConfig(mailserversConfigObj) + + var swarmConfigObj: JsonNode + if(jsonObj.getProp("SwarmConfig", swarmConfigObj)): + result.SwarmConfig = toSwarmConfig(swarmConfigObj) + + var arr: JsonNode + if(jsonObj.getProp("RegisterTopics", arr)): + if(arr.kind == JArray): + for valueObj in arr: + result.RegisterTopics.add(valueObj.getStr) + + var requireTopicsObj: JsonNode + if(jsonObj.getProp("RequireTopics", requireTopicsObj)): + result.RequireTopics = toRequireTopics(requireTopicsObj) + + var pushNotificationServerConfigObj: JsonNode + if(jsonObj.getProp("PushNotificationServerConfig", pushNotificationServerConfigObj)): + result.PushNotificationServerConfig = toPushNotificationServerConfig(pushNotificationServerConfigObj) + +proc toJsonNode*(nodeConfigDto: NodeConfigDto): JsonNode = + let nodeConfigDtoAsString = $$nodeConfigDto + result = parseJson(nodeConfigDtoAsString) \ No newline at end of file diff --git a/src/app_service/service/node_configuration/service.nim b/src/app_service/service/node_configuration/service.nim new file mode 100644 index 0000000000..8a863bb2b4 --- /dev/null +++ b/src/app_service/service/node_configuration/service.nim @@ -0,0 +1,138 @@ +import chronicles, json, strutils + +import service_interface +import ./dto/node_config +import ../settings/service_interface as settings_service +import ../../../app/core/fleets/fleet_configuration +import status/statusgo_backend_new/node_config as status_node_config + +export service_interface + +logScope: + topics = "node-config-service" + +type + Service* = ref object of service_interface.ServiceInterface + configuration: NodeConfigDto + fleetConfiguration: FleetConfiguration + settingsService: settings_service.ServiceInterface + +method delete*(self: Service) = + discard + +proc newService*(fleetConfiguration: FleetConfiguration, settingsService: settings_service.ServiceInterface): Service = + result = Service() + result.fleetConfiguration = fleetConfiguration + result.settingsService = settingsService + +proc adaptNodeSettingsForTheAppNeed(self: Service) = + let currentNetworkDetails = self.settingsService.getCurrentNetworkDetails() + var dataDir = currentNetworkDetails.config.dataDir + dataDir.removeSuffix("_rpc") + + self.configuration.DataDir = dataDir + self.configuration.KeyStoreDir = "./keystore" + self.configuration.LogFile = "./geth.log" + self.configuration.ShhextConfig.BackupDisabledDataDir = "./" + +method init*(self: Service) = + try: + let response = status_node_config.getNodeConfig() + self.configuration = response.result.toNodeConfigDto() + + self.adaptNodeSettingsForTheAppNeed() + except Exception as e: + let errDesription = e.msg + error "error: ", errDesription + return + +proc saveConfiguration(self: Service, configuration: NodeConfigDto) = + if(not self.settingsService.saveNodeConfiguration(configuration.toJsonNode())): + error "error saving node configuration " + return + self.configuration = configuration + +method getWakuVersion*(self: Service): int = + if self.configuration.WakuConfig.Enabled: + return WAKU_VERSION_1 + elif self.configuration.WakuV2Config.Enabled: + return WAKU_VERSION_2 + return 0 + +method setWakuVersion*(self: Service, wakuVersion: int) = + var newConfiguration = self.configuration + newConfiguration.RegisterTopics = @["whispermail"] + newConfiguration.WakuConfig.Enabled = wakuVersion == WAKU_VERSION_1 + newConfiguration.WakuV2Config.Enabled = wakuVersion == WAKU_VERSION_2 + + if wakuVersion == WAKU_VERSION_1: + newConfiguration.NoDiscovery = false + newConfiguration.Rendezvous = true + elif wakuVersion == WAKU_VERSION_2: + newConfiguration.NoDiscovery = true + newConfiguration.Rendezvous = false + newConfiguration.WakuV2Config.DiscoveryLimit = 20 + newConfiguration.WakuV2Config.Rendezvous = true + self.saveConfiguration(newConfiguration) + +method setNetwork*(self: Service, network: string) = + if(not self.settingsService.saveCurrentNetwork(network)): + error "error saving network ", network, methodName="setNetwork" + return + + let currentNetworkDetails = self.settingsService.getCurrentNetworkDetails() + var dataDir = currentNetworkDetails.config.dataDir + dataDir.removeSuffix("_rpc") + + var newConfiguration = self.configuration + newConfiguration.NetworkId = currentNetworkDetails.config.networkId + newConfiguration.DataDir = dataDir + newConfiguration.UpstreamConfig.Enabled = currentNetworkDetails.config.upstreamConfig.enabled + newConfiguration.UpstreamConfig.URL = currentNetworkDetails.config.upstreamConfig.url + self.saveConfiguration(newConfiguration) + +method setBloomFilterMode*(self: Service, bloomFilterMode: bool) = + if(not self.settingsService.saveWakuBloomFilterMode(bloomFilterMode)): + error "error saving waku bloom filter mode ", methodName="setBloomFilterMode" + return + + var newConfiguration = self.configuration + newConfiguration.WakuConfig.BloomFilterMode = bloomFilterMode + self.saveConfiguration(newConfiguration) + +method setBloomLevel*(self: Service, bloomFilterMode: bool, fullNode: bool) = + if(not self.settingsService.saveWakuBloomFilterMode(bloomFilterMode)): + error "error saving waku bloom filter mode ", methodName="setBloomLevel" + return + + var newConfiguration = self.configuration + newConfiguration.WakuConfig.BloomFilterMode = bloomFilterMode + newConfiguration.WakuConfig.FullNode = fullNode + newConfiguration.WakuConfig.LightClient = not fullNode + self.saveConfiguration(newConfiguration) + +method setFleet*(self: Service, fleet: string) = + if(not self.settingsService.saveFleet(fleet)): + error "error saving fleet ", methodName="setFleet" + return + + let fleetType = parseEnum[Fleet](fleet) + var newConfiguration = self.configuration + newConfiguration.ClusterConfig.Fleet = fleet + newConfiguration.ClusterConfig.BootNodes = self.fleetConfiguration.getNodes(fleetType, FleetNodes.Bootnodes) + newConfiguration.ClusterConfig.TrustedMailServers = self.fleetConfiguration.getNodes(fleetType, FleetNodes.Mailservers) + newConfiguration.ClusterConfig.StaticNodes = self.fleetConfiguration.getNodes(fleetType, FleetNodes.Whisper) + newConfiguration.ClusterConfig.RendezvousNodes = self.fleetConfiguration.getNodes(fleetType, FleetNodes.Rendezvous) + newConfiguration.ClusterConfig.RelayNodes = @["enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"] + newConfiguration.ClusterConfig.StoreNodes = @["enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"] + newConfiguration.ClusterConfig.FilterNodes = @["enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"] + newConfiguration.ClusterConfig.LightpushNodes = @["enrtree://AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C@test.nodes.vac.dev"] + #TODO: in the meantime we're using the go-waku test fleet for rendezvous. + # once we have a prod fleet this code needs to be updated + newConfiguration.ClusterConfig.WakuRendezvousNodes = self.fleetConfiguration.getNodes(Fleet.GoWakuTest, FleetNodes.LibP2P) + self.saveConfiguration(newConfiguration) + +method setV2LightMode*(self: Service, enabled: bool) = + var newConfiguration = self.configuration + newConfiguration.WakuV2Config.LightClient = enabled + self.saveConfiguration(newConfiguration) diff --git a/src/app_service/service/node_configuration/service_interface.nim b/src/app_service/service/node_configuration/service_interface.nim new file mode 100644 index 0000000000..04bc0bf869 --- /dev/null +++ b/src/app_service/service/node_configuration/service_interface.nim @@ -0,0 +1,37 @@ +import ./dto/node_config + +export node_config + +const WAKU_VERSION_1* = 1 +const WAKU_VERSION_2* = 2 + +type + ServiceInterface* {.pure inheritable.} = ref object of RootObj + ## Abstract class for this service access. + +method delete*(self: ServiceInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method init*(self: ServiceInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method getWakuVersion*(self: ServiceInterface): int {.base.} = + raise newException(ValueError, "No implementation available") + +method setWakuVersion*(self: ServiceInterface, wakuVersion: int) {.base.} = + raise newException(ValueError, "No implementation available") + +method setNetwork*(self: ServiceInterface, network: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method setBloomFilterMode*(self: ServiceInterface, bloomFilterMode: bool) {.base.} = + raise newException(ValueError, "No implementation available") + +method setBloomLevel*(self: ServiceInterface, bloomFilterMode: bool, fullNode: bool) {.base.} = + raise newException(ValueError, "No implementation available") + +method setFleet*(self: ServiceInterface, fleet: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method setV2LightMode*(self: ServiceInterface, enabled: bool) {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app_service/service/settings/dto/settings.nim b/src/app_service/service/settings/dto/settings.nim index 0884445831..86369c69d3 100644 --- a/src/app_service/service/settings/dto/settings.nim +++ b/src/app_service/service/settings/dto/settings.nim @@ -60,6 +60,8 @@ type fleet*: string currentUserStatus*: CurrentUserStatus walletVisibleTokens*: WalletVisibleTokens + nodeConfig*: JsonNode + wakuBloomFilterMode*: bool proc toUpstreamConfig*(jsonObj: JsonNode): UpstreamConfig = discard jsonObj.getProp("Enabled", result.enabled) @@ -145,3 +147,6 @@ proc toSettingsDto*(jsonObj: JsonNode): SettingsDto = var walletVisibleTokensObj: JsonNode if(jsonObj.getProp("wallet/visible-tokens", walletVisibleTokensObj)): result.walletVisibleTokens = toWalletVisibleTokens(walletVisibleTokensObj, result.currentNetwork) + + discard jsonObj.getProp("node-config", result.nodeConfig) + discard jsonObj.getProp("waku-bloom-filter-mode", result.wakuBloomFilterMode) diff --git a/src/app_service/service/settings/service.nim b/src/app_service/service/settings/service.nim index e6b5ec7dd1..2f6eacb589 100644 --- a/src/app_service/service/settings/service.nim +++ b/src/app_service/service/settings/service.nim @@ -36,6 +36,8 @@ const KEY_SEND_STATUS_UPDATES = "send-status-updates?" const KEY_TELEMETRY_SERVER_URL = "telemetry-server-url" const KEY_FLEET = "fleet" const KEY_WALLET_VISIBLE_TOKENS = "wallet/visible-tokens" +const KEY_NODE_CONFIG = "node-config" +const KEY_WAKU_BLOOM_FILTER_MODE = "waku-bloom-filter-mode" type Service* = ref object of service_interface.ServiceInterface @@ -366,3 +368,15 @@ method saveWalletVisibleTokens*(self: Service, tokens: seq[string]): bool = self.settings.walletVisibleTokens.tokens = tokens return true return false + +method saveNodeConfiguration*(self: Service, value: JsonNode): bool = + if(self.saveSetting(KEY_NODE_CONFIG, value)): + self.settings.nodeConfig = value + return true + return false + +method saveWakuBloomFilterMode*(self: Service, value: bool): bool = + if(self.saveSetting(KEY_WAKU_BLOOM_FILTER_MODE, value)): + self.settings.wakuBloomFilterMode = value + return true + return false \ No newline at end of file diff --git a/src/app_service/service/settings/service_interface.nim b/src/app_service/service/settings/service_interface.nim index 6fa3faa4e0..1c88a089be 100644 --- a/src/app_service/service/settings/service_interface.nim +++ b/src/app_service/service/settings/service_interface.nim @@ -1,3 +1,4 @@ +import json import ./dto/settings as settings_dto export settings_dto @@ -201,4 +202,10 @@ method getWalletVisibleTokens*(self: ServiceInterface): seq[string] {.base.} = raise newException(ValueError, "No implementation available") method saveWalletVisibleTokens*(self: ServiceInterface, tokens: seq[string]): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method saveNodeConfiguration*(self: ServiceInterface, value: JsonNode): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method saveWakuBloomFilterMode*(self: ServiceInterface, value: bool): bool {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file