eth2.0-specs/test_libs/pyspec/eth2spec/utils/test_merkle_minimal.py

81 lines
3.0 KiB
Python
Raw Normal View History

2019-06-22 19:27:56 +00:00
import pytest
2019-06-28 18:16:16 +00:00
from .merkle_minimal import zerohashes, merkleize_chunks, get_merkle_root
2019-06-22 19:27:56 +00:00
from .hash_function import hash
def h(a: bytes, b: bytes) -> bytes:
return hash(a + b)
def e(v: int) -> bytes:
# prefix with 0xfff... to make it non-zero
return b'\xff' * 28 + v.to_bytes(length=4, byteorder='little')
2019-06-22 19:27:56 +00:00
def z(i: int) -> bytes:
return zerohashes[i]
cases = [
# limit 0: always zero hash
(0, 0, z(0)),
2019-07-12 19:23:45 +00:00
(1, 0, None), # cut-off due to limit
(2, 0, None), # cut-off due to limit
# limit 1: padded to 1 element if not already. Returned (like identity func)
(0, 1, z(0)),
(1, 1, e(0)),
2019-07-12 19:23:45 +00:00
(2, 1, None), # cut-off due to limit
(1, 1, e(0)),
(0, 2, h(z(0), z(0))),
(1, 2, h(e(0), z(0))),
(2, 2, h(e(0), e(1))),
2019-07-12 19:23:45 +00:00
(3, 2, None), # cut-off due to limit
(16, 2, None), # bigger cut-off due to limit
(0, 4, h(h(z(0), z(0)), z(1))),
(1, 4, h(h(e(0), z(0)), z(1))),
(2, 4, h(h(e(0), e(1)), z(1))),
(3, 4, h(h(e(0), e(1)), h(e(2), z(0)))),
(4, 4, h(h(e(0), e(1)), h(e(2), e(3)))),
2019-07-12 19:23:45 +00:00
(5, 4, None), # cut-off due to limit
(0, 8, h(h(h(z(0), z(0)), z(1)), z(2))),
(1, 8, h(h(h(e(0), z(0)), z(1)), z(2))),
(2, 8, h(h(h(e(0), e(1)), z(1)), z(2))),
(3, 8, h(h(h(e(0), e(1)), h(e(2), z(0))), z(2))),
(4, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), z(2))),
(5, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), z(0)), z(1)))),
(6, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(z(0), z(0))))),
(7, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), z(0))))),
(8, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), e(7))))),
2019-07-12 19:23:45 +00:00
(9, 8, None), # cut-off due to limit
(0, 16, h(h(h(h(z(0), z(0)), z(1)), z(2)), z(3))),
(1, 16, h(h(h(h(e(0), z(0)), z(1)), z(2)), z(3))),
(2, 16, h(h(h(h(e(0), e(1)), z(1)), z(2)), z(3))),
(3, 16, h(h(h(h(e(0), e(1)), h(e(2), z(0))), z(2)), z(3))),
(4, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), z(2)), z(3))),
(5, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), z(0)), z(1))), z(3))),
(6, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(z(0), z(0)))), z(3))),
(7, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), z(0)))), z(3))),
(8, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), e(7)))), z(3))),
(9, 16, h(h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), e(7)))), h(h(h(e(8), z(0)), z(1)), z(2)))),
2019-06-22 19:27:56 +00:00
]
@pytest.mark.parametrize(
'count,limit,value',
2019-06-22 19:27:56 +00:00
cases,
)
def test_merkleize_chunks_and_get_merkle_root(count, limit, value):
2019-06-22 19:27:56 +00:00
chunks = [e(i) for i in range(count)]
2019-07-12 19:23:45 +00:00
if value is None:
bad = False
try:
merkleize_chunks(chunks, limit=limit)
bad = True
except AssertionError:
pass
if bad:
assert False, "expected merkleization to be invalid"
else:
assert merkleize_chunks(chunks, limit=limit) == value
assert get_merkle_root(chunks, pad_to=limit) == value