mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-02-02 21:35:18 -05:00
PR feedback
This commit is contained in:
@@ -746,26 +746,36 @@ Beacon block production is significantly different because of the proof of stake
|
||||
|
||||
The beacon chain fork choice rule is a hybrid that combines justification and finality with Latest Message Driven (LMD) Greediest Heaviest Observed SubTree (GHOST). At any point in time a [validator](#dfn-validator) `v` subjectively calculates the beacon chain head as follows.
|
||||
|
||||
* Let `store` be the set of attestations and blocks that the [validator](#dfn-validator) `v` has observed and verified (in particular, block ancestors must be recursively verified). Attestations not part of any chain are still included in `store`.
|
||||
* Abstractly define `Store` as the type of storage object for the chain data and `store` be the set of attestations and blocks that the [validator](#dfn-validator) `v` has observed and verified (in particular, block ancestors must be recursively verified). Attestations not part of any chain are still included in `store`.
|
||||
* Let `finalized_head` be the finalized block with the highest slot number. (A block `B` is finalized if there is a descendant of `B` in `store` the processing of which sets `B` as finalized.)
|
||||
* Let `justified_head` be the descendant of `finalized_head` with the highest slot number that has been justified for at least `EPOCH_LENGTH` slots. (A block `B` is justified if there is a descendant of `B` in `store` the processing of which sets `B` as justified.) If no such descendant exists set `justified_head` to `finalized_head`.
|
||||
* Let `get_ancestor(store, block, slot)` be the ancestor of `block` with slot number `slot`. The `get_ancestor` function can be defined recursively as `def get_ancestor(store, block, slot): return block if block.slot == slot else get_ancestor(store, store.get_parent(block), slot)`.
|
||||
* Let `get_latest_attestation(store, validator)` be the attestation with the highest slot number in `store` from `validator`. If several such attestations exist, use the one the [validator](#dfn-validator) `v` observed first.
|
||||
* Let `get_latest_attestation_target(store, validator)` be the target block in the attestation `get_latest_attestation(store, validator)`.
|
||||
* The head is `lmd_ghost(store, justified_head)` where the function `lmd_ghost` is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count.
|
||||
* Let `get_ancestor(store: Store, block: BeaconBlock, slot: SlotNumber) -> BeaconBlock` be the ancestor of `block` with slot number `slot`. The `get_ancestor` function can be defined recursively as `def get_ancestor(store: Store, block: BeaconBlock, slot: SlotNumber) -> BeaconBlock: return block if block.slot == slot else get_ancestor(store, store.get_parent(block), slot)`.
|
||||
* Let `get_latest_attestation(store: Store, validator: Validator) -> Attestation` be the attestation with the highest slot number in `store` from `validator`. If several such attestations exist, use the one the [validator](#dfn-validator) `v` observed first.
|
||||
* Let `get_latest_attestation_target(store: Store, validator: Validator) -> BeaconBlock` be the target block in the attestation `get_latest_attestation(store, validator)`.
|
||||
* Let `get_children(block: BeaconBlock) -> List[BeaconBlock]` returns the children blocks of the given `block`.
|
||||
* Let `justified_head_state` be the `BeaconState` object after processing `justified_head`.
|
||||
* The `head` is `lmd_ghost(store, justified_head_state, justified_head)` where the function `lmd_ghost` is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count.
|
||||
|
||||
```python
|
||||
def lmd_ghost(store, start):
|
||||
validators = start.state.validator_registry
|
||||
active_validators = [validators[i] for i in
|
||||
get_active_validator_indices(validators, start.state.slot)]
|
||||
attestation_targets = [get_latest_attestation_target(store, validator)
|
||||
for validator in active_validators]
|
||||
def get_vote_count(block):
|
||||
return len([target for target in attestation_targets if
|
||||
get_ancestor(store, target, block.slot) == block])
|
||||
def lmd_ghost(store: Store, start_state: BeaconState, start_block: BeaconBlock) -> BeaconBlock:
|
||||
validators = start_state.validator_registry
|
||||
active_validators = [
|
||||
validators[i]
|
||||
for i in get_active_validator_indices(validators, start_state.slot)
|
||||
]
|
||||
attestation_targets = [
|
||||
get_latest_attestation_target(store, validator)
|
||||
for validator in active_validators
|
||||
]
|
||||
|
||||
head = start
|
||||
def get_vote_count(block: BeaconBlock) -> int:
|
||||
return len([
|
||||
target
|
||||
for target in attestation_targets
|
||||
if get_ancestor(store, target, block.slot) == block
|
||||
])
|
||||
|
||||
head = start_block
|
||||
while 1:
|
||||
children = get_children(head)
|
||||
if len(children) == 0:
|
||||
|
||||
Reference in New Issue
Block a user