diff --git a/setup.py b/setup.py index a47d4732fa..0ae71212cb 100644 --- a/setup.py +++ b/setup.py @@ -397,10 +397,6 @@ def finalize_options(self): print("no paths were specified, using default markdown file paths for pyspec" " build (spec fork: %s)" % self.spec_fork) self.md_doc_paths = get_md_doc_paths(self.spec_fork) - if self.spec_fork not in ('phase0', 'altair'): - self.md_doc_paths += """ - fork_choice/confirmation-rule.md - """ if len(self.md_doc_paths) == 0: raise Exception('no markdown files specified, and spec fork "%s" is unknown', self.spec_fork) diff --git a/specs/_features/eip7732/confirmation-rule.md b/specs/_features/eip7732/confirmation-rule.md new file mode 100644 index 0000000000..17aad0e8ac --- /dev/null +++ b/specs/_features/eip7732/confirmation-rule.md @@ -0,0 +1,60 @@ +# Fork Choice -- Confirmation Rule + +## Table of contents + + + + +- [Confirmation Rule](#confirmation-rule) + - [Helper Functions](#helper-functions) + - [Modified `get_ffg_support`](#modified-get_ffg_support) + + + + +## Confirmation Rule + +### Helper Functions + +#### Modified `get_ffg_support` + +```python +def get_ffg_support(store: Store, checkpoint: Root) -> Gwei: + """ + Returns the total weight supporting the checkpoint in the block's chain at block's epoch. + """ + current_epoch = get_current_store_epoch(store) + + # This function is only applicable to current and previous epoch blocks + assert current_epoch in [checkpoint.epoch, checkpoint.epoch + 1] + + if checkpoint not in store.checkpoint_states: + return Gwei(0) + + checkpoint_state = store.checkpoint_states[checkpoint] + + leaf_roots = [ + leaf for leaf in get_leaf_block_roots(store, checkpoint.root) + if get_checkpoint_block(store, leaf, checkpoint.epoch) == checkpoint.root] + + active_checkpoint_indices = get_active_validator_indices(checkpoint_state, checkpoint.epoch) + participating_indices_from_blocks = set().union(*[ + get_epoch_participating_indices( + store.block_states[root], + active_checkpoint_indices, + checkpoint.epoch == current_epoch + ) + for root in leaf_roots + ]) + + participating_indices_from_lmds = set([ + i + for i in store.latest_messages + if get_checkpoint_block( + store, store.latest_messages[i].root, + compute_epoch_at_slot(store.latest_messages[i].slot), # Modified in EIP7732 + ) == checkpoint.root + ]) + + return get_total_balance(checkpoint_state, participating_indices_from_blocks.union(participating_indices_from_lmds)) +``` \ No newline at end of file diff --git a/fork_choice/confirmation-rule.md b/specs/bellatrix/confirmation-rule.md similarity index 100% rename from fork_choice/confirmation-rule.md rename to specs/bellatrix/confirmation-rule.md diff --git a/specs/bellatrix/fork-choice.md b/specs/bellatrix/fork-choice.md index 17fb8e024d..a4c3df75dd 100644 --- a/specs/bellatrix/fork-choice.md +++ b/specs/bellatrix/fork-choice.md @@ -13,6 +13,7 @@ - [`safe_block_hash`](#safe_block_hash) - [`should_override_forkchoice_update`](#should_override_forkchoice_update) - [Helpers](#helpers) + - [Modified `Store`](#modified-store) - [`PayloadAttributes`](#payloadattributes) - [`PowBlock`](#powblock) - [`get_pow_block`](#get_pow_block) @@ -159,6 +160,32 @@ the result of `should_override_forkchoice_update` (when proposer reorgs are enab ## Helpers +### Modified `Store` + +*Note*: It's not a hard fork change. `highest_confirmed_block_current_epoch`, `highest_confirmed_block_previous_epoch`, and `leaves_last_slot_previous_epoch` are added for [confirmation rule](confirmation-rule.md). + +```python +@dataclass +class Store(object): + time: uint64 + genesis_time: uint64 + justified_checkpoint: Checkpoint + finalized_checkpoint: Checkpoint + unrealized_justified_checkpoint: Checkpoint + unrealized_finalized_checkpoint: Checkpoint + proposer_boost_root: Root + highest_confirmed_block_current_epoch: Root # New for confirmation rule + highest_confirmed_block_previous_epoch: Root # New for confirmation rule + leaves_last_slot_previous_epoch: Set[Root] # New for confirmation rule + equivocating_indices: Set[ValidatorIndex] + blocks: Dict[Root, BeaconBlock] = field(default_factory=dict) + block_states: Dict[Root, BeaconState] = field(default_factory=dict) + block_timeliness: Dict[Root, boolean] = field(default_factory=dict) + checkpoint_states: Dict[Checkpoint, BeaconState] = field(default_factory=dict) + latest_messages: Dict[ValidatorIndex, LatestMessage] = field(default_factory=dict) + unrealized_justifications: Dict[Root, Checkpoint] = field(default_factory=dict) +``` + ### `PayloadAttributes` Used to signal to initiate the payload build process via `notify_forkchoice_updated`. diff --git a/tests/core/pyspec/eth2spec/test/electra/confirmation_rule/test_confirmation_rule.py b/tests/core/pyspec/eth2spec/test/bellatrix/confirmation_rule/test_confirmation_rule.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/electra/confirmation_rule/test_confirmation_rule.py rename to tests/core/pyspec/eth2spec/test/bellatrix/confirmation_rule/test_confirmation_rule.py