mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-10 04:15:54 +00:00
df1217b7ca
* Removed some Windows specific unit test annoyances details: + Short put()/get() cycles on persistent database have a race condition with vendor rocksdb. On a specific (and slow) qemu/win7 a 50ms `sleep()` in between will mostly do the job (i.e. unless heavy CPU load.) This issue was not observed on github/ci. + Removed annoyances when qemu/Win7 keeps the rocksdb database files locked even after closing the db. The problem is solved by strictly using fresh names for each test. No assumption made to be able to properly clean up. This issue was not observed on github/ci. * Silence some compiler gossip -- part 7, misc/non(sync or graphql) details: Adding some missing exception annotation
113 lines
3.3 KiB
Nim
113 lines
3.3 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2021 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
# at your option.
|
|
# This file may not be copied, modified, or distributed except according to
|
|
# those terms.
|
|
|
|
{.push raises: [].}
|
|
|
|
import
|
|
std/[os, json, tables, strutils],
|
|
stew/[byteutils, results],
|
|
eth/[keyfile, common, keys]
|
|
|
|
from nimcrypto/utils import burnMem
|
|
|
|
type
|
|
NimbusAccount* = object
|
|
privateKey*: PrivateKey
|
|
keystore*: JsonNode
|
|
unlocked*: bool
|
|
|
|
AccountsManager* = object
|
|
accounts: Table[EthAddress, NimbusAccount]
|
|
|
|
proc init*(_: type AccountsManager): AccountsManager =
|
|
discard
|
|
|
|
proc loadKeystores*(am: var AccountsManager, path: string): Result[void, string]
|
|
{.gcsafe, raises: [OSError].}=
|
|
try:
|
|
createDir(path)
|
|
except OSError, IOError:
|
|
return err("keystore: cannot create directory")
|
|
|
|
for filename in walkDirRec(path):
|
|
try:
|
|
var data = json.parseFile(filename)
|
|
let address: EthAddress = hexToByteArray[20](data["address"].getStr())
|
|
am.accounts[address] = NimbusAccount(keystore: data, unlocked: false)
|
|
except JsonParsingError:
|
|
return err("keystore: json parsing error " & filename)
|
|
except ValueError:
|
|
return err("keystore: data parsing error")
|
|
except IOError:
|
|
return err("keystore: data read error")
|
|
except CatchableError as e: # json raises Exception
|
|
return err("keystore: " & e.msg)
|
|
except Exception as e:
|
|
{.warning: "Kludge(BareExcept): `parseFile()` in json vendor package needs to be updated".}
|
|
raiseAssert "Ooops loadKeystores(): name=" & $e.name & " msg=" & e.msg
|
|
|
|
|
|
ok()
|
|
|
|
proc getAccount*(am: var AccountsManager, address: EthAddress): Result[NimbusAccount, string] =
|
|
am.accounts.withValue(address, value) do:
|
|
return ok(value[])
|
|
do:
|
|
return err("getAccount: not available " & address.toHex)
|
|
|
|
proc unlockAccount*(am: var AccountsManager, address: EthAddress, password: string): Result[void, string] =
|
|
let accRes = am.getAccount(address)
|
|
if accRes.isErr:
|
|
return err(accRes.error)
|
|
|
|
var acc = accRes.get()
|
|
let res = decodeKeyFileJson(acc.keystore, password)
|
|
if res.isOk:
|
|
acc.privateKey = res.get()
|
|
acc.unlocked = true
|
|
am.accounts[address] = acc
|
|
return ok()
|
|
|
|
err($res.error)
|
|
|
|
proc lockAccount*(am: var AccountsManager, address: EthAddress): Result[void, string] =
|
|
am.accounts.withValue(address, acc) do:
|
|
acc.unlocked = false
|
|
burnMem(acc.privateKey)
|
|
am.accounts[address] = acc[]
|
|
return ok()
|
|
do:
|
|
return err("getAccount: not available " & address.toHex)
|
|
|
|
proc numAccounts*(am: AccountsManager): int =
|
|
am.accounts.len
|
|
|
|
iterator addresses*(am: AccountsManager): EthAddress =
|
|
for a in am.accounts.keys:
|
|
yield a
|
|
|
|
proc importPrivateKey*(am: var AccountsManager, fileName: string): Result[void, string] =
|
|
try:
|
|
let pkhex = readFile(fileName)
|
|
let res = PrivateKey.fromHex(pkhex.strip)
|
|
if res.isErr:
|
|
return err("not a valid private key, expect 32 bytes hex")
|
|
|
|
let seckey = res.get()
|
|
let acc = seckey.toPublicKey().toCanonicalAddress()
|
|
|
|
am.accounts[acc] = NimbusAccount(
|
|
privateKey: seckey,
|
|
unlocked: true
|
|
)
|
|
|
|
return ok()
|
|
except CatchableError as ex:
|
|
return err(ex.msg)
|