make exceeding limit raise an error

This commit is contained in:
protolambda
2019-07-12 21:23:45 +02:00
parent a8dc9157b8
commit 5a13684c7f
2 changed files with 26 additions and 12 deletions

View File

@@ -41,11 +41,15 @@ def merkleize_chunks(chunks, limit=None):
# If no limit is defined, we are just merkleizing chunks (e.g. SSZ container).
if limit is None:
limit = len(chunks)
count = len(chunks)
# See if the input is within expected size.
# If not, a list-limit is set incorrectly, or a value is unexpectedly large.
assert count <= limit
if limit == 0:
return zerohashes[0]
# Limit strictly. Makes no sense to merkleize objects above the intended padding.
# And illegal to exceed list limits, just as with serialization.
count = min(len(chunks), limit)
depth = max(count - 1, 0).bit_length()
max_depth = (limit - 1).bit_length()
tmp = [None for _ in range(max_depth + 1)]

View File

@@ -19,24 +19,24 @@ def z(i: int) -> bytes:
cases = [
# limit 0: always zero hash
(0, 0, z(0)),
(1, 0, z(0)), # cut-off due to limit
(2, 0, z(0)), # cut-off due to limit
(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)),
(2, 1, e(0)), # cut-off due to limit
(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))),
(3, 2, h(e(0), e(1))), # cut-off due to limit
(16, 2, h(e(0), e(1))), # bigger cut-off due to limit
(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)))),
(5, 4, h(h(e(0), e(1)), h(e(2), e(3)))), # cut-off due to limit
(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))),
@@ -46,7 +46,7 @@ cases = [
(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))))),
(9, 8, h(h(h(e(0), e(1)), h(e(2), e(3))), h(h(e(4), e(5)), h(e(6), e(7))))), # cut-off due to limit
(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))),
@@ -66,5 +66,15 @@ cases = [
)
def test_merkleize_chunks_and_get_merkle_root(count, limit, value):
chunks = [e(i) for i in range(count)]
assert merkleize_chunks(chunks, limit=limit) == value
assert get_merkle_root(chunks, pad_to=limit) == value
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