diff --git a/specs/test_formats/shuffling/README.md b/specs/test_formats/shuffling/README.md index 24ec8c568..a2184020b 100644 --- a/specs/test_formats/shuffling/README.md +++ b/specs/test_formats/shuffling/README.md @@ -22,7 +22,7 @@ count: int mapping: List[int] ``` -- The `bytes32` is encoded a string, hexadecimal encoding, prefixed with `0x`. +- The `bytes32` is encoded as a string, hexadecimal encoding, prefixed with `0x`. - Integers are validator indices. These are `uint64`, but realistically they are not as big. The `count` specifies the validator registry size. One should compute the shuffling for indices `0, 1, 2, 3, ..., count (exclusive)`. diff --git a/specs/test_formats/ssz_generic/README.md b/specs/test_formats/ssz_generic/README.md index da0898087..a47d1aca8 100644 --- a/specs/test_formats/ssz_generic/README.md +++ b/specs/test_formats/ssz_generic/README.md @@ -1,20 +1,197 @@ # SSZ, generic tests This set of test-suites provides general testing for SSZ: - to instantiate any container/list/vector/other type from binary data. + to decode any container/list/vector/other type from binary data, encode it back, and compute the hash-tree-root. -Since SSZ is in a development-phase, the full suite of features is not covered yet. -Note that these tests are based on the older SSZ package. -The tests are still relevant, but limited in scope: - more complex object encodings have changed since the original SSZ testing. +This test collection for general-purpose SSZ is experimental. +The `ssz_static` suite is the required minimal support for SSZ, and should be prioritized. -A minimal but useful series of tests covering `uint` encoding and decoding is provided. -This is a direct port of the older SSZ `uint` tests (minus outdated test cases). +The `ssz_generic` tests are split up into different handler, each specialized into a SSZ type: -Test format documentation can be found here: [uint test format](./uint.md). +- Vectors + - `basic_vector` + - `complex_vector` *not supported yet* +- List + - `basic_list` *not supported yet* + - `complex_list` *not supported yet* +- Bitfields + - `bitvector` + - `bitlist` +- Basic types + - `boolean` + - `uints` +- Containers + - `containers` -*Note*: The current Phase 0 spec does not use larger uints, and uses byte vectors (fixed length) instead to represent roots etc. -The exact uint lengths to support may be redefined in the future. -Extension of the SSZ tests collection is planned, with an update to the new spec-maintained `minimal_ssz.py`; - see CI/testing issues for progress tracking. +## Format + +For each type, a `valid` and a `invalid` suite is implemented. +The cases have the same format, but those in the `invalid` suite only declare a subset of the data a test in the `valid` declares. + +Each of the handlers encodes the SSZ type declaration in the file-name. See [Type Declarations](#type-declarations). + +### `valid` + +Valid has 3 parts: `meta.yaml`, `serialized.ssz`, `value.yaml` + +### `meta.yaml` + +Valid ssz objects can have a hash-tree-root, and for some types also a signing-root. +The expected roots are encoded into the metadata yaml: + +```yaml +root: Bytes32 -- Hash-tree-root of the object +signing_root: Bytes32 -- Signing-root of the object +``` + +The `Bytes32` is encoded as a string, hexadecimal encoding, prefixed with `0x`. + +### `serialized.ssz` + +The serialized form of the object, as raw SSZ bytes. + +### `value.yaml` + +The object, encoded as a YAML structure. Using the same familiar encoding as YAML data in the other test suites. + +### Conditions + +The conditions are the same for each type: + +- Encoding: After encoding the given `value` object, the output should match `serialized`. +- Decoding: After decoding the given `serialized` bytes, it should match the `value` object. +- Hash-tree-root: the root should match the root declared in the metadata. +- Signing-root: if present in metadata, the signing root of the object should match the container. + +## `invalid` + +Test cases in the `invalid` suite only include the `serialized.ssz` + +#### Condition + +Unlike the `valid` suite, invalid encodings do not have any `value` or hash tree root. +The `serialized` data should simply not be decoded without raising an error. + +Note that for some type declarations in the invalid suite, the type itself may technically be invalid. +This is a valid way of detecting `invalid` data too. E.g. a 0-length basic vector. + + +## Type declarations + +Most types are not as static, and reasonably be constructed during test runtime from the test case name. +Formats are listed below. + +For each test case, an additional `_{extra...}` may be appended to the name, + where `{extra...}` contains a human readable indication of the test case contents for debugging purposes. + +### `basic_vector` + +``` +Template: + +vec_{element type}_{length} + +Data: + +{element type}: bool, uint8, uint16, uint32, uint64, uint128, uint256 + +{length}: an unsigned integer +``` + + +### `bitlist` + +``` +Template: + +bitlist_{limit} + +Data: + +{limit}: the list limit, in bits, of the bitlist. Does not include the length-delimiting bit in the serialized form. +``` + + +### `bitvector` + +``` +Template: + +bitvec_{length} + +Data: + +{length}: the length, in bits, of the bitvector. +``` + +### `boolean` + +A boolean has no type variations. Instead, file names just plainly describe the contents for debugging. + +### `uints` + +``` +Template: + +uint_{size} + +Data: + +{size}: the uint size: 8, 16, 32, 64, 128 or 256. +``` + +### `containers` + +Containers are more complicated than the other types. Instead, a set of pre-defined container structures is referenced: + +``` +Template: + +{container name} + +Data: + +{container name}: Any of the container names listed below (exluding the `(Container)` python super type) +``` + +```python + +class SingleFieldTestStruct(Container): + A: byte + + +class SmallTestStruct(Container): + A: uint16 + B: uint16 + + +class FixedTestStruct(Container): + A: uint8 + B: uint64 + C: uint32 + + +class VarTestStruct(Container): + A: uint16 + B: List[uint16, 1024] + C: uint8 + + +class ComplexTestStruct(Container): + A: uint16 + B: List[uint16, 128] + C: uint8 + D: Bytes[256] + E: VarTestStruct + F: Vector[FixedTestStruct, 4] + G: Vector[VarTestStruct, 2] + + +class BitsStruct(Container): + A: Bitlist[5] + B: Bitvector[2] + C: Bitvector[1] + D: Bitlist[6] + E: Bitvector[8] +``` diff --git a/specs/test_formats/ssz_generic/uint.md b/specs/test_formats/ssz_generic/uint.md deleted file mode 100644 index fd7cf3221..000000000 --- a/specs/test_formats/ssz_generic/uint.md +++ /dev/null @@ -1,19 +0,0 @@ -# Test format: SSZ uints - -SSZ supports encoding of uints up to 32 bytes. These are considered to be basic types. - -## Test case format - -```yaml -type: "uintN" -- string, where N is one of [8, 16, 32, 64, 128, 256] -valid: bool -- expected validity of the input data -value: string -- string, decimal encoding, to support up to 256 bit integers -ssz: bytes -- string, input data, hex encoded, with prefix 0x -tags: List[string] -- description of test case, in the form of a list of labels -``` - -## Condition - -Two-way testing can be implemented in the test-runner: -- Encoding: After encoding the given input number `value`, the output should match `ssz` -- Decoding: After decoding the given `ssz` bytes, it should match the input number `value`