From cc130990b6f3c4d6f789c70def2567b861c04eb4 Mon Sep 17 00:00:00 2001 From: Joanne Fuller <43776922+booleanfunction@users.noreply.github.com> Date: Thu, 25 Jun 2020 13:20:57 +1000 Subject: [PATCH 1/3] Clarify wording of pack, pack_bits and merkleize --- ssz/simple-serialize.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ssz/simple-serialize.md b/ssz/simple-serialize.md index a9d1da56e..a58a4c188 100644 --- a/ssz/simple-serialize.md +++ b/ssz/simple-serialize.md @@ -213,13 +213,17 @@ We first define helper functions: * `List[B, N]` and `Vector[B, N]`, where `B` is a basic type: `(N * size_of(B) + 31) // 32` (dividing by chunk size, rounding up) * `List[C, N]` and `Vector[C, N]`, where `C` is a composite type: `N` * containers: `len(fields)` -* `pack(value)`: given ordered objects of the same basic type, serialize them, pack them into `BYTES_PER_CHUNK`-byte chunks, right-pad the last chunk with zero bytes, and return the chunks. -* `pack_bits(bits)`: Given the `bits` of bitlist or bitvector, get `bitfield_bytes` by packing them in bytes and aligning to the start. The length-delimiting bit for bitlists is excluded. And then pack `bitfield_bytes` into `BYTES_PER_CHUNK`-byte chunks, right-pad the last chunk with zero bytes, and return the chunks. +* `pack(values)`: Given ordered objects of the same basic type: + 1. Serialize the values into bytes. + 1. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple. + 1. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks. + 1. Return the chunks. +* `pack_bits(bits)`: Given the bits of bitlist or bitvector, get `bitfield_bytes` by packing them in bytes and aligning to the start. The length-delimiting bit for bitlists is excluded. Then return `pack(bitfield_bytes)`. * `next_pow_of_two(i)`: get the next power of 2 of `i`, if not already a power of 2, with 0 mapping to 1. Examples: `0->1, 1->1, 2->2, 3->4, 4->4, 6->8, 9->16` * `merkleize(chunks, limit=None)`: Given ordered `BYTES_PER_CHUNK`-byte chunks, merkleize the chunks, and return the root: - * The merkleization depends on the effective input, which can be padded/limited: + * The merkleization depends on the effective input, which must be padded/limited: - if no limit: pad the `chunks` with zeroed chunks to `next_pow_of_two(len(chunks))` (virtually for memory efficiency). - - if `limit > len(chunks)`, pad the `chunks` with zeroed chunks to `next_pow_of_two(limit)` (virtually for memory efficiency). + - if `limit >= len(chunks)`, pad the `chunks` with zeroed chunks to `next_pow_of_two(limit)` (virtually for memory efficiency). - if `limit < len(chunks)`: do not merkleize, input exceeds limit. Raise an error instead. * Then, merkleize the chunks (empty input is padded to 1 zero chunk): - If `1` chunk: the root is the chunk itself. From 7f3e6564ebb277868b3f7598a56c4eedf180d029 Mon Sep 17 00:00:00 2001 From: Joanne Fuller <43776922+booleanfunction@users.noreply.github.com> Date: Fri, 26 Jun 2020 13:32:56 +1000 Subject: [PATCH 2/3] Update ssz/simple-serialize.md Co-authored-by: Hsiao-Wei Wang --- ssz/simple-serialize.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ssz/simple-serialize.md b/ssz/simple-serialize.md index a58a4c188..688c6a210 100644 --- a/ssz/simple-serialize.md +++ b/ssz/simple-serialize.md @@ -215,9 +215,9 @@ We first define helper functions: * containers: `len(fields)` * `pack(values)`: Given ordered objects of the same basic type: 1. Serialize the values into bytes. - 1. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple. - 1. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks. - 1. Return the chunks. + 2. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple. + 3. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks. + 4. Return the chunks. * `pack_bits(bits)`: Given the bits of bitlist or bitvector, get `bitfield_bytes` by packing them in bytes and aligning to the start. The length-delimiting bit for bitlists is excluded. Then return `pack(bitfield_bytes)`. * `next_pow_of_two(i)`: get the next power of 2 of `i`, if not already a power of 2, with 0 mapping to 1. Examples: `0->1, 1->1, 2->2, 3->4, 4->4, 6->8, 9->16` * `merkleize(chunks, limit=None)`: Given ordered `BYTES_PER_CHUNK`-byte chunks, merkleize the chunks, and return the root: From 588fcd0a6541261c611327fd8b019fa609e190b0 Mon Sep 17 00:00:00 2001 From: Joanne Fuller <43776922+booleanfunction@users.noreply.github.com> Date: Fri, 26 Jun 2020 13:33:23 +1000 Subject: [PATCH 3/3] Update ssz/simple-serialize.md Co-authored-by: Hsiao-Wei Wang --- ssz/simple-serialize.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssz/simple-serialize.md b/ssz/simple-serialize.md index 688c6a210..4f0c5c9fa 100644 --- a/ssz/simple-serialize.md +++ b/ssz/simple-serialize.md @@ -214,7 +214,7 @@ We first define helper functions: * `List[C, N]` and `Vector[C, N]`, where `C` is a composite type: `N` * containers: `len(fields)` * `pack(values)`: Given ordered objects of the same basic type: - 1. Serialize the values into bytes. + 1. Serialize `values` into bytes. 2. If not aligned to a multiple of `BYTES_PER_CHUNK` bytes, right-pad with zeroes to the next multiple. 3. Partition the bytes into `BYTES_PER_CHUNK`-byte chunks. 4. Return the chunks.