Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardcode terminal total difficulty #2605

Merged
merged 7 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
# Extends the mainnet preset
PRESET_BASE: 'mainnet'

# Transition
# ---------------------------------------------------------------
# TBD, 2**256-1 is a placeholder
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935


# Genesis
# ---------------------------------------------------------------
# `2**14` (= 16,384)
Expand Down Expand Up @@ -31,9 +37,6 @@ MERGE_FORK_EPOCH: 18446744073709551615
SHARDING_FORK_VERSION: 0x03000000
SHARDING_FORK_EPOCH: 18446744073709551615

# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D.
MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 4294967296


# Time parameters
# ---------------------------------------------------------------
Expand Down
9 changes: 6 additions & 3 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
# Extends the minimal preset
PRESET_BASE: 'minimal'

# Transition
# ---------------------------------------------------------------
# TBD, 2**256-1 is a placeholder
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935


# Genesis
# ---------------------------------------------------------------
# [customized]
Expand Down Expand Up @@ -30,9 +36,6 @@ MERGE_FORK_EPOCH: 18446744073709551615
SHARDING_FORK_VERSION: 0x03000001
SHARDING_FORK_EPOCH: 18446744073709551615

djrtwo marked this conversation as resolved.
Show resolved Hide resolved
# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D.
MIN_ANCHOR_POW_BLOCK_DIFFICULTY: 4294967296


