commit
4bd64d1e26
|
@ -160,7 +160,7 @@ Additional topics are used to propagate lower frequency validator messages. Thei
|
|||
|
||||
#### Interop
|
||||
|
||||
Unaggregated and aggregated attestations from all shards are sent to the `beacon_attestation` topic. Clients are not required to publish aggregate attestations but must be able to process them.
|
||||
Unaggregated and aggregated attestations from all shards are sent to the `beacon_attestation` topic. Clients are not required to publish aggregate attestations but must be able to process them. All validating clients SHOULD try to perform local attestation aggregation to prepare for block proposing.
|
||||
|
||||
#### Mainnet
|
||||
|
||||
|
@ -301,7 +301,7 @@ Here, `result` represents the 1-byte response code.
|
|||
|
||||
The token of the negotiated protocol ID specifies the type of encoding to be used for the req/resp interaction. Two values are possible at this time:
|
||||
|
||||
- `ssz`: The contents are [SSZ-encoded](../simple-serialize.md). This encoding type MUST be supported by all clients. For objects containing a single field, only the field is SSZ-encoded not a container with a single field. For example, the `BeaconBlocks` response would be an SSZ-encoded list of `BeaconBlock`s. All SSZ-Lists in the Req/Resp domain will have a maximum list size of `SSZ_MAX_LIST_SIZE`.
|
||||
- `ssz`: the contents are [SSZ-encoded](#ssz-encoding). This encoding type MUST be supported by all clients. For objects containing a single field, only the field is SSZ-encoded not a container with a single field. For example, the `BeaconBlocks` response would be an SSZ-encoded list of `BeaconBlock`s. All SSZ-Lists in the Req/Resp domain will have a maximum list size of `SSZ_MAX_LIST_SIZE`.
|
||||
- `ssz_snappy`: The contents are SSZ-encoded and then compressed with [Snappy](https://github.com/google/snappy). MAY be supported in the interoperability testnet; MUST be supported in mainnet.
|
||||
|
||||
#### SSZ-encoding strategy (with or without Snappy)
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
* **bitlist**: ordered variable-length collection of `boolean` values, limited to `N` bits
|
||||
* notation `Bitlist[N]`
|
||||
* **union**: union type containing one of the given subtypes
|
||||
* notation `Union[type_1, type_2, ...]`, e.g. `union[null, uint64]`
|
||||
* notation `Union[type_0, type_1, ...]`, e.g. `union[null, uint64]`
|
||||
|
||||
### Variable-size and fixed-size
|
||||
|
||||
|
@ -79,8 +79,18 @@ For convenience we alias:
|
|||
* `null`: `{}`
|
||||
|
||||
### Default values
|
||||
Assuming a helper function `default(type)` which returns the default value for `type`, we can recursively define the default value for all types.
|
||||
|
||||
The default value of a type upon initialization is recursively defined using `0` for `uintN`, `False` for `boolean` and the elements of `Bitvector`, and `[]` for lists and `Bitlist`. Unions default to the first type in the union (with type index zero), which is `null` if present in the union.
|
||||
| Type | Default Value |
|
||||
| ---- | ------------- |
|
||||
| `uintN` | `0` |
|
||||
| `boolean` | `False` |
|
||||
| `Container` | `[default(type) for type in container]` |
|
||||
| `Vector[type, N]` | `[default(type)] * N` |
|
||||
| `Bitvector[boolean, N]` | `[False] * N` |
|
||||
| `List[type, N]` | `[]` |
|
||||
| `Bitlist[boolean, N]` | `[]` |
|
||||
| `Union[type_0, type_1, ...]` | `default(type_0)` |
|
||||
|
||||
#### `is_zero`
|
||||
|
||||
|
|
|
@ -5,11 +5,19 @@ from random import Random
|
|||
from eth2spec.debug.random_value import RandomizationMode, get_random_ssz_object
|
||||
|
||||
|
||||
def bitvector_case_fn(rng: Random, mode: RandomizationMode, size: int):
|
||||
return get_random_ssz_object(rng, Bitvector[size],
|
||||
def bitvector_case_fn(rng: Random, mode: RandomizationMode, size: int, invalid_making_pos: int=None):
|
||||
bits = get_random_ssz_object(rng, Bitvector[size],
|
||||
max_bytes_length=(size + 7) // 8,
|
||||
max_list_length=size,
|
||||
mode=mode, chaos=False)
|
||||
if invalid_making_pos is not None and invalid_making_pos <= size:
|
||||
already_invalid = False
|
||||
for i in range(invalid_making_pos, size):
|
||||
if bits[i]:
|
||||
already_invalid = True
|
||||
if not already_invalid:
|
||||
bits[invalid_making_pos] = True
|
||||
return bits
|
||||
|
||||
|
||||
def valid_cases():
|
||||
|
@ -23,8 +31,12 @@ def invalid_cases():
|
|||
# zero length bitvecors are illegal
|
||||
yield 'bitvec_0', invalid_test_case(lambda: b'')
|
||||
rng = Random(1234)
|
||||
# Create a vector with test_size bits, but make the type typ_size instead,
|
||||
# which is invalid when used with the given type size
|
||||
# (and a bit set just after typ_size bits if necessary to avoid the valid 0 padding-but-same-last-byte case)
|
||||
for (typ_size, test_size) in [(1, 2), (2, 3), (3, 4), (4, 5),
|
||||
(5, 6), (8, 9), (9, 8), (16, 8), (32, 33), (512, 513)]:
|
||||
for mode in [RandomizationMode.mode_random, RandomizationMode.mode_zero, RandomizationMode.mode_max]:
|
||||
yield f'bitvec_{typ_size}_{mode.to_name()}_{test_size}', \
|
||||
invalid_test_case(lambda: serialize(bitvector_case_fn(rng, mode, test_size)))
|
||||
invalid_test_case(lambda: serialize(bitvector_case_fn(rng, mode, test_size,
|
||||
invalid_making_pos=typ_size)))
|
||||
|
|
|
@ -94,6 +94,8 @@ def get_random_ssz_object(rng: Random,
|
|||
length = 1
|
||||
elif mode == RandomizationMode.mode_max_count:
|
||||
length = max_list_length
|
||||
elif mode == RandomizationMode.mode_nil_count:
|
||||
length = 0
|
||||
|
||||
if typ.length < length: # SSZ imposes a hard limit on lists, we can't put in more than that
|
||||
length = typ.length
|
||||
|
|
Loading…
Reference in New Issue