2023-06-22 10:32:18 +00:00
|
|
|
import std/os
|
|
|
|
import std/macros
|
2023-12-20 02:24:40 +00:00
|
|
|
import std/json
|
2023-06-22 10:32:18 +00:00
|
|
|
import std/httpclient
|
2023-12-20 02:24:40 +00:00
|
|
|
import pkg/chronicles
|
2023-06-22 10:32:18 +00:00
|
|
|
import ../ethertest
|
|
|
|
import ./codexclient
|
|
|
|
import ./nodes
|
|
|
|
|
|
|
|
export ethertest
|
|
|
|
export codexclient
|
|
|
|
export nodes
|
|
|
|
|
2023-09-13 14:17:56 +00:00
|
|
|
type
|
|
|
|
RunningNode* = ref object
|
|
|
|
role*: Role
|
|
|
|
node*: NodeProcess
|
|
|
|
restClient*: CodexClient
|
|
|
|
datadir*: string
|
|
|
|
ethAccount*: Address
|
|
|
|
StartNodes* = object
|
|
|
|
clients*: uint
|
|
|
|
providers*: uint
|
|
|
|
validators*: uint
|
|
|
|
DebugNodes* = object
|
|
|
|
client*: bool
|
2023-12-18 09:34:04 +00:00
|
|
|
ethProvider*: bool
|
2023-09-13 14:17:56 +00:00
|
|
|
validator*: bool
|
|
|
|
topics*: string
|
|
|
|
Role* {.pure.} = enum
|
|
|
|
Client,
|
|
|
|
Provider,
|
|
|
|
Validator
|
|
|
|
|
|
|
|
proc new*(_: type RunningNode,
|
|
|
|
role: Role,
|
|
|
|
node: NodeProcess,
|
|
|
|
restClient: CodexClient,
|
|
|
|
datadir: string,
|
|
|
|
ethAccount: Address): RunningNode =
|
|
|
|
RunningNode(role: role,
|
|
|
|
node: node,
|
|
|
|
restClient: restClient,
|
|
|
|
datadir: datadir,
|
|
|
|
ethAccount: ethAccount)
|
|
|
|
|
|
|
|
proc init*(_: type StartNodes,
|
|
|
|
clients, providers, validators: uint): StartNodes =
|
|
|
|
StartNodes(clients: clients, providers: providers, validators: validators)
|
|
|
|
|
|
|
|
proc init*(_: type DebugNodes,
|
2023-12-18 09:34:04 +00:00
|
|
|
client, ethProvider, validator: bool,
|
2023-09-13 14:17:56 +00:00
|
|
|
topics: string = "validator,proving,market"): DebugNodes =
|
2023-12-18 09:34:04 +00:00
|
|
|
DebugNodes(client: client, ethProvider: ethProvider, validator: validator,
|
2023-09-13 14:17:56 +00:00
|
|
|
topics: topics)
|
|
|
|
|
2023-06-22 10:32:18 +00:00
|
|
|
template multinodesuite*(name: string,
|
|
|
|
startNodes: StartNodes, debugNodes: DebugNodes, body: untyped) =
|
|
|
|
|
2023-12-18 09:34:04 +00:00
|
|
|
if (debugNodes.client or debugNodes.ethProvider) and
|
2023-06-22 10:32:18 +00:00
|
|
|
(enabledLogLevel > LogLevel.TRACE or
|
|
|
|
enabledLogLevel == LogLevel.NONE):
|
|
|
|
echo ""
|
|
|
|
echo "More test debug logging is available by running the tests with " &
|
|
|
|
"'-d:chronicles_log_level=TRACE " &
|
|
|
|
"-d:chronicles_disabled_topics=websock " &
|
|
|
|
"-d:chronicles_default_output_device=stdout " &
|
|
|
|
"-d:chronicles_sinks=textlines'"
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
ethersuite name:
|
|
|
|
|
|
|
|
var running: seq[RunningNode]
|
|
|
|
var bootstrap: string
|
|
|
|
|
|
|
|
proc newNodeProcess(index: int,
|
|
|
|
addlOptions: seq[string],
|
|
|
|
debug: bool): (NodeProcess, string, Address) =
|
|
|
|
|
|
|
|
if index > accounts.len - 1:
|
|
|
|
raiseAssert("Cannot start node at index " & $index &
|
|
|
|
", not enough eth accounts.")
|
|
|
|
|
|
|
|
let datadir = getTempDir() / "Codex" & $index
|
|
|
|
var options = @[
|
|
|
|
"--api-port=" & $(8080 + index),
|
|
|
|
"--data-dir=" & datadir,
|
|
|
|
"--nat=127.0.0.1",
|
2023-10-24 14:52:06 +00:00
|
|
|
"--listen-addrs=/ip4/127.0.0.1/tcp/0",
|
2023-06-22 10:32:18 +00:00
|
|
|
"--disc-ip=127.0.0.1",
|
|
|
|
"--disc-port=" & $(8090 + index),
|
|
|
|
"--eth-account=" & $accounts[index]]
|
|
|
|
.concat(addlOptions)
|
|
|
|
if debug: options.add "--log-level=INFO;TRACE: " & debugNodes.topics
|
|
|
|
let node = startNode(options, debug = debug)
|
2023-09-13 14:17:56 +00:00
|
|
|
node.waitUntilStarted()
|
2023-06-22 10:32:18 +00:00
|
|
|
(node, datadir, accounts[index])
|
|
|
|
|
|
|
|
proc newCodexClient(index: int): CodexClient =
|
|
|
|
CodexClient.new("http://localhost:" & $(8080 + index) & "/api/codex/v1")
|
|
|
|
|
|
|
|
proc startClientNode() =
|
|
|
|
let index = running.len
|
|
|
|
let (node, datadir, account) = newNodeProcess(
|
|
|
|
index, @["--persistence"], debugNodes.client)
|
|
|
|
let restClient = newCodexClient(index)
|
|
|
|
running.add RunningNode.new(Role.Client, node, restClient, datadir,
|
|
|
|
account)
|
|
|
|
if debugNodes.client:
|
|
|
|
debug "started new client node and codex client",
|
|
|
|
restApiPort = 8080 + index, discPort = 8090 + index, account
|
|
|
|
|
|
|
|
proc startProviderNode(failEveryNProofs: uint = 0) =
|
|
|
|
let index = running.len
|
|
|
|
let (node, datadir, account) = newNodeProcess(index, @[
|
|
|
|
"--bootstrap-node=" & bootstrap,
|
|
|
|
"--persistence",
|
|
|
|
"--simulate-proof-failures=" & $failEveryNProofs],
|
2023-12-18 09:34:04 +00:00
|
|
|
debugNodes.ethProvider)
|
2023-06-22 10:32:18 +00:00
|
|
|
let restClient = newCodexClient(index)
|
|
|
|
running.add RunningNode.new(Role.Provider, node, restClient, datadir,
|
|
|
|
account)
|
2023-12-18 09:34:04 +00:00
|
|
|
if debugNodes.ethProvider:
|
|
|
|
debug "started new ethProvider node and codex client",
|
2023-06-22 10:32:18 +00:00
|
|
|
restApiPort = 8080 + index, discPort = 8090 + index, account
|
|
|
|
|
|
|
|
proc startValidatorNode() =
|
|
|
|
let index = running.len
|
|
|
|
let (node, datadir, account) = newNodeProcess(index, @[
|
|
|
|
"--bootstrap-node=" & bootstrap,
|
|
|
|
"--validator"],
|
|
|
|
debugNodes.validator)
|
|
|
|
let restClient = newCodexClient(index)
|
|
|
|
running.add RunningNode.new(Role.Validator, node, restClient, datadir,
|
|
|
|
account)
|
|
|
|
if debugNodes.validator:
|
|
|
|
debug "started new validator node and codex client",
|
|
|
|
restApiPort = 8080 + index, discPort = 8090 + index, account
|
|
|
|
|
2023-09-13 14:17:56 +00:00
|
|
|
proc clients(): seq[RunningNode] {.used.} =
|
2023-06-22 10:32:18 +00:00
|
|
|
running.filter(proc(r: RunningNode): bool = r.role == Role.Client)
|
|
|
|
|
2023-09-13 14:17:56 +00:00
|
|
|
proc providers(): seq[RunningNode] {.used.} =
|
2023-06-22 10:32:18 +00:00
|
|
|
running.filter(proc(r: RunningNode): bool = r.role == Role.Provider)
|
|
|
|
|
2023-09-13 14:17:56 +00:00
|
|
|
proc validators(): seq[RunningNode] {.used.} =
|
2023-06-22 10:32:18 +00:00
|
|
|
running.filter(proc(r: RunningNode): bool = r.role == Role.Validator)
|
|
|
|
|
|
|
|
setup:
|
|
|
|
for i in 0..<startNodes.clients:
|
|
|
|
startClientNode()
|
|
|
|
if i == 0:
|
|
|
|
bootstrap = running[0].restClient.info()["spr"].getStr()
|
|
|
|
|
|
|
|
for i in 0..<startNodes.providers:
|
|
|
|
startProviderNode()
|
|
|
|
|
|
|
|
for i in 0..<startNodes.validators:
|
|
|
|
startValidatorNode()
|
|
|
|
|
|
|
|
teardown:
|
|
|
|
for r in running:
|
|
|
|
r.restClient.close()
|
|
|
|
r.node.stop()
|
|
|
|
removeDir(r.datadir)
|
|
|
|
running = @[]
|
|
|
|
|
|
|
|
body
|