Skip to content

Commit

Permalink
Merge pull request #3352 from michaelsproul/boost-first-block
Browse files Browse the repository at this point in the history
Apply proposer boost to first block in case of equivocation
  • Loading branch information
hwwhww authored Sep 12, 2023
2 parents 7a53194 + fa1015c commit c5c7233
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
3 changes: 2 additions & 1 deletion specs/bellatrix/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
# Add proposer score boost if the block is timely
time_into_slot = (store.time - store.genesis_time) % SECONDS_PER_SLOT
is_before_attesting_interval = time_into_slot < SECONDS_PER_SLOT // INTERVALS_PER_SLOT
if get_current_slot(store) == block.slot and is_before_attesting_interval:
is_first_block = store.proposer_boost_root == Root()
if get_current_slot(store) == block.slot and is_before_attesting_interval and is_first_block:
store.proposer_boost_root = hash_tree_root(block)

# Update checkpoints in store if necessary
Expand Down
3 changes: 2 additions & 1 deletion specs/capella/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
# Add proposer score boost if the block is timely
time_into_slot = (store.time - store.genesis_time) % SECONDS_PER_SLOT
is_before_attesting_interval = time_into_slot < SECONDS_PER_SLOT // INTERVALS_PER_SLOT
if get_current_slot(store) == block.slot and is_before_attesting_interval:
is_first_block = store.proposer_boost_root == Root()
if get_current_slot(store) == block.slot and is_before_attesting_interval and is_first_block:
store.proposer_boost_root = hash_tree_root(block)

# Update checkpoints in store if necessary
Expand Down
3 changes: 2 additions & 1 deletion specs/deneb/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
# Add proposer score boost if the block is timely
time_into_slot = (store.time - store.genesis_time) % SECONDS_PER_SLOT
is_before_attesting_interval = time_into_slot < SECONDS_PER_SLOT // INTERVALS_PER_SLOT
if get_current_slot(store) == block.slot and is_before_attesting_interval:
is_first_block = store.proposer_boost_root == Root()
if get_current_slot(store) == block.slot and is_before_attesting_interval and is_first_block:
store.proposer_boost_root = hash_tree_root(block)

# Update checkpoints in store if necessary
Expand Down
3 changes: 2 additions & 1 deletion specs/phase0/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
# Add proposer score boost if the block is timely
time_into_slot = (store.time - store.genesis_time) % SECONDS_PER_SLOT
is_before_attesting_interval = time_into_slot < SECONDS_PER_SLOT // INTERVALS_PER_SLOT
if get_current_slot(store) == block.slot and is_before_attesting_interval:
is_first_block = store.proposer_boost_root == Root()
if get_current_slot(store) == block.slot and is_before_attesting_interval and is_first_block:
store.proposer_boost_root = hash_tree_root(block)

# Update checkpoints in store if necessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,56 @@ def test_proposer_boost_root_same_slot_untimely_block(spec, state):
yield 'steps', test_steps


@with_altair_and_later
@spec_state_test
def test_proposer_boost_is_first_block(spec, state):
test_steps = []
genesis_state = state.copy()

# Initialization
store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
yield 'anchor_state', state
yield 'anchor_block', anchor_block

# Build block that serves as head ONLY on timely arrival, and ONLY in that slot
state = genesis_state.copy()
next_slots(spec, state, 3)
pre_state = state.copy()
block_a = build_empty_block_for_next_slot(spec, state)
signed_block_a = state_transition_and_sign_block(spec, state, block_a)

# Process block on timely arrival just before end of boost interval
time = (store.genesis_time + block_a.slot * spec.config.SECONDS_PER_SLOT +
spec.config.SECONDS_PER_SLOT // spec.INTERVALS_PER_SLOT - 1)
on_tick_and_append_step(spec, store, time, test_steps)
yield from add_block(spec, store, signed_block_a, test_steps)
# `proposer_boost_root` is now `block_a`
assert store.proposer_boost_root == spec.hash_tree_root(block_a)
assert spec.get_weight(store, spec.hash_tree_root(block_a)) > 0
test_steps.append({
'checks': {
'proposer_boost_root': encode_hex(store.proposer_boost_root),
}
})

# make a different block at the same slot
state = pre_state.copy()
block_b = block_a.copy()
block_b.body.graffiti = b'\x34' * 32
signed_block_b = state_transition_and_sign_block(spec, state, block_b)
yield from add_block(spec, store, signed_block_b, test_steps)
# `proposer_boost_root` is still `block_a`
assert store.proposer_boost_root == spec.hash_tree_root(block_a)
assert spec.get_weight(store, spec.hash_tree_root(block_b)) == 0
test_steps.append({
'checks': {
'proposer_boost_root': encode_hex(store.proposer_boost_root),
}
})

yield 'steps', test_steps


@with_altair_and_later
@spec_state_test
@with_presets([MINIMAL], reason="too slow")
Expand Down

0 comments on commit c5c7233

Please sign in to comment.