From 4d88163de1ddb216b6b7beb6f7e322445184c190 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 29 Oct 2020 14:55:58 -0400 Subject: [PATCH 1/4] feat: open/close db connection and connect to web3 when calling a login()/logout() proc --- nim_status.nimble | 2 +- nim_status/lib/accounts.nim | 44 +++++++++++++++++++++++++++++++++++ nim_status/lib/callrpc.nim | 5 +++- nim_status/lib/util.nim | 4 ++++ test/nim/login.nim | 44 ----------------------------------- test/nim/login_and_logout.nim | 42 +++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 46 deletions(-) create mode 100644 nim_status/lib/accounts.nim delete mode 100644 test/nim/login.nim create mode 100644 test/nim/login_and_logout.nim diff --git a/nim_status.nimble b/nim_status.nimble index 42a7131..6d26db0 100644 --- a/nim_status.nimble +++ b/nim_status.nimble @@ -69,7 +69,7 @@ proc buildAndRunTest(name: string, task tests, "Run all tests": buildAndRunTest "shims" - buildAndRunTest "login" + buildAndRunTest "login_and_logout" buildAndRunTest "db_smoke" buildAndRunTest "waku_smoke" buildAndRunTest "settings" diff --git a/nim_status/lib/accounts.nim b/nim_status/lib/accounts.nim new file mode 100644 index 0000000..ebc6114 --- /dev/null +++ b/nim_status/lib/accounts.nim @@ -0,0 +1,44 @@ +import os, json +import sqlcipher, web3, chronos, json_serialization +import settings, database, callrpc + +var db_conn*: DbConn +var web3_conn*: Web3 + +proc login*(accountData, password: string) = + # TODO get account, validate password, etc + # TODO: should this be async? + # TODO: db should have been initialized somewhere, not here + # TODO: determine where will the DB connection live. In the meantime I'm storing it into a global variable + # TODO: determine where the web3 conn will live + + let path = currentSourcePath.parentDir().parentDir().parentDir() & "/build/" & accountData + db_conn = initializeDB(path, password) + + # TODO: these settings should have been set when calling saveAccountAndLogin + let settingsStr = """{ + "address": "0x1122334455667788990011223344556677889900", + "networks/current-network": "mainnet_rpc", + "dapps-address": "0x1122334455667788990011223344556677889900", + "eip1581-address": "0x1122334455667788990011223344556677889900", + "installation-id": "ABC-DEF-GHI", + "key-uid": "XYZ", + "latest-derived-path": 0, + "networks/networks": [{"id":"mainnet_rpc","etherscan-link":"https://etherscan.io/address/","name":"Mainnet with upstream RPC","config":{"NetworkId":1,"DataDir":"/ethereum/mainnet_rpc","UpstreamConfig":{"Enabled":true,"URL":"wss://mainnet.infura.io/ws/v3/7230123556ec4a8aac8d89ccd0dd74d7"}}}], + "photo-path": "ABXYZC", + "preview-privacy?": false, + "public-key": "0x123", + "signing-phrase": "ABC DEF GHI" + }""" + let settingsObj = JSON.decode(settingsStr, Settings, allowUnknownFields = true) + let nodeConfig = %* {"config": 1} + db_conn.createSettings(settingsObj, nodeConfig) + + web3_conn = newWeb3(getSettings(db_conn)) + + +proc logout*() = + waitFor web3_conn.close() + db_conn.close() + web3_conn = nil + diff --git a/nim_status/lib/callrpc.nim b/nim_status/lib/callrpc.nim index d0d5786..25a0da2 100644 --- a/nim_status/lib/callrpc.nim +++ b/nim_status/lib/callrpc.nim @@ -68,7 +68,10 @@ proc callRPC*(web3Conn: Web3, rpcMethod: RemoteMethod, params: JsonNode): Respon proc callRPC*(web3Conn: Web3, rpcMethod: string, params: JsonNode): Response = - try: + if web3Conn == nil: + raise (ref Web3Error)(msg: "Web3 connection is not available") + + try: var m = parseEnum[RemoteMethod](rpcMethod) except: return (true, %* {"code": -32601, "message": "the method " & rpcMethod & " does not exist/is not available"}) diff --git a/nim_status/lib/util.nim b/nim_status/lib/util.nim index 7eea964..19a16fe 100644 --- a/nim_status/lib/util.nim +++ b/nim_status/lib/util.nim @@ -1,4 +1,5 @@ import re +import web3/ethtypes let reHex = re("^[0-9a-f]+$", {reIgnoreCase}) @@ -12,3 +13,6 @@ proc isPubKey*(str: string): bool = str.len == 132 and str[0..3] == "0x04" and match(str[2..^1], reHex) + +proc parseAddress*(strAddress: string): Address = + fromHex(Address, strAddress) \ No newline at end of file diff --git a/test/nim/login.nim b/test/nim/login.nim deleted file mode 100644 index d696323..0000000 --- a/test/nim/login.nim +++ /dev/null @@ -1,44 +0,0 @@ -import ../../nim_status -import test_helpers -import utils - -import chronos -import os -import unittest - -var success = false - -proc checkMessage(message: string): void = - echo "SIGNAL RECEIVED:\n" & message - if message == """{"type":"node.login","event":{}}""": - success = true - -procSuite "nim_status": - asyncTest "login": - var onSignal = proc(message: cstring) {.cdecl.} = - setupForeignThreadGC() - checkMessage($message) - tearDownForeignThreadGc() - - setSignalEventCallback(onSignal) - resetDirectories() # Recreates the data and nobackup dir - init() - - # Call either `createAccountAndLogin("somePassword")` to create a new random account - # Or: `restoreAccountAndLogin("cattle act enable unable own music material canvas either shoe must junior", "somePassword")` - # If no password is specified, it will use "qwerty" - # There's a `login("somePassword")` function that will login the first - # account. It assumes the directories have been already set. - discard createAccountAndLogin("somePassword") - - var seconds = 0 - - while seconds < 300: - if success: - break - echo "..." - sleep 1000 - seconds += 1 - - check: - success == true diff --git a/test/nim/login_and_logout.nim b/test/nim/login_and_logout.nim new file mode 100644 index 0000000..637f920 --- /dev/null +++ b/test/nim/login_and_logout.nim @@ -0,0 +1,42 @@ +import sqlcipher +import os, json, json_serialization +import options +import ../../nim_status/lib/settings +import ../../nim_status/lib/database +import ../../nim_status/lib/callrpc +import ../../nim_status/lib/accounts +import web3/conversions + + +let accountData = "someAccount" +let passwd = "qwerty" + + +try: + assert web3_conn == nil + discard callRPC(web3_conn, "eth_gasPrice", %[]) + assert "Should fail if reaches this point" == "" +except: + assert getCurrentExceptionMsg() == "Web3 connection is not available" + + +login(accountData, passwd) + +# Using an ugly global var :( +let rGasPrice = callRPC(web3_conn, "eth_gasPrice", %[]) +assert rGasPrice.error == false +assert rGasPrice.result.getStr()[0..1] == "0x" + +logout() + + +try: + assert web3_conn == nil + discard callRPC(web3_conn, "eth_gasPrice", %[]) + assert "Should fail if reaches this point" == "" +except: + assert getCurrentExceptionMsg() == "Web3 connection is not available" + + +# Removing DB to be able to run the test again +removeFile(currentSourcePath.parentDir().parentDir().parentDir() & "/build/" & accountData) From bcb3e6d5c81d25fe44ad040636689b0d2818652b Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 7 Dec 2020 20:52:39 -0400 Subject: [PATCH 2/4] fix: db initialization --- nim_status/lib/accounts.nim | 2 +- test/nim/login_and_logout.nim | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nim_status/lib/accounts.nim b/nim_status/lib/accounts.nim index ebc6114..3cadcf7 100644 --- a/nim_status/lib/accounts.nim +++ b/nim_status/lib/accounts.nim @@ -12,7 +12,7 @@ proc login*(accountData, password: string) = # TODO: determine where will the DB connection live. In the meantime I'm storing it into a global variable # TODO: determine where the web3 conn will live - let path = currentSourcePath.parentDir().parentDir().parentDir() & "/build/" & accountData + let path = currentSourcePath.parentDir() / accountData & ".db" db_conn = initializeDB(path, password) # TODO: these settings should have been set when calling saveAccountAndLogin diff --git a/test/nim/login_and_logout.nim b/test/nim/login_and_logout.nim index 637f920..bbc2171 100644 --- a/test/nim/login_and_logout.nim +++ b/test/nim/login_and_logout.nim @@ -11,6 +11,9 @@ import web3/conversions let accountData = "someAccount" let passwd = "qwerty" +# Removing DB since we still dont have migration code +removeFile(currentSourcePath.parentDir().parentDir().parentDir() / "nim_status/lib" / accountData & ".db") + try: assert web3_conn == nil @@ -37,6 +40,5 @@ try: except: assert getCurrentExceptionMsg() == "Web3 connection is not available" - # Removing DB to be able to run the test again -removeFile(currentSourcePath.parentDir().parentDir().parentDir() & "/build/" & accountData) +removeFile(currentSourcePath.parentDir().parentDir().parentDir() / "nim_status/lib" / accountData & ".db") From 50503194d2d65d4e0bba652191e03f593110c6bc Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 5 Jan 2021 09:28:56 -0400 Subject: [PATCH 3/4] fix: invalid network --- nim_status.nimble | 2 +- nim_status/lib/accounts.nim | 13 ++++++++++--- nim_status/lib/callrpc.nim | 6 +++--- test/nim/login_and_logout.nim | 10 ++++------ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/nim_status.nimble b/nim_status.nimble index 6d26db0..92c55fb 100644 --- a/nim_status.nimble +++ b/nim_status.nimble @@ -69,10 +69,10 @@ proc buildAndRunTest(name: string, task tests, "Run all tests": buildAndRunTest "shims" + buildAndRunTest "settings" buildAndRunTest "login_and_logout" buildAndRunTest "db_smoke" buildAndRunTest "waku_smoke" - buildAndRunTest "settings" buildAndRunTest "callrpc" buildAndRunTest "migrations" buildAndRunTest "mailservers" diff --git a/nim_status/lib/accounts.nim b/nim_status/lib/accounts.nim index 3cadcf7..0ed89f3 100644 --- a/nim_status/lib/accounts.nim +++ b/nim_status/lib/accounts.nim @@ -1,12 +1,12 @@ import os, json import sqlcipher, web3, chronos, json_serialization -import settings, database, callrpc +import settings, database, conversions, callrpc var db_conn*: DbConn var web3_conn*: Web3 proc login*(accountData, password: string) = - # TODO get account, validate password, etc + # TODO: get account, validate password, etc # TODO: should this be async? # TODO: db should have been initialized somewhere, not here # TODO: determine where will the DB connection live. In the meantime I'm storing it into a global variable @@ -18,6 +18,7 @@ proc login*(accountData, password: string) = # TODO: these settings should have been set when calling saveAccountAndLogin let settingsStr = """{ "address": "0x1122334455667788990011223344556677889900", + "chaos-mode": true, "networks/current-network": "mainnet_rpc", "dapps-address": "0x1122334455667788990011223344556677889900", "eip1581-address": "0x1122334455667788990011223344556677889900", @@ -25,11 +26,14 @@ proc login*(accountData, password: string) = "key-uid": "XYZ", "latest-derived-path": 0, "networks/networks": [{"id":"mainnet_rpc","etherscan-link":"https://etherscan.io/address/","name":"Mainnet with upstream RPC","config":{"NetworkId":1,"DataDir":"/ethereum/mainnet_rpc","UpstreamConfig":{"Enabled":true,"URL":"wss://mainnet.infura.io/ws/v3/7230123556ec4a8aac8d89ccd0dd74d7"}}}], + "name": "test", "photo-path": "ABXYZC", "preview-privacy?": false, "public-key": "0x123", - "signing-phrase": "ABC DEF GHI" + "signing-phrase": "ABC DEF GHI", + "wallet-root-address": "0x1122334455667788990011223344556677889900" }""" + let settingsObj = JSON.decode(settingsStr, Settings, allowUnknownFields = true) let nodeConfig = %* {"config": 1} db_conn.createSettings(settingsObj, nodeConfig) @@ -42,3 +46,6 @@ proc logout*() = db_conn.close() web3_conn = nil +proc test_removeDB*(accountData: string) = # TODO: remove this once proper db initialization is available + let path = currentSourcePath.parentDir() / accountData & ".db" + removeFile(path) \ No newline at end of file diff --git a/nim_status/lib/callrpc.nim b/nim_status/lib/callrpc.nim index 25a0da2..0830476 100644 --- a/nim_status/lib/callrpc.nim +++ b/nim_status/lib/callrpc.nim @@ -53,10 +53,10 @@ type RemoteMethod* {.pure.} = enum proc newWeb3*(settings: Settings): Web3 = let network = settings.getNetwork() if network.isNone: - raise (ref Web3Error)(msg: "Config not found for network " & settings.currentNetwork) + raise (ref Web3Error)(msg: "config not found for network " & settings.currentNetwork) if not network.get().config.upstreamConfig.enabled: - raise (ref Web3Error)(msg: "Network " & settings.currentNetwork & " is not enabled") + raise (ref Web3Error)(msg: "network " & settings.currentNetwork & " is not enabled") result = waitFor newWeb3(network.get().config.upstreamConfig.url) @@ -69,7 +69,7 @@ proc callRPC*(web3Conn: Web3, rpcMethod: RemoteMethod, params: JsonNode): Respon proc callRPC*(web3Conn: Web3, rpcMethod: string, params: JsonNode): Response = if web3Conn == nil: - raise (ref Web3Error)(msg: "Web3 connection is not available") + raise (ref Web3Error)(msg: "web3 connection is not available") try: var m = parseEnum[RemoteMethod](rpcMethod) diff --git a/test/nim/login_and_logout.nim b/test/nim/login_and_logout.nim index bbc2171..44b80cb 100644 --- a/test/nim/login_and_logout.nim +++ b/test/nim/login_and_logout.nim @@ -11,16 +11,14 @@ import web3/conversions let accountData = "someAccount" let passwd = "qwerty" -# Removing DB since we still dont have migration code -removeFile(currentSourcePath.parentDir().parentDir().parentDir() / "nim_status/lib" / accountData & ".db") - +test_removeDB(accountData) try: assert web3_conn == nil discard callRPC(web3_conn, "eth_gasPrice", %[]) assert "Should fail if reaches this point" == "" except: - assert getCurrentExceptionMsg() == "Web3 connection is not available" + assert getCurrentExceptionMsg() == "web3 connection is not available" login(accountData, passwd) @@ -38,7 +36,7 @@ try: discard callRPC(web3_conn, "eth_gasPrice", %[]) assert "Should fail if reaches this point" == "" except: - assert getCurrentExceptionMsg() == "Web3 connection is not available" + assert getCurrentExceptionMsg() == "web3 connection is not available" # Removing DB to be able to run the test again -removeFile(currentSourcePath.parentDir().parentDir().parentDir() / "nim_status/lib" / accountData & ".db") +test_removeDB(accountData) \ No newline at end of file From 3269e35cb0f5b5266f21efce4c417427eb93fff7 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 5 Jan 2021 09:32:38 -0400 Subject: [PATCH 4/4] fix: tmp db path --- nim_status/lib/accounts.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nim_status/lib/accounts.nim b/nim_status/lib/accounts.nim index 0ed89f3..b748229 100644 --- a/nim_status/lib/accounts.nim +++ b/nim_status/lib/accounts.nim @@ -12,7 +12,7 @@ proc login*(accountData, password: string) = # TODO: determine where will the DB connection live. In the meantime I'm storing it into a global variable # TODO: determine where the web3 conn will live - let path = currentSourcePath.parentDir() / accountData & ".db" + let path = getCurrentDir() / accountData & ".db" db_conn = initializeDB(path, password) # TODO: these settings should have been set when calling saveAccountAndLogin @@ -47,5 +47,5 @@ proc logout*() = web3_conn = nil proc test_removeDB*(accountData: string) = # TODO: remove this once proper db initialization is available - let path = currentSourcePath.parentDir() / accountData & ".db" + let path = getCurrentDir() / accountData & ".db" removeFile(path) \ No newline at end of file