# Time parameters
# ---------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions specs/merge/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- [Execution](#execution)
- [Configuration](#configuration)
- [Genesis testing settings](#genesis-testing-settings)
- [Transition settings](#transition-settings)
- [Containers](#containers)
- [Extended containers](#extended-containers)
- [`BeaconBlockBody`](#beaconblockbody)
Expand Down Expand Up @@ -77,6 +78,12 @@ This patch adds transaction execution to the beacon chain as part of the Merge f
| `GENESIS_GAS_LIMIT` | `uint64(30000000)` (= 30,000,000) |
| `GENESIS_BASE_FEE_PER_GAS` | `Bytes32('0x00ca9a3b00000000000000000000000000000000000000000000000000000000')` (= 1,000,000,000) |

### Transition settings

| Name | Value |
| - | - |
| `TERMINAL_TOTAL_DIFFICULTY` | **TBD** |

## Containers

### Extended containers
Expand Down
9 changes: 2 additions & 7 deletions specs/merge/client-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@ This document specifies configurable settings that clients must implement for th

### Override terminal total difficulty

To coordinate manual overrides to [`terminal_total_difficulty`](fork-choice.md#transitionstore), clients
must provide `--terminal-total-difficulty-override` as a configurable setting.
To coordinate manual overrides to [`TERMINAL_TOTAL_DIFFICULTY`](./beacon-chain.md#Transition-settings) parameter, clients must provide `--terminal-total-difficulty-override` as a configurable setting. The value provided by this setting must take precedence over pre-configured `TERMINAL_TOTAL_DIFFICULTY` parameter.

If `TransitionStore` has already [been initialized](./fork.md#initializing-transition-store), this alters the previously initialized value of
`TransitionStore.terminal_total_difficulty`, otherwise this setting initializes `TransitionStore` with the specified, bypassing `compute_terminal_total_difficulty` and the use of an `anchor_pow_block`.
`terminal_total_difficulty`.
Except under exceptional scenarios, this setting is expected to not be used. Sufficient warning to the user about this exceptional configurable setting should be provided.

Except under exceptional scenarios, this setting is expected to not be used, and `terminal_total_difficulty` will operate with [default functionality](./fork.md#initializing-transition-store). Sufficient warning to the user about this exceptional configurable setting should be provided.
[here](fork.md#initializing-transition-store).
21 changes: 6 additions & 15 deletions specs/merge/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
- [`set_head`](#set_head)
- [`finalize_block`](#finalize_block)
- [Helpers](#helpers)
- [`TransitionStore`](#transitionstore)
- [`PowBlock`](#powblock)
- [`get_pow_block`](#get_pow_block)
- [`is_valid_terminal_pow_block`](#is_valid_terminal_pow_block)
Expand Down Expand Up @@ -68,14 +67,6 @@ def finalize_block(self: ExecutionEngine, block_hash: Hash32) -> bool:

## Helpers

### `TransitionStore`

```python
@dataclass
class TransitionStore(object):
terminal_total_difficulty: uint256
```

### `PowBlock`

```python
Expand All @@ -98,9 +89,9 @@ Let `get_pow_block(block_hash: Hash32) -> PowBlock` be the function that given t
Used by fork-choice handler, `on_block`.

```python
def is_valid_terminal_pow_block(transition_store: TransitionStore, block: PowBlock, parent: PowBlock) -> bool:
is_total_difficulty_reached = block.total_difficulty >= transition_store.terminal_total_difficulty
is_parent_total_difficulty_valid = parent.total_difficulty < transition_store.terminal_total_difficulty
def is_valid_terminal_pow_block(block: PowBlock, parent: PowBlock) -> bool:
is_total_difficulty_reached = block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
is_parent_total_difficulty_valid = parent.total_difficulty < TERMINAL_TOTAL_DIFFICULTY
return is_total_difficulty_reached and is_parent_total_difficulty_valid
```

Expand All @@ -111,7 +102,7 @@ def is_valid_terminal_pow_block(transition_store: TransitionStore, block: PowBlo
*Note*: The only modification is the addition of the verification of transition block conditions.

```python
def on_block(store: Store, signed_block: SignedBeaconBlock, transition_store: TransitionStore=None) -> None:
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
block = signed_block.message
# Parent block must be known
assert block.parent_root in store.block_states
Expand All @@ -131,10 +122,10 @@ def on_block(store: Store, signed_block: SignedBeaconBlock, transition_store: Tr
state_transition(state, signed_block, True)

# [New in Merge]
if (transition_store is not None) and is_merge_block(pre_state, block.body):
if is_merge_block(pre_state, block.body):
pow_block = get_pow_block(block.body.execution_payload.parent_hash)
pow_parent = get_pow_block(pow_block.parent_hash)
assert is_valid_terminal_pow_block(transition_store, pow_block, pow_parent)
assert is_valid_terminal_pow_block(pow_block, pow_parent)

# Add new block to the store
store.blocks[hash_tree_root(block)] = block
Expand Down
35 changes: 0 additions & 35 deletions specs/merge/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
- [Fork to Merge](#fork-to-merge)
- [Fork trigger](#fork-trigger)
- [Upgrading the state](#upgrading-the-state)
- [Initializing transition store](#initializing-transition-store)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand All @@ -28,17 +27,13 @@ Warning: this configuration is not definitive.
| - | - |
| `MERGE_FORK_VERSION` | `Version('0x02000000')` |
| `MERGE_FORK_EPOCH` | `Epoch(18446744073709551615)` **TBD** |
| `MIN_ANCHOR_POW_BLOCK_DIFFICULTY` | **TBD** |
| `TARGET_SECONDS_TO_MERGE` | `uint64(7 * 86400)` = (604,800) |

## Fork to Merge

### Fork trigger

TBD. Social consensus, along with state conditions such as epoch boundary, finality, deposits, active validator count, etc. may be part of the decision process to trigger the fork. For now we assume the condition will be triggered at epoch `MERGE_FORK_EPOCH`.

Since the Merge transition process relies on `Eth1Data` in the beacon state we do want to make sure that this data is fresh. This is achieved by forcing `MERGE_FORK_EPOCH` to point to eth1 voting period boundary, i.e. `MERGE_FORK_EPOCH` should satisfy the following condition `MERGE_FORK_EPOCH % EPOCHS_PER_ETH1_VOTING_PERIOD == 0`.

Note that for the pure Merge networks, we don't apply `upgrade_to_merge` since it starts with Merge version logic.

### Upgrading the state
Expand Down Expand Up @@ -100,33 +95,3 @@ def upgrade_to_merge(pre: altair.BeaconState) -> BeaconState:

return post
```

### Initializing transition store

If `state.slot % SLOTS_PER_EPOCH == 0`, `compute_epoch_at_slot(state.slot) == MERGE_FORK_EPOCH`, and the transition store has not already been initialized, a transition store is initialized to be further utilized by the transition process of the Merge.

Transition store initialization occurs after the state has been modified by corresponding `upgrade_to_merge` function.

```python
def compute_terminal_total_difficulty(anchor_pow_block: PowBlock) -> uint256:
seconds_per_voting_period = EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH * SECONDS_PER_SLOT
pow_blocks_per_voting_period = seconds_per_voting_period // SECONDS_PER_ETH1_BLOCK
pow_blocks_to_merge = TARGET_SECONDS_TO_MERGE // SECONDS_PER_ETH1_BLOCK
pow_blocks_after_anchor_block = ETH1_FOLLOW_DISTANCE + pow_blocks_per_voting_period + pow_blocks_to_merge
anchor_difficulty = max(MIN_ANCHOR_POW_BLOCK_DIFFICULTY, anchor_pow_block.difficulty)

return anchor_pow_block.total_difficulty + anchor_difficulty * pow_blocks_after_anchor_block


def get_transition_store(anchor_pow_block: PowBlock) -> TransitionStore:
terminal_total_difficulty = compute_terminal_total_difficulty(anchor_pow_block)
return TransitionStore(terminal_total_difficulty=terminal_total_difficulty)


def initialize_transition_store(state: BeaconState) -> TransitionStore:
pow_block = get_pow_block(state.eth1_data.block_hash)
return get_transition_store(pow_block)
```

*Note*: Transition store can also be initialized at client startup by [overriding terminal total
difficulty](client_settings.md#override-terminal-total-difficulty).
5 changes: 2 additions & 3 deletions specs/merge/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ All validator responsibilities remain unchanged other than those noted below. Na

##### Execution Payload

* Set `block.body.execution_payload = get_execution_payload(state, transition_store, execution_engine, pow_chain)` where:
* Set `block.body.execution_payload = get_execution_payload(state, execution_engine, pow_chain)` where:

```python
def get_pow_block_at_total_difficulty(total_difficulty: uint256, pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]:
Expand All @@ -84,11 +84,10 @@ def produce_execution_payload(state: BeaconState,


def get_execution_payload(state: BeaconState,
transition_store: TransitionStore,
execution_engine: ExecutionEngine,
pow_chain: Sequence[PowBlock]) -> ExecutionPayload:
if not is_merge_complete(state):
terminal_pow_block = get_pow_block_at_total_difficulty(transition_store.terminal_total_difficulty, pow_chain)
terminal_pow_block = get_pow_block_at_total_difficulty(TERMINAL_TOTAL_DIFFICULTY, pow_chain)
if terminal_pow_block is None:
# Pre-merge, empty payload
return ExecutionPayload()
Expand Down