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

Rebase EIP-4844 on Capella #3052

Merged
merged 25 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
242e1b7
Rebase Capella on EIP-4844
Inphi Oct 20, 2022
f6f2474
Update specs/eip4844/beacon-chain.md
Inphi Oct 20, 2022
2ac57c7
Fix py setup
Inphi Oct 24, 2022
0488c0c
remove unchanged epoch processing section
Inphi Oct 24, 2022
459310f
Fix test_process_execution_payload
Inphi Oct 24, 2022
6d270cd
Add CAPELLA_FORK_EPOCH overrides
Inphi Oct 24, 2022
ca538f5
Update specs/eip4844/beacon-chain.md
Inphi Oct 25, 2022
3172095
Make pyspec disable withdrawal-functions in EIP4844
hwwhww Oct 26, 2022
e460005
Add tests for no-op functions
hwwhww Oct 26, 2022
60187e5
Add `test_process_withdrawals` no-op test
hwwhww Oct 26, 2022
95ee291
Merge branch 'dev' into pr3052
hwwhww Nov 7, 2022
e3e73a8
Add Capella fork version
Inphi Nov 8, 2022
a59dd37
Merge remote-tracking branch 'origin/dev' into inphi/eip4844-rebase
Inphi Nov 10, 2022
a04f06b
Fix merge conflict
Inphi Nov 10, 2022
bed1df0
Remove withdrawal_queue from BeaconState upgrade
Inphi Nov 10, 2022
2fbb1ed
fix test_process_withdrawals
Inphi Nov 10, 2022
fcafdc1
remove eip4844 partial/full withdrawwals tests
Inphi Nov 10, 2022
67ba28c
remove eip4844 epoch_processing package
Inphi Nov 10, 2022
104cba0
replace get_blobs_and_kzg_commitments
Inphi Nov 11, 2022
6327ffa
rename excess_blobs
Inphi Nov 11, 2022
cd1e113
excess_data_gas uint256
Inphi Nov 11, 2022
3df1371
Merge remote-tracking branch 'origin/dev' into inphi/eip4844-rebase
Inphi Nov 11, 2022
3714446
Fix merge conflict
Inphi Nov 11, 2022
f1d4c90
Merge branch 'dev' into pr3052
hwwhww Nov 17, 2022
ee0e2a0
Merge branch 'dev' into pr3052
hwwhww Nov 17, 2022
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
32 changes: 29 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,14 +618,14 @@ def imports(cls, preset_name: str):
#
# EIP4844SpecBuilder
#
class EIP4844SpecBuilder(BellatrixSpecBuilder):
class EIP4844SpecBuilder(CapellaSpecBuilder):
fork: str = EIP4844

@classmethod
def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.utils import kzg
from eth2spec.bellatrix import {preset_name} as bellatrix
from eth2spec.capella import {preset_name} as capella
'''


Expand All @@ -652,6 +652,32 @@ def sundry_functions(cls) -> str:
ROOTS_OF_UNITY = kzg.compute_roots_of_unity(TESTING_FIELD_ELEMENTS_PER_BLOB)


#
# Temporarily disable Withdrawals functions for EIP4844 testnets
#


def no_op(fn): # type: ignore
def wrapper(*args, **kw): # type: ignore
return None
return wrapper


def get_empty_list_result(fn): # type: ignore
def wrapper(*args, **kw): # type: ignore
return []
return wrapper


process_withdrawals = no_op(process_withdrawals)
process_bls_to_execution_change = no_op(process_bls_to_execution_change)
get_expected_withdrawals = get_empty_list_result(get_expected_withdrawals)


#
# End
#

def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
return "TEST"'''

