Tidy, finish duties

This commit is contained in:
Paul Hauner 2021-12-13 17:09:09 +11:00
parent c99e48c60c
commit 38fffd3e2f
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
1 changed files with 74 additions and 31 deletions

View File

@ -2,52 +2,71 @@
## Introduction
In order to provide a syncing execution engine with a (partially-verified) view
of the head of the chain, it may be desirable for a consensus engine to import
beacon blocks without verifying the execution payloads. This partial sync is
called an *optimistic sync*.
In order to provide a syncing execution engine with a partial view of the head
of the chain, it may be desirable for a consensus engine to import beacon
blocks without verifying the execution payloads. This partial sync is called an
*optimistic sync*.
## Mechanisms
To perform an optimistic sync:
- The `execute_payload` function MUST return `True` if the execution
engine returns SYNCING or VALID. An INVALID response MUST return `False`.
engine returns `SYNCING` or `VALID`. An `INVALID` response MUST return `False`.
- The `validate_merge_block` function MUST NOT raise an assertion if both the
`pow_block` and `pow_parent` are unknown to the execution engine.
In addition to these changes to validation, the consensus engine MUST be able
to ascertain, after import, which blocks returned SYNCING and which returned
VALID. This document will assume consensus engines store the following sets:
to ascertain, after import, which blocks returned `SYNCING` and which returned
`VALID`. This document will assume that consensus engines store the following
sets:
- `valid_roots: Set[Root]`: `hash_tree_root(block)` where
`block.body.execution_payload` is known to be VALID.
`block.body.execution_payload` is known to be `VALID`.
- `optimistic_roots: Set[Root]`: `hash_tree_root(block)` where
`block.body.execution_payload` is known to be SYNCING.
`block.body.execution_payload` is known to be `SYNCING`.
Notably, `optimistic_roots` only includes blocks which have execution enabled
whilst `valid_roots` contains blocks *with or without* execution enabled (i.e.,
all blocks).
Notably, `optimistic_roots` only includes blocks which have execution enabled.
On the other hand, `valid_roots` contains blocks *with or without* execution
enabled (i.e., all blocks).
A consensus engine MUST be able to retrospectively (i.e., after import) modify
the status of SYNCING blocks to be either VALID or INVALID based upon responses
the status of `SYNCING` blocks to be either `VALID` or `INVALID` based upon responses
from an execution engine. I.e., perform the following transitions:
- SYNCING -> VALID
- SYNCING -> INVALID
- `SYNCING` -> `VALID`
- `SYNCING` -> `INVALID`
When a block transitions from SYNCING -> VALID, all *ancestors* of the block MUST
also transition from SYNCING -> VALID.
When a block transitions from `SYNCING` -> `VALID`, all *ancestors* of the block MUST
also transition from `SYNCING` -> `VALID`.
When a block transitions from SYNCING -> INVALID, all *descendants* of the
block MUST also transition from SYNCING -> INVALID.
When a block transitions from `SYNCING` -> `INVALID`, all *descendants* of the
block MUST also transition from `SYNCING` -> `INVALID`.
### Execution Engine Errors
A consensus engine MUST NOT interpret an error or failure to respond to a
message as a `SYNCING`, `VALID` or `INVALID` response. A consensus engine MAY
queue such a message for later processing.
## Merge Transition
To protect against attacks during the transition from empty `ExecutionPayload`
values to those which include the terminal PoW block, a consensus engine MUST
NOT perform an optimistic sync unless the `finalized_checkpoint.root` of the head
block references a block for which
`is_execution_enabled(head_state, head_block.body) == True`.
TODO: this restriction is very onerous, however it is the best known remedy for
the attack described in https://hackmd.io/S5ZEVhsNTqqfJirTAkBPlg I hope we can
do better.
## Fork Choice
Consensus engines MUST support removing blocks that transition from SYNCING to
INVALID. Specifically, an INVALID block MUST NOT be included in the canonical
chain and the weights from INVALID blocks MUST NOT be applied to any VALID or
SYNCING ancestors.
Consensus engines MUST support removing from fork choice blocks that transition
from `SYNCING` to `INVALID`. Specifically, a block deemed `INVALID` at any
point MUST NOT be included in the canonical chain and the weights from those
`INVALID` blocks MUST NOT be applied to any `VALID` or `SYNCING` ancestors.
## Validator assignments
@ -56,6 +75,8 @@ produce blocks, since an execution engine cannot produce a payload upon an
unknown parent. It cannot faithfully attest to the head block of the chain,
since it has not fully verified that block.
### Helpers
Let `head_block: BeaconBlock` be the result of calling of the fork choice
algorithm at the time of block production. Let `justified_block: BeaconBlock`
be the latest current justified ancestor ancestor of the `head_block`.
@ -75,8 +96,18 @@ def latest_valid_ancestor(block: BeaconBlock) -> Optional[BeaconBlock]:
return None
```
Let a node which returns `is_optimistic(head) == True` be an *optimistic
node*. Let a validator on an optimistic node be an *optimistic validator*.
```python
def recent_valid_ancestor(block: BeaconBlock) -> Optional[BeaconBlock]:
ancestor = latest_valid_ancestor(block)
if ancestor is None or ancestor.slot + SLOTS_PER_EPOCH >= block.slot:
return None
return ancestor
```
Let only a node which returns `is_optimistic(head) == True` be an *optimistic
node*. Let only a validator on an optimistic node be an *optimistic validator*.
### Block production
@ -86,9 +117,11 @@ A optimistic validator MUST NOT produce a block (i.e., sign across the
#### Exception 1.
If the justified block is fully verified (i.e., `not
is_optimistic(justified_block)`, the validator MUST produce a block upon
is_optimistic(justified_block)`, the validator MAY produce a block upon
`latest_valid_ancestor(head)`.
If the latest valid ancestor is `None`, the validator MUST NOT produce a block.
### Attesting
An optimistic validator MUST NOT participate in attestation (i.e., sign across the
@ -96,10 +129,20 @@ An optimistic validator MUST NOT participate in attestation (i.e., sign across t
`DOMAIN_AGGREGATE_AND_PROOF` domains), unless one of the follow exceptions are
met:
#### Exception
#### Exception 1.
If a validator *does not* have an optimistic head (i.e., `not
is_optimistic(head_block)`), the node is *fully synced*.
The validator may produce an attestation.
If the justified block is fully verified (i.e., `not
is_optimistic(justified_block)`, the validator MAY sign across the following
domains:
- `DOMAIN_BEACON_ATTESTER`: where `attestation.data.beacon_block_root == hash_tree_root(recent_valid_ancestor(head))`.
- `DOMAIN_AGGREGATE_AND_PROOF` and `DOMAIN_SELECTION_PROOF`: where `aggregate.message.aggregate.data.beacon_block_root == hash_tree_root(recent_valid_ancestor(head))`
If the recent valid ancestor is `None`, the validator MUST NOT participate in
attestation.
### Participating in Sync Committees
An optimistic validator MUST NOT participate in sync committees (i.e., sign across the
`DOMAIN_SYNC_COMMITTEE`, `DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF` or
`DOMAIN_CONTRIBUTION_AND_PROOF` domains).