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

minor Merge and forkchoice updates release #2733

Merged
merged 66 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
0b0fe15
Make altair transition tests support merge forks
hwwhww Oct 29, 2021
fa4dc0c
Apply suggestions from code review
hwwhww Nov 2, 2021
0641d1c
`ALL_FORKS` sounds like a list of fork names. Rename it to `ALL_FORK_…
hwwhww Nov 2, 2021
6cfd38e
Patch for genesis blocks
paulhauner Nov 11, 2021
61207c5
Apply suggestions from code review
djrtwo Nov 11, 2021
fb34e16
Merge pull request #2719 from paulhauner/patch-33
djrtwo Nov 11, 2021
e70da78
Merge branch 'dev' into transition-reuse
hwwhww Nov 12, 2021
49d96f9
Add a sample altair-to-merge-only transition
hwwhww Nov 12, 2021
cd3d2ce
working through test issues
djrtwo Nov 12, 2021
f643554
Fix issue around on_attestation validation by skipping epoch scope
hwwhww Nov 13, 2021
d9e8306
Refactoring
hwwhww Nov 13, 2021
f0bb032
Fix `test_transition_with_one_fourth_exiting_validators_exit_at_fork`…
hwwhww Nov 15, 2021
63c9e5e
Minor refactoring and add comments
hwwhww Nov 15, 2021
16aaf74
Remove `difficulty` from `PowBlock`
paulhauner Nov 15, 2021
257173f
Add The Merge spec to coverage report targets
hwwhww Nov 16, 2021
2b9692a
Add a test to cover the case of `is_execution_enabled` result is false
hwwhww Nov 16, 2021
79f1f16
Clean `PowBlock.difficulty` leftover
hwwhww Nov 16, 2021
e56bbb8
Fix `get_pow_block_at_terminal_total_difficulty` and add unit tests
hwwhww Nov 17, 2021
2876209
PR feedback from @mkalinin
hwwhww Nov 17, 2021
eb00f8f
cleanup forkchoice tests
djrtwo Nov 18, 2021
3d4ece4
port phase0 forkchocie changes to merge
djrtwo Nov 18, 2021
2c865e3
Resolve the commented out code in `test_new_finalized_slot_is_not_jus…
hwwhww Nov 18, 2021
58968f9
Rename coinbase to fee_recipient
mkalinin Nov 18, 2021
140f30d
Merge pull request #2728 from mkalinin/coinbase-to-fee_recipient
djrtwo Nov 18, 2021
dc14b79
Merge pull request #2720 from paulhauner/patch-34
djrtwo Nov 18, 2021
8333514
Update specs/merge/validator.md
djrtwo Nov 19, 2021
e7df64b
Merge pull request #2723 from ethereum/add-test_is_execution_enabled_…
djrtwo Nov 19, 2021
b898810
Merge pull request #2721 from ethereum/cov-merge
djrtwo Nov 19, 2021
3c25da8
Merge pull request #2726 from ethereum/get_pow_block_at_ttd-tests
djrtwo Nov 19, 2021
29beba6
Merge pull request #2706 from ethereum/transition-reuse
hwwhww Nov 20, 2021
97e6d5c
Merge branch 'fc-dev-validate_target_epoch_scope-patch' into dev
djrtwo Nov 22, 2021
bbdb0d8
Merge pull request #2727 from ethereum/fc-dev-validate_target_epoch_s…
djrtwo Nov 22, 2021
7736c8b
Merge branch 'dev' of github.com:ethereum/eth2.0-specs into dev
djrtwo Nov 22, 2021
2d161b4
Add proposer score boosting & related tests
adiasg Nov 19, 2021
281c1b2
Update validator guide with ATTESTATION_OFFSET_QUOTIENT
adiasg Nov 19, 2021
47fa6d1
Add parameter for score boost value
adiasg Nov 20, 2021
504d82c
Add datatype to new parameters
adiasg Nov 20, 2021
b0fb861
Make PROPOSER_SCORE_BOOST a percentage value
adiasg Nov 20, 2021
3b20e3e
Apply suggestions from code review
adiasg Nov 22, 2021
859bbf4
This reverts commit 4c726cdff39a10c5d096b294fb562cfc99c1f068.
adiasg Nov 22, 2021
88c76ab
Apply Danny's code review
adiasg Nov 22, 2021
cebe6ba
minor formatting cleanups
djrtwo Nov 22, 2021
282d85b
simplify on_tick proposer boost update
djrtwo Nov 22, 2021
ea09df5
toc
djrtwo Nov 22, 2021
1d835c5
Apply Danny's code review & suggestions
adiasg Nov 22, 2021
d85d439
Rename test
adiasg Nov 22, 2021
9999331
How to write tests for the consensus layer (#2700)
qbzzt Nov 22, 2021
64b4ca2
add PROPOSER_SCORE_BOOST to configuration yaml files
djrtwo Nov 23, 2021
bdd7b07
Add configuration value checks
hwwhww Nov 23, 2021
a0b5a80
Apply HWW code's review - fix is_before_attesting_interval
adiasg Nov 23, 2021
44fec31
Eth1 block hashes have type Hash32 (#2693)
benjaminion Nov 23, 2021
ecbe919
Apply HWW code's review - properly update test steps
adiasg Nov 23, 2021
2a5c9d8
Set PROPOSER_SCORE_BOOST to 70%
adiasg Nov 23, 2021
6f95637
Merging local branch to remote latest
adiasg Nov 23, 2021
2ba0586
Add `proposer_boost_root` field to test vector "checks" step
hwwhww Nov 23, 2021
40f1c85
Merge pull request #2736 from ethereum/proposer-score-boost-add-check
djrtwo Nov 23, 2021
975931b
pr feedback
djrtwo Nov 23, 2021
8050de3
Fix spec typo and add `test_prepare_execution_payload` unit tests
hwwhww Nov 23, 2021
395fdd4
Merge pull request #2730 from ethereum/proposer-score-boost
djrtwo Nov 23, 2021
32e8ca2
Merge pull request #2737 from ethereum/test_prepare_execution_payload
djrtwo Nov 23, 2021
a0d008b
is_merge -> is_merge_transition
djrtwo Nov 23, 2021
69e7f58
Merge pull request #2738 from ethereum/fix-names
djrtwo Nov 23, 2021
4370b9c
bump VERSION.txt to 1.1.6
djrtwo Nov 23, 2021
3a5f7d3
Merge pull request #2739 from ethereum/bump-version
djrtwo Nov 23, 2021
d33a939
Apply suggestions from code review
djrtwo Nov 23, 2021
cebc514
Merge branch 'master' into dev
djrtwo Nov 24, 2021
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ install_test:
# Testing against `minimal` config by default
test: pyspec
. venv/bin/activate; cd $(PY_SPEC_DIR); \
python3 -m pytest -n 4 --disable-bls --cov=eth2spec.phase0.minimal --cov=eth2spec.altair.minimal --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec
python3 -m pytest -n 4 --disable-bls --cov=eth2spec.phase0.minimal --cov=eth2spec.altair.minimal --cov=eth2spec.merge.minimal --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec

# Testing against `minimal` config by default
find_test: pyspec
. venv/bin/activate; cd $(PY_SPEC_DIR); \
python3 -m pytest -k=$(K) --disable-bls --cov=eth2spec.phase0.minimal --cov=eth2spec.altair.minimal --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec
python3 -m pytest -k=$(K) --disable-bls --cov=eth2spec.phase0.minimal --cov=eth2spec.altair.minimal --cov=eth2spec.merge.minimal --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec

citest: pyspec
mkdir -p tests/core/pyspec/test-reports/eth2spec;
Expand Down
5 changes: 5 additions & 0 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ MIN_PER_EPOCH_CHURN_LIMIT: 4
CHURN_LIMIT_QUOTIENT: 65536


# Fork choice
# ---------------------------------------------------------------
# 70%
PROPOSER_SCORE_BOOST: 70

# Deposit contract
# ---------------------------------------------------------------
# Ethereum PoW Mainnet
Expand Down
6 changes: 6 additions & 0 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ MIN_PER_EPOCH_CHURN_LIMIT: 4
CHURN_LIMIT_QUOTIENT: 32


# Fork choice
# ---------------------------------------------------------------
# 70%
PROPOSER_SCORE_BOOST: 70


# Deposit contract
# ---------------------------------------------------------------
# Ethereum Goerli testnet
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def sundry_functions(cls) -> str:


def get_pow_block(hash: Bytes32) -> Optional[PowBlock]:
return PowBlock(block_hash=hash, parent_hash=Bytes32(), total_difficulty=uint256(0), difficulty=uint256(0))
return PowBlock(block_hash=hash, parent_hash=Bytes32(), total_difficulty=uint256(0))


def get_execution_state(execution_state_root: Bytes32) -> ExecutionState:
Expand Down
2 changes: 1 addition & 1 deletion specs/altair/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ This helper function is only for initializing the state for pure Altair testnets
*Note*: The function `initialize_beacon_state_from_eth1` is modified: (1) using `ALTAIR_FORK_VERSION` as the current fork version, (2) utilizing the Altair `BeaconBlockBody` when constructing the initial `latest_block_header`, and (3) adding initial sync committees.

```python
def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
eth1_timestamp: uint64,
deposits: Sequence[Deposit]) -> BeaconState:
fork = Fork(
Expand Down
26 changes: 13 additions & 13 deletions specs/merge/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
- [`ExecutionPayloadHeader`](#executionpayloadheader)
- [Helper functions](#helper-functions)
- [Predicates](#predicates)
- [`is_merge_complete`](#is_merge_complete)
- [`is_merge_block`](#is_merge_block)
- [`is_merge_transition_complete`](#is_merge_transition_complete)
- [`is_merge_transition_block`](#is_merge_transition_block)
- [`is_execution_enabled`](#is_execution_enabled)
- [Misc](#misc)
- [`compute_timestamp_at_slot`](#compute_timestamp_at_slot)
Expand Down Expand Up @@ -167,7 +167,7 @@ class BeaconState(Container):
class ExecutionPayload(Container):
# Execution block header fields
parent_hash: Hash32
coinbase: ExecutionAddress # 'beneficiary' in the yellow paper
fee_recipient: ExecutionAddress # 'beneficiary' in the yellow paper
state_root: Bytes32
receipt_root: Bytes32 # 'receipts root' in the yellow paper
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
Expand All @@ -189,7 +189,7 @@ class ExecutionPayload(Container):
class ExecutionPayloadHeader(Container):
# Execution block header fields
parent_hash: Hash32
coinbase: ExecutionAddress
fee_recipient: ExecutionAddress
state_root: Bytes32
receipt_root: Bytes32
logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM]
Expand All @@ -209,25 +209,25 @@ class ExecutionPayloadHeader(Container):

### Predicates

#### `is_merge_complete`
#### `is_merge_transition_complete`

```python
def is_merge_complete(state: BeaconState) -> bool:
def is_merge_transition_complete(state: BeaconState) -> bool:
return state.latest_execution_payload_header != ExecutionPayloadHeader()
```

#### `is_merge_block`
#### `is_merge_transition_block`

```python
def is_merge_block(state: BeaconState, body: BeaconBlockBody) -> bool:
return not is_merge_complete(state) and body.execution_payload != ExecutionPayload()
def is_merge_transition_block(state: BeaconState, body: BeaconBlockBody) -> bool:
return not is_merge_transition_complete(state) and body.execution_payload != ExecutionPayload()
```

#### `is_execution_enabled`

```python
def is_execution_enabled(state: BeaconState, body: BeaconBlockBody) -> bool:
return is_merge_block(state, body) or is_merge_complete(state)
return is_merge_transition_block(state, body) or is_merge_transition_complete(state)
```

### Misc
Expand Down Expand Up @@ -346,7 +346,7 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
```python
def process_execution_payload(state: BeaconState, payload: ExecutionPayload, execution_engine: ExecutionEngine) -> None:
# Verify consistency of the parent hash with respect to the previous execution payload header
if is_merge_complete(state):
if is_merge_transition_complete(state):
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
# Verify random
assert payload.random == get_randao_mix(state, get_current_epoch(state))
Expand All @@ -357,7 +357,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
# Cache execution payload header
state.latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=payload.parent_hash,
coinbase=payload.coinbase,
fee_recipient=payload.fee_recipient,
state_root=payload.state_root,
receipt_root=payload.receipt_root,
logs_bloom=payload.logs_bloom,
Expand Down Expand Up @@ -406,7 +406,7 @@ Modifications include:
Else, the Merge starts from genesis and the transition is incomplete.

```python
def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
eth1_timestamp: uint64,
deposits: Sequence[Deposit],
execution_payload_header: ExecutionPayloadHeader=ExecutionPayloadHeader()
Expand Down
25 changes: 9 additions & 16 deletions specs/merge/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Used to signal to initiate the payload build process via `notify_forkchoice_upda
class PayloadAttributes(object):
timestamp: uint64
random: Bytes32
fee_recipient: ExecutionAddress
suggested_fee_recipient: ExecutionAddress
```

### `PowBlock`
Expand All @@ -87,7 +87,6 @@ class PowBlock(Container):
block_hash: Hash32
parent_hash: Hash32
total_difficulty: uint256
difficulty: uint256
```

### `get_pow_block`
Expand Down Expand Up @@ -168,14 +167,20 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
state_transition(state, signed_block, True)

# [New in Merge]
if is_merge_block(pre_state, block.body):
if is_merge_transition_block(pre_state, block.body):
validate_merge_block(block)

# Add new block to the store
store.blocks[hash_tree_root(block)] = block
# Add new state for this block to the store
store.block_states[hash_tree_root(block)] = state

# Add proposer score boost if the block is timely
time_into_slot = (store.time - store.genesis_time) % SECONDS_PER_SLOT
is_before_attesting_interval = time_into_slot < SECONDS_PER_SLOT // INTERVALS_PER_SLOT
if get_current_slot(store) == block.slot and is_before_attesting_interval:
store.proposer_boost_root = hash_tree_root(block)

# Update justified checkpoint
if state.current_justified_checkpoint.epoch > store.justified_checkpoint.epoch:
if state.current_justified_checkpoint.epoch > store.best_justified_checkpoint.epoch:
Expand All @@ -186,17 +191,5 @@ 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
if state.current_justified_checkpoint.epoch > store.justified_checkpoint.epoch:
store.justified_checkpoint = state.current_justified_checkpoint
return

# Update justified if store justified is not in chain with finalized checkpoint
finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
store.justified_checkpoint = state.current_justified_checkpoint
store.justified_checkpoint = state.current_justified_checkpoint
```
26 changes: 15 additions & 11 deletions specs/merge/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@ Please see related Beacon Chain doc before continuing and use them as a referenc
```python
def get_pow_block_at_terminal_total_difficulty(pow_chain: Dict[Hash32, PowBlock]) -> Optional[PowBlock]:
# `pow_chain` abstractly represents all blocks in the PoW chain
for block in pow_chain:
parent = pow_chain[block.parent_hash]
for block in pow_chain.values():
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
if block_reached_ttd:
# If genesis block, no parent exists so reaching TTD alone qualifies as valid terminal block
if block.parent_hash == Hash32():
return block
parent = pow_chain[block.parent_hash]
parent_reached_ttd = parent.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
if not parent_reached_ttd:
return block

return None
```
Expand Down Expand Up @@ -106,22 +110,22 @@ All validator responsibilities remain unchanged other than those noted below. Na

To obtain an execution payload, a block proposer building a block on top of a `state` must take the following actions:

1. Set `payload_id = prepare_execution_payload(state, pow_chain, finalized_block_hash, fee_recipient, execution_engine)`, where:
1. Set `payload_id = prepare_execution_payload(state, pow_chain, finalized_block_hash, suggested_fee_recipient, execution_engine)`, where:
* `state` is the state object after applying `process_slots(state, slot)` transition to the resulting state of the parent block processing
* `pow_chain` is a `Dict[Hash32, PowBlock]` dictionary that abstractly represents all blocks in the PoW chain with block hash as the dictionary key
* `finalized_block_hash` is the hash of the latest finalized execution payload (`Hash32()` if none yet finalized)
* `fee_recipient` is the value suggested to be used for the `coinbase` field of the execution payload
* `suggested_fee_recipient` is the value suggested to be used for the `fee_recipient` field of the execution payload


```python
def prepare_execution_payload(state: BeaconState,
pow_chain: Dict[Hash32, PowBlock],
finalized_block_hash: Hash32,
fee_recipient: ExecutionAddress,
suggested_fee_recipient: ExecutionAddress,
execution_engine: ExecutionEngine) -> Optional[PayloadId]:
if not is_merge_complete(state):
if not is_merge_transition_complete(state):
is_terminal_block_hash_set = TERMINAL_BLOCK_HASH != Hash32()
is_activation_epoch_reached = get_current_epoch(state.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
is_activation_epoch_reached = get_current_epoch(state) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
if is_terminal_block_hash_set and not is_activation_epoch_reached:
# Terminal block hash is set but activation epoch is not yet reached, no prepare payload call is needed
return None
Expand All @@ -140,7 +144,7 @@ def prepare_execution_payload(state: BeaconState,
payload_attributes = PayloadAttributes(
timestamp=compute_timestamp_at_slot(state, state.slot),
random=get_randao_mix(state, get_current_epoch(state)),
fee_recipient=fee_recipient,
suggested_fee_recipient=suggested_fee_recipient,
)
return execution_engine.notify_forkchoice_updated(parent_hash, finalized_block_hash, payload_attributes)
```
Expand Down
3 changes: 1 addition & 2 deletions specs/phase0/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ We define the following Python custom types for type hinting and readability:
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |


## Constants

The following values are (non-configurable) constants used throughout the specification.
Expand Down Expand Up @@ -1175,7 +1174,7 @@ Before the Ethereum beacon chain genesis has been triggered, and for every Ether
Proof-of-work blocks must only be considered once they are at least `SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE` seconds old (i.e. `eth1_timestamp + SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE <= current_unix_time`). Due to this constraint, if `GENESIS_DELAY < SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE`, then the `genesis_time` can happen before the time/state is first known. Values should be configured to avoid this case.

```python
def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
eth1_timestamp: uint64,
deposits: Sequence[Deposit]) -> BeaconState:
fork = Fork(
Expand Down
Loading