Enable testing of a third of the SSZ consensus objects (minimal and mainnet)

This commit is contained in:
Mamy André-Ratsimbazafy 2019-11-12 16:21:15 +01:00 committed by Dustin Brody
parent f14d4c4796
commit a44925cd24
3 changed files with 150 additions and 4 deletions

View File

@ -54,8 +54,8 @@ task test, "Run all tests":
buildBinary "test_fixture_ssz_generic_types", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG"
# Consensus object SSZ tests
#buildBinary "test_fixture_ssz_static", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=minimal"
#buildBinary "test_fixture_ssz_static", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=mainnet"
buildBinary "test_fixture_ssz_consensus_objects", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=minimal"
buildBinary "test_fixture_ssz_consensus_objects", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=mainnet"
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=minimal"
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=mainnet"

View File

@ -28,5 +28,4 @@ import # Refactor state transition unit tests
import # Official fixtures that don't require SSZ parsing of invalid BLS signatures
# https://github.com/status-im/nim-beacon-chain/issues/374
./official/test_fixture_shuffling,
./official/test_fixture_bls,
./official/test_fixture_ssz_uint
./official/test_fixture_bls

View File

@ -0,0 +1,147 @@
# 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, unittest, strutils, streams, strformat, strscans,
macros, sets,
# Status libraries
stint, stew/bitseqs,
# Third-party
yaml,
# Beacon chain internals
../../beacon_chain/spec/[datatypes, digest],
../../beacon_chain/ssz,
# Test utilities
../testutil
# SSZ tests of consensus objects (minimal/mainnet preset specific)
# Parsing definitions
# ----------------------------------------------------------------
const
FixturesDir = currentSourcePath.rsplit(DirSep, 1)[0] / "fixtures"
SSZDir = FixturesDir/"tests-v0.9.1"/const_preset/"phase0"/"ssz_static"
type
SSZHashTreeRoot = object
# The test files have the values at the "root"
# so we **must** use "root" as a field name
root: string
# Some have a signing_root field
signing_root: string
# Make signing root optional
setDefaultValue(SSZHashTreeRoot, signing_root, "")
# Note this onyl tracks HashTreeRoot and SigningRoot
# Checking the values against the yaml file is TODO (require more flexible Yaml parser)
const Unsupported = toHashSet([
"AggregateAndProof", # Type for signature aggregation - not implemented
"Attestation", # RangeError on deserialization
# "AttestationData",
"AttesterSlashing", # RangeError on deserialization
"BeaconBlock", # RangeError on deserialization
"BeaconBlockBody", # RangeError on deserialization
# "BeaconBlockHeader", # HashTreeRoot KO - SigningRook OK
"BeaconState", # HashTreeRoot KO
# "Checkpoint",
"Deposit", # HashTreeRoot KO
"DepositData", # HashTreeRoot KO - SigningRoot KO
# "Eth1Data",
# "Fork",
# "HistoricalBatch", # OK
"IndexedAttestation", # RangeError on deserialization
# "PendingAttestation", # OK
"ProposerSlashing", # HashTreeRoot KO
"Validator", # HashTreeRoot KO
# "VoluntaryExit" # hashTreeRoot KO - SigningRoot OK
])
const UnsupportedMainnet = toHashSet([
"PendingAttestation", # HashTreeRoot KO
])
type Skip = enum
SkipNone
SkipHashTreeRoot
SkipSigningRoot
proc checkSSZ(T: typedesc, dir: string, expectedHash: SSZHashTreeRoot, skip = SkipNone) =
# Deserialize into a ref object to not fill Nim stack
var deserialized: ref T
new deserialized
deserialized[] = SSZ.loadFile(dir/"serialized.ssz", T)
if not(skip == SkipHashTreeRoot):
check: expectedHash.root == "0x" & toLowerASCII($deserialized.hashTreeRoot())
if expectedHash.signing_root != "" and not(skip == SkipSigningRoot):
check: expectedHash.signing_root == "0x" & toLowerASCII($deserialized[].signingRoot())
# TODO check the value
proc loadExpectedHashTreeRoot(dir: string): SSZHashTreeRoot =
var s = openFileStream(dir/"roots.yaml")
yaml.load(s, result)
s.close()
# Test runner
# ----------------------------------------------------------------
proc runSSZtests() =
for pathKind, sszType in walkDir(SSZDir, relative = true):
assert pathKind == pcDir
if sszType in Unsupported:
test &" Skipping {sszType:20} consensus object ✗✗✗":
discard
continue
when const_preset == "mainnet":
if sszType in UnsupportedMainnet:
test &" Skipping {sszType:20} consensus object ✗✗✗ (skipped on mainnet-only)":
discard
continue
let signingRootOnly = &" ↶↶↶ {sszType} - Skipping HashTreeRoot and testing SigningRoot only"
if sszType == "BeaconBlockHeader" or sszType == "VoluntaryExit":
echo signingRootOnly
test &" Testing {sszType:20} consensus object ✓✓✓":
let path = SSZDir/sszType
for pathKind, sszTestKind in walkDir(path, relative = true):
assert pathKind == pcDir
let path = SSZDir/sszType/sszTestKind
for pathKind, sszTestCase in walkDir(path, relative = true):
let path = SSZDir/sszType/sszTestKind/sszTestCase
let hash = loadExpectedHashTreeRoot(path)
case sszType:
# of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash)
of "Attestation": checkSSZ(Attestation, path, hash)
of "AttestationData": checkSSZ(AttestationData, path, hash)
of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash)
of "BeaconBlock": checkSSZ(BeaconBlock, path, hash)
of "BeaconBlockBody": checkSSZ(BeaconBlockBody, path, hash)
of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash, SkipHashTreeRoot) # TODO
of "BeaconState": checkSSZ(BeaconState, path, hash)
of "Checkpoint": checkSSZ(Checkpoint, path, hash)
of "Deposit": checkSSZ(Deposit, path, hash)
of "DepositData": checkSSZ(DepositData, path, hash)
of "Eth1Data": checkSSZ(Eth1Data, path, hash)
of "Fork": checkSSZ(Fork, path, hash)
of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash)
of "IndexedAttestation": checkSSZ(IndexedAttestation, path, hash)
of "PendingAttestation": checkSSZ(PendingAttestation, path, hash)
of "ProposerSlashing": checkSSZ(ProposerSlashing, path, hash)
of "Validator": checkSSZ(VoluntaryExit, path, hash)
of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash, SkipHashTreeRoot) # TODO
else:
raise newException(ValueError, "Unsupported test: " & sszType)
suite "Official - 0.9.1 - SSZ consensus objects " & preset():
runSSZtests()