From 96dc7f6061ae42a6fed91ad591b348b3fb8c9d62 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 24 May 2021 20:03:24 +0200 Subject: [PATCH] add `historical_state_roots` * enables proving the state for empty slots * allows verifying the backfilled fields against the previous `historical_roots` field * allows trivially computing `historical_roots`, for any existing use cases --- presets/mainnet/altair.yaml | 5 ----- presets/minimal/altair.yaml | 5 ----- specs/altair/beacon-chain.md | 18 ++++++------------ specs/altair/fork.md | 22 ++++++++++++++-------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/presets/mainnet/altair.yaml b/presets/mainnet/altair.yaml index 2f0b72cc5..9f0ad9b4c 100644 --- a/presets/mainnet/altair.yaml +++ b/presets/mainnet/altair.yaml @@ -1,10 +1,5 @@ # Mainnet preset - Altair -# State vector lengths -# --------------------------------------------------------------- -# 2**24 (= 16,777,216) historical roots, ~26,131 years -HISTORICAL_BLOCK_ROOTS_LIMIT: 16777216 - # Updated penalty values # --------------------------------------------------------------- # 3 * 2**24 (= 50,331,648) diff --git a/presets/minimal/altair.yaml b/presets/minimal/altair.yaml index 6799f3533..88d78bea3 100644 --- a/presets/minimal/altair.yaml +++ b/presets/minimal/altair.yaml @@ -1,10 +1,5 @@ # Minimal preset - Altair -# State vector lengths -# --------------------------------------------------------------- -# 2**24 (= 16,777,216) historical roots, ~26,131 years -HISTORICAL_BLOCK_ROOTS_LIMIT: 16777216 - # Updated penalty values # --------------------------------------------------------------- # 3 * 2**24 (= 50,331,648) diff --git a/specs/altair/beacon-chain.md b/specs/altair/beacon-chain.md index 08a6d1366..559b344ee 100644 --- a/specs/altair/beacon-chain.md +++ b/specs/altair/beacon-chain.md @@ -16,7 +16,6 @@ - [Preset](#preset) - [Updated penalty values](#updated-penalty-values) - [Sync committee](#sync-committee) - - [State list lengths](#state-list-lengths) - [Configuration](#configuration) - [Inactivity penalties](#inactivity-penalties) - [Containers](#containers) @@ -133,12 +132,6 @@ This patch updates a few configuration values to move penalty parameters closer | `SYNC_COMMITTEE_SIZE` | `uint64(2**9)` (= 512) | Validators | | | `EPOCHS_PER_SYNC_COMMITTEE_PERIOD` | `uint64(2**9)` (= 512) | epochs | ~54 hours | -### State list lengths - -| Name | Value | Unit | Duration | -| - | - | :-: | :-: | -| `HISTORICAL_BLOCK_ROOTS_LIMIT` | `uint64(2**24)` (= 16,777,216) | historical roots | ~52,262 years | - ## Configuration ### Inactivity penalties @@ -182,8 +175,8 @@ class BeaconState(Container): latest_block_header: BeaconBlockHeader block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] - historical_root: Root - historical_block_roots: List[Root, HISTORICAL_BLOCK_ROOTS_LIMIT] + historical_block_roots: List[Root, HISTORICAL_ROOTS_LIMIT] + historical_state_roots: List[Root, HISTORICAL_ROOTS_LIMIT] # Eth1 eth1_data: Eth1Data eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] @@ -607,7 +600,7 @@ def process_epoch(state: BeaconState) -> None: process_effective_balance_updates(state) process_slashings_reset(state) process_randao_mixes_reset(state) - process_historical_block_roots_update(state) + process_historical_roots_update(state) process_participation_flag_updates(state) # [New in Altair] process_sync_committee_updates(state) # [New in Altair] ``` @@ -698,14 +691,15 @@ def process_participation_flag_updates(state: BeaconState) -> None: #### Historical roots updates -*Note*: The function `process_historical_block_roots_update` is new and replaces the `process_historical_roots_update` function from phase0. +*Note*: The function `process_historical_roots_update` changes definition compared to phase0. ```python -def process_historical_block_roots_update(state: BeaconState) -> None: +def process_historical_roots_update(state: BeaconState) -> None: # Set historical block root accumulator next_epoch = Epoch(get_current_epoch(state) + 1) if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0: state.historical_block_roots.append(hash_tree_root(state.block_roots)) + state.historical_state_roots.append(hash_tree_root(state.state_roots)) ``` #### Sync committee updates diff --git a/specs/altair/fork.md b/specs/altair/fork.md index a6876e76c..e8165bfb9 100644 --- a/specs/altair/fork.md +++ b/specs/altair/fork.md @@ -58,13 +58,17 @@ def translate_participation(state: BeaconState, pending_attestations: Sequence[p for flag_index in participation_flag_indices: epoch_participation[index] = add_flag(epoch_participation[index], flag_index) -def backfill_historical_block_roots(pre: BeaconState) -> List[Root, HISTORICAL_BLOCK_ROOTS_LIMIT]: - # Split historical blocks into chunks of SLOTS_PER_HISTORICAL_ROOT - # For each chunk, compute hash_tree_root(chunk) and add to returned list - # For new altair-based chains, use an empty list - # Backfilling requires access to external block storage. +def backfill_historical_roots(state: BeaconState, pre: BeaconState) -> None: + # Clients need to recreate `historical_block_roots` and + # `historical_state_roots` from their history. A large part can be + # precalculated and verified against historical_roots in state. + # Before the fork, clients should start collecting the part that has not + # been pre-calculated. + # + # The calclulated split historical roots can be verified against the existing + # historical_roots field up to the fork. + - return [] def upgrade_to_altair(pre: phase0.BeaconState) -> BeaconState: epoch = phase0.get_current_epoch(pre) @@ -82,8 +86,8 @@ def upgrade_to_altair(pre: phase0.BeaconState) -> BeaconState: latest_block_header=pre.latest_block_header, block_roots=pre.block_roots, state_roots=pre.state_roots, - historical_root=hash_tree_root(pre.historical_roots), - historical_block_roots=backfill_historical_block_roots(pre), + historical_block_roots=[], + historical_state_roots=[], # Eth1 eth1_data=pre.eth1_data, eth1_data_votes=pre.eth1_data_votes, @@ -109,6 +113,8 @@ def upgrade_to_altair(pre: phase0.BeaconState) -> BeaconState: # Fill in previous epoch participation from the pre state's pending attestations translate_participation(post, pre.previous_epoch_attestations) + backfill_historical_roots(post, pre) + # Fill in sync committees # Note: A duplicate committee is assigned for the current and next committee at the fork boundary post.current_sync_committee = get_next_sync_committee(post)