Skip to content

Commit

Permalink
Merge pull request #2617 from lsankar4033/terminal_blockhash_override_2
Browse files Browse the repository at this point in the history
Add terminal block hash override
  • Loading branch information
djrtwo authored Sep 27, 2021
2 parents 795d147 + 757ad78 commit cc92c2a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 8 deletions.
2 changes: 2 additions & 0 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ PRESET_BASE: 'mainnet'
# ---------------------------------------------------------------
# TBD, 2**256-2**10 is a placeholder
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912
# By default, don't use this param
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000


# Genesis
Expand Down
2 changes: 2 additions & 0 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ PRESET_BASE: 'minimal'
# ---------------------------------------------------------------
# TBD, 2**256-2**10 is a placeholder
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912
# By default, don't use this param
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000


# Genesis
Expand Down
1 change: 1 addition & 0 deletions specs/merge/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ This patch adds transaction execution to the beacon chain as part of the Merge f
| Name | Value |
| - | - |
| `TERMINAL_TOTAL_DIFFICULTY` | **TBD** |
| `TERMINAL_BLOCK_HASH` | `Hash32('0x0000000000000000000000000000000000000000000000000000000000000000')` |

## Containers

Expand Down
7 changes: 7 additions & 0 deletions specs/merge/client-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- [The Merge -- Client Settings](#the-merge----client-settings)
- [Override terminal total difficulty](#override-terminal-total-difficulty)
- [Override terminal block hash](#override-terminal-block-hash)

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

Expand All @@ -19,3 +20,9 @@ To coordinate manual overrides to [`TERMINAL_TOTAL_DIFFICULTY`](./beacon-chain.m

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.

### Override terminal block hash

To allow for transition coordination around a specific PoW block, clients must also provide `--terminal-block-hash-override` as a configurable setting.
The value provided by this setting takes precedence over the pre-configured `TERMINAL_BLOCK_HASH` parameter.

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.
7 changes: 5 additions & 2 deletions specs/merge/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ Used by fork-choice handler, `on_block`.

```python
def is_valid_terminal_pow_block(block: PowBlock, parent: PowBlock) -> bool:
if block.block_hash == TERMINAL_BLOCK_HASH:
return True

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 @@ -100,7 +103,7 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
assert block.slot > finalized_slot
# Check block is a descendant of the finalized block at the checkpoint finalized slot
assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root

# Check the block is valid and compute the post-state
state = pre_state.copy()
state_transition(state, signed_block, True)
Expand All @@ -126,7 +129,7 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
# Update finalized checkpoint
if state.finalized_checkpoint.epoch > store.finalized_checkpoint.epoch:
store.finalized_checkpoint = state.finalized_checkpoint

# Potentially update justified if different from store
if store.justified_checkpoint != state.current_justified_checkpoint:
# Update justified if new justified is later than store justified
Expand Down
25 changes: 19 additions & 6 deletions specs/merge/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,29 +97,42 @@ To obtain an execution payload, a block proposer building a block on top of a `s
* `pow_chain` is a list that abstractly represents all blocks in the PoW chain
* `fee_recipient` is the value suggested to be used for the `coinbase` field of the execution payload


```python
def get_pow_block_at_total_difficulty(total_difficulty: uint256, pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]:
def get_pow_block_at_terminal_total_difficulty(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]:
# `pow_chain` abstractly represents all blocks in the PoW chain
for block in pow_chain:
parent = get_pow_block(block.parent_hash)
if block.total_difficulty >= total_difficulty and parent.total_difficulty < total_difficulty:
block_reached_ttd = block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
parent_reached_ttd = parent.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
if block_reached_ttd and not parent_reached_ttd:
return block

return None


def get_terminal_pow_block(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]:
if TERMINAL_BLOCK_HASH != Hash32():
# Terminal block hash override takes precedence over terminal total difficulty
pow_block_overrides = [block for block in pow_chain if block.block_hash == TERMINAL_BLOCK_HASH]
if not any(pow_block_overrides):
return None
return pow_block_overrides[0]

return get_pow_block_at_terminal_total_difficulty(pow_chain)


def prepare_execution_payload(state: BeaconState,
pow_chain: Sequence[PowBlock],
fee_recipient: ExecutionAddress,
execution_engine: ExecutionEngine) -> Optional[PayloadId]:
if not is_merge_complete(state):
terminal_pow_block = get_pow_block_at_total_difficulty(TERMINAL_TOTAL_DIFFICULTY, pow_chain)
terminal_pow_block = get_terminal_pow_block(pow_chain)
if terminal_pow_block is None:
# Pre-merge, no prepare payload call is needed
return None
else:
# Signify merge via producing on top of the last PoW block
parent_hash = terminal_pow_block.block_hash
# Signify merge via producing on top of the terminal PoW block
parent_hash = terminal_pow_block.block_hash
else:
# Post-merge, normal payload
parent_hash = state.latest_execution_payload_header.block_hash
Expand Down

0 comments on commit cc92c2a

Please sign in to comment.