more explicit about merkleization limit/pad

This commit is contained in:
protolambda 2019-07-12 20:39:55 +02:00
parent b2c8570606
commit 65b0311582
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
3 changed files with 15 additions and 9 deletions

View File

@ -37,12 +37,17 @@ def get_merkle_proof(tree, item_index):
return proof
def merkleize_chunks(chunks, pad_to: int=1):
if pad_to == 0:
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)
if limit == 0:
return zerohashes[0]
count = min(len(chunks), pad_to)
# 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 = (pad_to - 1).bit_length()
max_depth = (limit - 1).bit_length()
tmp = [None for _ in range(max_depth + 1)]
def merge(h, i):

View File

@ -126,6 +126,7 @@ def item_length(typ: SSZType) -> int:
def chunk_count(typ: SSZType) -> int:
# note that for lists, .length *on the type* describes the list limit.
if isinstance(typ, BasicType):
return 1
elif issubclass(typ, Bits):
@ -150,7 +151,7 @@ def hash_tree_root(obj: SSZValue):
raise Exception(f"Type not supported: {type(obj)}")
if isinstance(obj, (List, Bytes, Bitlist)):
return mix_in_length(merkleize_chunks(leaves, pad_to=chunk_count(obj.type())), len(obj))
return mix_in_length(merkleize_chunks(leaves, limit=chunk_count(obj.type())), len(obj))
else:
return merkleize_chunks(leaves)

View File

@ -61,10 +61,10 @@ cases = [
@pytest.mark.parametrize(
'count,pad_to,value',
'count,limit,value',
cases,
)
def test_merkleize_chunks_and_get_merkle_root(count, pad_to, value):
def test_merkleize_chunks_and_get_merkle_root(count, limit, value):
chunks = [e(i) for i in range(count)]
assert merkleize_chunks(chunks, pad_to=pad_to) == value
assert get_merkle_root(chunks, pad_to=pad_to) == value
assert merkleize_chunks(chunks, limit=limit) == value
assert get_merkle_root(chunks, pad_to=limit) == value