Expand Down Expand Up @@ -1002,7 +1028,7 @@ def finalize_options(self):
specs/bellatrix/p2p-interface.md
sync/optimistic.md
"""
if self.spec_fork == CAPELLA:
if self.spec_fork in (CAPELLA, EIP4844):
self.md_doc_paths += """
specs/capella/beacon-chain.md
specs/capella/fork.md
Expand Down
24 changes: 19 additions & 5 deletions specs/eip4844/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@
- [`process_execution_payload`](#process_execution_payload)
- [Blob KZG commitments](#blob-kzg-commitments)
- [Testing](#testing)
- [Disabling Withdrawals](#disabling-withdrawals)

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

## Introduction

This upgrade adds blobs to the beacon chain as part of EIP-4844.
This upgrade adds blobs to the beacon chain as part of EIP-4844. This is an extension of the Capella upgrade.

## Custom types

Expand Down Expand Up @@ -89,6 +90,7 @@ class BeaconBlockBody(Container):
sync_aggregate: SyncAggregate
# Execution
execution_payload: ExecutionPayload
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
blob_kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK] # [New in EIP-4844]
```

Expand All @@ -109,10 +111,11 @@ class ExecutionPayload(Container):
timestamp: uint64
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
base_fee_per_gas: uint256
excess_blobs: uint64 # [New in EIP-4844]
excess_data_gas: uint256 # [New in EIP-4844]
# Extra payload fields
block_hash: Hash32 # Hash of execution block
transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
```

#### `ExecutionPayloadHeader`
Expand All @@ -132,10 +135,11 @@ class ExecutionPayloadHeader(Container):
timestamp: uint64
extra_data: ByteList[MAX_EXTRA_DATA_BYTES]
base_fee_per_gas: uint256
excess_blobs: uint64 # [New in EIP-4844]
excess_data_gas: uint256 # [New in EIP-4844]
# Extra payload fields
block_hash: Hash32 # Hash of execution block
transactions_root: Root
withdrawals_root: Root
```

## Helper functions
Expand Down Expand Up @@ -227,7 +231,8 @@ def verify_kzg_commitments_against_transactions(transactions: Sequence[Transacti
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
if is_execution_enabled(state, block.body):
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE)
process_withdrawals(state, block.body.execution_payload)
process_execution_payload(state, block.body.execution_payload, EXECUTION_ENGINE) # [Modified in EIP-4844]
process_randao(state, block.body)
process_eth1_data(state, block.body)
process_operations(state, block.body)
Expand All @@ -253,6 +258,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
assert payload.timestamp == compute_timestamp_at_slot(state, state.slot)
# Verify the execution payload is valid
assert execution_engine.notify_new_payload(payload)

# Cache execution payload header
state.latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=payload.parent_hash,
Expand All @@ -267,9 +273,10 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe
timestamp=payload.timestamp,
extra_data=payload.extra_data,
base_fee_per_gas=payload.base_fee_per_gas,
excess_blobs=payload.excess_blobs, # [New in EIP-4844]
excess_data_gas=payload.excess_data_gas, # [New in EIP-4844]
block_hash=payload.block_hash,
transactions_root=hash_tree_root(payload.transactions),
withdrawals_root=hash_tree_root(payload.withdrawals),
)
```

Expand Down Expand Up @@ -335,3 +342,10 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,

return state
```

### Disabling Withdrawals
During testing we avoid Capella-specific updates to the state transition. We do this by replacing the following functions with a no-op implementation:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This no-op works fine for clients?
I'm out of the loop, but I thought they would use the full functionality here (yes, complicating testing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to avoid submitted withdrawals from interfering with the testnet. By no-op'ing these functions, withdrawals won't have any effect.

- `process_withdrawals`
- `process_bls_to_execution_change`

The `get_expected_withdrawals` function is also modified to return an empty withdrawals list. As such, the PayloadAttributes used to update forkchoice does not contain withdrawals.
16 changes: 10 additions & 6 deletions specs/eip4844/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def compute_fork_version(epoch: Epoch) -> Version:
"""
if epoch >= EIP4844_FORK_EPOCH:
return EIP4844_FORK_VERSION
if epoch >= CAPELLA_FORK_EPOCH:
return CAPELLA_FORK_VERSION
if epoch >= BELLATRIX_FORK_EPOCH:
return BELLATRIX_FORK_VERSION
if epoch >= ALTAIR_FORK_EPOCH:
Expand All @@ -62,12 +64,11 @@ Note that for the pure EIP-4844 networks, we don't apply `upgrade_to_eip4844` si

### Upgrading the state

Since the `eip4844.BeaconState` format is equal to the `bellatrix.BeaconState` format, we only have to update `BeaconState.fork`.
Since the `eip4844.BeaconState` format is equal to the `capella.BeaconState` format, we only have to update `BeaconState.fork`.

```python
def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
# TODO: if Capella gets scheduled, add sync it with Capella.BeaconState
epoch = bellatrix.get_current_epoch(pre)
def upgrade_to_eip4844(pre: capella.BeaconState) -> BeaconState:
epoch = capella.get_current_epoch(pre)
latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=pre.latest_execution_payload_header.parent_hash,
fee_recipient=pre.latest_execution_payload_header.fee_recipient,
Expand All @@ -81,7 +82,7 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
timestamp=pre.latest_execution_payload_header.timestamp,
extra_data=pre.latest_execution_payload_header.extra_data,
base_fee_per_gas=pre.latest_execution_payload_header.base_fee_per_gas,
excess_data_gas=uint256(0), # [New in EIP-4844]
excess_data_gas=uint256(0), # [New in EIP-4844]
block_hash=pre.latest_execution_payload_header.block_hash,
transactions_root=pre.latest_execution_payload_header.transactions_root,
withdrawals_root=pre.latest_execution_payload_header.withdrawals_root,
Expand Down Expand Up @@ -126,7 +127,10 @@ def upgrade_to_eip4844(pre: bellatrix.BeaconState) -> BeaconState:
current_sync_committee=pre.current_sync_committee,
next_sync_committee=pre.next_sync_committee,
# Execution-layer
latest_execution_payload_header=latest_execution_payload_header,
latest_execution_payload_header=latest_execution_payload_header, # [Modified in EIP4844]
# Withdrawals
next_withdrawal_index=pre.next_withdrawal_index,
next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
)

return post
Expand Down
4 changes: 3 additions & 1 deletion specs/eip4844/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Some gossip meshes are upgraded in the fork of EIP4844 to support upgraded types
Topics follow the same specification as in prior upgrades.
All topics remain stable except the beacon block topic which is updated with the modified type.

The specification around the creation, validation, and dissemination of messages has not changed from the Bellatrix document unless explicitly noted here.
The specification around the creation, validation, and dissemination of messages has not changed from the Capella document unless explicitly noted here.

The derivation of the `message-id` remains stable.

Expand Down Expand Up @@ -124,6 +124,7 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
| `EIP4844_FORK_VERSION` | `eip4844.SignedBeaconBlock` |

#### BeaconBlocksByRoot v2
Expand All @@ -142,6 +143,7 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential merge conflict with #3089. I can fix that after this is merged

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in f1d4c90


#### BeaconBlockAndBlobsSidecarByRoot v1

Expand Down
4 changes: 2 additions & 2 deletions specs/eip4844/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ This document represents the changes to be made in the code of an "honest valida

## Prerequisites

This document is an extension of the [Bellatrix -- Honest Validator](../bellatrix/validator.md) guide.
This document is an extension of the [Capella -- Honest Validator](../capella/validator.md) guide.
All behaviors and definitions defined in this document, and documents it extends, carry over unless explicitly noted or overridden.

All terminology, constants, functions, and protocol mechanics defined in the updated [Beacon Chain doc of EIP4844](./beacon-chain.md) are requisite for this document and used throughout.
Expand Down Expand Up @@ -60,7 +60,7 @@ Namely, the blob handling and the addition of `SignedBeaconBlockAndBlobsSidecar`

##### Blob KZG commitments

1. After retrieving the execution payload from the execution engine as specified in Bellatrix,
1. After retrieving the execution payload from the execution engine as specified in Capella,
use the `payload_id` to retrieve `blobs` and `blob_kzg_commitments` via `get_blobs_and_kzg_commitments(payload_id)`.
2. Validate `blobs` and `blob_kzg_commitments`:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from eth2spec.test.helpers.constants import CAPELLA
from eth2spec.test.helpers.keys import pubkeys
from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change

from eth2spec.test.context import spec_state_test, expect_assertion_error, with_capella_and_later, always_bls
from eth2spec.test.context import spec_state_test, expect_assertion_error, with_phases, always_bls


def run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=True):
Expand Down Expand Up @@ -37,14 +38,14 @@ def run_bls_to_execution_change_processing(spec, state, signed_address_change, v
yield 'post', state


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success(spec, state):
signed_address_change = get_signed_address_change(spec, state)
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)


@with_capella_and_later
@with_phases([CAPELLA])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be capella and later, no?

Ah, the no-op change will break this test... If we do this, we need to remember to go back and change these all :/
When we were rebasing here, I didn't realize we were rebasing and mutating. How much will we be blocked on 4844 if we don't do the capella no-op within 4844 spec?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is to prevent random semi-public testnet users/validators from invoking any withdrawals?

Agreed with this complicating testing but given that we have 3-4 in-discussion changes on Capella, it makes sense that EIP-4844 devs want to disable Capella now... 😭

Btw I also added the tests to test the Capella no-op. So we must undo it altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is to prevent random semi-public testnet users/validators from invoking any withdrawals?

Yes it's exactly this.

@spec_state_test
def test_success_not_activated(spec, state):
validator_index = 3
Expand All @@ -62,7 +63,7 @@ def test_success_not_activated(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_in_activation_queue(spec, state):
validator_index = 3
Expand All @@ -80,7 +81,7 @@ def test_success_in_activation_queue(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_in_exit_queue(spec, state):
validator_index = 3
Expand All @@ -93,7 +94,7 @@ def test_success_in_exit_queue(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change)


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_exited(spec, state):
validator_index = 4
Expand All @@ -110,7 +111,7 @@ def test_success_exited(spec, state):
assert not spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_withdrawable(spec, state):
validator_index = 4
Expand All @@ -128,7 +129,7 @@ def test_success_withdrawable(spec, state):
assert spec.is_fully_withdrawable_validator(validator, balance, spec.get_current_epoch(state))


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_val_index_out_of_range(spec, state):
# Create for one validator beyond the validator list length
Expand All @@ -137,7 +138,7 @@ def test_fail_val_index_out_of_range(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_already_0x01(spec, state):
# Create for one validator beyond the validator list length
Expand All @@ -149,7 +150,7 @@ def test_fail_already_0x01(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_fail_incorrect_from_bls_pubkey(spec, state):
# Create for one validator beyond the validator list length
Expand All @@ -163,7 +164,7 @@ def test_fail_incorrect_from_bls_pubkey(spec, state):
yield from run_bls_to_execution_change_processing(spec, state, signed_address_change, valid=False)


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
@always_bls
def test_fail_bad_signature(spec, state):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from eth2spec.test.context import (
spec_state_test,
with_capella_and_later,
with_phases,
)
from eth2spec.test.helpers.constants import CAPELLA
from eth2spec.test.helpers.state import next_epoch_via_block
from eth2spec.test.helpers.deposits import (
prepare_state_and_deposit,
Expand All @@ -10,7 +11,7 @@
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable


@with_capella_and_later
@with_phases([CAPELLA])
@spec_state_test
def test_success_top_up_to_withdrawn_validator(spec, state):
validator_index = 0
Expand Down
Loading