Skip to content

Commit

Permalink
Historical batches
Browse files Browse the repository at this point in the history
This PR, a continuation of
replaces `historical_roots` with
`historical_block_roots`.

By keeping an accumulator of historical block roots in the state, it
becomes possible to validate the entire block history that led up to
that particular state without executing the transitions, and without
checking them one by one in backwards order using a parent chain.

This is interesting for archival purposes as well as when implementing
sync protocols that can verify chunks of blocks quickly, meaning they
can be downloaded in any order.

It's also useful as it provides a canonical hash by which such chunks of
blocks can be named, with a direct reference in the state.

In this PR, `historical_roots` is frozen at its current value and
`historical_batches` are computed from the merge epoch onwards.

After this PR, `block_batch_root` in the state can be used to verify an
era of blocks against the state with a simple root check.

The `historical_roots` values on the other hand can be used to verify
that a constant distributed with clients is valid for a particular
state, and therefore extends the block validation all the way back to
genesis without backfilling `block_batch_root` and without introducing
any new security assumptions in the client.

As far as naming goes, it's convenient to talk about an "era" being 8192
slots ~= 1.14 days. The 8192 number comes from the
SLOTS_PER_HISTORICAL_ROOT constant.

With multiple easily verifable blocks in a file, it becomes trivial to
offload block history to out-of-protocol transfer methods (bittorrent /
ftp / whatever) - including execution payloads, paving the way for a
future in which clients purge block history in p2p.

This PR can be applied along with the merge which simplifies payload
distribution from the get-go. Both execution and consensus clients
benefit because from the merge onwards, they both need to be able to
supply ranges of blocks in the sync protocol from what effectively is
"cold storage".

Another possibility is to include it in a future cleanup PR - this
complicates the "cold storage" mode above by not covering exection
payloads from start.
  • Loading branch information
arnetheduck committed Oct 27, 2022
1 parent aac851f commit 1c8d57e
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions specs/capella/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [`Withdrawal`](#withdrawal)
- [`BLSToExecutionChange`](#blstoexecutionchange)
- [`SignedBLSToExecutionChange`](#signedblstoexecutionchange)
- [`HistoricalBatchSummary`](#historicalbatchsummary)
- [Extended Containers](#extended-containers)
- [`ExecutionPayload`](#executionpayload)
- [`ExecutionPayloadHeader`](#executionpayloadheader)
Expand All @@ -37,6 +38,7 @@
- [Epoch processing](#epoch-processing)
- [Full withdrawals](#full-withdrawals)
- [Partial withdrawals](#partial-withdrawals)
- [Historical batches updates](#historical-batches-updates)
- [Block processing](#block-processing)
- [New `process_withdrawals`](#new-process_withdrawals)
- [Modified `process_execution_payload`](#modified-process_execution_payload)
Expand Down Expand Up @@ -132,6 +134,18 @@ class SignedBLSToExecutionChange(Container):
signature: BLSSignature
```

#### `HistoricalBatchSummary`

```python
class HistoricalBatchSummary(Container):
"""
`HistoricalBatchSummary` matches the components of the phase0 HistoricalBatch
making the two hash_tree_root-compatible.
"""
block_batch_root: Root
state_batch_root: Root
```

### Extended Containers

#### `ExecutionPayload`
Expand Down Expand Up @@ -213,7 +227,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_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] # Frozen in Merge, replaced by historical_batches
historical_batches: List[HistoricalBatchSummary, HISTORICAL_ROOTS_LIMIT] # Valid from Merge onwards
# Eth1
eth1_data: Eth1Data
eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH]
Expand Down Expand Up @@ -320,7 +335,7 @@ def process_epoch(state: BeaconState) -> None:
process_effective_balance_updates(state)
process_slashings_reset(state)
process_randao_mixes_reset(state)
process_historical_roots_update(state)
process_historical_batches_update(state)
process_participation_flag_updates(state)
process_sync_committee_updates(state)
process_full_withdrawals(state) # [New in Capella]
Expand Down Expand Up @@ -367,6 +382,21 @@ def process_partial_withdrawals(state: BeaconState) -> None:
state.next_partial_withdrawal_validator_index = validator_index
```

#### Historical batches updates

*Note*: The function `process_historical_batches_update` replaces `process_historical_roots_update` in phase0.

```python
def process_historical_batches_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:
historical_batch = HistoricalBatchSummary(
block_batch_root=hash_tree_root(state.block_roots),
state_batch_root=hash_tree_root(state.state_roots))
state.historical_batches.append(historical_batch)
```

### Block processing

```python
Expand Down

0 comments on commit 1c8d57e

Please sign in to comment.