2019-09-03 03:12:09 +00:00
|
|
|
# beacon_chain
|
2024-01-06 14:26:56 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2019-09-03 03:12:09 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2019-09-03 03:12:09 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2024-02-22 10:03:09 +00:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2019-09-03 03:12:09 +00:00
|
|
|
import
|
|
|
|
# Standard library
|
2023-02-10 20:59:38 +00:00
|
|
|
std/[strutils, typetraits],
|
2019-09-03 03:12:09 +00:00
|
|
|
# Internals
|
2023-02-10 20:59:38 +00:00
|
|
|
./os_ops,
|
2022-07-23 05:54:01 +00:00
|
|
|
../../beacon_chain/spec/datatypes/[phase0, altair, bellatrix],
|
2021-08-18 18:57:58 +00:00
|
|
|
../../beacon_chain/spec/[
|
2022-07-06 10:33:02 +00:00
|
|
|
eth2_merkleization, eth2_ssz_serialization, forks],
|
2021-05-24 08:42:40 +00:00
|
|
|
# Status libs,
|
|
|
|
snappy,
|
2021-08-18 18:57:58 +00:00
|
|
|
stew/byteutils
|
2019-09-03 03:12:09 +00:00
|
|
|
|
2021-08-18 18:57:58 +00:00
|
|
|
export
|
|
|
|
eth2_merkleization, eth2_ssz_serialization
|
2019-09-03 03:12:09 +00:00
|
|
|
|
2020-01-27 10:56:32 +00:00
|
|
|
# Process current EF test format
|
2019-09-03 03:12:09 +00:00
|
|
|
# ---------------------------------------------
|
|
|
|
|
2022-07-06 10:33:02 +00:00
|
|
|
# #######################
|
|
|
|
# Path parsing
|
|
|
|
|
2023-01-28 19:53:41 +00:00
|
|
|
func forkForPathComponent*(forkPath: string): Opt[ConsensusFork] =
|
|
|
|
for fork in ConsensusFork:
|
2022-07-06 10:33:02 +00:00
|
|
|
if ($fork).toLowerAscii() == forkPath:
|
|
|
|
return ok fork
|
|
|
|
err()
|
|
|
|
|
2019-09-03 03:12:09 +00:00
|
|
|
# #######################
|
|
|
|
# JSON deserialization
|
|
|
|
|
2021-05-24 08:42:40 +00:00
|
|
|
func readValue*(r: var JsonReader, a: var seq[byte]) =
|
2019-09-03 03:12:09 +00:00
|
|
|
## Custom deserializer for seq[byte]
|
|
|
|
a = hexToSeqByte(r.readValue(string))
|
|
|
|
|
2022-07-06 10:33:02 +00:00
|
|
|
# #######################
|
|
|
|
# Mock RuntimeConfig
|
|
|
|
|
2023-03-11 00:35:52 +00:00
|
|
|
func genesisTestRuntimeConfig*(consensusFork: ConsensusFork): RuntimeConfig =
|
2022-07-06 10:33:02 +00:00
|
|
|
var res = defaultRuntimeConfig
|
2023-03-11 00:35:52 +00:00
|
|
|
case consensusFork
|
2024-04-03 14:43:43 +00:00
|
|
|
of ConsensusFork.Electra:
|
|
|
|
res.ELECTRA_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.DENEB_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
2023-03-04 13:35:39 +00:00
|
|
|
of ConsensusFork.Deneb:
|
2023-02-15 14:44:09 +00:00
|
|
|
res.DENEB_FORK_EPOCH = GENESIS_EPOCH
|
2022-12-07 16:47:23 +00:00
|
|
|
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
2023-01-28 19:53:41 +00:00
|
|
|
of ConsensusFork.Capella:
|
2022-11-02 16:23:30 +00:00
|
|
|
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
2023-01-28 19:53:41 +00:00
|
|
|
of ConsensusFork.Bellatrix:
|
2022-07-06 10:33:02 +00:00
|
|
|
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
2023-01-28 19:53:41 +00:00
|
|
|
of ConsensusFork.Altair:
|
2022-07-06 10:33:02 +00:00
|
|
|
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
2023-01-28 19:53:41 +00:00
|
|
|
of ConsensusFork.Phase0:
|
2022-07-06 10:33:02 +00:00
|
|
|
discard
|
|
|
|
res
|
|
|
|
|
2019-09-03 03:12:09 +00:00
|
|
|
# #######################
|
|
|
|
# Test helpers
|
|
|
|
|
2020-05-11 16:27:44 +00:00
|
|
|
type
|
|
|
|
UnconsumedInput* = object of CatchableError
|
|
|
|
TestSizeError* = object of ValueError
|
|
|
|
|
2023-05-11 09:54:29 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/tree/v1.3.0/tests/formats/rewards#rewards-tests
|
2021-10-19 14:38:41 +00:00
|
|
|
Deltas* = object
|
2024-03-19 13:22:07 +00:00
|
|
|
rewards*: List[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]
|
|
|
|
penalties*: List[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]
|
2021-10-19 14:38:41 +00:00
|
|
|
|
2024-01-20 11:19:47 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#eth1block
|
2021-10-20 11:36:38 +00:00
|
|
|
Eth1Block* = object
|
|
|
|
timestamp*: uint64
|
|
|
|
deposit_root*: Eth2Digest
|
|
|
|
deposit_count*: uint64
|
|
|
|
# All other eth1 block fields
|
|
|
|
|
2019-09-03 03:12:09 +00:00
|
|
|
const
|
2020-06-16 15:12:59 +00:00
|
|
|
FixturesDir* =
|
|
|
|
currentSourcePath.rsplit(DirSep, 1)[0] / ".." / ".." / "vendor" / "nim-eth2-scenarios"
|
2022-01-05 13:41:39 +00:00
|
|
|
SszTestsDir* = FixturesDir / "tests-v" & SPEC_VERSION
|
2021-05-24 08:42:40 +00:00
|
|
|
MaxObjectSize* = 3_000_000
|
2019-09-03 03:12:09 +00:00
|
|
|
|
2024-02-22 10:03:09 +00:00
|
|
|
proc relativeTestPathComponent*(path: string, suitePath = SszTestsDir): string =
|
|
|
|
try:
|
|
|
|
path.relativePath(suitePath)
|
|
|
|
except Exception as exc:
|
|
|
|
raiseAssert "relativePath failed unexpectedly: " & $exc.msg
|
|
|
|
|
2021-05-24 08:42:40 +00:00
|
|
|
proc parseTest*(path: string, Format: typedesc[Json], T: typedesc): T =
|
2019-09-03 03:12:09 +00:00
|
|
|
try:
|
|
|
|
# debugEcho " [Debug] Loading file: \"", path, '\"'
|
2023-02-10 20:59:38 +00:00
|
|
|
result = Format.decode(readFileBytes(path), T)
|
2019-09-03 03:12:09 +00:00
|
|
|
except SerializationError as err:
|
|
|
|
writeStackTrace()
|
2024-02-22 10:03:09 +00:00
|
|
|
try:
|
|
|
|
stderr.write $Format & " load issue for file \"", path, "\"\n"
|
|
|
|
stderr.write err.formatMsg(path), "\n"
|
|
|
|
except IOError:
|
|
|
|
discard
|
2019-09-03 03:12:09 +00:00
|
|
|
quit 1
|
2020-05-11 16:27:44 +00:00
|
|
|
|
2024-02-22 10:03:09 +00:00
|
|
|
proc sszDecodeEntireInput*(
|
|
|
|
input: openArray[byte],
|
|
|
|
Decoded: type
|
|
|
|
): Decoded {.raises: [IOError, SerializationError, UnconsumedInput].} =
|
2022-02-20 20:13:06 +00:00
|
|
|
let stream = unsafeMemoryInput(input)
|
2020-05-28 12:36:37 +00:00
|
|
|
var reader = init(SszReader, stream)
|
2020-05-27 15:04:43 +00:00
|
|
|
reader.readValue(result)
|
2020-05-11 16:27:44 +00:00
|
|
|
|
|
|
|
if stream.readable:
|
|
|
|
raise newException(UnconsumedInput, "Remaining bytes in the input")
|
2020-10-22 18:53:40 +00:00
|
|
|
|
2024-02-22 10:03:09 +00:00
|
|
|
iterator walkTests*(dir: static string): string {.raises: [OSError].} =
|
2021-10-19 14:38:41 +00:00
|
|
|
for kind, path in walkDir(
|
|
|
|
dir/"pyspec_tests", relative = true, checkDir = true):
|
|
|
|
yield path
|
|
|
|
|
2021-05-24 08:42:40 +00:00
|
|
|
proc parseTest*(path: string, Format: typedesc[SSZ], T: typedesc): T =
|
|
|
|
try:
|
|
|
|
# debugEcho " [Debug] Loading file: \"", path, '\"'
|
|
|
|
sszDecodeEntireInput(snappy.decode(readFileBytes(path), MaxObjectSize), T)
|
2024-02-22 10:03:09 +00:00
|
|
|
except IOError as err:
|
|
|
|
writeStackTrace()
|
|
|
|
try:
|
|
|
|
stderr.write $Format & " load issue for file \"", path, "\"\n"
|
|
|
|
stderr.write "IOError: " & err.msg, "\n"
|
|
|
|
except IOError:
|
|
|
|
discard
|
|
|
|
quit 1
|
2021-05-24 08:42:40 +00:00
|
|
|
except SerializationError as err:
|
|
|
|
writeStackTrace()
|
2024-02-22 10:03:09 +00:00
|
|
|
try:
|
|
|
|
stderr.write $Format & " load issue for file \"", path, "\"\n"
|
|
|
|
stderr.write err.formatMsg(path), "\n"
|
|
|
|
except IOError:
|
|
|
|
discard
|
|
|
|
quit 1
|
|
|
|
except UnconsumedInput as err:
|
|
|
|
writeStackTrace()
|
|
|
|
try:
|
|
|
|
stderr.write $Format & " load issue for file \"", path, "\"\n"
|
|
|
|
stderr.write "UnconsumedInput: " & err.msg, "\n"
|
|
|
|
except IOError:
|
|
|
|
discard
|
2021-05-24 08:42:40 +00:00
|
|
|
quit 1
|
2022-07-23 05:54:01 +00:00
|
|
|
|
|
|
|
proc loadForkedState*(
|
2024-01-09 17:27:32 +00:00
|
|
|
path: string, consensusFork: ConsensusFork): ref ForkedHashedBeaconState =
|
|
|
|
let state = (ref ForkedHashedBeaconState)(kind: consensusFork)
|
|
|
|
withState(state[]):
|
|
|
|
forkyState.data = parseTest(path, SSZ, consensusFork.BeaconState)
|
|
|
|
forkyState.root = hash_tree_root(forkyState.data)
|
2024-04-03 14:43:43 +00:00
|
|
|
state
|