Skip to content

Commit 6e36d41

Browse files
authored
Merge branch 'master' into add-helpers
2 parents e0ae3ef + ef9ebec commit 6e36d41

File tree

1 file changed

+53
-27
lines changed

1 file changed

+53
-27
lines changed

specs/_features/eip7805/fork-choice.md

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
- [New `validate_inclusion_lists`](#new-validate_inclusion_lists)
1717
- [New `get_attester_head`](#new-get_attester_head)
1818
- [Modified `get_proposer_head`](#modified-get_proposer_head)
19+
- [Updated fork-choice helpers](#updated-fork-choice-helpers)
20+
- [Modified `update_proposer_boost_root`](#modified-update_proposer_boost_root)
1921
- [New fork-choice helpers](#new-fork-choice-helpers)
2022
- [New `get_view_freeze_cutoff_ms`](#new-get_view_freeze_cutoff_ms)
2123
- [New `get_inclusion_list_submission_due_ms`](#new-get_inclusion_list_submission_due_ms)
2224
- [New `get_proposer_inclusion_list_cutoff_ms`](#new-get_proposer_inclusion_list_cutoff_ms)
25+
- [New `record_block_inclusion_list_satisfaction`](#new-record_block_inclusion_list_satisfaction)
2326
- [Updated fork-choice handlers](#updated-fork-choice-handlers)
2427
- [New `on_inclusion_list`](#new-on_inclusion_list)
2528
- [Modified `on_block`](#modified-on_block)
@@ -234,6 +237,13 @@ def get_proposer_head(store: Store, head_root: Root, slot: Slot) -> Root:
234237
# Check that the missing votes are assigned to the parent and not being hoarded.
235238
parent_strong = is_parent_strong(store, head_root)
236239

240+
# Re-org more aggressively if there is a proposer equivocation in the previous slot.
241+
proposer_equivocation = is_proposer_equivocation(store, head_root)
242+
243+
# [New in EIP7805]
244+
# Check that the head block is in the unsatisfied inclusion list blocks
245+
inclusion_list_unsatisfied = head_root in store.unsatisfied_inclusion_list_blocks
246+
237247
reorg_prerequisites = all(
238248
[
239249
shuffling_stable,
@@ -246,16 +256,39 @@ def get_proposer_head(store: Store, head_root: Root, slot: Slot) -> Root:
246256
]
247257
)
248258

249-
# [New in EIP7805]
250-
# Check that the head block is in the unsatisfied inclusion list blocks
251-
inclusion_list_unsatisfied = head_root in store.unsatisfied_inclusion_list_blocks
252-
253259
if reorg_prerequisites and (head_late or inclusion_list_unsatisfied):
254260
return parent_root
261+
elif all([head_weak, current_time_ok, proposer_equivocation]):
262+
return parent_root
255263
else:
256264
return head_root
257265
```
258266

267+
## Updated fork-choice helpers
268+
269+
### Modified `update_proposer_boost_root`
270+
271+
```python
272+
def update_proposer_boost_root(store: Store, root: Root) -> None:
273+
is_first_block = store.proposer_boost_root == Root()
274+
is_timely = store.block_timeliness[root]
275+
is_inclusion_list_satisfied = root not in store.unsatisfied_inclusion_list_blocks
276+
277+
# [Modified in EIP7805]
278+
# Add proposer score boost if the block is timely, not conflicting with an
279+
# existing block, with the same the proposer as the canonical chain
280+
# and satisfies the inclusion list constraints.
281+
if is_timely and is_first_block and is_inclusion_list_satisfied:
282+
head_state = copy(store.block_states[get_head(store)])
283+
slot = get_current_slot(store)
284+
if head_state.slot < slot:
285+
process_slots(head_state, slot)
286+
block = store.blocks[root]
287+
# Only update if the proposer is the same as on the canonical chain
288+
if block.proposer_index == get_beacon_proposer_index(head_state):
289+
store.proposer_boost_root = root
290+
```
291+
259292
## New fork-choice helpers
260293

261294
### New `get_view_freeze_cutoff_ms`
@@ -279,6 +312,17 @@ def get_proposer_inclusion_list_cutoff_ms(epoch: Epoch) -> uint64:
279312
return get_slot_component_duration_ms(PROPOSER_INCLUSION_LIST_CUTOFF_BPS)
280313
```
281314

315+
### New `record_block_inclusion_list_satisfaction`
316+
317+
```python
318+
def record_block_inclusion_list_satisfaction(store: Store, root: Root) -> None:
319+
# Check if block satisfies the inclusion list constraints
320+
# If not, add this block to the store as inclusion list constraints unsatisfied
321+
is_inclusion_list_satisfied = validate_inclusion_lists(store, root, EXECUTION_ENGINE)
322+
if not is_inclusion_list_satisfied:
323+
store.unsatisfied_inclusion_list_blocks.add(root)
324+
```
325+
282326
## Updated fork-choice handlers
283327

284328
### New `on_inclusion_list`
@@ -320,6 +364,8 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
320364
block = signed_block.message
321365
# Parent block must be known
322366
assert block.parent_root in store.block_states
367+
# Make a copy of the state to avoid mutability issues
368+
state = copy(store.block_states[block.parent_root])
323369
# Blocks cannot be in the future. If they are, their consideration must be delayed until they are in the past.
324370
assert get_current_slot(store) >= block.slot
325371

@@ -339,8 +385,6 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
339385
assert is_data_available(hash_tree_root(block))
340386

341387
# Check the block is valid and compute the post-state
342-
# Make a copy of the state to avoid mutability issues
343-
state = copy(store.block_states[block.parent_root])
344388
block_root = hash_tree_root(block)
345389
state_transition(state, signed_block, True)
346390

@@ -349,28 +393,10 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
349393
# Add new state for this block to the store
350394
store.block_states[block_root] = state
351395

352-
# Add block timeliness to the store
353-
seconds_since_genesis = store.time - store.genesis_time
354-
time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
355-
epoch = get_current_store_epoch(store)
356-
attestation_threshold_ms = get_attestation_due_ms(epoch)
357-
is_before_attesting_interval = time_into_slot_ms < attestation_threshold_ms
358-
is_timely = get_current_slot(store) == block.slot and is_before_attesting_interval
359-
store.block_timeliness[hash_tree_root(block)] = is_timely
360-
396+
record_block_timeliness(store, block_root)
361397
# [New in EIP7805]
362-
# Check if block satisfies the inclusion list constraints
363-
# If not, add this block to the store as inclusion list constraints unsatisfied
364-
is_inclusion_list_satisfied = validate_inclusion_lists(store, block_root, EXECUTION_ENGINE)
365-
if not is_inclusion_list_satisfied:
366-
store.unsatisfied_inclusion_list_blocks.add(block_root)
367-
368-
# Add proposer score boost if the block is timely, not conflicting with an existing block
369-
# and satisfies the inclusion list constraints.
370-
is_first_block = store.proposer_boost_root == Root()
371-
# [Modified in EIP7805]
372-
if is_timely and is_first_block and is_inclusion_list_satisfied:
373-
store.proposer_boost_root = hash_tree_root(block)
398+
record_block_inclusion_list_satisfaction(store, block_root)
399+
update_proposer_boost_root(store, block_root)
374400

375401
# Update checkpoints in store if necessary
376402
update_checkpoints(store, state.current_justified_checkpoint, state.finalized_checkpoint)

0 commit comments

Comments
 (0)