Make flake8 check pass

This commit is contained in:
Hsiao-Wei Wang 2019-08-15 15:30:01 +08:00
parent 722a69467f
commit dc93391421
No known key found for this signature in database
GPG Key ID: 95B070122902DEA4
2 changed files with 96 additions and 43 deletions

View File

@ -39,6 +39,9 @@ from eth2spec.utils.hash_function import hash
PHASE1_IMPORTS = '''from typing import (
Any, Dict, Optional, Set, Sequence, MutableSequence, Tuple, Union,
)
from math import (
log2,
)
from dataclasses import (
dataclass,
@ -51,8 +54,10 @@ from eth2spec.utils.ssz.ssz_impl import (
is_zero,
)
from eth2spec.utils.ssz.ssz_typing import (
uint64, bit, boolean, Container, List, Vector, Bytes, BytesN,
Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
BasicValue, Elements, BaseList, SSZType,
Container, List, Vector, Bytes, BytesN, Bitlist, Bitvector, Bits,
Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96,
uint64, bit, boolean,
)
from eth2spec.utils.bls import (
bls_aggregate_pubkeys,

View File

@ -6,17 +6,54 @@
<!-- TOC -->
- [Merkle proof formats](#merkle-proof-formats)
- [Table of contents](#table-of-contents)
- [Constants](#constants)
- [Generalized Merkle tree index](#generalized-merkle-tree-index)
- [SSZ object to index](#ssz-object-to-index)
- [Merkle multiproofs](#merkle-multiproofs)
- [MerklePartial](#merklepartial)
- [`SSZMerklePartial`](#sszmerklepartial)
- [Proofs for execution](#proofs-for-execution)
- [Table of contents](#table-of-contents)
- [Custom types](#custom-types)
- [Helpers](#helpers)
- [Generalized Merkle tree index](#generalized-merkle-tree-index)
- [SSZ object to index](#ssz-object-to-index)
- [Helpers for generalized indices](#helpers-for-generalized-indices)
- [`concat_generalized_indices`](#concat_generalized_indices)
- [`get_generalized_index_length`](#get_generalized_index_length)
- [`get_generalized_index_bit`](#get_generalized_index_bit)
- [`generalized_index_sibling`](#generalized_index_sibling)
- [`generalized_index_child`](#generalized_index_child)
- [`generalized_index_parent`](#generalized_index_parent)
- [Merkle multiproofs](#merkle-multiproofs)
<!-- /TOC -->
## Custom types
We define the following Python custom types for type hinting and readability:
| Name | SSZ equivalent | Description |
| - | - | - |
| `GeneralizedIndex` | `uint64` | the index of a node in a binary Merkle tree |
## Helpers
```python
def get_next_power_of_two(x: int) -> int:
"""
Get next power of 2 >= the input.
"""
if x <= 2:
return x
elif x % 2 == 0:
return 2 * get_next_power_of_two(x // 2)
else:
return 2 * get_next_power_of_two((x + 1) // 2)
```
```python
def get_previous_power_of_two(x: int) -> int:
"""
Get the previous power of 2 >= the input.
"""
assert x >= 2
return get_next_power_of_two(x) // 2
```
## Generalized Merkle tree index
In a binary Merkle tree, we define a "generalized index" of a node as `2**depth + index`. Visually, this looks as follows:
@ -32,8 +69,8 @@ Note that the generalized index has the convenient property that the two childre
```python
def merkle_tree(leaves: List[Bytes32]) -> List[Bytes32]:
padded_length = next_power_of_2(len(leaves))
o = [ZERO_HASH] * padded_length + leaves + [ZERO_HASH] * (padded_length - len(leaves))
padded_length = get_next_power_of_two(len(leaves))
o = [Hash()] * padded_length + leaves + [Hash()] * (padded_length - len(leaves))
for i in range(len(leaves) - 1, 0, -1):
o[i] = hash(o[i * 2] + o[i * 2 + 1])
return o
@ -61,25 +98,27 @@ We can now define a concept of a "path", a way of describing a function that tak
```python
def item_length(typ: SSZType) -> int:
"""
Returns the number of bytes in a basic type, or 32 (a full hash) for compound types.
Return the number of bytes in a basic type, or 32 (a full hash) for compound types.
"""
if issubclass(typ, BasicValue):
return typ.byte_len
else:
return 32
def get_elem_type(typ: ComplexType, index: Union[int, str]) -> Type:
```
```python
def get_elem_type(typ: Union[BaseList, Container], index: Union[int, str]) -> SSZType:
"""
Returns the type of the element of an object of the given type with the given index
Return the type of the element of an object of the given type with the given index
or member variable name (eg. `7` for `x[7]`, `"foo"` for `x.foo`)
"""
return typ.get_fields()[index] if issubclass(typ, Container) else typ.elem_type
return typ.get_fields()[index] if issubclass(typ, Container) else typ.elem_type
```
```python
def chunk_count(typ: SSZType) -> int:
"""
Returns the number of hashes needed to represent the top-level elements in the given type
Return the number of hashes needed to represent the top-level elements in the given type
(eg. `x.foo` or `x[7]` but not `x[7].bar` or `x.foo.baz`). In all cases except lists/vectors
of basic types, this is simply the number of top-level elements, as each element gets one
hash. For lists/vectors of basic types, it is often fewer because multiple basic elements
@ -96,13 +135,16 @@ def chunk_count(typ: SSZType) -> int:
return len(typ.get_fields())
else:
raise Exception(f"Type not supported: {typ}")
```
```python
def get_item_position(typ: SSZType, index: Union[int, str]) -> Tuple[int, int, int]:
"""
Returns three variables: (i) the index of the chunk in which the given element of the item is
represented, (ii) the starting byte position within the chunk, (iii) the ending byte position within the chunk. For example for
a 6-item list of uint64 values, index=2 will return (0, 16, 24), index=5 will return (1, 8, 16)
Return three variables:
(i) the index of the chunk in which the given element of the item is represented;
(ii) the starting byte position within the chunk;
(iii) the ending byte position within the chunk.
For example: for a 6-item list of uint64 values, index=2 will return (0, 16, 24), index=5 will return (1, 8, 16)
"""
if issubclass(typ, Elements):
start = index * item_length(typ.elem_type)
@ -111,9 +153,10 @@ def get_item_position(typ: SSZType, index: Union[int, str]) -> Tuple[int, int, i
return typ.get_field_names().index(index), 0, item_length(get_elem_type(typ, index))
else:
raise Exception("Only lists/vectors/containers supported")
```
def get_generalized_index(typ: Type, path: List[Union[int, str]]) -> GeneralizedIndex:
```python
def get_generalized_index(typ: SSZType, path: List[Union[int, str]]) -> GeneralizedIndex:
"""
Converts a path (eg. `[7, "foo", 3]` for `x[7].foo[3]`, `[12, "bar", "__len__"]` for
`len(x[12].bar)`) into the generalized index representing its position in the Merkle tree.
@ -125,7 +168,7 @@ def get_generalized_index(typ: Type, path: List[Union[int, str]]) -> Generalized
typ, root = uint64, root * 2 + 1 if issubclass(typ, (List, Bytes)) else None
else:
pos, _, _ = get_item_position(typ, p)
root = root * (2 if issubclass(typ, (List, Bytes)) else 1) * next_power_of_two(chunk_count(typ)) + pos
root = root * (2 if issubclass(typ, (List, Bytes)) else 1) * get_next_power_of_two(chunk_count(typ)) + pos
typ = get_elem_type(typ, p)
return root
```
@ -144,7 +187,7 @@ def concat_generalized_indices(*indices: Sequence[GeneralizedIndex]) -> Generali
"""
o = GeneralizedIndex(1)
for i in indices:
o = o * get_previous_power_of_2(i) + (i - get_previous_power_of_2(i))
o = o * get_previous_power_of_two(i) + (i - get_previous_power_of_two(i))
return o
```
@ -152,41 +195,41 @@ def concat_generalized_indices(*indices: Sequence[GeneralizedIndex]) -> Generali
```python
def get_generalized_index_length(index: GeneralizedIndex) -> int:
"""
Returns the length of a path represented by a generalized index.
"""
return log2(index)
"""
Return the length of a path represented by a generalized index.
"""
return log2(index)
```
#### `get_generalized_index_bit`
```python
def get_generalized_index_bit(index: GeneralizedIndex, position: int) -> bool:
"""
Returns the given bit of a generalized index.
"""
return (index & (1 << position)) > 0
"""
Return the given bit of a generalized index.
"""
return (index & (1 << position)) > 0
```
#### `generalized_index_sibling`
```python
def generalized_index_sibling(index: GeneralizedIndex) -> GeneralizedIndex:
return index ^ 1
return index ^ 1
```
#### `generalized_index_child`
```python
def generalized_index_child(index: GeneralizedIndex, right_side: bool) -> GeneralizedIndex:
return index * 2 + right_side
return index * 2 + right_side
```
#### `generalized_index_parent`
```python
def generalized_index_parent(index: GeneralizedIndex) -> GeneralizedIndex:
return index // 2
return index // 2
```
## Merkle multiproofs
@ -214,7 +257,9 @@ def get_branch_indices(tree_index: GeneralizedIndex) -> List[GeneralizedIndex]:
while o[-1] > 1:
o.append(generalized_index_sibling(generalized_index_parent(o[-1])))
return o[:-1]
```
```python
def get_helper_indices(indices: List[GeneralizedIndex]) -> List[GeneralizedIndex]:
"""
Get the generalized indices of all "extra" chunks in the tree needed to prove the chunks with the given
@ -224,7 +269,7 @@ def get_helper_indices(indices: List[GeneralizedIndex]) -> List[GeneralizedIndex
all_indices = set()
for index in indices:
all_indices = all_indices.union(set(get_branch_indices(index) + [index]))
return sorted([
x for x in all_indices if not
(generalized_index_child(x, 0) in all_indices and generalized_index_child(x, 1) in all_indices) and not
@ -248,13 +293,16 @@ def verify_merkle_proof(leaf: Hash, proof: Sequence[Hash], index: GeneralizedInd
Now for multi-item proofs:
```python
def verify_merkle_multiproof(leaves: Sequence[Hash], proof: Sequence[Hash], indices: Sequence[GeneralizedIndex], root: Hash) -> bool:
def verify_merkle_multiproof(leaves: Sequence[Hash],
proof: Sequence[Hash],
indices: Sequence[GeneralizedIndex],
root: Hash) -> bool:
assert len(leaves) == len(indices)
helper_indices = get_helper_indices(indices)
assert len(proof) == len(helper_indices)
objects = {
**{index:node for index, node in zip(indices, leaves)},
**{index:node for index, node in zip(helper_indices, proof)}
**{index: node for index, node in zip(indices, leaves)},
**{index: node for index, node in zip(helper_indices, proof)}
}
keys = sorted(objects.keys(), reverse=True)
pos = 0