From df6a834889969cdb417bb56947e9f460942f836e Mon Sep 17 00:00:00 2001 From: lsankar4033 Date: Wed, 22 Sep 2021 11:18:41 -0700 Subject: [PATCH 1/8] Add TERMINAL_BLOCK_HASH override --- configs/mainnet.yaml | 3 ++- configs/minimal.yaml | 3 ++- specs/merge/beacon-chain.md | 1 + specs/merge/client-settings.md | 6 ++++++ specs/merge/fork-choice.md | 7 +++++-- specs/merge/validator.md | 10 +++++++++- 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index 6f2f582fac..d5ea308d06 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -7,7 +7,8 @@ PRESET_BASE: 'mainnet' # --------------------------------------------------------------- # TBD, 2**256-1 is a placeholder TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 - +# By default, don't use this param +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 # Genesis # --------------------------------------------------------------- diff --git a/configs/minimal.yaml b/configs/minimal.yaml index 8da3260f5c..8f7bd63397 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -7,7 +7,8 @@ PRESET_BASE: 'minimal' # --------------------------------------------------------------- # TBD, 2**256-1 is a placeholder TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129639935 - +# By default, don't use this param +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 # Genesis # --------------------------------------------------------------- diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 39f457252b..35f1407be5 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -83,6 +83,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` | `Bytes32('0x0000000000000000000000000000000000000000000000000000000000000000')` | ## Containers diff --git a/specs/merge/client-settings.md b/specs/merge/client-settings.md index 64b2b20e68..efef1344fe 100644 --- a/specs/merge/client-settings.md +++ b/specs/merge/client-settings.md @@ -19,3 +19,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 fork 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. diff --git a/specs/merge/fork-choice.md b/specs/merge/fork-choice.md index 8051ab3eb5..53266cf467 100644 --- a/specs/merge/fork-choice.md +++ b/specs/merge/fork-choice.md @@ -90,6 +90,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 @@ -116,7 +119,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) @@ -142,7 +145,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 diff --git a/specs/merge/validator.md b/specs/merge/validator.md index 645e1967b2..88e24a2126 100644 --- a/specs/merge/validator.md +++ b/specs/merge/validator.md @@ -74,6 +74,14 @@ def get_pow_block_at_total_difficulty(total_difficulty: uint256, pow_chain: Sequ return None +def get_terminal_pow_block(total_difficulty: uint256, block_hash_override: Hash32, pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]: + # check block hash override prior to total difficulty + pow_block_overrides = [pow_block for pow_block in pow_chain if pow_block.block_hash == block_hash_override] + if len(pow_block_overrides) != 0: + return pow_block_overrides[0] + + return get_pow_block_at_total_difficulty(total_difficulty, pow_chain) + def produce_execution_payload(state: BeaconState, parent_hash: Hash32, @@ -87,7 +95,7 @@ def get_execution_payload(state: BeaconState, execution_engine: ExecutionEngine, pow_chain: Sequence[PowBlock]) -> ExecutionPayload: 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(TERMINAL_TOTAL_DIFFICULTY, TERMINAL_BLOCK_HASH, pow_chain) if terminal_pow_block is None: # Pre-merge, empty payload return ExecutionPayload() From 56fc984333eefdb69598854e8b0db125aa0e68e1 Mon Sep 17 00:00:00 2001 From: lsankar4033 Date: Wed, 22 Sep 2021 11:24:05 -0700 Subject: [PATCH 2/8] Re-run doctoc --- specs/merge/client-settings.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specs/merge/client-settings.md b/specs/merge/client-settings.md index efef1344fe..fdf7a25d5e 100644 --- a/specs/merge/client-settings.md +++ b/specs/merge/client-settings.md @@ -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) From 9d1cdf5ce1d879ca8e443a6453163beae474bc10 Mon Sep 17 00:00:00 2001 From: Lakshman Sankar Date: Thu, 23 Sep 2021 09:31:43 -0700 Subject: [PATCH 3/8] Bytes32 -> Hash32 Co-authored-by: Mikhail Kalinin --- specs/merge/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/merge/beacon-chain.md b/specs/merge/beacon-chain.md index 35f1407be5..3b467e78f6 100644 --- a/specs/merge/beacon-chain.md +++ b/specs/merge/beacon-chain.md @@ -83,7 +83,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` | `Bytes32('0x0000000000000000000000000000000000000000000000000000000000000000')` | +| `TERMINAL_BLOCK_HASH` | `Hash32('0x0000000000000000000000000000000000000000000000000000000000000000')` | ## Containers From 1ccb7d0a52d633c3404e5700b8e5a8e505f88bec Mon Sep 17 00:00:00 2001 From: lsankar4033 Date: Thu, 23 Sep 2021 09:52:02 -0700 Subject: [PATCH 4/8] Inline TERMINAL_BLOCK_HASH and TERMINAL_TOTAL_DIFFICULTY usages --- specs/merge/validator.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/specs/merge/validator.md b/specs/merge/validator.md index 88e24a2126..6b95830cc5 100644 --- a/specs/merge/validator.md +++ b/specs/merge/validator.md @@ -65,22 +65,25 @@ All validator responsibilities remain unchanged other than those noted below. Na * 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]: +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: + if block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY and parent.total_difficulty < TERMINAL_TOTAL_DIFFICULTY: return block return None -def get_terminal_pow_block(total_difficulty: uint256, block_hash_override: Hash32, pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]: - # check block hash override prior to total difficulty - pow_block_overrides = [pow_block for pow_block in pow_chain if pow_block.block_hash == block_hash_override] - if len(pow_block_overrides) != 0: - return pow_block_overrides[0] +def get_terminal_pow_block(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]: + if TERMINAL_BLOCK_HASH != Hash32(): + # Check block hash override prior to total difficulty + pow_block_overrides = [pow_block for pow_block in pow_chain if pow_block.block_hash == TERMINAL_BLOCK_HASH] + if len(pow_block_overrides) != 0: + return pow_block_overrides[0] + else: + return None - return get_pow_block_at_total_difficulty(total_difficulty, pow_chain) + return get_pow_block_at_terminal_total_difficulty(pow_chain) def produce_execution_payload(state: BeaconState, @@ -95,7 +98,7 @@ def get_execution_payload(state: BeaconState, execution_engine: ExecutionEngine, pow_chain: Sequence[PowBlock]) -> ExecutionPayload: if not is_merge_complete(state): - terminal_pow_block = get_terminal_pow_block(TERMINAL_TOTAL_DIFFICULTY, TERMINAL_BLOCK_HASH, pow_chain) + terminal_pow_block = get_terminal_pow_block(pow_chain) if terminal_pow_block is None: # Pre-merge, empty payload return ExecutionPayload() From c9c7ab72898b4bf483a93bde55c6187e10d826eb Mon Sep 17 00:00:00 2001 From: lsankar4033 Date: Thu, 23 Sep 2021 16:51:20 -0700 Subject: [PATCH 5/8] Add back newlines in configs --- configs/mainnet.yaml | 1 + configs/minimal.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index d5ea308d06..dc3006ea6b 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -10,6 +10,7 @@ TERMINAL_TOTAL_DIFFICULTY: 11579208923731619542357098500868790785326998466564056 # By default, don't use this param TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 + # Genesis # --------------------------------------------------------------- # `2**14` (= 16,384) diff --git a/configs/minimal.yaml b/configs/minimal.yaml index 8f7bd63397..aaa7f8504c 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -10,6 +10,7 @@ TERMINAL_TOTAL_DIFFICULTY: 11579208923731619542357098500868790785326998466564056 # By default, don't use this param TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 + # Genesis # --------------------------------------------------------------- # [customized] From 35a42c9d458ecd00b911f2f72a875eb3d8134645 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 24 Sep 2021 06:23:59 -0600 Subject: [PATCH 6/8] Apply suggestions from code review --- specs/merge/client-settings.md | 2 +- specs/merge/validator.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/merge/client-settings.md b/specs/merge/client-settings.md index fdf7a25d5e..287e557db8 100644 --- a/specs/merge/client-settings.md +++ b/specs/merge/client-settings.md @@ -22,7 +22,7 @@ Except under exceptional scenarios, this setting is expected to not be used. Suf ### Override terminal block hash -To allow for fork coordination around a specific PoW block, clients must also provide `--terminal-block-hash-override` as a configurable setting. +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. diff --git a/specs/merge/validator.md b/specs/merge/validator.md index 6b95830cc5..1ccd7fe9ea 100644 --- a/specs/merge/validator.md +++ b/specs/merge/validator.md @@ -76,7 +76,7 @@ def get_pow_block_at_terminal_total_difficulty(pow_chain: Sequence[PowBlock]) -> def get_terminal_pow_block(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]: if TERMINAL_BLOCK_HASH != Hash32(): - # Check block hash override prior to total difficulty + # Terminal lock hash override takes precedence over terminal total difficulty pow_block_overrides = [pow_block for pow_block in pow_chain if pow_block.block_hash == TERMINAL_BLOCK_HASH] if len(pow_block_overrides) != 0: return pow_block_overrides[0] From a48a6f46c4a4151bc75625e20bbee4abb8dd0d6d Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 24 Sep 2021 06:32:08 -0600 Subject: [PATCH 7/8] fix lint --- specs/merge/validator.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/specs/merge/validator.md b/specs/merge/validator.md index 1ccd7fe9ea..c4b9e0481a 100644 --- a/specs/merge/validator.md +++ b/specs/merge/validator.md @@ -69,15 +69,18 @@ def get_pow_block_at_terminal_total_difficulty(pow_chain: Sequence[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 >= TERMINAL_TOTAL_DIFFICULTY and parent.total_difficulty < TERMINAL_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 lock hash override takes precedence over terminal total difficulty - pow_block_overrides = [pow_block for pow_block in pow_chain if pow_block.block_hash == TERMINAL_BLOCK_HASH] + pow_block_overrides = [block for block in pow_chain if block.block_hash == TERMINAL_BLOCK_HASH] if len(pow_block_overrides) != 0: return pow_block_overrides[0] else: From 9353c71a6d2f3fb75c82d8321ba7c67ed48dd1bc Mon Sep 17 00:00:00 2001 From: lsankar4033 Date: Fri, 24 Sep 2021 11:57:58 -0700 Subject: [PATCH 8/8] Fix spelling --- specs/merge/validator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/merge/validator.md b/specs/merge/validator.md index c4b9e0481a..9eb140ef32 100644 --- a/specs/merge/validator.md +++ b/specs/merge/validator.md @@ -79,7 +79,7 @@ def get_pow_block_at_terminal_total_difficulty(pow_chain: Sequence[PowBlock]) -> def get_terminal_pow_block(pow_chain: Sequence[PowBlock]) -> Optional[PowBlock]: if TERMINAL_BLOCK_HASH != Hash32(): - # Terminal lock hash override takes precedence over terminal total difficulty + # 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 len(pow_block_overrides) != 0: return pow_block_overrides[0]