Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
14d4f44
Extend fork_choice test format with on_payload_info
mkalinin Aug 3, 2022
109250b
Replace `hash_tree_root(x)` with `hash(ssz_serialize(x))`
hwwhww Aug 22, 2022
f8d92c3
Add basic test case
hwwhww Aug 15, 2022
b67fb5b
Update tests/formats/fork_choice/README.md
mkalinin Aug 24, 2022
d8e7409
Merge pull request #2981 from ethereum/hash_to_bls_field-with-serialize
asn-d6 Aug 25, 2022
ac717b1
Address PR feedback from @mkalinin
hwwhww Aug 31, 2022
0f8b5ae
Apply PR feedback from @michaelsproul
hwwhww Sep 2, 2022
2e73091
Add `get_valid_flag_value` helper to determine the `valid` flag value
hwwhww Sep 8, 2022
e639a3b
Merge branch 'dev' into pr2965
hwwhww Sep 8, 2022
97c61fe
Merge pull request #2965 from mkalinin/optimistic-sync-tests
hwwhww Sep 12, 2022
f2c2656
Merge pull request #2982 from ethereum/optimistic-sync-tests
hwwhww Sep 12, 2022
e4407c6
Add `test_process_deposit::test_key_validate_invalid`
hwwhww Sep 10, 2022
4d2cfff
Add `test_key_validate_invalid_decompression`
hwwhww Sep 12, 2022
770a603
Merge pull request #2989 from ethereum/deposit-zero-pk
djrtwo Sep 13, 2022
d70dcd9
Fix link to beacon-chain doc
barnjamin Sep 15, 2022
9a2fcc0
Merge pull request #2993 from barnjamin/patch-1
hwwhww Sep 16, 2022
63d284a
bump version to v1.2.0
djrtwo Sep 16, 2022
b63ed22
Fix signature of compute_aggregated_poly_and_commitment
dankrad Sep 19, 2022
b351550
Rename matrix_lincomb to vector_lincomb and lincomb to g1_lincomb
dankrad Sep 19, 2022
00a8a13
Merge pull request #2995 from ethereum/version-bump
djrtwo Sep 19, 2022
0f8e12e
Add a redirection README.md for the sync tests
hwwhww Sep 20, 2022
9ec97ba
Merge pull request #3000 from ethereum/sync-readme
djrtwo Sep 20, 2022
93b7ae2
Update BLS test format: output `null` for invalid case
hwwhww Sep 20, 2022
3bc7ff9
Fix a few things in Capella specs
jtraglia Sep 20, 2022
603e27f
Fix state list lengths table
jtraglia Sep 20, 2022
b72afff
Merge pull request #3002 from jtraglia/fix-a-few-things
ralexstokes Sep 21, 2022
7066307
Fix section name for withdraw_balance
jtraglia Sep 21, 2022
5517729
Fix TOC with check_toc
jtraglia Sep 21, 2022
1bb863b
eip4844: signed_blobs_header -> signed_blobs_sidecar
terencechain Sep 21, 2022
c0ef942
Merge pull request #3007 from jtraglia/rename-withdraw-section
hwwhww Sep 22, 2022
73c96b2
Merge pull request #3001 from ethereum/bls-output-null
hwwhww Sep 22, 2022
e4fdb8a
Merge pull request #3005 from ethereum/eip4844-patch-dr
asn-d6 Sep 22, 2022
189d61e
Merge pull request #3008 from terencechain/patch-137
ralexstokes Sep 22, 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
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ 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.utils.ssz.ssz_impl import serialize as ssz_serialize
'''

@classmethod
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 @@ -47,7 +47,7 @@ Such environments include resource-constrained devices (e.g. phones for trust-mi
and metered VMs (e.g. blockchain VMs for cross-chain bridges).

This document suggests a minimal light client design for the beacon chain that
uses sync committees introduced in [this beacon chain extension](./beacon-chain.md).
uses sync committees introduced in [this beacon chain extension](../beacon-chain.md).

Additional documents describe how the light client sync protocol can be used:
- [Full node](./full-node.md)
Expand Down
20 changes: 10 additions & 10 deletions specs/capella/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
- [`BeaconState`](#beaconstate)
- [Helpers](#helpers)
- [Beacon state mutators](#beacon-state-mutators)
- [`withdraw`](#withdraw)
- [`withdraw_balance`](#withdraw_balance)
- [Predicates](#predicates)
- [`has_eth1_withdrawal_credential`](#has_eth1_withdrawal_credential)
- [`is_fully_withdrawable_validator`](#is_fully_withdrawable_validator)
Expand All @@ -52,19 +52,19 @@

Capella is a consensus-layer upgrade containing a number of features related
to validator withdrawals. Including:
* Automatic withdrawals of `withdrawable` validators
* Automatic withdrawals of `withdrawable` validators.
* Partial withdrawals sweep for validators with 0x01 withdrawal
credentials and balances in exceess of `MAX_EFFECTIVE_BALANCE`
credentials and balances in excess of `MAX_EFFECTIVE_BALANCE`.
* Operation to change from `BLS_WITHDRAWAL_PREFIX` to
`ETH1_ADDRESS_WITHDRAWAL_PREFIX` versioned withdrawal credentials to enable withdrawals for a validator
`ETH1_ADDRESS_WITHDRAWAL_PREFIX` versioned withdrawal credentials to enable withdrawals for a validator.

## Custom types

We define the following Python custom types for type hinting and readability:

| Name | SSZ equivalent | Description |
| - | - | - |
| `WithdrawalIndex` | `uint64` | an index of a `Withdrawal`|
| `WithdrawalIndex` | `uint64` | an index of a `Withdrawal` |

## Constants

Expand All @@ -84,9 +84,9 @@ We define the following Python custom types for type hinting and readability:

### State list lengths

| Name | Value | Unit | Duration |
| - | - | :-: | :-: |
| `WITHDRAWAL_QUEUE_LIMIT` | `uint64(2**40)` (= 1,099,511,627,776) | withdrawals enqueued in state|
| Name | Value | Unit |
| - | - | :-: |
| `WITHDRAWAL_QUEUE_LIMIT` | `uint64(2**40)` (= 1,099,511,627,776) | withdrawals enqueued in state |

### Max operations per block

Expand Down Expand Up @@ -266,7 +266,7 @@ class BeaconState(Container):

### Beacon state mutators

#### `withdraw`
#### `withdraw_balance`

```python
def withdraw_balance(state: BeaconState, validator_index: ValidatorIndex, amount: Gwei) -> None:
Expand All @@ -289,7 +289,7 @@ def withdraw_balance(state: BeaconState, validator_index: ValidatorIndex, amount
```python
def has_eth1_withdrawal_credential(validator: Validator) -> bool:
"""
Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential
Check if ``validator`` has an 0x01 prefixed "eth1" withdrawal credential.
"""
return validator.withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX
```
Expand Down
2 changes: 1 addition & 1 deletion specs/capella/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ class PayloadAttributes(object):
timestamp: uint64
prev_randao: Bytes32
suggested_fee_recipient: ExecutionAddress
withdrawals: Sequence[Withdrawal] # new in Capella
withdrawals: Sequence[Withdrawal] # [New in Capella]
```
2 changes: 1 addition & 1 deletion specs/capella/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ an irregular state change is made to upgrade to Capella.

The upgrade occurs after the completion of the inner loop of `process_slots` that sets `state.slot` equal to `CAPELLA_FORK_EPOCH * SLOTS_PER_EPOCH`.
Care must be taken when transitioning through the fork boundary as implementations will need a modified [state transition function](../phase0/beacon-chain.md#beacon-chain-state-transition-function) that deviates from the Phase 0 document.
In particular, the outer `state_transition` function defined in the Phase 0 document will not expose the precise fork slot to execute the upgrade in the presence of skipped slots at the fork boundary. Instead the logic must be within `process_slots`.
In particular, the outer `state_transition` function defined in the Phase 0 document will not expose the precise fork slot to execute the upgrade in the presence of skipped slots at the fork boundary. Instead, the logic must be within `process_slots`.

```python
def upgrade_to_capella(pre: bellatrix.BeaconState) -> BeaconState:
Expand Down
2 changes: 1 addition & 1 deletion specs/eip4844/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Alias `sidecar = signed_blobs_sidecar.message`.
- _[REJECT]_ the beacon proposer signature, `signed_blobs_sidecar.signature`, is valid -- i.e.
- Let `domain = get_domain(state, DOMAIN_BLOBS_SIDECAR, sidecar.beacon_block_slot // SLOTS_PER_EPOCH)`
- Let `signing_root = compute_signing_root(sidecar, domain)`
- Verify `bls.Verify(proposer_pubkey, signing_root, signed_blob_header.signature) is True`,
- Verify `bls.Verify(proposer_pubkey, signing_root, signed_blobs_sidecar.signature) is True`,
where `proposer_pubkey` is the pubkey of the beacon block proposer of `sidecar.beacon_block_slot`
- _[IGNORE]_ The sidecar is the first sidecar with valid signature received for the `(proposer_index, sidecar.beacon_block_slot)` combination,
where `proposer_index` is the validator index of the beacon block proposer of `sidecar.beacon_block_slot`
Expand Down
16 changes: 8 additions & 8 deletions specs/eip4844/polynomial-commitments.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
- [BLS12-381 helpers](#bls12-381-helpers)
- [`bls_modular_inverse`](#bls_modular_inverse)
- [`div`](#div)
- [`lincomb`](#lincomb)
- [`matrix_lincomb`](#matrix_lincomb)
- [`g1_lincomb`](#g1_lincomb)
- [`vector_lincomb`](#vector_lincomb)
- [KZG](#kzg)
- [`blob_to_kzg_commitment`](#blob_to_kzg_commitment)
- [`verify_kzg_proof`](#verify_kzg_proof)
Expand Down Expand Up @@ -85,10 +85,10 @@ def div(x: BLSFieldElement, y: BLSFieldElement) -> BLSFieldElement:
return (int(x) * int(bls_modular_inverse(y))) % BLS_MODULUS
```

#### `lincomb`
#### `g1_lincomb`

```python
def lincomb(points: Sequence[KZGCommitment], scalars: Sequence[BLSFieldElement]) -> KZGCommitment:
def g1_lincomb(points: Sequence[KZGCommitment], scalars: Sequence[BLSFieldElement]) -> KZGCommitment:
"""
BLS multiscalar multiplication. This function can be optimized using Pippenger's algorithm and variants.
"""
Expand All @@ -99,10 +99,10 @@ def lincomb(points: Sequence[KZGCommitment], scalars: Sequence[BLSFieldElement])
return KZGCommitment(bls.G1_to_bytes48(result))
```

#### `matrix_lincomb`
#### `vector_lincomb`

```python
def matrix_lincomb(vectors: Sequence[Sequence[BLSFieldElement]],
def vector_lincomb(vectors: Sequence[Sequence[BLSFieldElement]],
scalars: Sequence[BLSFieldElement]) -> Sequence[BLSFieldElement]:
"""
Given a list of ``vectors``, interpret it as a 2D matrix and compute the linear combination
Expand All @@ -123,7 +123,7 @@ KZG core functions. These are also defined in EIP-4844 execution specs.

```python
def blob_to_kzg_commitment(blob: Blob) -> KZGCommitment:
return lincomb(KZG_SETUP_LAGRANGE, blob)
return g1_lincomb(KZG_SETUP_LAGRANGE, blob)
```

#### `verify_kzg_proof`
Expand Down Expand Up @@ -165,7 +165,7 @@ def compute_kzg_proof(polynomial: Sequence[BLSFieldElement], z: BLSFieldElement)

# Calculate quotient polynomial by doing point-by-point division
quotient_polynomial = [div(a, b) for a, b in zip(polynomial_shifted, denominator_poly)]
return KZGProof(lincomb(KZG_SETUP_LAGRANGE, quotient_polynomial))
return KZGProof(g1_lincomb(KZG_SETUP_LAGRANGE, quotient_polynomial))
```

### Polynomials
Expand Down
11 changes: 6 additions & 5 deletions specs/eip4844/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments:
```python
def hash_to_bls_field(x: Container) -> BLSFieldElement:
"""
This function is used to generate Fiat-Shamir challenges. The output is not uniform over the BLS field.
Compute 32-byte hash of serialized container and convert it to BLS field.
The output is not uniform over the BLS field.
"""
return int.from_bytes(hash_tree_root(x), "little") % BLS_MODULUS
return int.from_bytes(hash(ssz_serialize(x)), "little") % BLS_MODULUS
```

### `compute_powers`
Expand All @@ -116,7 +117,7 @@ def compute_powers(x: BLSFieldElement, n: uint64) -> Sequence[BLSFieldElement]:

```python
def compute_aggregated_poly_and_commitment(
blobs: Sequence[BLSFieldElement],
blobs: Sequence[Sequence[BLSFieldElement]],
kzg_commitments: Sequence[KZGCommitment]) -> Tuple[Polynomial, KZGCommitment]:
"""
Return the aggregated polynomial and aggregated KZG commitment.
Expand All @@ -126,10 +127,10 @@ def compute_aggregated_poly_and_commitment(
r_powers = compute_powers(r, len(kzg_commitments))

# Create aggregated polynomial in evaluation form
aggregated_poly = Polynomial(matrix_lincomb(blobs, r_powers))
aggregated_poly = Polynomial(vector_lincomb(blobs, r_powers))

# Compute commitment to aggregated polynomial
aggregated_poly_commitment = KZGCommitment(lincomb(kzg_commitments, r_powers))
aggregated_poly_commitment = KZGCommitment(g1_lincomb(kzg_commitments, r_powers))

return aggregated_poly, aggregated_poly_commitment
```
Expand Down
4 changes: 2 additions & 2 deletions sync/optimistic.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ Let `current_slot: Slot` be `(time - genesis_time) // SECONDS_PER_SLOT` where
class OptimisticStore(object):
optimistic_roots: Set[Root]
head_block_root: Root
blocks: Dict[Root, BeaconBlock]
block_states: Dict[Root, BeaconState]
blocks: Dict[Root, BeaconBlock] = field(default_factory=dict)
block_states: Dict[Root, BeaconState] = field(default_factory=dict)
```

```python
Expand Down
2 changes: 1 addition & 1 deletion tests/core/pyspec/eth2spec/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.0-rc.3
1.2.0
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import json
from typing import Iterable, AnyStr, Any, Callable
import traceback

from ruamel.yaml import (
YAML,
)
Expand Down Expand Up @@ -98,6 +97,11 @@ def run_generator(generator_name, test_providers: Iterable[TestProvider]):
yaml = YAML(pure=True)
yaml.default_flow_style = None

def _represent_none(self, _):
return self.represent_scalar('tag:yaml.org,2002:null', 'null')

yaml.representer.add_representer(type(None), _represent_none)

# Spec config is using a YAML subset
cfg_yaml = YAML(pure=True)
cfg_yaml.default_flow_style = False # Emit separate line for each key
Expand Down
Empty file.
99 changes: 99 additions & 0 deletions tests/core/pyspec/eth2spec/test/bellatrix/sync/test_optimistic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from eth2spec.test.context import (
spec_state_test,
with_bellatrix_and_later,
)
from eth2spec.test.helpers.attestations import (
state_transition_with_full_block,
)
from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot,
)
from eth2spec.test.helpers.fork_choice import (
get_genesis_forkchoice_store_and_block,
on_tick_and_append_step,
)
from eth2spec.test.helpers.optimistic_sync import (
PayloadStatusV1,
PayloadStatusV1Status,
MegaStore,
add_optimistic_block,
get_optimistic_store,
)
from eth2spec.test.helpers.state import (
next_epoch,
state_transition_and_sign_block,
)


@with_bellatrix_and_later
@spec_state_test
def test_from_syncing_to_invalid(spec, state):
test_steps = []
# Initialization
fc_store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
op_store = get_optimistic_store(spec, state, anchor_block)
mega_store = MegaStore(spec, fc_store, op_store)
yield 'anchor_state', state
yield 'anchor_block', anchor_block

next_epoch(spec, state)

current_time = (
(spec.SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY * 10 + state.slot) * spec.config.SECONDS_PER_SLOT
+ fc_store.genesis_time
)
on_tick_and_append_step(spec, fc_store, current_time, test_steps)

# Block 0
block_0 = build_empty_block_for_next_slot(spec, state)
block_0.body.execution_payload.block_hash = spec.hash(bytes(f'block_0', 'UTF-8'))
signed_block = state_transition_and_sign_block(spec, state, block_0)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root

state_0 = state.copy()

# Create VALID chain `a`
signed_blocks_a = []
for i in range(3):
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_a_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_a_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash
)

signed_block = state_transition_and_sign_block(spec, state, block)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps, status=PayloadStatusV1Status.VALID)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root
signed_blocks_a.append(signed_block.copy())

# Create SYNCING chain `b`
signed_blocks_b = []
state = state_0.copy()
for i in range(3):
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_b_{i}', 'UTF-8'))
block.body.execution_payload.parent_hash = (
spec.hash(bytes(f'chain_b_{i - 1}', 'UTF-8')) if i != 0 else block_0.body.execution_payload.block_hash
)
signed_block = state_transition_with_full_block(spec, state, True, True, block=block)
signed_blocks_b.append(signed_block.copy())
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps,
status=PayloadStatusV1Status.SYNCING)
assert spec.get_head(mega_store.fc_store) == mega_store.opt_store.head_block_root

# Now add block 4 to chain `b` with INVALID
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.block_hash = spec.hash(bytes(f'chain_b_3', 'UTF-8'))
block.body.execution_payload.parent_hash = signed_blocks_b[-1].message.body.execution_payload.block_hash
signed_block = state_transition_and_sign_block(spec, state, block)
payload_status = PayloadStatusV1(
status=PayloadStatusV1Status.INVALID,
latest_valid_hash=block_0.body.execution_payload.block_hash,
validation_error="invalid",
)
yield from add_optimistic_block(spec, mega_store, signed_block, test_steps,
payload_status=payload_status)
assert mega_store.opt_store.head_block_root == signed_blocks_a[-1].message.hash_tree_root()

yield 'steps', test_steps
6 changes: 4 additions & 2 deletions tests/core/pyspec/eth2spec/test/helpers/attestations.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,13 @@ def state_transition_with_full_block(spec,
fill_cur_epoch,
fill_prev_epoch,
participation_fn=None,
sync_aggregate=None):
sync_aggregate=None,
block=None):
"""
Build and apply a block with attestions at the calculated `slot_to_attest` of current epoch and/or previous epoch.
"""
block = build_empty_block_for_next_slot(spec, state)
if block is None:
block = build_empty_block_for_next_slot(spec, state)
if fill_cur_epoch and state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY:
slot_to_attest = state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1
if slot_to_attest >= spec.compute_start_slot_at_epoch(spec.get_current_epoch(state)):
Expand Down
15 changes: 11 additions & 4 deletions tests/core/pyspec/eth2spec/test/helpers/deposits.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,21 @@ def prepare_random_genesis_deposits(spec,
return deposits, root, deposit_data_list


def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False):
def prepare_state_and_deposit(spec, state, validator_index, amount,
pubkey=None,
privkey=None,
withdrawal_credentials=None,
signed=False):
"""
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
"""
deposit_data_list = []

pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
if pubkey is None:
pubkey = pubkeys[validator_index]

if privkey is None:
privkey = privkeys[validator_index]

# insecurely use pubkey as withdrawal key if no credentials provided
if withdrawal_credentials is None:
Expand Down Expand Up @@ -196,7 +203,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef

yield 'post', state

if not effective:
if not effective or not bls.KeyValidate(deposit.data.pubkey):
assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count
if validator_index < pre_validator_count:
Expand Down
Loading