diff --git a/tests/official/fixtures_utils_v0_8_1.nim b/tests/official/fixtures_utils_v0_8_1.nim deleted file mode 100644 index e6838f98e..000000000 --- a/tests/official/fixtures_utils_v0_8_1.nim +++ /dev/null @@ -1,117 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-Present Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -import - # Standard library - os, strutils, - # Status libs - stew/byteutils, - serialization, json_serialization, - # Beacon chain internals - ../../beacon_chain/spec/datatypes - -export # Workaround: - # - https://github.com/status-im/nim-serialization/issues/4 - # - https://github.com/status-im/nim-serialization/issues/5 - # - https://github.com/nim-lang/Nim/issues/11225 - serialization.readValue - -# Process legacy EF test format (up to 0.8.1) -# ------------------------------------------- - -type - # TODO: use ref object to avoid allocating - # so much on the stack - pending https://github.com/status-im/nim-json-serialization/issues/3 - - TestConstants* = object - SHARD_COUNT*: int - TARGET_COMMITTEE_SIZE*: int - MAX_BALANCE_CHURN_QUOTIENT*: int - MAX_VALIDATORS_PER_COMMITTEE*: int - MIN_PER_EPOCH_CHURN_LIMIT*: int - SHUFFLE_ROUND_COUNT*: int - DEPOSIT_CONTRACT_TREE_DEPTH*: int - MIN_DEPOSIT_AMOUNT*: uint64 - MAX_EFFECTIVE_BALANCE*: uint64 - EJECTION_BALANCE*: uint64 - GENESIS_FORK_VERSION*: uint32 - GENESIS_SLOT*: Slot - GENESIS_EPOCH*: Epoch - GENESIS_START_SHARD*: uint64 - BLS_WITHDRAWAL_PREFIX*: array[1, byte] - SECONDS_PER_SLOT*: uint64 - MIN_ATTESTATION_INCLUSION_DELAY*: uint64 - SLOTS_PER_EPOCH*: int - MIN_SEED_LOOKAHEAD*: int - MAX_SEED_LOOKAHEAD*: int - EPOCHS_PER_ETH1_VOTING_PERIOD*: uint64 - SLOTS_PER_HISTORICAL_ROOT*: int - MIN_VALIDATOR_WITHDRAWABILITY_DELAY*: uint64 - PERSISTENT_COMMITTEE_PERIOD*: uint64 - LATEST_RANDAO_MIXES_LENGTH*: int - EPOCHS_PER_HISTORICAL_VECTOR*: int - EPOCHS_PER_SLASHINGS_VECTOR*: int - BASE_REWARD_FACTOR*: uint64 - WHISTLEBLOWER_REWARD_QUOTIENT*: uint64 - PROPOSER_REWARD_QUOTIENT*: uint64 - INACTIVITY_PENALTY_QUOTIENT*: uint64 - MIN_SLASHING_PENALTY_QUOTIENT*: int - MAX_PROPOSER_SLASHINGS*: int - MAX_ATTESTER_SLASHINGS*: int - MAX_ATTESTATIONS*: int - MAX_DEPOSITS*: int - MAX_VOLUNTARY_EXITS*: int - MAX_TRANSFERS*: int - DOMAIN_BEACON_PROPOSER*: DomainType - DOMAIN_RANDAO*: DomainType - DOMAIN_BEACON_ATTESTER*: DomainType - DOMAIN_DEPOSIT*: DomainType - DOMAIN_VOLUNTARY_EXIT*: DomainType - DOMAIN_TRANSFER*: DomainType - - Tests*[T] = object - title*: string - summary*: string - forks_timeline*: string - forks*: seq[string] - config*: string - runner*: string - handler*: string - test_cases*: seq[T] - -const - FixturesDir* = currentSourcePath.rsplit(DirSep, 1)[0] / "fixtures" - JsonTestsDir* = FixturesDir / "json_tests_v0.8.1" - -# ####################### -# Default init -proc default*(T: typedesc): T = discard - -# ####################### -# JSON deserialization - -proc readValue*[N: static int](r: var JsonReader, a: var array[N, byte]) {.inline.} = - # Needed for; - # - BLS_WITHDRAWAL_PREFIX - # - Fork datatypes - # TODO: are all bytes and bytearray serialized as hex? - # if so export that to nim-eth - hexToByteArray(r.readValue(string), a) - -proc readValue*(r: var JsonReader, a: var seq[byte]) {.inline.} = - ## Custom deserializer for seq[byte] - a = hexToSeqByte(r.readValue(string)) - -proc parseTests*(jsonPath: string, T: typedesc): Tests[T] = - try: - debugEcho " [Debug] Loading file: \"", jsonPath, '\"' - result = Json.loadFile(jsonPath, Tests[T]) - except SerializationError as err: - writeStackTrace() - stderr.write "Json load issue for file \"", jsonPath, "\"\n" - stderr.write err.formatMsg(jsonPath), "\n" - quit 1 diff --git a/tests/official/test_fixture_ssz_static.nim b/tests/official/test_fixture_ssz_static.nim deleted file mode 100644 index c4f8bc107..000000000 --- a/tests/official/test_fixture_ssz_static.nim +++ /dev/null @@ -1,215 +0,0 @@ -# beacon_chain -# Copyright (c) 2018 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -import - # Standard library - os, strutils, strformat, tables, unittest, sequtils, typetraits, - # Status libs - stew/[byteutils, bitseqs], nimcrypto/hash, - serialization/testing/tracing, - json_serialization, json_serialization/lexer, - # Beacon chain internals - ../../beacon_chain/ssz, - ../../beacon_chain/spec/[datatypes, validator, digest, crypto], - # Test utilities - ../testutil, - ./fixtures_utils_v0_8_1 - -const - failFast = defined(debug) and false - traceOnFailure = defined(debug) - -type - SpecObject[T] = ref object of RootObj - obj: ref T - - SszStaticTest* = object - obj: RootRef - objType, objJsonRepr: string - expectedBytes: seq[byte] - expectedRootHash, expectedSigHash: Eth2Digest - hasSigHash: bool - line: int - - ReaderProc = proc(r: var JsonReader): RootRef {.cdecl, gcsafe.} - TestingProc = proc(file: string, test: SszStaticTest) {.cdecl, gcsafe.} - - SpecTypeVtable = object - reader: ReaderProc - tester: TestingProc - -let testsDir = JsonTestsDir / "ssz_static" / "core" -let minDevTestFile = getTempDir() / "minimal_ssz_test.json" - -var specTypesRTTI = initTable[string, SpecTypeVtable]() - -proc readerImpl[T](r: var JsonReader): RootRef {.cdecl, gcsafe.} = - var res = SpecObject[T](obj: new T) - res.obj[] = r.readValue(T) - RootRef(res) - -# TODO: -# Fun fact: With mainnet settings, the BeaconState object -# is too large to safely exist as a stack variable. The -# `testerImpl` procedure below will trigger a segmentation -# fault on its very first line because of it. -# -# To work-around this issue, this file uses ref objects -# to store the loaded test cases, but we must compare them -# by value: -template valuesAreEqual[T](a, b: ref T): bool = - a[] == b[] - -template valuesAreEqual[T](a, b: T): bool = - a == b - -template `$`(x: ref auto): string = - $(x[]) - -proc readSszValueRef*(input: openarray[byte], T: type): ref T = - new result - result[] = readSszValue(input, T) - -proc testerImpl[T](path: string, sszTest: SszStaticTest) {.cdecl, gcsafe.} = - doAssert sszTest.obj != nil - var obj = SpecObject[T](sszTest.obj) - - test &"test case on line {sszTest.line}": - template execTest(testOpName, testOp, expectedRes) = - let ourRes = testOp - let success = valuesAreEqual(ourRes, expectedRes) - if not success and traceOnFailure: - {.gcsafe.}: - echo "====== ", testOpName, " failed ", path, ":", sszTest.line - echo " our result:" - echo " ", ourRes - echo " expected result:" - echo " ", expectedRes - when defined(serialization_tracing): - tracingEnabled = true - discard testOp - tracingEnabled = false - echo "======================================================" - if failFast: quit 1 - - # TODO BEWARE: Passing the boolean expression to `check` directly - # will trigger a Nim compilation bomb. This is most likely caused - # by a mis-behaving generics instantiations cache when a function - # is explicitly instantiated to get its address. - # There is a recursive instantiation loop of system's `$` operator. - check success - - execTest "serialization", - (let ourBytes = SSZ.encode(obj.obj[]); ourBytes), - sszTest.expectedBytes - - execTest "root hash check", - hash_tree_root(obj.obj[]), - sszTest.expectedRootHash - - when hasSigningRoot(T): - doAssert sszTest.hasSigHash - execTest "sig hash check", - signingRoot(obj.obj[]), - sszTest.expectedSigHash - - execTest "roundtrip", - readSszValueRef(sszTest.expectedBytes, T), - obj.obj - -template addSpecTypeRTTI(T: type) = - var reader = readerImpl[T] - var tester = testerImpl[T] - specTypesRTTI.add(T.name, SpecTypeVtable(reader: reader, - tester: tester)) -foreachSpecType(addSpecTypeRTTI) - -proc runTest(path: string, test: SszStaticTest) = - if test.objType != "Unsupported": - specTypesRTTI[test.objType].tester(path, test) - -proc advanceToClosingBrace(lexer: var JsonLexer, openedBraces = 1) = - var closedBraces = 0 - while closedBraces < openedBraces: - while lexer.tok notin {tkCurlyLe, tkCurlyRi}: - lexer.next - if lexer.tok == tkCurlyLe: - dec closedBraces - else: - inc closedBraces - lexer.next - -proc readValue*(r: var JsonReader, result: var SszStaticTest) {.gcsafe.} = - r.skipToken tkCurlyLe - - if r.lexer.tok != tkString: - r.raiseUnexpectedToken(etString) - - var reader: ReaderProc - let key = r.lexer.strVal - {.gcsafe.}: - if not specTypesRTTI.hasKey(key): - result.objType = "Unsupported" - r.lexer.advanceToClosingBrace - return - - result.objType = key - result.line = r.lexer.line - reader = specTypesRTTI[key].reader - - r.lexer.next - r.skipToken tkColon - r.skipToken tkCurlyLe - - while r.lexer.tok == tkString: - # TODO: I was hit by a very nasty Nim bug here. - # If you use `let` on the next line, the variable will be - # aliased to `r.lexer.strVar` instead of being copied. - # This will create problems, because the value is modified - # on the next line. - var field = r.lexer.strVal - r.lexer.next - r.skipToken tkColon - - case field - of "value": - result.obj = reader(r) - of "serialized": - result.expectedBytes = hexToSeqByte r.readValue(string) - of "root": - result.expectedRootHash = Eth2Digest.fromHex r.readValue(string) - of "signing_root": - result.expectedSigHash = Eth2Digest.fromHex r.readValue(string) - result.hasSigHash = true - else: - r.raiseUnexpectedField(field, type(result).name) - - if r.lexer.tok == tkComma: - r.lexer.next() - else: - break - - r.skipToken tkCurlyRi - r.skipToken tkCurlyRi - - when failFast: - # This will produce faster failures in debug builds - {.gcsafe.}: runTest result - -proc executeSuite(path: string) = - let sszSuite = path.parseTests SszStaticTest - suite &"{path}: {sszSuite.title}": - for sszTest in sszSuite.test_cases: - runTest path, sszTest - -if fileExists(minDevTestFile): - executeSuite minDevTestFile - -for kind, path in walkDir(testsDir): - if kind notin {pcFile, pcLinkToFile}: continue - if const_preset in path: - executeSuite path diff --git a/tests/official/test_fixture_ssz_static.nim.cfg b/tests/official/test_fixture_ssz_static.nim.cfg deleted file mode 100644 index 515f0a270..000000000 --- a/tests/official/test_fixture_ssz_static.nim.cfg +++ /dev/null @@ -1,2 +0,0 @@ --d:"serialization_tracing" --d:"ssz_testing" diff --git a/tests/official/test_fixture_ssz_uint.nim b/tests/official/test_fixture_ssz_uint.nim deleted file mode 100644 index c5c93951a..000000000 --- a/tests/official/test_fixture_ssz_uint.nim +++ /dev/null @@ -1,115 +0,0 @@ -# beacon_chain -# Copyright (c) 2018 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -import - # Standard library - ospaths, unittest, sequtils, - # Status libs - stint, serialization, - # Beacon chain internals - ../../beacon_chain/ssz, - ../../beacon_chain/spec/datatypes, - # Test utilities - ../testutil, - ./fixtures_utils_v0_8_1 - -type - SSZUint* = object - `type`*: string - value*: string - valid*: bool - ssz*: seq[byte] - tags*: seq[string] - -const - TestsDir = JsonTestsDir / "ssz_generic" / "uint" - -func to(val: string, T: typedesc): T = - when T is StUint: - val.parse(T) - else: # result is unsigned int - val.parse(StUint[8 * sizeof(T)]).data - -# TODO strformat for the skipped checks - -template checkSerialization(test: SSZUint, T: typedesc) = - if test.valid: - let value: T = test.value.to(T) - let serialized = SSZ.encode(value) - check(serialized == test.ssz) - elif test.value != "": - # No SSZ encoding -> expected failing serialization test - if test.tags.anyIt(it == "uint_underflow"): - # TODO: Stint throws RangeError for negative number parsing - # https://github.com/status-im/nim-stint/blob/ccf87daac1eef15238ff3d6d2edb138e22180d19/stint/io.nim#L130-L132 - # TODO: Stint checks with an assert that integer is positive or zero - # https://github.com/status-im/nim-stint/blob/ccf87daac1eef15238ff3d6d2edb138e22180d19/stint/io.nim#L35 - expect RangeError, OverflowError, AssertionError: - let value: T = test.value.to(T) - else: - # TODO tag "uint_overflow" does not throw an exception at the moment - echo " [Skipped - Serialization - TODO] tags: ", test.tags - else: - echo " [Skipped - Serialization - N/A] tags: ", test.tags - -template checkDeserialization(test: SSZUint, T: typedesc) = - if test.valid: - let deser = SSZ.decode(test.ssz, T) - check($deser == test.value) - elif test.value == "": - # No literal value -> expected failing deserialization test - if test.tags.anyIt(it == "wrong_length"): - expect IndexError: - let deser = SSZ.decode(test.ssz, T) - else: - echo " [Skipped - Deserialization] tags: ", test.tags - else: - echo " [Skipped - Deserialization - N/A] tags: ", test.tags - -proc runSSZUintTest(inputTests: Tests[SSZUint]) = - # We use Stint string -> uint parser + casting - # as it's generic over all unsigned integer size - # and not just BiggestUint - for test in inputTests.test_cases: - if test.`type` == "uint8": - test.checkSerialization(uint8) - test.checkDeserialization(uint8) - elif test.`type` == "uint16": - test.checkSerialization(uint16) - test.checkDeserialization(uint16) - elif test.`type` == "uint32": - test.checkSerialization(uint32) - test.checkDeserialization(uint32) - elif test.`type` == "uint64": - test.checkSerialization(uint64) - test.checkDeserialization(uint64) - # TODO: Stint serialization - # elif test.`type` == "uint128": - # test.checkSerialization(StUint[128]) - # elif test.`type` == "uint256": - # test.checkSerialization(StUint[256]) - else: - echo " [Skipped] uint size: ", test.`type` - -suite "Official - 0.8.1 - SSZ unsigned integer tests" & preset(): - block: # "Integers right at or beyond the bounds of the allowed value range" - let uintBounds = parseTests(TestsDir / "uint_bounds.json", SSZUint) - test uintBounds.summary & preset(): - runSSZUintTest(uintBounds) - - block: # "Random integers chosen uniformly over the allowed value range" - let uintRandom = parseTests(TestsDir / "uint_random.json", SSZUint) - test uintRandom.summary & preset(): - runSSZUintTest(uintRandom) - - # TODO: pending fix for https://github.com/status-im/nim-beacon-chain/issues/280 - block: # "Serialized integers that are too short or too long" - let uintWrongLength = parseTests(TestsDir / "uint_wrong_length.json", SSZUint) - test "[Skipped] " & uintWrongLength.summary & preset(): - # TODO: pending fix for https://github.com/status-im/nim-beacon-chain/issues/280 - echo " [Skipped] Pending https://github.com/status-im/nim-beacon-chain/issues/280" - # runSSZUintTest(uintWrongLength)