Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] SSZ update #32

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions ssz/basic_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from random import Random

import ssz
from ssz.sedes import (
boolean,
UInt,
)

from renderers import (
render_test_case,
render_test,
)


random = Random(0)

UINT_SIZES = tuple(8 * 2**exponent for exponent in range(0, 6)) # 8, 16, ..., 256
NUM_RANDOM_UINT_VALUES = 16


def generate_uint_test_cases():
for bit_size in UINT_SIZES:
sedes = UInt(bit_size)
max_int = 2**bit_size - 1

values = (
0,
1,
max_int - 1,
max_int,
) + tuple(
random.randint(0, max_int) for _ in range(NUM_RANDOM_UINT_VALUES)
)

for value in values:
serial = ssz.encode(value, sedes)
yield render_test_case(
sedes=sedes,
valid=True,
value=value,
serial=serial,
tags=["basic", "uint"],
)


def generate_uint_test():
return render_test(
title="UInt",
summary="UInt tests for all sizes",
version="0.1",
test_cases=generate_uint_test_cases(),
)


def generate_bool_test_cases():
for value in (True, False):
yield render_test_case(
sedes=boolean,
valid=True,
value=value,
serial=ssz.encode(value, boolean),
tags=["basic", "bool"],
)


def generate_bool_test():
return render_test(
title="Bool",
summary="Tests for the two bool values",
version="0.1",
test_cases=generate_bool_test_cases(),
)
168 changes: 168 additions & 0 deletions ssz/flat_composite_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
from itertools import chain
from random import Random

import ssz
from ssz.sedes import (
boolean,
Boolean,
Container,
List,
UInt,
Vector,
)

from renderers import (
render_test_case,
render_test,
)


random = Random(0)

UINT_SIZES = tuple(8 * 2**exponent for exponent in range(0, 6)) # 8, 16, ..., 256
NUM_RANDOM_LENGTHS = 16
MAX_RANDOM_LIST_LENGTH = 512
MAX_RANDOM_VECTOR_LENGTH = 512
MAX_RANDOM_CONTAINER_LENGTH = 32


def get_random_basic_value(sedes):
if isinstance(sedes, Boolean):
return random.choice((True, False))
elif isinstance(sedes, UInt):
return random.randint(0, 8**sedes.size)
else:
raise ValueError("Neither bool nor UInt")


def generate_flat_list_test_cases():
for element_sedes in (boolean,) + tuple(UInt(bit_size) for bit_size in UINT_SIZES):
sedes = List(element_sedes)
lengths = (
0,
1,
256 // element_sedes.size - 1,
256 // element_sedes.size,
) + tuple(
random.randint(0, MAX_RANDOM_LIST_LENGTH)
for _ in range(NUM_RANDOM_LENGTHS)
)
for length in lengths:
value = tuple(get_random_basic_value(element_sedes) for _ in range(length))
yield render_test_case(
sedes=sedes,
valid=True,
value=value,
serial=ssz.encode(value, sedes),
tags=["composite", "list", "flat"],
)


def generate_flat_homogenous_container_test_cases():
for element_sedes in (boolean,) + tuple(UInt(bit_size) for bit_size in UINT_SIZES):
lengths = (
0,
1,
) + tuple(
random.randint(0, MAX_RANDOM_CONTAINER_LENGTH)
for _ in range(NUM_RANDOM_LENGTHS)
)
for length in lengths:
field_names = tuple(f"field{field_index}" for field_index in range(length))
sedes = Container(tuple(
(field_name, element_sedes)
for field_name in field_names
))
value = {
field_name: get_random_basic_value(element_sedes)
for field_name in field_names
}
yield render_test_case(
sedes=sedes,
valid=True,
value=value,
serial=ssz.encode(value, sedes),
tags=["composite", "container", "flat", "homogenous"],
)


def generate_flat_heterogenous_container_test_cases():
lengths = tuple(
random.randint(0, MAX_RANDOM_CONTAINER_LENGTH)
for _ in range(NUM_RANDOM_LENGTHS)
)
element_sedes_choices = (
boolean,
) + tuple(
UInt(bit_size) for bit_size in UINT_SIZES
)
for length in lengths:
field_names = tuple(f"field{field_index}" for field_index in range(length))
field_sedes = tuple(random.choice(element_sedes_choices) for _ in range(length))
sedes = Container(tuple(
(field_name, field_sedes)
for field_name, field_sedes in zip(field_names, field_sedes)
))
value = {
field_name: get_random_basic_value(sedes)
for field_name, sedes in zip(field_names, field_sedes)
}

yield render_test_case(
sedes=sedes,
valid=True,
value=value,
serial=ssz.encode(value, sedes),
tags=["composite", "container", "flat", "heterogenous"],
)


def generate_flat_vector_test_cases():
for element_sedes in (boolean,) + tuple(UInt(bit_size) for bit_size in UINT_SIZES):
lengths = (
0,
1,
) + tuple(
random.randint(0, MAX_RANDOM_VECTOR_LENGTH)
for _ in range(NUM_RANDOM_LENGTHS)
)
for length in lengths:
sedes = Vector(length, element_sedes)
value = tuple(get_random_basic_value(element_sedes) for _ in range(length))
yield render_test_case(
sedes=sedes,
valid=True,
value=value,
serial=ssz.encode(value, sedes),
tags=["composite", "vector", "flat", "homogenous"],
)


def generate_flat_list_test():
return render_test(
title="Flat List",
summary="Tests for lists of basic types",
version="0.1",
test_cases=generate_flat_list_test_cases(),
)


def generate_flat_container_test():
return render_test(
title="Flat Container",
summary="Tests for containers consisting of only basic types",
version="0.1",
test_cases=chain(
generate_flat_homogenous_container_test_cases(),
generate_flat_heterogenous_container_test_cases(),
)
)


def generate_flat_vector_test():
return render_test(
title="Flat Vector",
summary="Tests for vectors of basic types",
version="0.1",
test_cases=generate_flat_vector_test_cases(),
)
Loading