ssz proofread
This commit is contained in:
parent
c6cf6926c2
commit
4c991bf3ca
|
@ -1,6 +1,6 @@
|
||||||
# [WIP] SimpleSerialize (SSZ) Spec
|
# [WIP] SimpleSerialize (SSZ) Spec
|
||||||
|
|
||||||
This is the **work in progress** document to describe `simpleserialize`, the
|
This is the **work in progress** document to describe `SimpleSerialize`, the
|
||||||
current selected serialization method for Ethereum 2.0 using the Beacon Chain.
|
current selected serialization method for Ethereum 2.0 using the Beacon Chain.
|
||||||
|
|
||||||
This document specifies the general information for serializing and
|
This document specifies the general information for serializing and
|
||||||
|
@ -13,19 +13,22 @@ deserializing objects and data types.
|
||||||
* [Constants](#constants)
|
* [Constants](#constants)
|
||||||
* [Overview](#overview)
|
* [Overview](#overview)
|
||||||
+ [Serialize/Encode](#serializeencode)
|
+ [Serialize/Encode](#serializeencode)
|
||||||
- [uint: 8/16/24/32/64/256](#uint-816243264256)
|
- [uint](#uint)
|
||||||
|
- [Bool](#bool)
|
||||||
- [Address](#address)
|
- [Address](#address)
|
||||||
- [Hash](#hash)
|
- [Hash](#hash)
|
||||||
- [Bytes](#bytes)
|
- [Bytes](#bytes)
|
||||||
- [List/Vectors](#listvectors)
|
- [List/Vectors](#listvectors)
|
||||||
- [Container](#container)
|
- [Container](#container)
|
||||||
+ [Deserialize/Decode](#deserializedecode)
|
+ [Deserialize/Decode](#deserializedecode)
|
||||||
- [uint: 8/16/24/32/64/256](#uint-816243264256-1)
|
- [uint](#uint-1)
|
||||||
|
- [Bool](#bool-1)
|
||||||
- [Address](#address-1)
|
- [Address](#address-1)
|
||||||
- [Hash](#hash-1)
|
- [Hash](#hash-1)
|
||||||
- [Bytes](#bytes-1)
|
- [Bytes](#bytes-1)
|
||||||
- [List/Vectors](#listvectors-1)
|
- [List/Vectors](#listvectors-1)
|
||||||
- [Container](#container-1)
|
- [Container](#container-1)
|
||||||
|
+ [Tree Hash](#tree-hash)
|
||||||
* [Implementations](#implementations)
|
* [Implementations](#implementations)
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
@ -53,13 +56,19 @@ overhead.
|
||||||
| Constant | Value | Definition |
|
| Constant | Value | Definition |
|
||||||
|:---------------|:-----:|:--------------------------------------------------------------------------------------|
|
|:---------------|:-----:|:--------------------------------------------------------------------------------------|
|
||||||
| `LENGTH_BYTES` | 4 | Number of bytes used for the length added before a variable-length serialized object. |
|
| `LENGTH_BYTES` | 4 | Number of bytes used for the length added before a variable-length serialized object. |
|
||||||
|
| `CHUNK_SIZE` | 128 | The chuck size of the Merkle tree leaf. |
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
### Serialize/Encode
|
### Serialize/Encode
|
||||||
|
|
||||||
#### uint: 8/16/24/32/64/256
|
#### uint
|
||||||
|
|
||||||
|
| uint Type | Usage |
|
||||||
|
|:---------:|:------------------------------------------------|
|
||||||
|
| `uintN` | Type of arbitrary `N` bits unsigned integer. |
|
||||||
|
|
||||||
|
|
||||||
Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||||
|
|
||||||
|
@ -75,7 +84,7 @@ buffer_size = int_size / 8
|
||||||
return value.to_bytes(buffer_size, 'big')
|
return value.to_bytes(buffer_size, 'big')
|
||||||
```
|
```
|
||||||
|
|
||||||
#### bool
|
#### Bool
|
||||||
|
|
||||||
Convert directly to a single 0x00 or 0x01 byte.
|
Convert directly to a single 0x00 or 0x01 byte.
|
||||||
|
|
||||||
|
@ -91,8 +100,7 @@ return b'\x01' if value is True else b'\x00'
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
|
|
||||||
The `address` should already come as a hash/byte format. Ensure that length is
|
The `address` should already come as a hash/byte format. Ensure that length is **20**.
|
||||||
**20**.
|
|
||||||
|
|
||||||
| Check to perform | Code |
|
| Check to perform | Code |
|
||||||
|:-----------------------|:---------------------|
|
|:-----------------------|:---------------------|
|
||||||
|
@ -126,8 +134,7 @@ return value
|
||||||
|
|
||||||
For general `bytes` type:
|
For general `bytes` type:
|
||||||
1. Get the length/number of bytes; Encode into a `4-byte` integer.
|
1. Get the length/number of bytes; Encode into a `4-byte` integer.
|
||||||
2. Append the value to the length and return: ``[ length_bytes ] + [
|
2. Append the value to the length and return: ``[ length_bytes ] + [ value_bytes ]``
|
||||||
value_bytes ]``
|
|
||||||
|
|
||||||
| Check to perform | Code |
|
| Check to perform | Code |
|
||||||
|:-------------------------------------|:-----------------------|
|
|:-------------------------------------|:-----------------------|
|
||||||
|
@ -233,7 +240,7 @@ At each step, the following checks should be made:
|
||||||
|:-------------------------|:-----------------------------------------------------------|
|
|:-------------------------|:-----------------------------------------------------------|
|
||||||
| Ensure sufficient length | ``length(rawbytes) >= current_index + deserialize_length`` |
|
| Ensure sufficient length | ``length(rawbytes) >= current_index + deserialize_length`` |
|
||||||
|
|
||||||
#### uint: 8/16/24/32/64/256
|
#### uint
|
||||||
|
|
||||||
Convert directly from bytes into integer utilising the number of bytes the same
|
Convert directly from bytes into integer utilising the number of bytes the same
|
||||||
size as the integer length. (e.g. ``uint16 == 2 bytes``)
|
size as the integer length. (e.g. ``uint16 == 2 bytes``)
|
||||||
|
@ -258,7 +265,7 @@ return True if rawbytes == b'\x01' else False
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
|
|
||||||
Return the 20 bytes.
|
Return the 20-byte deserialized address.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
assert(len(rawbytes) >= current_index + 20)
|
assert(len(rawbytes) >= current_index + 20)
|
||||||
|
@ -344,9 +351,7 @@ Instantiate a container with the full set of deserialized data, matching each me
|
||||||
To deserialize:
|
To deserialize:
|
||||||
|
|
||||||
1. Get the names of the container's fields and sort them.
|
1. Get the names of the container's fields and sort them.
|
||||||
|
|
||||||
2. For each name in the sorted list, attempt to deserialize a value for that type. Collect these values as they will be used to construct an instance of the container.
|
2. For each name in the sorted list, attempt to deserialize a value for that type. Collect these values as they will be used to construct an instance of the container.
|
||||||
|
|
||||||
3. Construct a container instance after successfully consuming the entire subset of the stream for the serialized container.
|
3. Construct a container instance after successfully consuming the entire subset of the stream for the serialized container.
|
||||||
|
|
||||||
**Example in Python**
|
**Example in Python**
|
||||||
|
@ -383,23 +388,23 @@ assert item_index == start + LENGTH_BYTES + length
|
||||||
return typ(**values), item_index
|
return typ(**values), item_index
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tree_hash
|
### Tree Hash
|
||||||
|
|
||||||
The below `tree_hash` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For the final output only (ie. not intermediate outputs), if the output is less than 32 bytes, right-zero-pad it to 32 bytes. The goal is collision resistance *within* each type, not between types.
|
The below `tree_hash` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For the final output only (ie. not intermediate outputs), if the output is less than 32 bytes, right-zero-pad it to 32 bytes. The goal is collision resistance *within* each type, not between types.
|
||||||
|
|
||||||
We define `hash(x)` as `BLAKE2b-512(x)[0:32]`.
|
We define `hash(x)` as `BLAKE2b-512(x)[0:32]`.
|
||||||
|
|
||||||
#### uint: 8/16/24/32/64/256, bool, address, hash32
|
#### `uintN`, `bool`, `address`, `hash32`
|
||||||
|
|
||||||
Return the serialization of the value.
|
Return the serialization of the value.
|
||||||
|
|
||||||
#### bytes, hash96
|
#### `bytes`, `hashN`
|
||||||
|
|
||||||
Return the hash of the serialization of the value.
|
Return the hash of the serialization of the value.
|
||||||
|
|
||||||
#### List/Vectors
|
#### List/Vectors
|
||||||
|
|
||||||
First, we define some helpers and then the Merkle tree function. The constant `CHUNK_SIZE` is set to 128.
|
First, we define some helpers and then the Merkle tree function.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Merkle tree hash of a list of homogenous, non-empty items
|
# Merkle tree hash of a list of homogenous, non-empty items
|
||||||
|
@ -409,10 +414,10 @@ def merkle_hash(lst):
|
||||||
|
|
||||||
if len(lst) == 0:
|
if len(lst) == 0:
|
||||||
# Handle empty list case
|
# Handle empty list case
|
||||||
chunkz = [b'\x00' * CHUNKSIZE]
|
chunkz = [b'\x00' * CHUNK_SIZE]
|
||||||
elif len(lst[0]) < CHUNKSIZE:
|
elif len(lst[0]) < CHUNK_SIZE:
|
||||||
# See how many items fit in a chunk
|
# See how many items fit in a chunk
|
||||||
items_per_chunk = CHUNKSIZE // len(lst[0])
|
items_per_chunk = CHUNK_SIZE // len(lst[0])
|
||||||
|
|
||||||
# Build a list of chunks based on the number of items in the chunk
|
# Build a list of chunks based on the number of items in the chunk
|
||||||
chunkz = [b''.join(lst[i:i+items_per_chunk]) for i in range(0, len(lst), items_per_chunk)]
|
chunkz = [b''.join(lst[i:i+items_per_chunk]) for i in range(0, len(lst), items_per_chunk)]
|
||||||
|
@ -423,7 +428,7 @@ def merkle_hash(lst):
|
||||||
# Tree-hash
|
# Tree-hash
|
||||||
while len(chunkz) > 1:
|
while len(chunkz) > 1:
|
||||||
if len(chunkz) % 2 == 1:
|
if len(chunkz) % 2 == 1:
|
||||||
chunkz.append(b'\x00' * CHUNKSIZE)
|
chunkz.append(b'\x00' * CHUNK_SIZE)
|
||||||
chunkz = [hash(chunkz[i] + chunkz[i+1]) for i in range(0, len(chunkz), 2)]
|
chunkz = [hash(chunkz[i] + chunkz[i+1]) for i in range(0, len(chunkz), 2)]
|
||||||
|
|
||||||
# Return hash of root and length data
|
# Return hash of root and length data
|
||||||
|
|
Loading…
Reference in New Issue