add bulk of naive aggregation strategy

This commit is contained in:
Danny Ryan 2019-10-23 17:13:01 +09:00
parent f63c122ddc
commit a9c2112571
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
2 changed files with 62 additions and 31 deletions

View File

@ -119,6 +119,7 @@ This section outlines constants that are used in this spec.
| `SHARD_SUBNET_COUNT` | `TODO` | The number of shard subnets used in the gossipsub protocol. | | `SHARD_SUBNET_COUNT` | `TODO` | The number of shard subnets used in the gossipsub protocol. |
| `TTFB_TIMEOUT` | `5s` | The maximum time to wait for first byte of request response (time-to-first-byte). | | `TTFB_TIMEOUT` | `5s` | The maximum time to wait for first byte of request response (time-to-first-byte). |
| `RESP_TIMEOUT` | `10s` | The maximum time for complete response transfer. | | `RESP_TIMEOUT` | `10s` | The maximum time for complete response transfer. |
| `ATTESTATION_PROPAGATION_SLOT_RANGE` | `4` | The maximum number of slots during which an attestation can be propagated. |
## The gossip domain: gossipsub ## The gossip domain: gossipsub
@ -147,10 +148,27 @@ Topics are plain UTF-8 strings and are encoded on the wire as determined by prot
Topic strings have form: `/eth2/TopicName/TopicEncoding`. This defines both the type of data being sent on the topic and how the data field of the message is encoded. (Further details can be found in [Messages](#Messages)). Topic strings have form: `/eth2/TopicName/TopicEncoding`. This defines both the type of data being sent on the topic and how the data field of the message is encoded. (Further details can be found in [Messages](#Messages)).
There are two main topics used to propagate attestations and beacon blocks to all nodes on the network. Their `TopicName`s are: There are two main topics used to propagate aggregate attestations and beacon blocks to all nodes on the network. Their `TopicName`s are:
- `beacon_block` - This topic is used solely for propagating new beacon blocks to all nodes on the networks. Blocks are sent in their entirety. Clients MUST validate the block proposer signature before forwarding it across the network. - `beacon_block` - This topic is used solely for propagating new beacon blocks to all nodes on the networks. Blocks are sent in their entirety. Clients MUST validate the block proposer signature before forwarding it across the network.
- `beacon_attestation` - This topic is used to propagate aggregated attestations (in their entirety) to subscribing nodes (typically block proposers) to be included in future blocks. Clients MUST validate that the block being voted for passes validation before forwarding the attestation on the network (TODO: [additional validations](https://github.com/ethereum/eth2.0-specs/issues/1332)). - `beacon_aggregate_and_proof` - This topic is used to propagate aggregated attestations (as `AggregateAndProof`s) to subscribing nodes (typically validators) to be included in future blocks. The following validations MUST pass before forwarding the `aggregate_and_proof` on the network.
- Clients MUST validate that the block being voted for (`aggregate_and_proof.aggregate.data.beacon_block_root`) passes validation.
- Clients MUST validate that `aggregate_and_proof.aggregate.data.slot` is
within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots.
- Clients MUST validate that the validator index is within the aggregate's
committee -- i.e. `aggregate_and_proof.index in get_attesting_indices(state, aggregate_and_proof.aggregate.data, aggregate_and_proof.aggregate.aggregation_bits)`.
- Clients MUST validate that `aggregate_and_proof.selection_proof` selects
the validator as an aggregator for the slot -- i.e. `is_aggregator(state, aggregate_and_proof.aggregate.data.index, aggregate_and_proof.selection_proof)` returns `True`.
- Clients MUST validate that the `aggregate_and_proof.selection_proof` is a
valid signature of the `aggregate_and_proof.aggregate.data.slot` by the validator with index `aggregate_and_proof.index`.
- Clients MUST validate that the signature of `aggregate_and_proof.aggregate`.
Attestation subnets are used to propagate unaggregated attestations to subsections of the network. Their `TopicName`s are:
- `index{index % ATTESTATION_SUBNET_COUNT}_beacon_attestation` - This topic is used to propagate unaggregated attestations to subsections of the network (typically beacon and persistent committees) to be aggregated before being passed to `beacon_aggregate_and_proof`. The following validations MUST pass before forwarding the `attestation` on the network.
- Clients MUST validate that the block being voted for (`attestation.data.beacon_block_root`) passes validation.
- Clients MUST validate that `attestation.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots.
- Clients MUST validate the signature of `attestation`.
Additional topics are used to propagate lower frequency validator messages. Their `TopicName`s are: Additional topics are used to propagate lower frequency validator messages. Their `TopicName`s are:
@ -160,13 +178,15 @@ Additional topics are used to propagate lower frequency validator messages. Thei
#### Interop #### 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. All validating clients SHOULD try to perform local attestation aggregation to prepare for block proposing. Unaggregated and aggregated attestations from all shards are sent as `Attestation` to the `beacon_aggregate_and_proof` 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 #### Mainnet
Attestation broadcasting is grouped into subnets defined by a topic. The number of subnets is defined via `ATTESTATION_SUBNET_COUNT`. The `CommitteeIndex`, `index`, is assigned to the topic: `index{index % ATTESTATION_SUBNET_COUNT}_beacon_attestation`. Attestation broadcasting is grouped into subnets defined by a topic. The number of subnets is defined via `ATTESTATION_SUBNET_COUNT`. The `CommitteeIndex`, `index`, is assigned to the topic: `index{index % ATTESTATION_SUBNET_COUNT}_beacon_attestation`.
Unaggregated attestations are sent to the subnet topic, `index{attestation.data.index % ATTESTATION_SUBNET_COUNT}_beacon_attestation`. Aggregated attestations are sent to the `beacon_attestation` topic. Unaggregated attestations are sent to the subnet topic, `index{attestation.data.index % ATTESTATION_SUBNET_COUNT}_beacon_attestation` as `Attestation`s.
Aggregated attestations are sent to the `beacon_aggregate_and_proof` topic as `AggregateAndProof`s.
### Messages ### Messages
@ -180,7 +200,7 @@ The payload is carried in the `data` field of a gossipsub message, and varies de
| Topic | Message Type | | Topic | Message Type |
|------------------------------|-------------------| |------------------------------|-------------------|
| beacon_block | BeaconBlock | | beacon_block | BeaconBlock |
| beacon_attestation | Attestation | | beacon_aggregate_and_proof | Attestation |
| shard{N}\_beacon_attestation | Attestation | | shard{N}\_beacon_attestation | Attestation |
| voluntary_exit | VoluntaryExit | | voluntary_exit | VoluntaryExit |
| proposer_slashing | ProposerSlashing | | proposer_slashing | ProposerSlashing |
@ -200,7 +220,7 @@ Topics are post-fixed with an encoding. Encodings define how the payload of a go
#### Mainnet #### Mainnet
- `ssz_snappy` - All objects are SSZ-encoded and then compressed with [Snappy](https://github.com/google/snappy). Example: The beacon attestation topic string is `/eth2/beacon_attestation/ssz_snappy`, and the data field of a gossipsub message is an `Attestation` that has been SSZ-encoded and then compressed with Snappy. - `ssz_snappy` - All objects are SSZ-encoded and then compressed with [Snappy](https://github.com/google/snappy). Example: The beacon aggregate attestation topic string is `/eth2/beacon_aggregate_and_proof/ssz_snappy`, and the data field of a gossipsub message is an `AggregateAndProof` that has been SSZ-encoded and then compressed with Snappy.
Implementations MUST use a single encoding. Changing an encoding will require coordination between participating implementations. Implementations MUST use a single encoding. Changing an encoding will require coordination between participating implementations.

View File

@ -354,31 +354,46 @@ Finally, the validator broadcasts `attestation` to the associated attestation su
## Attestation aggregation ## Attestation aggregation
The validator is expected to locally aggregate attestations with a similar `attestation_data` to their constructed `attestation` for the assigned `slot`. Some validators are selected to locally aggregate attestations with a similar `attestation_data` to their constructed `attestation` for the assigned `slot`.
The validator then _might_ broadcast their best aggregate to a global attestation channel two-thirds of the way through the `slot`-that is, `SECONDS_PER_SLOT * 2 / 3` seconds after the start of `slot`. ### Aggregation selection
#### Construct aggregate A validator is selected to aggregate based upon the following
Collect `attestations` seen via gossip during the `slot` that have an equivalent `attestation_data` to that constructed by the validator. ```python
def slot_signature(slot: Slot, privkey: int) -> BLSSignature:
domain = get_domain(state, DOMAIN_BEACON_AGGREGATOR, attestation.data.slot)
return bls_sign(prvkey, hash_tree_root(slot), domain)
```
The validator should create an `aggregate_attestation` with the following fields. ```python
def is_aggregator(state: BeaconState, slot: Slot, committee_index: CommitteeIndex, slot_signature: BLSSignature) -> bool:
committee = get_beacon_committee(state, slot, committee_index)
modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
return bytes_to_int(hash(slot_signature)[0:8]) % modulo == 0
```
##### Data ### Construct aggregate
If the validator is selected to aggregate (`is_aggregator()`), they construct an aggregate attestation via the following.
Collect `attestations` seen via gossip during the `slot` that have an equivalent `attestation_data` to that constructed by the validator, and create an `aggregate_attestation` with the following fields.
#### Data
Set `aggregate_attestation.data = attestation_data` where `attestation_data` is the `AttestationData` object that is the same for each individual attestation being aggregated. Set `aggregate_attestation.data = attestation_data` where `attestation_data` is the `AttestationData` object that is the same for each individual attestation being aggregated.
##### Aggregation bits #### Aggregation bits
Let `aggregate_attestation.aggregation_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE]` of length `len(committee)`, where each bit set from each individual attestation is set to `0b1`. Let `aggregate_attestation.aggregation_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE]` of length `len(committee)`, where each bit set from each individual attestation is set to `0b1`.
##### Custody bits #### Custody bits
- Let `aggregate_attestation.custody_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE]` filled with zeros of length `len(committee)`. - Let `aggregate_attestation.custody_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE]` filled with zeros of length `len(committee)`.
*Note*: This is a stub for Phase 0. *Note*: This is a stub for Phase 0.
##### Aggregate signature #### Aggregate signature
Set `aggregate_attestation.signature = aggregate_signature` where `aggregate_signature` is obtained from: Set `aggregate_attestation.signature = aggregate_signature` where `aggregate_signature` is obtained from:
@ -389,27 +404,23 @@ def get_aggregate_signature(attestations: Attestation) -> BLSSignature:
return aggregate_signature return aggregate_signature
``` ```
#### Broadcast aggregate ### Broadcast aggregate
Starting two-thirds of the way into the slot, the validator begins running the following routine to decide if their best aggregate should be broadcast to the global attestation channel (`beacon_attestation`). `seen()` is defined as having seen an aggregate If the validator is selected to aggregate (`is_aggregator`), then they broadcast their best aggregate to the global aggregate channel (`beacon_aggregate_and_proof`) two-thirds of the way through the `slot`-that is, `SECONDS_PER_SLOT * 2 / 3` seconds after the start of `slot`.
Aggregate attestations are broadcast as `AggregateAndProof` objects to prove to the gossip channel that the validator has been selected as an aggregator.
```python ```python
def should_broadcast_aggregate(aggregate_attestation: Attestation, index: ValidatorIndex) -> bool: class AggregateAndProof(Container):
if seen(index): index: ValidatorIndex
return False selection_proof: BLSSignature
if random.randrange(SIDED_DIE) == 0: aggregate: Attestation
return True
time.sleep(WAIT // 1000)
``` ```
Define `seen_better(aggregate_attestation, attestations)` as your aggregate Where
having more attestations included than any in the attestations you've seen on * `index` is the validator's `validator_index`.
the network so far. Could also make it better by _some_ amount. * `selection_proof` is the signature of the slot (`slot_signature()`).
* `aggregate` is the `aggregate_attestation` constructed in the previous section.
```python
def have_better_aggregate(aggregate_attestation, attestations):
```
## How to avoid slashing ## How to avoid slashing