From aec77b65df6e3c9f0a1603afb0429484d7bd0802 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 3 Nov 2020 15:42:55 -0400 Subject: [PATCH] feat: use fleets.json to set the node config --- .gitignore | 1 + Makefile | 10 ++++- src/app/onboarding/view.nim | 4 +- src/app/profile/view.nim | 2 +- src/nim_status_client.nim | 2 +- src/status/accounts.nim | 12 +++--- src/status/fleet.nim | 19 ++++++++++ src/status/libstatus/accounts.nim | 21 ++++++++--- src/status/libstatus/accounts/constants.nim | 25 +----------- src/status/libstatus/types.nim | 42 ++++++++++++++++++++- src/status/status.nim | 8 ++-- 11 files changed, 101 insertions(+), 45 deletions(-) create mode 100644 src/status/fleet.nim diff --git a/.gitignore b/.gitignore index 626215217b..993074e121 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ TODO resources.rcc resources.qrc status-react-translations/ +fleets.json diff --git a/Makefile b/Makefile index b4bcddc483..ead30a63c1 100644 --- a/Makefile +++ b/Makefile @@ -208,6 +208,11 @@ $(QRCODEGEN): | deps + cd vendor/QR-Code-generator/c && \ $(MAKE) $(QRCODEGEN_MAKE_PARAMS) +update-fleets: + curl -s https://fleets.status.im/ \ + | jq --indent 4 --sort-keys . \ + > fleets.json + rcc: echo -e $(BUILD_MSG) "resources.rcc" rm -f ./resources.rcc @@ -215,7 +220,7 @@ rcc: ./ui/generate-rcc.sh rcc --binary ui/resources.qrc -o ./resources.rcc -nim_status_client: | $(DOTHERSIDE) $(STATUSGO) $(QRCODEGEN) rcc deps +nim_status_client: | $(DOTHERSIDE) $(STATUSGO) $(QRCODEGEN) update-fleets rcc deps echo -e $(BUILD_MSG) "$@" && \ $(ENV_SCRIPT) nim c $(NIM_PARAMS) --passL:"-L$(STATUSGO_LIBDIR)" --passL:"-lstatus" $(NIM_EXTRA_PARAMS) --passL:"$(QRCODEGEN)" --passL:"-lm" src/nim_status_client.nim && \ [[ $$? = 0 ]] && \ @@ -251,6 +256,7 @@ $(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop cp status.svg tmp/linux/dist/status.svg cp status.svg tmp/linux/dist/usr/. cp -R resources.rcc tmp/linux/dist/usr/. + cp -R fleets.json tmp/linux/dist/usr/. mkdir -p tmp/linux/dist/usr/i18n cp ui/i18n/* tmp/linux/dist/usr/i18n @@ -289,6 +295,7 @@ $(STATUS_CLIENT_DMG): nim_status_client $(DMG_TOOL) cp status-icon.icns $(MACOS_OUTER_BUNDLE)/Contents/Resources/ cp status.svg $(MACOS_OUTER_BUNDLE)/Contents/ cp -R resources.rcc $(MACOS_OUTER_BUNDLE)/Contents/ + cp -R fleets.json $(MACOS_OUTER_BUNDLE)/Contents/ mkdir -p $(MACOS_OUTER_BUNDLE)/Contents/i18n cp ui/i18n/* $(MACOS_OUTER_BUNDLE)/Contents/i18n @@ -360,6 +367,7 @@ $(STATUS_CLIENT_ZIP): nim_status_client nim_windows_launcher $(NIM_WINDOWS_PREBU cp status.ico tmp/windows/dist/Status/resources/ cp status.svg tmp/windows/dist/Status/resources/ cp resources.rcc tmp/windows/dist/Status/resources/ + cp fleets.json tmp/windows/dist/Status/resources/ cp bin/nim_status_client.exe tmp/windows/dist/Status/bin/Status.exe cp bin/nim_windows_launcher.exe tmp/windows/dist/Status/Status.exe rcedit \ diff --git a/src/app/onboarding/view.nim b/src/app/onboarding/view.nim index 40332ac2ee..4273c7c077 100644 --- a/src/app/onboarding/view.nim +++ b/src/app/onboarding/view.nim @@ -67,7 +67,7 @@ QtObject: proc storeAccountAndLogin(self: OnboardingView, selectedAccountIndex: int, password: string): string {.slot.} = try: - result = self.status.accounts.storeAccountAndLogin(selectedAccountIndex, password).toJson + result = self.status.accounts.storeAccountAndLogin(self.status.fleet.config, selectedAccountIndex, password).toJson except: let e = getCurrentException() @@ -97,7 +97,7 @@ QtObject: proc storeDerivedAndLogin(self: OnboardingView, password: string): string {.slot.} = try: - result = self.status.accounts.storeDerivedAndLogin(self.currentAccount.account, password).toJson + result = self.status.accounts.storeDerivedAndLogin(self.status.fleet.config, self.currentAccount.account, password).toJson except StatusGoException as e: var msg = e.msg if e.msg.contains("account already exists"): diff --git a/src/app/profile/view.nim b/src/app/profile/view.nim index 29fbd8cca5..68250f998c 100644 --- a/src/app/profile/view.nim +++ b/src/app/profile/view.nim @@ -152,7 +152,7 @@ QtObject: proc setNetworkAndPersist*(self: ProfileView, network: string) {.slot.} = self.network = network self.networkChanged() - self.status.accounts.changeNetwork(network) + self.status.accounts.changeNetwork(self.status.fleet.config, network) quit(QuitSuccess) # quits the app TODO: change this to logout instead when supported QtProperty[QVariant] network: diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 6b450dd049..143c03cbbc 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -20,7 +20,7 @@ logScope: topics = "main" proc mainProc() = - let status = statuslib.newStatusInstance() + let status = statuslib.newStatusInstance(readFile(joinPath(getAppDir(), "../fleets.json"))) status.initNode() enableHDPI() diff --git a/src/status/accounts.nim b/src/status/accounts.nim index 73ede7c233..500e5303c8 100644 --- a/src/status/accounts.nim +++ b/src/status/accounts.nim @@ -30,12 +30,12 @@ proc login*(self: AccountModel, selectedAccountIndex: int, password: string): No let currentNodeAccount = self.nodeAccounts[selectedAccountIndex] result = status_accounts.login(currentNodeAccount, password) -proc storeAccountAndLogin*(self: AccountModel, selectedAccountIndex: int, password: string): Account = +proc storeAccountAndLogin*(self: AccountModel, fleetConfig: FleetConfig, selectedAccountIndex: int, password: string): Account = let generatedAccount: GeneratedAccount = self.generatedAddresses[selectedAccountIndex] - result = status_accounts.setupAccount(generatedAccount, password) + result = status_accounts.setupAccount(fleetConfig, generatedAccount, password) -proc storeDerivedAndLogin*(self: AccountModel, importedAccount: GeneratedAccount, password: string): Account = - result = status_accounts.setupAccount(importedAccount, password) +proc storeDerivedAndLogin*(self: AccountModel, fleetConfig: FleetConfig, importedAccount: GeneratedAccount, password: string): Account = + result = status_accounts.setupAccount(fleetConfig, importedAccount, password) proc importMnemonic*(self: AccountModel, mnemonic: string): GeneratedAccount = let importedAccount = status_accounts.multiAccountImportMnemonic(mnemonic) @@ -54,7 +54,7 @@ proc generateAlias*(publicKey: string): string = proc generateIdenticon*(publicKey: string): string = result = status_accounts.generateIdenticon(publicKey) -proc changeNetwork*(self: AccountModel, network: string) = +proc changeNetwork*(self: AccountModel, fleetConfig: FleetConfig, network: string) = # 1. update current network setting var statusGoResult = status_settings.saveSetting(Setting.Networks_CurrentNetwork, network) @@ -63,7 +63,7 @@ proc changeNetwork*(self: AccountModel, network: string) = # 2. update node config setting let installationId = status_settings.getSetting[string](Setting.InstallationId) - let updatedNodeConfig = status_accounts.getNodeConfig(installationId, network) + let updatedNodeConfig = status_accounts.getNodeConfig(fleetConfig, installationId, network) statusGoResult = status_settings.saveSetting(Setting.NodeConfig, updatedNodeConfig) if statusGoResult.error != "": error "Error saving updated node config", msg=statusGoResult.error diff --git a/src/status/fleet.nim b/src/status/fleet.nim new file mode 100644 index 0000000000..b4f2af6548 --- /dev/null +++ b/src/status/fleet.nim @@ -0,0 +1,19 @@ +import libstatus/core as status +import ../eventemitter +import tables +import json +import libstatus/types + +type + FleetModel* = ref object + events*: EventEmitter + config*: FleetConfig + +proc newFleetModel*(events: EventEmitter, fleetConfigJson: string): FleetModel = + result = FleetModel() + result.events = events + result.config = fleetConfigJson.toFleetConfig() + +proc delete*(self: FleetModel) = + discard + diff --git a/src/status/libstatus/accounts.nim b/src/status/libstatus/accounts.nim index 6fe1eb39a8..ea8e973a32 100644 --- a/src/status/libstatus/accounts.nim +++ b/src/status/libstatus/accounts.nim @@ -1,4 +1,4 @@ -import json, os, nimcrypto, uuids, json_serialization, chronicles, strutils +import json, os, nimcrypto, uuids, json_serialization, chronicles, strutils, sequtils, random, sugar from nim_status import multiAccountGenerateAndDeriveAddresses, generateAlias, identicon, saveAccountAndLogin, login, openAccounts import core @@ -11,25 +11,34 @@ import ../wallet/account proc getNetworkConfig(currentNetwork: string): JsonNode = result = constants.DEFAULT_NETWORKS.first("id", currentNetwork) -proc getNodeConfig*(installationId: string, currentNetwork: string = constants.DEFAULT_NETWORK_NAME): JsonNode = + +proc getNodeConfig*(fleetConfig: FleetConfig, installationId: string, currentNetwork: string = constants.DEFAULT_NETWORK_NAME, fleet: Fleet = Fleet.PROD): JsonNode = let networkConfig = getNetworkConfig(currentNetwork) let upstreamUrl = networkConfig["config"]["UpstreamConfig"]["URL"] var newDataDir = networkConfig["config"]["DataDir"].getStr newDataDir.removeSuffix("_rpc") - result = constants.NODE_CONFIG + + result = constants.NODE_CONFIG.copy() + result["ClusterConfig"]["BootNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Bootnodes) + result["ClusterConfig"]["TrustedMailServers"] = %* fleetConfig.getNodes(fleet, FleetNodes.Mailservers) + result["ClusterConfig"]["StaticNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Whisper) + result["ClusterConfig"]["RendezvousNodes"] = %* fleetConfig.getNodes(fleet, FleetNodes.Rendezvous) + result["Rendezvous"] = newJBool(fleetConfig.getNodes(fleet, FleetNodes.Rendezvous).len > 0) result["NetworkId"] = networkConfig["config"]["NetworkId"] result["DataDir"] = newDataDir.newJString() result["UpstreamConfig"]["Enabled"] = networkConfig["config"]["UpstreamConfig"]["Enabled"] result["UpstreamConfig"]["URL"] = upstreamUrl result["ShhextConfig"]["InstallationID"] = newJString(installationId) result["ListenAddr"] = if existsEnv("STATUS_PORT"): newJString("0.0.0.0:" & $getEnv("STATUS_PORT")) else: newJString("0.0.0.0:30305") - result = constants.NODE_CONFIG + proc hashPassword*(password: string): string = result = "0x" & $keccak_256.digest(password) proc getDefaultAccount*(): string = var response = callPrivateRPC("eth_accounts") + echo "========================== 2" + echo response result = parseJson(response)["result"][0].getStr() proc generateAddresses*(n = 5): seq[GeneratedAccount] = @@ -150,13 +159,13 @@ proc getAccountSettings*(account: GeneratedAccount, defaultNetworks: JsonNode, i "installation-id": installationId } -proc setupAccount*(account: GeneratedAccount, password: string): types.Account = +proc setupAccount*(fleetConfig: FleetConfig, account: GeneratedAccount, password: string): types.Account = try: let storeDerivedResult = storeDerivedAccounts(account, password) let accountData = getAccountData(account) let installationId = $genUUID() var settingsJSON = getAccountSettings(account, constants.DEFAULT_NETWORKS, installationId) - var nodeConfig = getNodeConfig(installationId) + var nodeConfig = getNodeConfig(fleetConfig, installationId) result = saveAccountAndLogin(account, $accountData, password, $nodeConfig, $settingsJSON) diff --git a/src/status/libstatus/accounts/constants.nim b/src/status/libstatus/accounts/constants.nim index 339ae44e90..8ba98eede2 100644 --- a/src/status/libstatus/accounts/constants.nim +++ b/src/status/libstatus/accounts/constants.nim @@ -100,31 +100,8 @@ var NODE_CONFIG* = %* { "Enabled": true }, "ClusterConfig": { - "BootNodes": [ - "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443", - "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443", - "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443", - "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443" - ], "Enabled": true, - "Fleet": "eth.prod", - "RendezvousNodes": [ - "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU", - "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf", - "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR" - ], - "StaticNodes": [ - "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443", - "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443" - ], - "TrustedMailServers": [ - "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443", - "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443", - "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443", - "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443", - "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443", - "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443" - ] + "Fleet": "eth.prod" }, "DataDir": "./ethereum/mainnet", "EnableNTPSync": true, diff --git a/src/status/libstatus/types.nim b/src/status/libstatus/types.nim index e860867d10..5e1985f115 100644 --- a/src/status/libstatus/types.nim +++ b/src/status/libstatus/types.nim @@ -1,4 +1,4 @@ -import json, options, typetraits +import json, options, typetraits, tables, sequtils import web3/ethtypes, json_serialization, stint import accounts/constants import ../../eventemitter @@ -189,3 +189,43 @@ type PendingTransactionType* {.pure.} = enum ReleaseENS = "ReleaseENS", BuyStickerPack = "BuyStickerPack" WalletTransfer = "WalletTransfer" + +type + Fleet* {.pure.} = enum + Prod = "eth.prod", + Staging = "eth.staging", + Test = "eth.test", + WakuV2Test = "wakuv2.test" + + FleetNodes* {.pure.} = enum + Bootnodes = "boot", + Mailservers = "mail", + Rendezvous = "rendezvous", + Whisper = "whisper", + Waku = "waku" + + FleetMeta* = object + hostname*: string + timestamp*: uint64 + + FleetConfig* = object + fleet*: Table[string, Table[string, Table[string, string]]] + meta*: FleetMeta + + +proc toFleetConfig*(jsonString: string): FleetConfig = + let fleetJson = jsonString.parseJSON + result.meta.hostname = fleetJson["meta"]["hostname"].getStr + result.meta.timestamp = fleetJson["meta"]["timestamp"].getBiggestInt.uint64 + result.fleet = initTable[string, Table[string, Table[string, string]]]() + + for fleet in fleetJson["fleets"].keys(): + result.fleet[fleet] = initTable[string, Table[string, string]]() + for nodes in fleetJson["fleets"][fleet].keys(): + result.fleet[fleet][nodes] = initTable[string, string]() + for server in fleetJson["fleets"][fleet][nodes].keys(): + result.fleet[fleet][nodes][server] = fleetJson["fleets"][fleet][nodes][server].getStr + + +proc getNodes*(self: FleetConfig, fleet: Fleet, nodeType: FleetNodes = FleetNodes.Bootnodes): seq[string] = + result = toSeq(self.fleet[$fleet][$nodeType].values) \ No newline at end of file diff --git a/src/status/status.nim b/src/status/status.nim index bba4f29778..47be519ac7 100644 --- a/src/status/status.nim +++ b/src/status/status.nim @@ -2,13 +2,14 @@ import libstatus/accounts as libstatus_accounts import libstatus/core as libstatus_core import libstatus/settings as libstatus_settings import libstatus/types as libstatus_types -import chat, accounts, wallet, node, network, mailservers, messages, contacts, profile, stickers, permissions +import chat, accounts, wallet, node, network, mailservers, messages, contacts, profile, stickers, permissions, fleet import ../eventemitter -export chat, accounts, node, mailservers, messages, contacts, profile, network, permissions +export chat, accounts, node, mailservers, messages, contacts, profile, network, permissions, fleet type Status* = ref object events*: EventEmitter + fleet*: FleetModel chat*: ChatModel messages*: MessagesModel mailservers*: MailserverModel @@ -21,9 +22,10 @@ type Status* = ref object stickers*: StickersModel permissions*: PermissionsModel -proc newStatusInstance*(): Status = +proc newStatusInstance*(fleetConfig: string): Status = result = Status() result.events = createEventEmitter() + result.fleet = fleet.newFleetModel(result.events, fleetConfig) result.chat = chat.newChatModel(result.events) result.accounts = accounts.newAccountModel(result.events) result.wallet = wallet.newWalletModel(result.events)