Skip to content

Commit

Permalink
Merge branch 'dev' into deposit-queue
Browse files Browse the repository at this point in the history
  • Loading branch information
mkalinin committed Sep 4, 2024
2 parents 0526592 + 5111cbf commit 3ebddad
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 69 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,19 @@ Documentation on the different components used during spec writing can be found
## Consensus spec tests

Conformance tests built from the executable python spec are available in the [Ethereum Proof-of-Stake Consensus Spec Tests](https://github.com/ethereum/consensus-spec-tests) repo. Compressed tarballs are available in [releases](https://github.com/ethereum/consensus-spec-tests/releases).


## Installation and Usage
The consensus-specs repo can be used by running the tests locally or inside a docker container.

To run the tests locally:
- Clone the repository with `git clone https://github.com/ethereum/consensus-specs.git`
- Switch to the directory `cd consensus-specs`
- Install the dependencies with: `make install_test && make preinstallation && make pyspec`
- Run the tests with `make citest`

To run the tests inside a docker container:
- Switch to the directory with `cd scripts`
- Run the script `./build_run_docker_tests.sh`
- Find the results in a folder called `./testResults`
- Find more ways to customize the script with `./build_run_docker_tests.sh --h`
3 changes: 3 additions & 0 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,6 @@ CUSTODY_REQUIREMENT: 4
# [New in Electra:EIP7251]
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000 # 2**7 * 10**9 (= 128,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000 # 2**8 * 10**9 (= 256,000,000,000)

# EIP7732
MAX_REQUEST_PAYLOADS: 128
3 changes: 3 additions & 0 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,6 @@ CUSTODY_REQUIREMENT: 4
# [New in Electra:EIP7251]
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000 # 2**6 * 10**9 (= 64,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000 # 2**7 * 10**9 (= 128,000,000,000)

# EIP7732
MAX_REQUEST_PAYLOADS: 128
6 changes: 3 additions & 3 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Ideally manual running of docker containers is for advanced users, we recommend
The `scripts/build_run_docker_tests.sh` script will cover most usecases. The script allows the user to configure the fork(altair/bellatrix/capella..), `$IMAGE_NAME` (specifies the container to use), preset type (mainnet/minimal), and test all forks flags. Ideally, this is the main way that users interact with the spec tests instead of running it locally with varying versions of dependencies.

E.g:
- `./build_run_test.sh --p mainnet` will run the mainnet preset tests
- `./build_run_test.sh --a` will run all the tests across all the forks
- `./build_run_test.sh --f deneb` will only run deneb tests
- `./build_run_docker_tests.sh --p mainnet` will run the mainnet preset tests
- `./build_run_docker_tests.sh --a` will run all the tests across all the forks
- `./build_run_docker_tests.sh --f deneb` will only run deneb tests

Results are always placed in a folder called `./testResults`. The results are `.xml` files and contain the fork they represent and the date/time they were run at.
2 changes: 1 addition & 1 deletion scripts/build_run_docker_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


# Set variables
ALL_EXECUTABLE_SPECS=("phase0" "altair" "bellatrix" "capella" "deneb" "electra" "whisk")
ALL_EXECUTABLE_SPECS=("phase0" "altair" "bellatrix" "capella" "deneb" "electra" "whisk" "eip7594")
TEST_PRESET_TYPE=minimal
FORK_TO_TEST=phase0
WORKDIR="//consensus-specs//tests//core//pyspec"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ def run(self):
install_requires=[
"eth-utils>=2.0.0,<3",
"eth-typing>=3.2.0,<4.0.0",
"pycryptodome==3.15.0",
"pycryptodome>=3.19.1",
"py_ecc==6.0.0",
"milagro_bls_binding==1.9.0",
"remerkleable==0.1.28",
Expand Down
4 changes: 2 additions & 2 deletions specs/_features/eip7594/das-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The following values are (non-configurable) constants used throughout the specif

| Name | Value | Description |
| - | - | - |
| `DATA_COLUMN_SIDECAR_SUBNET_COUNT` | `128` | The number of data column sidecar subnets used in the gossipsub protocol |
| `DATA_COLUMN_SIDECAR_SUBNET_COUNT` | `uint64(128)` | The number of data column sidecar subnets used in the gossipsub protocol |

### Custody setting

Expand Down Expand Up @@ -222,7 +222,7 @@ def get_data_column_sidecars(signed_block: SignedBeaconBlock,

Each node downloads and custodies a minimum of `CUSTODY_REQUIREMENT` subnets per slot. The particular subnets that the node is required to custody are selected pseudo-randomly (more on this below).

A node *may* choose to custody and serve more than the minimum honesty requirement. Such a node explicitly advertises a number greater than `CUSTODY_REQUIREMENT` via the peer discovery mechanism -- for example, in their ENR (e.g. `custody_subnet_count: 4` if the node custodies `4` subnets each slot) -- up to a `DATA_COLUMN_SIDECAR_SUBNET_COUNT` (i.e. a super-full node).
A node *may* choose to custody and serve more than the minimum honesty requirement. Such a node explicitly advertises a number greater than `CUSTODY_REQUIREMENT` through the peer discovery mechanism, specifically by setting a higher value in the `custody_subnet_count` field within its ENR. This value can be increased up to `DATA_COLUMN_SIDECAR_SUBNET_COUNT`, indicating a super-full node.

A node stores the custodied columns for the duration of the pruning period and responds to peer requests for samples on those columns.

Expand Down
6 changes: 3 additions & 3 deletions specs/_features/eip7594/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,14 @@ The `MetaData` stored locally by clients is updated with an additional field to
seq_number: uint64
attnets: Bitvector[ATTESTATION_SUBNET_COUNT]
syncnets: Bitvector[SYNC_COMMITTEE_SUBNET_COUNT]
custody_subnet_count: uint64
custody_subnet_count: uint64 # csc
)
```

Where

- `seq_number`, `attnets`, and `syncnets` have the same meaning defined in the Altair document.
- `custody_subnet_count` represents the node's custody subnet count. Clients MAY reject ENRs with a value less than `CUSTODY_REQUIREMENT`.
- `custody_subnet_count` represents the node's custody subnet count. Clients MAY reject peers with a value less than `CUSTODY_REQUIREMENT`.

### The gossip domain: gossipsub

Expand Down Expand Up @@ -324,4 +324,4 @@ A new field is added to the ENR under the key `csc` to facilitate custody data c

| Key | Value |
|--------|------------------------------------------|
| `csc` | Custody subnet count, big endian integer |
| `csc` | Custody subnet count, `uint64` big endian integer with no leading zero bytes (`0` is encoded as empty byte string) |
11 changes: 7 additions & 4 deletions specs/_features/eip7732/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ class BeaconBlockBody(Container):
graffiti: Bytes32 # Arbitrary data
# Operations
proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS]
attestations: List[Attestation, MAX_ATTESTATIONS]
attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS_ELECTRA]
attestations: List[Attestation, MAX_ATTESTATIONS_ELECTRA]
deposits: List[Deposit, MAX_DEPOSITS]
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
sync_aggregate: SyncAggregate
Expand Down Expand Up @@ -493,9 +493,12 @@ def process_execution_payload_header(state: BeaconState, block: BeaconBlock) ->
signed_header = block.body.signed_execution_payload_header
assert verify_execution_payload_header_signature(state, signed_header)

# Check that the builder has funds to cover the bid
# Check that the builder is active non-slashed has funds to cover the bid
header = signed_header.message
builder_index = header.builder_index
builder = state.validators[builder_index]
assert is_active_validator(builder, get_current_epoch(state))
assert not builder.slashed
amount = header.value
assert state.balances[builder_index] >= amount

Expand Down Expand Up @@ -662,7 +665,7 @@ def process_execution_payload(state: BeaconState,

for_ops(payload.deposit_requests, process_deposit_request)
for_ops(payload.withdrawal_requests, process_withdrawal_request)
for_ops(payload, process_consolidation_request)
for_ops(payload.consolidation_requests, process_consolidation_request)

# Cache the execution payload header and proposer
state.latest_block_hash = payload.block_hash
Expand Down
28 changes: 19 additions & 9 deletions specs/_features/eip7732/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This document contains the consensus-layer networking specification for EIP7732.

- [Modification in EIP-7732](#modification-in-eip-7732)
- [Preset](#preset)
- [Configuration](#configuration)
- [Containers](#containers)
- [`BlobSidecar`](#blobsidecar)
- [Helpers](#helpers)
Expand All @@ -23,7 +24,7 @@ This document contains the consensus-layer networking specification for EIP7732.
- [BeaconBlocksByRange v3](#beaconblocksbyrange-v3)
- [BeaconBlocksByRoot v3](#beaconblocksbyroot-v3)
- [BlobSidecarsByRoot v2](#blobsidecarsbyroot-v2)
- [ExecutionPayloadEnvelopeByRoot v1](#executionpayloadenvelopebyroot-v1)
- [ExecutionPayloadEnvelopesByRoot v1](#executionpayloadenvelopesbyroot-v1)

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

Expand All @@ -37,6 +38,14 @@ This document contains the consensus-layer networking specification for EIP7732.
|------------------------------------------|-----------------------------------|---------------------------------------------------------------------|
| `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH_EIP7732` | `13` # TODO: Compute it when the spec stabilizes | Merkle proof depth for the `blob_kzg_commitments` list item |

### Configuration

*[New in EIP7732]*

| Name | Value | Description |
|------------------------|----------------|-------------------------------------------------------------------|
| `MAX_REQUEST_PAYLOADS` | `2**7` (= 128) | Maximum number of execution payload envelopes in a single request |


### Containers

Expand Down Expand Up @@ -170,9 +179,10 @@ The following validations MUST pass before forwarding the `signed_execution_payl

- _[IGNORE]_ this is the first signed bid seen with a valid signature from the given builder for this slot.
- _[IGNORE]_ this bid is the highest value bid seen for the pair of the corresponding slot and the given parent block hash.
- _[REJECT]_ The signed builder bid, `header.builder_index` is a valid and non-slashed builder index in state.
- _[REJECT]_ The signed builder bid, `header.builder_index` is a valid, active, and non-slashed builder index in state.
- _[IGNORE]_ The signed builder bid value, `header.value`, is less or equal than the builder's balance in state. i.e. `MIN_BUILDER_BALANCE + header.value < state.builder_balances[header.builder_index]`.
- _[IGNORE]_ `header.parent_block_hash` is the block hash of a known execution payload in fork choice.
_ _[IGNORE]_ `header.parent_block_root` is the hash tree root of a known beacon block in fork choice.
- _[IGNORE]_ `header.slot` is the current slot or the next slot.
- _[REJECT]_ The builder signature, `signed_execution_payload_header_envelope.signature`, is valid with respect to the `header_envelope.builder_index`.

Expand Down Expand Up @@ -225,9 +235,9 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `EIP7732_FORK_VERSION` | `eip7732.BlobSidecar` |


##### ExecutionPayloadEnvelopeByRoot v1
##### ExecutionPayloadEnvelopesByRoot v1

**Protocol ID:** `/eth2/beacon_chain/req/execution_payload_envelope_by_root/1/`
**Protocol ID:** `/eth2/beacon_chain/req/execution_payload_envelopes_by_root/1/`

The `<context-bytes>` field is calculated as `context = compute_fork_digest(fork_version, genesis_validators_root)`:

Expand All @@ -241,22 +251,22 @@ Request Content:

```
(
List[Root, MAX_REQUEST_PAYLOAD]
List[Root, MAX_REQUEST_PAYLOADS]
)
```

Response Content:

```
(
List[SignedExecutionPayloadEnvelope, MAX_REQUEST_PAYLOAD]
List[SignedExecutionPayloadEnvelope, MAX_REQUEST_PAYLOADS]
)
```
Requests execution payload envelope by `signed_execution_payload_envelope.message.block_root`. The response is a list of `SignedExecutionPayloadEnvelope` whose length is less than or equal to the number of requested execution payload envelopes. It may be less in the case that the responding peer is missing payload envelopes.
Requests execution payload envelopes by `signed_execution_payload_envelope.message.block_root`. The response is a list of `SignedExecutionPayloadEnvelope` whose length is less than or equal to the number of requested execution payload envelopes. It may be less in the case that the responding peer is missing payload envelopes.

No more than `MAX_REQUEST_PAYLOAD` may be requested at a time.
No more than `MAX_REQUEST_PAYLOADS` may be requested at a time.

ExecutionPayloadEnvelopeByRoot is primarily used to recover recent execution payload envelope (e.g. when receiving a payload attestation with revealed status as true but never received a payload).
ExecutionPayloadEnvelopesByRoot is primarily used to recover recent execution payload envelopes (e.g. when receiving a payload attestation with revealed status as true but never received a payload).

The request MUST be encoded as an SSZ-field.

Expand Down
2 changes: 1 addition & 1 deletion specs/altair/light-client/sync-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def is_better_update(new_update: LightClientUpdate, old_update: LightClientUpdat
new_has_supermajority = new_num_active_participants * 3 >= max_active_participants * 2
old_has_supermajority = old_num_active_participants * 3 >= max_active_participants * 2
if new_has_supermajority != old_has_supermajority:
return new_has_supermajority > old_has_supermajority
return new_has_supermajority
if not new_has_supermajority and new_num_active_participants != old_num_active_participants:
return new_num_active_participants > old_num_active_participants

Expand Down
21 changes: 10 additions & 11 deletions specs/electra/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
- [Modified `is_partially_withdrawable_validator`](#modified-is_partially_withdrawable_validator)
- [Misc](#misc-1)
- [New `get_committee_indices`](#new-get_committee_indices)
- [New `get_validator_max_effective_balance`](#new-get_validator_max_effective_balance)
- [New `get_max_effective_balance`](#new-get_max_effective_balance)
- [Beacon state accessors](#beacon-state-accessors)
- [New `get_balance_churn_limit`](#new-get_balance_churn_limit)
- [New `get_activation_exit_churn_limit`](#new-get_activation_exit_churn_limit)
Expand Down Expand Up @@ -521,14 +521,14 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch:

#### Modified `is_partially_withdrawable_validator`

*Note*: The function `is_partially_withdrawable_validator` is modified to use `get_validator_max_effective_balance` instead of `MAX_EFFECTIVE_BALANCE` and `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`.
*Note*: The function `is_partially_withdrawable_validator` is modified to use `get_max_effective_balance` instead of `MAX_EFFECTIVE_BALANCE` and `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`.

```python
def is_partially_withdrawable_validator(validator: Validator, balance: Gwei) -> bool:
"""
Check if ``validator`` is partially withdrawable.
"""
max_effective_balance = get_validator_max_effective_balance(validator)
max_effective_balance = get_max_effective_balance(validator)
has_max_effective_balance = validator.effective_balance == max_effective_balance # [Modified in Electra:EIP7251]
has_excess_balance = balance > max_effective_balance # [Modified in Electra:EIP7251]
return (
Expand All @@ -547,10 +547,10 @@ def get_committee_indices(committee_bits: Bitvector) -> Sequence[CommitteeIndex]
return [CommitteeIndex(index) for index, bit in enumerate(committee_bits) if bit]
```

#### New `get_validator_max_effective_balance`
#### New `get_max_effective_balance`

```python
def get_validator_max_effective_balance(validator: Validator) -> Gwei:
def get_max_effective_balance(validator: Validator) -> Gwei:
"""
Get max effective balance for ``validator``.
"""
Expand Down Expand Up @@ -597,7 +597,7 @@ def get_consolidation_churn_limit(state: BeaconState) -> Gwei:

```python
def get_active_balance(state: BeaconState, validator_index: ValidatorIndex) -> Gwei:
max_effective_balance = get_validator_max_effective_balance(state.validators[validator_index])
max_effective_balance = get_max_effective_balance(state.validators[validator_index])
return min(state.balances[validator_index], max_effective_balance)
```

Expand Down Expand Up @@ -1078,7 +1078,7 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal],
index=withdrawal_index,
validator_index=validator_index,
address=ExecutionAddress(validator.withdrawal_credentials[12:]),
amount=balance - get_validator_max_effective_balance(validator), # [Modified in Electra:EIP7251]
amount=balance - get_max_effective_balance(validator), # [Modified in Electra:EIP7251]
))
withdrawal_index += WithdrawalIndex(1)
if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD:
Expand All @@ -1095,10 +1095,9 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal],
def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None:
expected_withdrawals, partial_withdrawals_count = get_expected_withdrawals(state) # [Modified in Electra:EIP7251]

assert len(payload.withdrawals) == len(expected_withdrawals)
assert payload.withdrawals == expected_withdrawals

for expected_withdrawal, withdrawal in zip(expected_withdrawals, payload.withdrawals):
assert withdrawal == expected_withdrawal
for withdrawal in expected_withdrawals:
decrease_balance(state, withdrawal.validator_index, withdrawal.amount)

# Update pending partial withdrawals [New in Electra:EIP7251]
Expand Down Expand Up @@ -1583,7 +1582,7 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
balance = state.balances[index]
# [Modified in Electra:EIP7251]
validator.effective_balance = min(
balance - balance % EFFECTIVE_BALANCE_INCREMENT, get_validator_max_effective_balance(validator))
balance - balance % EFFECTIVE_BALANCE_INCREMENT, get_max_effective_balance(validator))
if validator.effective_balance >= MIN_ACTIVATION_BALANCE:
validator.activation_eligibility_epoch = GENESIS_EPOCH
validator.activation_epoch = GENESIS_EPOCH
Expand Down
Loading

0 comments on commit 3ebddad

Please sign in to comment.