231 lines
9.3 KiB
Nim
231 lines
9.3 KiB
Nim
import
|
|
json, tables, sugar, sequtils, strutils, atomics, os
|
|
|
|
import
|
|
json_serialization, chronicles, uuids
|
|
from status_go import nil
|
|
|
|
import
|
|
./core, ./accounts/constants, ../utils
|
|
|
|
import ../types/[setting, network_type, fleet, rpc_response]
|
|
|
|
var
|
|
settings {.threadvar.}: JsonNode
|
|
settingsInited {.threadvar.}: bool
|
|
dirty: Atomic[bool]
|
|
|
|
dirty.store(true)
|
|
settings = %* {}
|
|
|
|
proc saveSetting*(key: Setting, value: string | JsonNode | bool): StatusGoError =
|
|
try:
|
|
let response = callPrivateRPC("settings_saveSetting", %* [key, value])
|
|
let responseResult = $(response.parseJSON(){"result"})
|
|
if responseResult == "null":
|
|
result.error = ""
|
|
else: result = Json.decode(response, StatusGoError)
|
|
dirty.store(true)
|
|
except Exception as e:
|
|
error "Error saving setting", key=key, value=value, msg=e.msg
|
|
|
|
proc getSettings*(useCached: bool = true, keepSensitiveData: bool = false): JsonNode =
|
|
let cacheIsDirty = (not settingsInited) or dirty.load
|
|
if useCached and (not cacheIsDirty) and (not keepSensitiveData):
|
|
result = settings
|
|
else:
|
|
var
|
|
allSettings = callPrivateRPC("settings_getSettings").parseJSON()["result"]
|
|
var
|
|
noSensitiveData = allSettings.deepCopy
|
|
noSensitiveData.delete("mnemonic")
|
|
if not keepSensitiveData:
|
|
result = noSensitiveData
|
|
else:
|
|
result = allSettings
|
|
dirty.store(false)
|
|
settings = noSensitiveData # never include sensitive data in cache
|
|
settingsInited = true
|
|
|
|
proc getSetting*[T](name: Setting, defaultValue: T, useCached: bool = true): T =
|
|
let settings: JsonNode = getSettings(useCached, $name == "mnemonic")
|
|
if not settings.contains($name) or settings{$name}.isEmpty():
|
|
return defaultValue
|
|
let value = $settings{$name}
|
|
try:
|
|
result = Json.decode(value, T)
|
|
except Exception as e:
|
|
error "Error decoding setting", name=name, value=value, msg=e.msg
|
|
return defaultValue
|
|
|
|
proc getSetting*[T](name: Setting, useCached: bool = true): T =
|
|
result = getSetting(name, default(type(T)), useCached)
|
|
|
|
proc getWeb3ClientVersion*(): string =
|
|
parseJson(callPrivateRPC("web3_clientVersion"))["result"].getStr
|
|
|
|
proc getCurrentNetwork*(): NetworkType =
|
|
case getSetting[string](Setting.Networks_CurrentNetwork, constants.DEFAULT_NETWORK_NAME):
|
|
of "mainnet_rpc":
|
|
result = NetworkType.Mainnet
|
|
of "testnet_rpc":
|
|
result = NetworkType.Testnet
|
|
of "rinkeby_rpc":
|
|
result = NetworkType.Rinkeby
|
|
of "goerli_rpc":
|
|
result = NetworkType.Goerli
|
|
of "xdai_rpc":
|
|
result = NetworkType.XDai
|
|
of "poa_rpc":
|
|
result = NetworkType.Poa
|
|
else:
|
|
result = NetworkType.Other
|
|
|
|
proc getCurrentNetworkDetails*(): NetworkDetails =
|
|
let currNetwork = getSetting[string](Setting.Networks_CurrentNetwork, constants.DEFAULT_NETWORK_NAME)
|
|
let networks = getSetting[seq[NetworkDetails]](Setting.Networks_Networks)
|
|
networks.find((network: NetworkDetails) => network.id == currNetwork)
|
|
|
|
proc getLinkPreviewWhitelist*(): JsonNode =
|
|
result = callPrivateRPC("getLinkPreviewWhitelist".prefix, %* []).parseJSON()["result"]
|
|
|
|
proc getFleet*(): Fleet =
|
|
let fleet = getSetting[string](Setting.Fleet, $Fleet.PROD)
|
|
result = parseEnum[Fleet](fleet)
|
|
|
|
proc getPinnedMailserver*(): string =
|
|
let pinnedMailservers = getSetting[JsonNode](Setting.PinnedMailservers, %*{})
|
|
let fleet = getSetting[string](Setting.Fleet, $Fleet.PROD)
|
|
result = pinnedMailservers{fleet}.getStr()
|
|
info "getPinnedMailserver", topics="mailserver-interaction", fleet, result
|
|
|
|
proc pinMailserver*(enode: string = "") =
|
|
let pinnedMailservers = getSetting[JsonNode](Setting.PinnedMailservers, %*{})
|
|
let fleet = getSetting[string](Setting.Fleet, $Fleet.PROD)
|
|
|
|
pinnedMailservers[fleet] = newJString(enode)
|
|
let response = saveSetting(Setting.PinnedMailservers, pinnedMailservers)
|
|
info "pinMailserver", topics="mailserver-interaction", enode, response
|
|
|
|
proc saveMailserver*(name, enode: string) =
|
|
let fleet = getSetting[string](Setting.Fleet, $Fleet.PROD)
|
|
let id = $genUUID()
|
|
let response = callPrivateRPC("mailservers_addMailserver", %* [
|
|
%*{
|
|
"id": id,
|
|
"name": name,
|
|
"address": enode,
|
|
"fleet": $fleet
|
|
}
|
|
])
|
|
let result = response.parseJSON()["result"]
|
|
info "saveMailserver", topics="mailserver-interaction", rpc_method="mailservers_addMailserver", id, name, enode, fleet, response
|
|
|
|
proc getMailservers*(): JsonNode =
|
|
let response = callPrivateRPC("mailservers_getMailservers")
|
|
result = response.parseJSON()["result"]
|
|
info "getMailservers", topics="mailserver-interaction", rpc_method="mailservers_getMailservers", response
|
|
|
|
proc getNodeConfig*(): JsonNode =
|
|
result = status_go.getNodeConfig().parseJSON()
|
|
|
|
# setting correct values in json
|
|
let currNetwork = getSetting[string](Setting.Networks_CurrentNetwork, constants.DEFAULT_NETWORK_NAME)
|
|
let networks = getSetting[JsonNode](Setting.Networks_Networks)
|
|
let networkConfig = networks.getElems().find((n:JsonNode) => n["id"].getStr() == currNetwork)
|
|
var newDataDir = networkConfig["config"]["DataDir"].getStr
|
|
newDataDir.removeSuffix("_rpc")
|
|
result["DataDir"] = newDataDir.newJString()
|
|
result["KeyStoreDir"] = newJString("./keystore")
|
|
result["LogFile"] = newJString("./geth.log")
|
|
result["ShhextConfig"]["BackupDisabledDataDir"] = newJString("./")
|
|
|
|
proc getWakuVersion*():int =
|
|
let nodeConfig = getNodeConfig()
|
|
if nodeConfig["WakuConfig"]["Enabled"].getBool():
|
|
return 1
|
|
if nodeConfig["WakuV2Config"]["Enabled"].getBool():
|
|
return 2
|
|
return 0
|
|
|
|
proc setWakuVersion*(newVersion: int) =
|
|
let nodeConfig = getNodeConfig()
|
|
nodeConfig["RegisterTopics"] = %* @["whispermail"]
|
|
if newVersion == 1:
|
|
nodeConfig["WakuConfig"]["Enabled"] = newJBool(true)
|
|
nodeConfig["WakuV2Config"]["Enabled"] = newJBool(false)
|
|
nodeConfig["NoDiscovery"] = newJBool(false)
|
|
nodeConfig["Rendezvous"] = newJBool(true)
|
|
else:
|
|
nodeConfig["WakuConfig"]["Enabled"] = newJBool(false)
|
|
nodeConfig["WakuV2Config"]["Enabled"] = newJBool(true)
|
|
nodeConfig["WakuV2Config"]["DiscoveryLimit"] = newJInt(20)
|
|
nodeConfig["NoDiscovery"] = newJBool(true)
|
|
nodeConfig["Rendezvous"] = newJBool(false)
|
|
nodeConfig["WakuV2Config"]["Rendezvous"] = newJBool(true)
|
|
discard saveSetting(Setting.NodeConfig, nodeConfig)
|
|
|
|
proc setNetwork*(network: string): StatusGoError =
|
|
let statusGoResult = saveSetting(Setting.Networks_CurrentNetwork, network)
|
|
if statusGoResult.error != "":
|
|
return statusGoResult
|
|
|
|
let networks = getSetting[JsonNode](Setting.Networks_Networks)
|
|
let networkConfig = networks.getElems().find((n:JsonNode) => n["id"].getStr() == network)
|
|
|
|
var nodeConfig = getNodeConfig()
|
|
let upstreamUrl = networkConfig["config"]["UpstreamConfig"]["URL"]
|
|
var newDataDir = networkConfig["config"]["DataDir"].getStr
|
|
newDataDir.removeSuffix("_rpc")
|
|
|
|
nodeConfig["NetworkId"] = networkConfig["config"]["NetworkId"]
|
|
nodeConfig["DataDir"] = newDataDir.newJString()
|
|
nodeConfig["UpstreamConfig"]["Enabled"] = networkConfig["config"]["UpstreamConfig"]["Enabled"]
|
|
nodeConfig["UpstreamConfig"]["URL"] = upstreamUrl
|
|
|
|
return saveSetting(Setting.NodeConfig, nodeConfig)
|
|
|
|
proc setBloomFilterMode*(bloomFilterMode: bool): StatusGoError =
|
|
let statusGoResult = saveSetting(Setting.WakuBloomFilterMode, bloomFilterMode)
|
|
if statusGoResult.error != "":
|
|
return statusGoResult
|
|
var nodeConfig = getNodeConfig()
|
|
nodeConfig["WakuConfig"]["BloomFilterMode"] = newJBool(bloomFilterMode)
|
|
return saveSetting(Setting.NodeConfig, nodeConfig)
|
|
|
|
proc setBloomLevel*(bloomFilterMode: bool, fullNode: bool): StatusGoError =
|
|
let statusGoResult = saveSetting(Setting.WakuBloomFilterMode, bloomFilterMode)
|
|
if statusGoResult.error != "":
|
|
return statusGoResult
|
|
var nodeConfig = getNodeConfig()
|
|
nodeConfig["WakuConfig"]["BloomFilterMode"] = newJBool(bloomFilterMode)
|
|
nodeConfig["WakuConfig"]["FullNode"] = newJBool(fullNode)
|
|
nodeConfig["WakuConfig"]["LightClient"] = newJBool(not fullNode)
|
|
return saveSetting(Setting.NodeConfig, nodeConfig)
|
|
|
|
proc setFleet*(fleetConfig: FleetConfig, fleet: Fleet): StatusGoError =
|
|
let statusGoResult = saveSetting(Setting.Fleet, $fleet)
|
|
if statusGoResult.error != "":
|
|
return statusGoResult
|
|
var nodeConfig = getNodeConfig()
|
|
nodeConfig["ClusterConfig"]["Fleet"] = newJString($fleet)
|
|
nodeConfig["ClusterConfig"]["BootNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Bootnodes)
|
|
nodeConfig["ClusterConfig"]["TrustedMailServers"] = %* fleetConfig.getNodes(fleet, FleetNodes.Mailservers)
|
|
nodeConfig["ClusterConfig"]["StaticNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Whisper)
|
|
nodeConfig["ClusterConfig"]["RendezvousNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Rendezvous)
|
|
nodeConfig["ClusterConfig"]["RelayNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Waku)
|
|
nodeConfig["ClusterConfig"]["StoreNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Waku)
|
|
nodeConfig["ClusterConfig"]["FilterNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Waku)
|
|
nodeConfig["ClusterConfig"]["LightpushNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Waku)
|
|
|
|
#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
|
|
nodeConfig["ClusterConfig"]["WakuRendezvousNodes"] = %* fleetConfig.getNodes(Fleet.GoWakuTest, FleetNodes.LibP2P)
|
|
|
|
return saveSetting(Setting.NodeConfig, nodeConfig)
|
|
|
|
proc setV2LightMode*(enabled: bool): StatusGoError =
|
|
var nodeConfig = getNodeConfig()
|
|
nodeConfig["WakuV2Config"]["LightClient"] = newJBool(enabled)
|
|
return saveSetting(Setting.NodeConfig, nodeConfig)
|