mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 21:04:11 +00:00
config: remove accounts management from NimbusConfiguration
a new AccountsManager and EthContext is created for managing keystore and accounts this is a preparation for new config using ConfUtils
This commit is contained in:
parent
07b2116f6b
commit
34972c6cea
104
nimbus/accounts/manager.nim
Normal file
104
nimbus/accounts/manager.nim
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
import
|
||||||
|
std/[os, json, tables],
|
||||||
|
stew/[byteutils, results],
|
||||||
|
eth/[keyfile, common, keys],
|
||||||
|
chronicles
|
||||||
|
|
||||||
|
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] =
|
||||||
|
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 Exception: # json raises Exception
|
||||||
|
return err("keystore: " & getCurrentExceptionMsg())
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
@ -114,11 +114,6 @@ type
|
|||||||
Full
|
Full
|
||||||
Archive
|
Archive
|
||||||
|
|
||||||
NimbusAccount* = object
|
|
||||||
privateKey*: PrivateKey
|
|
||||||
keystore*: JsonNode
|
|
||||||
unlocked*: bool
|
|
||||||
|
|
||||||
NimbusConfiguration* = ref object
|
NimbusConfiguration* = ref object
|
||||||
## Main Nimbus configuration object
|
## Main Nimbus configuration object
|
||||||
dataDir*: string
|
dataDir*: string
|
||||||
@ -133,7 +128,7 @@ type
|
|||||||
# You should only create one instance of the RNG per application / library
|
# You should only create one instance of the RNG per application / library
|
||||||
# Ref is used so that it can be shared between components
|
# Ref is used so that it can be shared between components
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref BrHmacDrbgContext
|
||||||
accounts*: Table[EthAddress, NimbusAccount]
|
importKey*: string
|
||||||
importFile*: string
|
importFile*: string
|
||||||
verifyFromOk*: bool ## activate `verifyFrom` setting
|
verifyFromOk*: bool ## activate `verifyFrom` setting
|
||||||
verifyFrom*: uint64 ## verification start block, 0 for disable
|
verifyFrom*: uint64 ## verification start block, 0 for disable
|
||||||
@ -383,26 +378,6 @@ proc processEthAddress(value: string, address: var EthAddress): ConfigStatus =
|
|||||||
except CatchableError:
|
except CatchableError:
|
||||||
return ErrorParseOption
|
return ErrorParseOption
|
||||||
|
|
||||||
proc importPrivateKey(conf: NimbusConfiguration, fileName: string): ConfigStatus =
|
|
||||||
|
|
||||||
try:
|
|
||||||
let pkhex = readFile(fileName)
|
|
||||||
let res = PrivateKey.fromHex(pkhex)
|
|
||||||
if res.isErr:
|
|
||||||
error "not a valid private key, expect 32 bytes hex"
|
|
||||||
return ErrorParseOption
|
|
||||||
|
|
||||||
let seckey = res.get()
|
|
||||||
let acc = seckey.toPublicKey().toCanonicalAddress()
|
|
||||||
|
|
||||||
conf.accounts[acc] = NimbusAccount(
|
|
||||||
privateKey: seckey,
|
|
||||||
unlocked: true
|
|
||||||
)
|
|
||||||
|
|
||||||
except CatchableError:
|
|
||||||
return ErrorParseOption
|
|
||||||
|
|
||||||
proc processEthArguments(key, value: string): ConfigStatus =
|
proc processEthArguments(key, value: string): ConfigStatus =
|
||||||
result = Success
|
result = Success
|
||||||
let config = getConfiguration()
|
let config = getConfiguration()
|
||||||
@ -423,7 +398,7 @@ proc processEthArguments(key, value: string): ConfigStatus =
|
|||||||
of "engine-signer":
|
of "engine-signer":
|
||||||
result = processEthAddress(value, config.engineSigner)
|
result = processEthAddress(value, config.engineSigner)
|
||||||
of "import-key":
|
of "import-key":
|
||||||
result = config.importPrivateKey(value)
|
config.importKey = value
|
||||||
else:
|
else:
|
||||||
result = EmptyOption
|
result = EmptyOption
|
||||||
|
|
||||||
@ -686,7 +661,6 @@ proc initConfiguration(): NimbusConfiguration =
|
|||||||
## Allocates and initializes `NimbusConfiguration` with default values
|
## Allocates and initializes `NimbusConfiguration` with default values
|
||||||
result = new NimbusConfiguration
|
result = new NimbusConfiguration
|
||||||
result.rng = newRng()
|
result.rng = newRng()
|
||||||
result.accounts = initTable[EthAddress, NimbusAccount]()
|
|
||||||
|
|
||||||
## Graphql defaults
|
## Graphql defaults
|
||||||
result.graphql.enabled = false
|
result.graphql.enabled = false
|
||||||
|
22
nimbus/context.nim
Normal file
22
nimbus/context.nim
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
import
|
||||||
|
accounts/manager
|
||||||
|
|
||||||
|
export manager
|
||||||
|
|
||||||
|
type
|
||||||
|
EthContext* = ref object
|
||||||
|
am*: AccountsManager
|
||||||
|
|
||||||
|
|
||||||
|
proc newEthContext*(): EthContext =
|
||||||
|
result = new(EthContext)
|
||||||
|
result.am = AccountsManager.init()
|
@ -11,8 +11,8 @@ import
|
|||||||
times, options, tables,
|
times, options, tables,
|
||||||
json_rpc/rpcserver, hexstrings, stint, stew/byteutils,
|
json_rpc/rpcserver, hexstrings, stint, stew/byteutils,
|
||||||
eth/[common, keys, rlp, p2p], nimcrypto,
|
eth/[common, keys, rlp, p2p], nimcrypto,
|
||||||
../transaction, ../config, ../vm_state, ../constants,
|
".."/[transaction, config, vm_state, constants, utils, context],
|
||||||
../utils, ../db/[db_chain, state_db],
|
../db/[db_chain, state_db],
|
||||||
rpc_types, rpc_utils,
|
rpc_types, rpc_utils,
|
||||||
../transaction/call_evm
|
../transaction/call_evm
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ import
|
|||||||
type cast to avoid extra processing.
|
type cast to avoid extra processing.
|
||||||
]#
|
]#
|
||||||
|
|
||||||
proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
proc setupEthRpc*(node: EthereumNode, ctx: EthContext, chain: BaseChainDB , server: RpcServer) =
|
||||||
|
|
||||||
proc getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
proc getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
||||||
## Retrieves the account db from canonical head
|
## Retrieves the account db from canonical head
|
||||||
@ -83,10 +83,9 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
|||||||
result = encodeQuantity(calculateMedianGasPrice(chain).uint64)
|
result = encodeQuantity(calculateMedianGasPrice(chain).uint64)
|
||||||
|
|
||||||
server.rpc("eth_accounts") do() -> seq[EthAddressStr]:
|
server.rpc("eth_accounts") do() -> seq[EthAddressStr]:
|
||||||
## Returns a list of addresses owned by client.
|
## Returns a list of addresses owned by client.
|
||||||
let conf = getConfiguration()
|
result = newSeqOfCap[EthAddressStr](ctx.am.numAccounts)
|
||||||
result = newSeqOfCap[EthAddressStr](conf.accounts.len)
|
for k in ctx.am.addresses:
|
||||||
for k in keys(conf.accounts):
|
|
||||||
result.add ethAddressStr(k)
|
result.add ethAddressStr(k)
|
||||||
|
|
||||||
server.rpc("eth_blockNumber") do() -> HexQuantityStr:
|
server.rpc("eth_blockNumber") do() -> HexQuantityStr:
|
||||||
@ -199,9 +198,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
|||||||
## message: message to sign.
|
## message: message to sign.
|
||||||
## Returns signature.
|
## Returns signature.
|
||||||
let
|
let
|
||||||
address = data.toAddress
|
address = data.toAddress
|
||||||
conf = getConfiguration()
|
acc = ctx.am.getAccount(address).tryGet()
|
||||||
acc = conf.getAccount(address).tryGet()
|
|
||||||
msg = hexToSeqByte(message.string)
|
msg = hexToSeqByte(message.string)
|
||||||
|
|
||||||
if not acc.unlocked:
|
if not acc.unlocked:
|
||||||
@ -213,8 +211,7 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
|||||||
## eth_sendRawTransaction
|
## eth_sendRawTransaction
|
||||||
let
|
let
|
||||||
address = data.source.toAddress
|
address = data.source.toAddress
|
||||||
conf = getConfiguration()
|
acc = ctx.am.getAccount(address).tryGet()
|
||||||
acc = conf.getAccount(address).tryGet()
|
|
||||||
|
|
||||||
if not acc.unlocked:
|
if not acc.unlocked:
|
||||||
raise newException(ValueError, "Account locked, please unlock it first")
|
raise newException(ValueError, "Account locked, please unlock it first")
|
||||||
@ -237,8 +234,7 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
|||||||
# TODO: Relies on pending pool implementation
|
# TODO: Relies on pending pool implementation
|
||||||
let
|
let
|
||||||
address = data.source.toAddress
|
address = data.source.toAddress
|
||||||
conf = getConfiguration()
|
acc = ctx.am.getAccount(address).tryGet()
|
||||||
acc = conf.getAccount(address).tryGet()
|
|
||||||
|
|
||||||
if not acc.unlocked:
|
if not acc.unlocked:
|
||||||
raise newException(ValueError, "Account locked, please unlock it first")
|
raise newException(ValueError, "Account locked, please unlock it first")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import
|
import
|
||||||
os, tables, json, ./config, stew/[results, byteutils],
|
pkg/[nimcrypto],
|
||||||
eth/trie/db, eth/[trie, rlp, common, keyfile], nimcrypto
|
eth/[trie, rlp, common, trie/db]
|
||||||
|
|
||||||
export nimcrypto.`$`
|
export nimcrypto.`$`
|
||||||
|
|
||||||
@ -58,40 +58,3 @@ proc crc32*(crc: uint32, buf: openArray[byte]): uint32 =
|
|||||||
crcu32 = (crcu32 shr 4) xor kcrc32[int((crcu32 and 0xF) xor (uint32(b) shr 4'u32))]
|
crcu32 = (crcu32 shr 4) xor kcrc32[int((crcu32 and 0xF) xor (uint32(b) shr 4'u32))]
|
||||||
|
|
||||||
result = not crcu32
|
result = not crcu32
|
||||||
|
|
||||||
proc loadKeystoreFiles*(conf: NimbusConfiguration): Result[void, string] =
|
|
||||||
try:
|
|
||||||
createDir(conf.keyStore)
|
|
||||||
except OSError, IOError:
|
|
||||||
return err("keystore: cannot create directory")
|
|
||||||
|
|
||||||
for filename in walkDirRec(conf.keyStore):
|
|
||||||
try:
|
|
||||||
var data = json.parseFile(filename)
|
|
||||||
let address: EthAddress = hexToByteArray[20](data["address"].getStr())
|
|
||||||
conf.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 Exception: # json raises Exception
|
|
||||||
return err("keystore: " & getCurrentExceptionMsg())
|
|
||||||
|
|
||||||
result = ok()
|
|
||||||
|
|
||||||
proc getAccount*(conf: NimbusConfiguration, address: EthAddress): Result[NimbusAccount, string] =
|
|
||||||
conf.accounts.withValue(address, val) do:
|
|
||||||
result = ok(val[])
|
|
||||||
do:
|
|
||||||
result = err("getAccount: not available " & address.toHex)
|
|
||||||
|
|
||||||
proc unlockAccount*(conf: NimbusConfiguration, address: EthAddress, password: string): Result[void, string] =
|
|
||||||
var acc = conf.getAccount(address).tryGet()
|
|
||||||
let res = decodeKeyFileJson(acc.keystore, password)
|
|
||||||
if res.isOk:
|
|
||||||
acc.privateKey = res.get()
|
|
||||||
acc.unlocked = true
|
|
||||||
conf.accounts[address] = acc
|
|
||||||
result = ok()
|
|
||||||
else:
|
|
||||||
result = err($res.error)
|
|
||||||
|
@ -19,7 +19,7 @@ import
|
|||||||
clique/clique_helpers
|
clique/clique_helpers
|
||||||
],
|
],
|
||||||
../nimbus/utils/ec_recover,
|
../nimbus/utils/ec_recover,
|
||||||
../nimbus/[config, utils, constants],
|
../nimbus/[config, utils, constants, context],
|
||||||
./test_clique/[pool, undump],
|
./test_clique/[pool, undump],
|
||||||
eth/[common, keys],
|
eth/[common, keys],
|
||||||
stint, stew/byteutils,
|
stint, stew/byteutils,
|
||||||
@ -248,15 +248,19 @@ proc cliqueMiscTests() =
|
|||||||
var opt = initOptParser("--engine-signer:$1 --import-key:$2" % [engineSigner, privateKey])
|
var opt = initOptParser("--engine-signer:$1 --import-key:$2" % [engineSigner, privateKey])
|
||||||
let res = processArguments(msg, opt)
|
let res = processArguments(msg, opt)
|
||||||
check res == Success
|
check res == Success
|
||||||
let signer = hexToByteArray[20](engineSigner)
|
|
||||||
let conf = getConfiguration()
|
let
|
||||||
check signer in conf.accounts
|
signer = hexToByteArray[20](engineSigner)
|
||||||
|
ctx = newEthContext()
|
||||||
|
conf = getConfiguration()
|
||||||
|
|
||||||
|
check ctx.am.importPrivateKey(conf.importKey).isOk()
|
||||||
|
check ctx.am.getAccount(signer).isOk()
|
||||||
|
|
||||||
proc signFunc(signer: EthAddress, message: openArray[byte]): Result[RawSignature, cstring] {.gcsafe.} =
|
proc signFunc(signer: EthAddress, message: openArray[byte]): Result[RawSignature, cstring] {.gcsafe.} =
|
||||||
let
|
let
|
||||||
hashData = keccakHash(message)
|
hashData = keccakHash(message)
|
||||||
conf = getConfiguration()
|
acc = ctx.am.getAccount(signer).tryGet()
|
||||||
acc = conf.accounts[signer]
|
|
||||||
rawSign = sign(acc.privateKey, SkMessage(hashData.data)).toRaw
|
rawSign = sign(acc.privateKey, SkMessage(hashData.data)).toRaw
|
||||||
|
|
||||||
ok(rawSign)
|
ok(rawSign)
|
||||||
|
@ -16,6 +16,7 @@ import
|
|||||||
../nimbus/p2p/[chain, executor, executor/executor_helpers],
|
../nimbus/p2p/[chain, executor, executor/executor_helpers],
|
||||||
../nimbus/sync/protocol_eth65,
|
../nimbus/sync/protocol_eth65,
|
||||||
../nimbus/utils/difficulty,
|
../nimbus/utils/difficulty,
|
||||||
|
../nimbus/context,
|
||||||
./rpcclient/test_hexstrings, ./test_helpers, ./macro_assembler
|
./rpcclient/test_hexstrings, ./test_helpers, ./macro_assembler
|
||||||
|
|
||||||
# Perform checks for hex string validation
|
# Perform checks for hex string validation
|
||||||
@ -35,11 +36,11 @@ type
|
|||||||
txHash: Hash256
|
txHash: Hash256
|
||||||
blockHash: HAsh256
|
blockHash: HAsh256
|
||||||
|
|
||||||
proc setupEnv(chain: BaseChainDB, signer, ks2: EthAddress, conf: NimbusConfiguration): TestEnv =
|
proc setupEnv(chain: BaseChainDB, signer, ks2: EthAddress, ctx: EthContext): TestEnv =
|
||||||
var
|
var
|
||||||
parent = chain.getCanonicalHead()
|
parent = chain.getCanonicalHead()
|
||||||
ac = newAccountStateDB(chain.db, parent.stateRoot, chain.pruneTrie)
|
ac = newAccountStateDB(chain.db, parent.stateRoot, chain.pruneTrie)
|
||||||
acc = conf.getAccount(signer).tryGet()
|
acc = ctx.am.getAccount(signer).tryGet()
|
||||||
blockNumber = 1.toBlockNumber
|
blockNumber = 1.toBlockNumber
|
||||||
parentHash = parent.blockHash
|
parentHash = parent.blockHash
|
||||||
|
|
||||||
@ -131,23 +132,24 @@ proc rpcMain*() =
|
|||||||
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
||||||
ks3: EthAddress = hexToByteArray[20]("0x597176e9a64aad0845d83afdaf698fbeff77703b")
|
ks3: EthAddress = hexToByteArray[20]("0x597176e9a64aad0845d83afdaf698fbeff77703b")
|
||||||
conf = getConfiguration()
|
conf = getConfiguration()
|
||||||
|
ctx = newEthContext()
|
||||||
|
|
||||||
ethNode.chain = newChain(chain)
|
ethNode.chain = newChain(chain)
|
||||||
conf.keyStore = "tests" / "keystore"
|
conf.keyStore = "tests" / "keystore"
|
||||||
let res = conf.loadKeystoreFiles()
|
let res = ctx.am.loadKeystores(conf.keyStore)
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
debugEcho res.error
|
debugEcho res.error
|
||||||
doAssert(res.isOk)
|
doAssert(res.isOk)
|
||||||
|
|
||||||
let acc1 = conf.getAccount(signer).tryGet()
|
let acc1 = ctx.am.getAccount(signer).tryGet()
|
||||||
let unlock = conf.unlockAccount(signer, acc1.keystore["password"].getStr())
|
let unlock = ctx.am.unlockAccount(signer, acc1.keystore["password"].getStr())
|
||||||
if unlock.isErr:
|
if unlock.isErr:
|
||||||
debugEcho unlock.error
|
debugEcho unlock.error
|
||||||
doAssert(unlock.isOk)
|
doAssert(unlock.isOk)
|
||||||
|
|
||||||
defaultGenesisBlockForNetwork(conf.net.networkId).commit(chain)
|
defaultGenesisBlockForNetwork(conf.net.networkId).commit(chain)
|
||||||
doAssert(canonicalHeadHashKey().toOpenArray in chain.db)
|
doAssert(canonicalHeadHashKey().toOpenArray in chain.db)
|
||||||
let env = setupEnv(chain, signer, ks2, conf)
|
let env = setupEnv(chain, signer, ks2, ctx)
|
||||||
|
|
||||||
# Create Ethereum RPCs
|
# Create Ethereum RPCs
|
||||||
let RPC_PORT = 8545
|
let RPC_PORT = 8545
|
||||||
@ -155,7 +157,7 @@ proc rpcMain*() =
|
|||||||
rpcServer = newRpcSocketServer(["localhost:" & $RPC_PORT])
|
rpcServer = newRpcSocketServer(["localhost:" & $RPC_PORT])
|
||||||
client = newRpcSocketClient()
|
client = newRpcSocketClient()
|
||||||
setupCommonRpc(ethNode, rpcServer)
|
setupCommonRpc(ethNode, rpcServer)
|
||||||
setupEthRpc(ethNode, chain, rpcServer)
|
setupEthRpc(ethNode, ctx, chain, rpcServer)
|
||||||
|
|
||||||
# Begin tests
|
# Begin tests
|
||||||
rpcServer.start()
|
rpcServer.start()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user