2019-07-27 21:57:07 +00:00
|
|
|
from ssz_test_case import invalid_test_case, valid_test_case
|
2020-03-11 22:18:06 +00:00
|
|
|
from eth2spec.utils.ssz.ssz_typing import boolean, uint8, uint16, uint32, uint64, uint128, uint256, Vector, BasicView
|
2019-07-27 20:31:04 +00:00
|
|
|
from eth2spec.utils.ssz.ssz_impl import serialize
|
|
|
|
from random import Random
|
2020-03-11 22:18:06 +00:00
|
|
|
from typing import Dict, Type
|
2019-07-27 20:31:04 +00:00
|
|
|
from eth2spec.debug.random_value import RandomizationMode, get_random_ssz_object
|
|
|
|
|
|
|
|
|
2020-03-11 22:18:06 +00:00
|
|
|
def basic_vector_case_fn(rng: Random, mode: RandomizationMode, elem_type: Type[BasicView], length: int):
|
2019-07-27 20:31:04 +00:00
|
|
|
return get_random_ssz_object(rng, Vector[elem_type, length],
|
|
|
|
max_bytes_length=length * 8,
|
|
|
|
max_list_length=length,
|
|
|
|
mode=mode, chaos=False)
|
|
|
|
|
|
|
|
|
2020-03-11 22:18:06 +00:00
|
|
|
BASIC_TYPES: Dict[str, Type[BasicView]] = {
|
2019-07-27 20:31:04 +00:00
|
|
|
'bool': boolean,
|
|
|
|
'uint8': uint8,
|
|
|
|
'uint16': uint16,
|
|
|
|
'uint32': uint32,
|
|
|
|
'uint64': uint64,
|
|
|
|
'uint128': uint128,
|
|
|
|
'uint256': uint256
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def valid_cases():
|
|
|
|
rng = Random(1234)
|
|
|
|
for (name, typ) in BASIC_TYPES.items():
|
2019-07-27 21:57:07 +00:00
|
|
|
random_modes = [RandomizationMode.mode_zero, RandomizationMode.mode_max]
|
|
|
|
if name != 'bool':
|
|
|
|
random_modes.append(RandomizationMode.mode_random)
|
2019-07-27 20:31:04 +00:00
|
|
|
for length in [1, 2, 3, 4, 5, 8, 16, 31, 512, 513]:
|
2019-07-27 21:57:07 +00:00
|
|
|
for mode in random_modes:
|
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}', \
|
2019-07-27 20:31:04 +00:00
|
|
|
valid_test_case(lambda: basic_vector_case_fn(rng, mode, typ, length))
|
|
|
|
|
|
|
|
|
|
|
|
def invalid_cases():
|
|
|
|
# zero length vectors are illegal
|
2019-07-27 21:57:07 +00:00
|
|
|
for (name, typ) in BASIC_TYPES.items():
|
|
|
|
yield f'vec_{name}_0', invalid_test_case(lambda: b'')
|
2019-07-27 20:31:04 +00:00
|
|
|
|
|
|
|
rng = Random(1234)
|
|
|
|
for (name, typ) in BASIC_TYPES.items():
|
2019-07-27 21:57:07 +00:00
|
|
|
random_modes = [RandomizationMode.mode_zero, RandomizationMode.mode_max]
|
|
|
|
if name != 'bool':
|
|
|
|
random_modes.append(RandomizationMode.mode_random)
|
2019-07-27 20:31:04 +00:00
|
|
|
for length in [1, 2, 3, 4, 5, 8, 16, 31, 512, 513]:
|
|
|
|
yield f'vec_{name}_{length}_nil', invalid_test_case(lambda: b'')
|
2019-07-27 21:57:07 +00:00
|
|
|
for mode in random_modes:
|
2020-03-11 22:18:06 +00:00
|
|
|
if length == 1:
|
|
|
|
# empty bytes, no elements. It may seem valid, but empty fixed-size elements are not valid SSZ.
|
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}_one_less', \
|
|
|
|
invalid_test_case(lambda: b"")
|
|
|
|
else:
|
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}_one_less', \
|
|
|
|
invalid_test_case(lambda: serialize(basic_vector_case_fn(rng, mode, typ, length - 1)))
|
2019-07-27 20:31:04 +00:00
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}_one_more', \
|
|
|
|
invalid_test_case(lambda: serialize(basic_vector_case_fn(rng, mode, typ, length + 1)))
|
2019-07-27 21:57:07 +00:00
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}_one_byte_less', \
|
|
|
|
invalid_test_case(lambda: serialize(basic_vector_case_fn(rng, mode, typ, length))[:-1])
|
|
|
|
yield f'vec_{name}_{length}_{mode.to_name()}_one_byte_more', \
|
|
|
|
invalid_test_case(lambda: serialize(basic_vector_case_fn(rng, mode, typ, length))
|
|
|
|
+ serialize(basic_vector_case_fn(rng, mode, uint8, 1)))
|