From f1435d456d26b43e0aea77b95e390e52091e8c9c Mon Sep 17 00:00:00 2001 From: Emilia Hane <58548332+emhane@users.noreply.github.com> Date: Thu, 19 Jan 2023 21:26:21 +0100 Subject: [PATCH 01/15] Update p2p-interface.md --- specs/eip4844/p2p-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/eip4844/p2p-interface.md b/specs/eip4844/p2p-interface.md index 3e0456713..e86e7a219 100644 --- a/specs/eip4844/p2p-interface.md +++ b/specs/eip4844/p2p-interface.md @@ -218,7 +218,7 @@ Each _successful_ `response_chunk` MUST contain a single `BlobsSidecar` payload. Clients MUST keep a record of signed blobs sidecars seen on the epoch range `[max(current_epoch - MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS, EIP4844_FORK_EPOCH), current_epoch]` where `current_epoch` is defined by the current wall-clock time, -and clients MUST support serving requests of blocks on this range. +and clients MUST support serving requests of blobs on this range. Peers that are unable to reply to blobs sidecars requests within the `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` epoch range SHOULD respond with error code `3: ResourceUnavailable`. From a0791712cd1afda05807b3f79aee1a50a1bc59ed Mon Sep 17 00:00:00 2001 From: Pawan Dhananjay Date: Fri, 20 Jan 2023 21:32:00 +0530 Subject: [PATCH 02/15] Remove kzg point validations in gossip --- specs/eip4844/p2p-interface.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/specs/eip4844/p2p-interface.md b/specs/eip4844/p2p-interface.md index 3e0456713..01051dc39 100644 --- a/specs/eip4844/p2p-interface.md +++ b/specs/eip4844/p2p-interface.md @@ -85,17 +85,12 @@ This topic is used to propagate new signed and coupled beacon blocks and blobs s In addition to the gossip validations for the `beacon_block` topic from prior specifications, the following validations MUST pass before forwarding the `signed_beacon_block_and_blobs_sidecar` on the network. Alias `signed_beacon_block = signed_beacon_block_and_blobs_sidecar.beacon_block`, `block = signed_beacon_block.message`, `execution_payload = block.body.execution_payload`. -- _[REJECT]_ The KZG commitments of the blobs are all correctly encoded compressed BLS G1 points - -- i.e. `all(bls.KeyValidate(commitment) for commitment in block.body.blob_kzg_commitments)` - _[REJECT]_ The KZG commitments correspond to the versioned hashes in the transactions list -- i.e. `verify_kzg_commitments_against_transactions(block.body.execution_payload.transactions, block.body.blob_kzg_commitments)` Alias `sidecar = signed_beacon_block_and_blobs_sidecar.blobs_sidecar`. - _[IGNORE]_ the `sidecar.beacon_block_slot` is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `sidecar.beacon_block_slot == block.slot`. -- _[REJECT]_ the `sidecar.blobs` are all well formatted, i.e. the `BLSFieldElement` in valid range (`x < BLS_MODULUS`). -- _[REJECT]_ The KZG proof is a correctly encoded compressed BLS G1 point - -- i.e. `bls.KeyValidate(blobs_sidecar.kzg_aggregated_proof)` - _[REJECT]_ The KZG commitments in the block are valid against the provided blobs sidecar -- i.e. `validate_blobs_sidecar(block.slot, hash_tree_root(block), block.body.blob_kzg_commitments, sidecar)` From 26261269354e86f4e095d3c635c44f737c86b29b Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 24 Jan 2023 14:02:22 +0100 Subject: [PATCH 03/15] EIP4844: compute_kzg_proof() now takes bytes as input (#3219) --- specs/eip4844/polynomial-commitments.md | 18 +++++++++++++++--- .../test_polynomial_commitments.py | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/specs/eip4844/polynomial-commitments.md b/specs/eip4844/polynomial-commitments.md index 26ee00487..53293cee8 100644 --- a/specs/eip4844/polynomial-commitments.md +++ b/specs/eip4844/polynomial-commitments.md @@ -35,6 +35,7 @@ - [`verify_kzg_proof`](#verify_kzg_proof) - [`verify_kzg_proof_impl`](#verify_kzg_proof_impl) - [`compute_kzg_proof`](#compute_kzg_proof) + - [`compute_kzg_proof_impl`](#compute_kzg_proof_impl) - [`compute_aggregated_poly_and_commitment`](#compute_aggregated_poly_and_commitment) - [`compute_aggregate_kzg_proof`](#compute_aggregate_kzg_proof) - [`verify_aggregate_kzg_proof`](#verify_aggregate_kzg_proof) @@ -370,12 +371,23 @@ def verify_kzg_proof_impl(polynomial_kzg: KZGCommitment, #### `compute_kzg_proof` ```python -def compute_kzg_proof(polynomial: Polynomial, z: BLSFieldElement) -> KZGProof: +def compute_kzg_proof(blob: Blob, z: Bytes32) -> KZGProof: """ - Compute KZG proof at point `z` with `polynomial` being in evaluation form. + Compute KZG proof at point `z` for the polynomial represented by `blob`. Do this by computing the quotient polynomial in evaluation form: q(x) = (p(x) - p(z)) / (x - z). Public method. """ + polynomial = blob_to_polynomial(blob) + return compute_kzg_proof_impl(polynomial, bytes_to_bls_field(z)) +``` + +#### `compute_kzg_proof_impl` + +```python +def compute_kzg_proof_impl(polynomial: Polynomial, z: BLSFieldElement) -> KZGProof: + """ + Helper function for compute_kzg_proof() and compute_aggregate_kzg_proof(). + """ y = evaluate_polynomial_in_evaluation_form(polynomial, z) polynomial_shifted = [BLSFieldElement((int(p) - int(y)) % BLS_MODULUS) for p in polynomial] @@ -430,7 +442,7 @@ def compute_aggregate_kzg_proof(blobs: Sequence[Blob]) -> KZGProof: blobs, commitments ) - return compute_kzg_proof(aggregated_poly, evaluation_challenge) + return compute_kzg_proof_impl(aggregated_poly, evaluation_challenge) ``` #### `verify_aggregate_kzg_proof` diff --git a/tests/core/pyspec/eth2spec/test/eip4844/unittests/polynomial_commitments/test_polynomial_commitments.py b/tests/core/pyspec/eth2spec/test/eip4844/unittests/polynomial_commitments/test_polynomial_commitments.py index 24b45475e..04f5857f3 100644 --- a/tests/core/pyspec/eth2spec/test/eip4844/unittests/polynomial_commitments/test_polynomial_commitments.py +++ b/tests/core/pyspec/eth2spec/test/eip4844/unittests/polynomial_commitments/test_polynomial_commitments.py @@ -18,7 +18,7 @@ def test_verify_kzg_proof(spec, state): blob = get_sample_blob(spec) commitment = spec.blob_to_kzg_commitment(blob) polynomial = spec.blob_to_polynomial(blob) - proof = spec.compute_kzg_proof(polynomial, x) + proof = spec.compute_kzg_proof_impl(polynomial, x) y = spec.evaluate_polynomial_in_evaluation_form(polynomial, x) assert spec.verify_kzg_proof_impl(commitment, x, y, proof) From d54c87a5c0703587012c0965cf2351cf4d0fb933 Mon Sep 17 00:00:00 2001 From: Ben Edgington Date: Tue, 24 Jan 2023 13:08:41 +0000 Subject: [PATCH 04/15] Add genesis_block to get_forkchoice_store() params --- specs/phase0/fork-choice.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/phase0/fork-choice.md b/specs/phase0/fork-choice.md index 661ad613b..f8f88cf47 100644 --- a/specs/phase0/fork-choice.md +++ b/specs/phase0/fork-choice.md @@ -43,7 +43,7 @@ This document is the beacon chain fork choice spec, part of Phase 0. It assumes ## Fork choice -The head block root associated with a `store` is defined as `get_head(store)`. At genesis, let `store = get_forkchoice_store(genesis_state)` and update `store` by running: +The head block root associated with a `store` is defined as `get_head(store)`. At genesis, let `store = get_forkchoice_store(genesis_state, genesis_block)` and update `store` by running: - `on_tick(store, time)` whenever `time > store.time` where `time` is the current Unix time - `on_block(store, block)` whenever a block `block: SignedBeaconBlock` is received @@ -485,4 +485,4 @@ def on_attester_slashing(store: Store, attester_slashing: AttesterSlashing) -> N indices = set(attestation_1.attesting_indices).intersection(attestation_2.attesting_indices) for index in indices: store.equivocating_indices.add(index) -``` \ No newline at end of file +``` From 8a0de1c5957bb37654b7181d188700b947598707 Mon Sep 17 00:00:00 2001 From: Ben Edgington Date: Tue, 24 Jan 2023 13:25:40 +0000 Subject: [PATCH 05/15] Add on_attester_slashing() to handlers list --- specs/phase0/fork-choice.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/phase0/fork-choice.md b/specs/phase0/fork-choice.md index 661ad613b..289c7a04c 100644 --- a/specs/phase0/fork-choice.md +++ b/specs/phase0/fork-choice.md @@ -48,6 +48,7 @@ The head block root associated with a `store` is defined as `get_head(store)`. A - `on_tick(store, time)` whenever `time > store.time` where `time` is the current Unix time - `on_block(store, block)` whenever a block `block: SignedBeaconBlock` is received - `on_attestation(store, attestation)` whenever an attestation `attestation` is received +- `on_attester_slashing(store, attester_slashing)` whenever an attester slashing `attester_slashing` is received Any of the above handlers that trigger an unhandled exception (e.g. a failed assert or an out-of-range list access) are considered invalid. Invalid calls to handlers must not modify `store`. @@ -485,4 +486,4 @@ def on_attester_slashing(store: Store, attester_slashing: AttesterSlashing) -> N indices = set(attestation_1.attesting_indices).intersection(attestation_2.attesting_indices) for index in indices: store.equivocating_indices.add(index) -``` \ No newline at end of file +``` From 5eca56901e7f8929b5420c4043cebcb16f89d713 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Tue, 24 Jan 2023 14:14:25 +0000 Subject: [PATCH 06/15] Update polynomial-commitments.md (#3223) --- specs/eip4844/polynomial-commitments.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/eip4844/polynomial-commitments.md b/specs/eip4844/polynomial-commitments.md index 53293cee8..e13bd7e46 100644 --- a/specs/eip4844/polynomial-commitments.md +++ b/specs/eip4844/polynomial-commitments.md @@ -56,10 +56,10 @@ Functions flagged as "Public method" MUST be provided by the underlying KZG libr | `G1Point` | `Bytes48` | | | `G2Point` | `Bytes96` | | | `BLSFieldElement` | `uint256` | `x < BLS_MODULUS` | -| `KZGCommitment` | `Bytes48` | Same as BLS standard "is valid pubkey" check but also allows `0x00..00` for point-at-infinity | +| `KZGCommitment` | `Bytes48` | Same as BLS standard "KeyValidate" check but allows the identity point | | `KZGProof` | `Bytes48` | Same as for `KZGCommitment` | -| `Polynomial` | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | a polynomial in evaluation form | -| `Blob` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` | a basic blob data | +| `Polynomial` | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | A polynomial in evaluation form | +| `Blob` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` | A basic blob data | ## Constants From 065b303dca6876337a501f86f183ac981ac8c0f7 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 25 Jan 2023 10:59:30 +0100 Subject: [PATCH 07/15] Add tests of mixing top-ups and withdrawals, rename old test case --- .../test_process_withdrawals.py | 6 +- .../test/capella/sanity/test_blocks.py | 78 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_withdrawals.py b/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_withdrawals.py index 674231096..d7813fb1f 100644 --- a/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_withdrawals.py +++ b/tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_withdrawals.py @@ -147,12 +147,14 @@ def test_success_one_partial_withdrawal(spec, state): @with_capella_and_later @spec_state_test -def test_success_max_per_slot(spec, state): +def test_success_mixed_fully_and_partial_withdrawable(spec, state): num_full_withdrawals = spec.MAX_WITHDRAWALS_PER_PAYLOAD // 2 num_partial_withdrawals = spec.MAX_WITHDRAWALS_PER_PAYLOAD - num_full_withdrawals fully_withdrawable_indices, partial_withdrawals_indices = prepare_expected_withdrawals( spec, state, - num_full_withdrawals=num_full_withdrawals, num_partial_withdrawals=num_partial_withdrawals) + num_full_withdrawals=num_full_withdrawals, + num_partial_withdrawals=num_partial_withdrawals, + ) next_slot(spec, state) execution_payload = build_empty_execution_payload(spec, state) diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index 1cd1c1317..6e54b4b55 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -3,6 +3,7 @@ from eth2spec.test.context import ( ) from eth2spec.test.helpers.state import ( state_transition_and_sign_block, + next_epoch_via_block, ) from eth2spec.test.helpers.block import ( build_empty_block_for_next_slot, @@ -13,10 +14,14 @@ from eth2spec.test.helpers.state import ( next_slot, ) from eth2spec.test.helpers.withdrawals import ( + set_eth1_withdrawal_credential_with_balance, set_validator_fully_withdrawable, set_validator_partially_withdrawable, prepare_expected_withdrawals, ) +from eth2spec.test.helpers.deposits import ( + prepare_state_and_deposit, +) from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits @@ -255,3 +260,76 @@ def test_invalid_withdrawal_fail_second_block_payload_isnt_compatible(spec, stat yield 'blocks', [signed_block_2] yield 'post', None + + +# +# Mix top-ups and withdrawals +# + + +@with_capella_and_later +@spec_state_test +def test_top_up_and_partial_withdrawal_validator(spec, state): + next_withdrawal_validator_index = 0 + validator_index = next_withdrawal_validator_index + 1 + + set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, spec.MAX_EFFECTIVE_BALANCE) + validator = state.validators[validator_index] + balance = state.balances[validator_index] + assert not spec.is_partially_withdrawable_validator(validator, balance) + + # Make a top-up balance to validator + amount = spec.MAX_EFFECTIVE_BALANCE // 4 + deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) + + yield 'pre', state + + block = build_empty_block_for_next_slot(spec, state) + block.body.deposits.append(deposit) + + signed_block = state_transition_and_sign_block(spec, state, block) + + yield 'blocks', [signed_block] + yield 'post', state + + validator = state.validators[validator_index] + balance = state.balances[validator_index] + assert spec.is_partially_withdrawable_validator(validator, balance) + + +@with_capella_and_later +@spec_state_test +def test_top_up_and_fully_withdrawal_validator(spec, state): + """ + Similar to `teste_process_deposit::test_success_top_up_to_withdrawn_validator` test. + """ + next_withdrawal_validator_index = 0 + validator_index = next_withdrawal_validator_index + 1 + + # Fully withdraw validator + set_validator_fully_withdrawable(spec, state, validator_index) + assert state.balances[validator_index] > 0 + next_epoch_via_block(spec, state) + assert state.balances[validator_index] == 0 + assert state.validators[validator_index].effective_balance > 0 + next_epoch_via_block(spec, state) + assert state.validators[validator_index].effective_balance == 0 + + # Make a top-up balance to validator + amount = spec.MAX_EFFECTIVE_BALANCE // 4 + deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) + + yield 'pre', state + + block = build_empty_block_for_next_slot(spec, state) + block.body.deposits.append(deposit) + + signed_block = state_transition_and_sign_block(spec, state, block) + + yield 'blocks', [signed_block] + yield 'post', state + + validator = state.validators[validator_index] + balance = state.balances[validator_index] + current_epoch = spec.get_current_epoch(state) + assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch) From 6e397b195b8e7d5390a63634038c4615464fb7ff Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 25 Jan 2023 16:15:19 +0100 Subject: [PATCH 08/15] EIP4844: Public methods take bytes as input (explicit validation) (#3224) --- specs/eip4844/polynomial-commitments.md | 77 ++++++++++++++++++++----- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/specs/eip4844/polynomial-commitments.md b/specs/eip4844/polynomial-commitments.md index e13bd7e46..9a0500d96 100644 --- a/specs/eip4844/polynomial-commitments.md +++ b/specs/eip4844/polynomial-commitments.md @@ -21,6 +21,9 @@ - [BLS12-381 helpers](#bls12-381-helpers) - [`hash_to_bls_field`](#hash_to_bls_field) - [`bytes_to_bls_field`](#bytes_to_bls_field) + - [`validate_kzg_g1`](#validate_kzg_g1) + - [`bytes_to_kzg_commitment`](#bytes_to_kzg_commitment) + - [`bytes_to_kzg_proof`](#bytes_to_kzg_proof) - [`blob_to_polynomial`](#blob_to_polynomial) - [`compute_challenges`](#compute_challenges) - [`bls_modular_inverse`](#bls_modular_inverse) @@ -49,14 +52,16 @@ This document specifies basic polynomial operations and KZG polynomial commitmen Functions flagged as "Public method" MUST be provided by the underlying KZG library as public functions. All other functions are private functions used internally by the KZG library. +Public functions MUST accept raw bytes as input and perform the required cryptographic normalization before invoking any internal functions. + ## Custom types | Name | SSZ equivalent | Description | | - | - | - | | `G1Point` | `Bytes48` | | | `G2Point` | `Bytes96` | | -| `BLSFieldElement` | `uint256` | `x < BLS_MODULUS` | -| `KZGCommitment` | `Bytes48` | Same as BLS standard "KeyValidate" check but allows the identity point | +| `BLSFieldElement` | `uint256` | Validation: `x < BLS_MODULUS` | +| `KZGCommitment` | `Bytes48` | Validation: Perform [BLS standard's](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.5) "KeyValidate" check but do allow the identity point | | `KZGProof` | `Bytes48` | Same as for `KZGCommitment` | | `Polynomial` | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | A polynomial in evaluation form | | `Blob` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` | A basic blob data | @@ -67,6 +72,8 @@ Functions flagged as "Public method" MUST be provided by the underlying KZG libr | - | - | - | | `BLS_MODULUS` | `52435875175126190479447740508185965837690552500527637822603658699938581184513` | Scalar field modulus of BLS12-381 | | `BYTES_PER_FIELD_ELEMENT` | `uint64(32)` | Bytes used to encode a BLS scalar field element | +| `G1_POINT_AT_INFINITY` | `Bytes48(b'\xc0' + b'\x00' * 47)` | Serialized form of the point at infinity on the G1 group | + ## Preset @@ -157,7 +164,7 @@ def hash_to_bls_field(data: bytes) -> BLSFieldElement: ```python def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement: """ - Convert 32-byte value to a BLS scalar field element. + Convert untrusted bytes to a trusted and validated BLS scalar field element. This function does not accept inputs greater than the BLS modulus. """ field_element = int.from_bytes(b, ENDIANNESS) @@ -165,6 +172,42 @@ def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement: return BLSFieldElement(field_element) ``` + +#### `validate_kzg_g1` + +```python +def validate_kzg_g1(b: Bytes48) -> None: + """ + Perform BLS validation required by the types `KZGProof` and `KZGCommitment`. + """ + if b == G1_POINT_AT_INFINITY: + return + + assert bls.KeyValidate(b) +``` + +#### `bytes_to_kzg_commitment` + +```python +def bytes_to_kzg_commitment(b: Bytes48) -> KZGCommitment: + """ + Convert untrusted bytes into a trusted and validated KZGCommitment. + """ + validate_kzg_g1(b) + return KZGCommitment(b) +``` + +#### `bytes_to_kzg_proof` + +```python +def bytes_to_kzg_proof(b: Bytes48) -> KZGProof: + """ + Convert untrusted bytes into a trusted and validated KZGProof. + """ + validate_kzg_g1(b) + return KZGProof(b) +``` + #### `blob_to_polynomial` ```python @@ -336,35 +379,38 @@ def blob_to_kzg_commitment(blob: Blob) -> KZGCommitment: #### `verify_kzg_proof` ```python -def verify_kzg_proof(polynomial_kzg: KZGCommitment, +def verify_kzg_proof(commitment_bytes: Bytes48, z: Bytes32, y: Bytes32, - kzg_proof: KZGProof) -> bool: + proof_bytes: Bytes48) -> bool: """ Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``. Receives inputs as bytes. Public method. """ - return verify_kzg_proof_impl(polynomial_kzg, bytes_to_bls_field(z), bytes_to_bls_field(y), kzg_proof) + return verify_kzg_proof_impl(bytes_to_kzg_commitment(commitment_bytes), + bytes_to_bls_field(z), + bytes_to_bls_field(y), + bytes_to_kzg_proof(proof_bytes)) ``` #### `verify_kzg_proof_impl` ```python -def verify_kzg_proof_impl(polynomial_kzg: KZGCommitment, +def verify_kzg_proof_impl(commitment: KZGCommitment, z: BLSFieldElement, y: BLSFieldElement, - kzg_proof: KZGProof) -> bool: + proof: KZGProof) -> bool: """ Verify KZG proof that ``p(z) == y`` where ``p(z)`` is the polynomial represented by ``polynomial_kzg``. """ # Verify: P - y = Q * (X - z) X_minus_z = bls.add(bls.bytes96_to_G2(KZG_SETUP_G2[1]), bls.multiply(bls.G2, BLS_MODULUS - z)) - P_minus_y = bls.add(bls.bytes48_to_G1(polynomial_kzg), bls.multiply(bls.G1, BLS_MODULUS - y)) + P_minus_y = bls.add(bls.bytes48_to_G1(commitment), bls.multiply(bls.G1, BLS_MODULUS - y)) return bls.pairing_check([ [P_minus_y, bls.neg(bls.G2)], - [bls.bytes48_to_G1(kzg_proof), X_minus_z] + [bls.bytes48_to_G1(proof), X_minus_z] ]) ``` @@ -449,21 +495,24 @@ def compute_aggregate_kzg_proof(blobs: Sequence[Blob]) -> KZGProof: ```python def verify_aggregate_kzg_proof(blobs: Sequence[Blob], - expected_kzg_commitments: Sequence[KZGCommitment], - kzg_aggregated_proof: KZGProof) -> bool: + commitments_bytes: Sequence[Bytes48], + aggregated_proof_bytes: Bytes48) -> bool: """ Given a list of blobs and an aggregated KZG proof, verify that they correspond to the provided commitments. Public method. """ + commitments = [bytes_to_kzg_commitment(c) for c in commitments_bytes] + aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment( blobs, - expected_kzg_commitments, + commitments ) # Evaluate aggregated polynomial at `evaluation_challenge` (evaluation function checks for div-by-zero) y = evaluate_polynomial_in_evaluation_form(aggregated_poly, evaluation_challenge) # Verify aggregated proof - return verify_kzg_proof_impl(aggregated_poly_commitment, evaluation_challenge, y, kzg_aggregated_proof) + aggregated_proof = bytes_to_kzg_proof(aggregated_proof_bytes) + return verify_kzg_proof_impl(aggregated_poly_commitment, evaluation_challenge, y, aggregated_proof) ``` From e3b42ca397bc6a7c03aa8e3dd23822c03039c1f9 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 25 Jan 2023 15:01:49 +0100 Subject: [PATCH 09/15] Add activate and partial withdrawal tests --- .../test/capella/sanity/test_blocks.py | 84 ++++++++++++++++++- .../pyspec/eth2spec/test/helpers/state.py | 3 +- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index 6e54b4b55..ff78f0e61 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -1,17 +1,25 @@ +from eth2spec.test.helpers.constants import MINIMAL from eth2spec.test.context import ( - with_capella_and_later, spec_state_test + with_capella_and_later, + spec_state_test, + with_presets, ) +from eth2spec.test.helpers.keys import pubkeys from eth2spec.test.helpers.state import ( - state_transition_and_sign_block, next_epoch_via_block, + state_transition_and_sign_block, + transition_to, + transition_to_slot_via_block, + next_epoch, + next_slot, ) from eth2spec.test.helpers.block import ( build_empty_block_for_next_slot, build_empty_block, ) from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change -from eth2spec.test.helpers.state import ( - next_slot, +from eth2spec.test.helpers.attestations import ( + next_epoch_with_attestations, ) from eth2spec.test.helpers.withdrawals import ( set_eth1_withdrawal_credential_with_balance, @@ -333,3 +341,71 @@ def test_top_up_and_fully_withdrawal_validator(spec, state): balance = state.balances[validator_index] current_epoch = spec.get_current_epoch(state) assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch) + + +def _insert_validator(spec, state, balance): + effective_balance = balance if balance < spec.MAX_EFFECTIVE_BALANCE else spec.MAX_EFFECTIVE_BALANCE + validator_index = len(state.validators) + validator = spec.Validator( + pubkey=pubkeys[validator_index], + withdrawal_credentials=spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + b'\x00' * 11 + b'\x56' * 20, + activation_eligibility_epoch=1, + activation_epoch=2, + exit_epoch=spec.FAR_FUTURE_EPOCH, + withdrawable_epoch=spec.FAR_FUTURE_EPOCH, + effective_balance=effective_balance, + ) + state.validators.append(validator) + state.balances.append(balance) + state.previous_epoch_participation.append(spec.ParticipationFlags(0b0000_0000)) + state.current_epoch_participation.append(spec.ParticipationFlags(0b0000_0000)) + state.inactivity_scores.append(0) + + return validator_index + + +def _run_activate_and_partial_withdrawal(spec, state, initial_balance): + validator_index = _insert_validator(spec, state, balance=initial_balance) + + next_epoch(spec, state) + transition_to(spec, state, spec.compute_start_slot_at_epoch(2) - 1) + + assert not spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state)) + + yield 'pre', state + + blocks = [] + # To activate + signed_block = transition_to_slot_via_block(spec, state, state.slot + 1) + blocks.append(signed_block) + + assert spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state)) + + if initial_balance > spec.MAX_EFFECTIVE_BALANCE: + assert spec.is_partially_withdrawable_validator( + state.validators[validator_index], state.balances[validator_index]) + else: + assert not spec.is_partially_withdrawable_validator( + state.validators[validator_index], state.balances[validator_index]) + + # Getting attester rewards and getting partial withdrawals + for _ in range(2): + _, new_blocks, state = next_epoch_with_attestations(spec, state, True, True) + blocks += new_blocks + + yield 'blocks', blocks + yield 'post', state + + +@with_capella_and_later +@with_presets([MINIMAL], reason="too many validators with mainnet config") +@spec_state_test +def test_activate_and_partial_withdrawal_max_effective_balance(spec, state): + yield from _run_activate_and_partial_withdrawal(spec, state, initial_balance=spec.MAX_EFFECTIVE_BALANCE) + + +@with_capella_and_later +@with_presets([MINIMAL], reason="too many validators with mainnet config") +@spec_state_test +def test_activate_and_partial_withdrawal_overdeposit(spec, state): + yield from _run_activate_and_partial_withdrawal(spec, state, initial_balance=spec.MAX_EFFECTIVE_BALANCE + 10000000) diff --git a/tests/core/pyspec/eth2spec/test/helpers/state.py b/tests/core/pyspec/eth2spec/test/helpers/state.py index 0dc17b00f..9d01b11ae 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/state.py +++ b/tests/core/pyspec/eth2spec/test/helpers/state.py @@ -38,8 +38,9 @@ def transition_to_slot_via_block(spec, state, slot): Transition to ``slot`` via an empty block transition """ assert state.slot < slot - apply_empty_block(spec, state, slot) + signed_block = apply_empty_block(spec, state, slot) assert state.slot == slot + return signed_block def transition_to_valid_shard_slot(spec, state): From 507a7ec113ff4925a5202fe91eba3fd9478f9269 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 26 Jan 2023 10:14:53 +0100 Subject: [PATCH 10/15] Add BLS_TO_EXECUTION_CHANGE fork transition tests --- .../capella/transition/test_operations.py | 54 +++++++++++++++++++ .../pyspec/eth2spec/test/helpers/constants.py | 3 ++ .../eth2spec/test/helpers/fork_transition.py | 9 ++++ 3 files changed, 66 insertions(+) create mode 100644 tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py diff --git a/tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py b/tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py new file mode 100644 index 000000000..cb4021aa4 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py @@ -0,0 +1,54 @@ +from eth2spec.test.context import ( + ForkMeta, + always_bls, + with_fork_metas, +) +from eth2spec.test.helpers.constants import ( + AFTER_CAPELLA_PRE_POST_FORKS, +) +from eth2spec.test.helpers.fork_transition import ( + OperationType, + run_transition_with_operation, +) + + +# +# BLSToExecutionChange +# + +@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2) + for pre, post in AFTER_CAPELLA_PRE_POST_FORKS]) +@always_bls +def test_transition_with_btec_right_after_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag): + """ + Create a BLS_TO_EXECUTION_CHANGE right *after* the transition + """ + yield from run_transition_with_operation( + state, + fork_epoch, + spec, + post_spec, + pre_tag, + post_tag, + operation_type=OperationType.BLS_TO_EXECUTION_CHANGE, + operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH, + ) + + +@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2) + for pre, post in AFTER_CAPELLA_PRE_POST_FORKS]) +@always_bls +def test_transition_with_btec_right_before_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag): + """ + Create a BLS_TO_EXECUTION_CHANGE right *before* the transition + """ + yield from run_transition_with_operation( + state, + fork_epoch, + spec, + post_spec, + pre_tag, + post_tag, + operation_type=OperationType.BLS_TO_EXECUTION_CHANGE, + operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1, + ) diff --git a/tests/core/pyspec/eth2spec/test/helpers/constants.py b/tests/core/pyspec/eth2spec/test/helpers/constants.py index b67b11f10..05e5ee19b 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/constants.py +++ b/tests/core/pyspec/eth2spec/test/helpers/constants.py @@ -37,6 +37,9 @@ ALL_FORK_UPGRADES = { ALL_PRE_POST_FORKS = ALL_FORK_UPGRADES.items() AFTER_BELLATRIX_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() if key != PHASE0} AFTER_BELLATRIX_PRE_POST_FORKS = AFTER_BELLATRIX_UPGRADES.items() +AFTER_CAPELLA_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() + if key not in [PHASE0, ALTAIR, BELLATRIX]} +AFTER_CAPELLA_PRE_POST_FORKS = AFTER_CAPELLA_UPGRADES.items() # # Config diff --git a/tests/core/pyspec/eth2spec/test/helpers/fork_transition.py b/tests/core/pyspec/eth2spec/test/helpers/fork_transition.py index 1e3374a64..ca961bde4 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/fork_transition.py +++ b/tests/core/pyspec/eth2spec/test/helpers/fork_transition.py @@ -9,6 +9,7 @@ from eth2spec.test.helpers.block import ( build_empty_block, sign_block, ) +from eth2spec.test.helpers.bls_to_execution_changes import get_signed_address_change from eth2spec.test.helpers.constants import ( ALTAIR, BELLATRIX, @@ -36,6 +37,7 @@ class OperationType(Enum): ATTESTER_SLASHING = auto() DEPOSIT = auto() VOLUNTARY_EXIT = auto() + BLS_TO_EXECUTION_CHANGE = auto() def _set_operations_by_dict(block, operation_dict): @@ -267,6 +269,10 @@ def run_transition_with_operation(state, selected_validator_index = 0 signed_exits = prepare_signed_exits(spec, state, [selected_validator_index]) operation_dict = {'voluntary_exits': signed_exits} + elif operation_type == OperationType.BLS_TO_EXECUTION_CHANGE: + selected_validator_index = 0 + bls_to_execution_changes = [get_signed_address_change(spec, state, selected_validator_index)] + operation_dict = {'bls_to_execution_changes': bls_to_execution_changes} def _check_state(): if operation_type == OperationType.PROPOSER_SLASHING: @@ -288,6 +294,9 @@ def run_transition_with_operation(state, elif operation_type == OperationType.VOLUNTARY_EXIT: validator = state.validators[selected_validator_index] assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH + elif operation_type == OperationType.BLS_TO_EXECUTION_CHANGE: + validator = state.validators[selected_validator_index] + assert validator.withdrawal_credentials[:1] == spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX yield "pre", state From 230dfb011ee4775b43a4d981bb6f8d1484d858a5 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 26 Jan 2023 23:21:07 +0800 Subject: [PATCH 11/15] Apply suggestions from code review Co-authored-by: Danny Ryan --- .../core/pyspec/eth2spec/test/capella/sanity/test_blocks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index ff78f0e61..7f5d64186 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -277,7 +277,7 @@ def test_invalid_withdrawal_fail_second_block_payload_isnt_compatible(spec, stat @with_capella_and_later @spec_state_test -def test_top_up_and_partial_withdrawal_validator(spec, state): +def test_top_up_and_partial_withdrawable_validator(spec, state): next_withdrawal_validator_index = 0 validator_index = next_withdrawal_validator_index + 1 @@ -307,7 +307,7 @@ def test_top_up_and_partial_withdrawal_validator(spec, state): @with_capella_and_later @spec_state_test -def test_top_up_and_fully_withdrawal_validator(spec, state): +def test_top_up_to_fully_withdrawn_validator(spec, state): """ Similar to `teste_process_deposit::test_success_top_up_to_withdrawn_validator` test. """ @@ -323,7 +323,7 @@ def test_top_up_and_fully_withdrawal_validator(spec, state): next_epoch_via_block(spec, state) assert state.validators[validator_index].effective_balance == 0 - # Make a top-up balance to validator + # Make a top-up deposit to validator amount = spec.MAX_EFFECTIVE_BALANCE // 4 deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) From 3e78448fd16ec84bf3fa0e917e54c37874b3abe6 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 27 Jan 2023 10:44:32 +0100 Subject: [PATCH 12/15] Address PR feedback --- .../test/capella/sanity/test_blocks.py | 37 ++++++++++++------- .../transition/test_operations.py | 6 +-- .../pyspec/eth2spec/test/helpers/constants.py | 5 ++- 3 files changed, 30 insertions(+), 18 deletions(-) rename tests/core/pyspec/eth2spec/test/{capella => eip4844}/transition/test_operations.py (89%) diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index 7f5d64186..808f1b581 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -10,7 +10,6 @@ from eth2spec.test.helpers.state import ( state_transition_and_sign_block, transition_to, transition_to_slot_via_block, - next_epoch, next_slot, ) from eth2spec.test.helpers.block import ( @@ -300,6 +299,7 @@ def test_top_up_and_partial_withdrawable_validator(spec, state): yield 'blocks', [signed_block] yield 'post', state + # Since withdrawals happen before deposits, it becomes partially withdrawable after state transition. validator = state.validators[validator_index] balance = state.balances[validator_index] assert spec.is_partially_withdrawable_validator(validator, balance) @@ -332,16 +332,28 @@ def test_top_up_to_fully_withdrawn_validator(spec, state): block = build_empty_block_for_next_slot(spec, state) block.body.deposits.append(deposit) - signed_block = state_transition_and_sign_block(spec, state, block) + signed_block_1 = state_transition_and_sign_block(spec, state, block) - yield 'blocks', [signed_block] + assert spec.is_fully_withdrawable_validator( + state.validators[validator_index], + state.balances[validator_index], + spec.get_current_epoch(state) + ) + + # Apply an empty block + signed_block_2 = transition_to_slot_via_block(spec, state, state.slot + 1) + + # With mainnet preset, it holds + if len(state.validators) <= spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: + assert not spec.is_fully_withdrawable_validator( + state.validators[validator_index], + state.balances[validator_index], + spec.get_current_epoch(state) + ) + + yield 'blocks', [signed_block_1, signed_block_2] yield 'post', state - validator = state.validators[validator_index] - balance = state.balances[validator_index] - current_epoch = spec.get_current_epoch(state) - assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch) - def _insert_validator(spec, state, balance): effective_balance = balance if balance < spec.MAX_EFFECTIVE_BALANCE else spec.MAX_EFFECTIVE_BALANCE @@ -367,9 +379,8 @@ def _insert_validator(spec, state, balance): def _run_activate_and_partial_withdrawal(spec, state, initial_balance): validator_index = _insert_validator(spec, state, balance=initial_balance) - next_epoch(spec, state) + # To make it eligibile activation transition_to(spec, state, spec.compute_start_slot_at_epoch(2) - 1) - assert not spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state)) yield 'pre', state @@ -388,10 +399,8 @@ def _run_activate_and_partial_withdrawal(spec, state, initial_balance): assert not spec.is_partially_withdrawable_validator( state.validators[validator_index], state.balances[validator_index]) - # Getting attester rewards and getting partial withdrawals - for _ in range(2): - _, new_blocks, state = next_epoch_with_attestations(spec, state, True, True) - blocks += new_blocks + _, new_blocks, state = next_epoch_with_attestations(spec, state, True, True) + blocks += new_blocks yield 'blocks', blocks yield 'post', state diff --git a/tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py b/tests/core/pyspec/eth2spec/test/eip4844/transition/test_operations.py similarity index 89% rename from tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py rename to tests/core/pyspec/eth2spec/test/eip4844/transition/test_operations.py index cb4021aa4..f945afa8f 100644 --- a/tests/core/pyspec/eth2spec/test/capella/transition/test_operations.py +++ b/tests/core/pyspec/eth2spec/test/eip4844/transition/test_operations.py @@ -4,7 +4,7 @@ from eth2spec.test.context import ( with_fork_metas, ) from eth2spec.test.helpers.constants import ( - AFTER_CAPELLA_PRE_POST_FORKS, + AFTER_DENEB_PRE_POST_FORKS, ) from eth2spec.test.helpers.fork_transition import ( OperationType, @@ -17,7 +17,7 @@ from eth2spec.test.helpers.fork_transition import ( # @with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2) - for pre, post in AFTER_CAPELLA_PRE_POST_FORKS]) + for pre, post in AFTER_DENEB_PRE_POST_FORKS]) @always_bls def test_transition_with_btec_right_after_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag): """ @@ -36,7 +36,7 @@ def test_transition_with_btec_right_after_fork(state, fork_epoch, spec, post_spe @with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2) - for pre, post in AFTER_CAPELLA_PRE_POST_FORKS]) + for pre, post in AFTER_DENEB_PRE_POST_FORKS]) @always_bls def test_transition_with_btec_right_before_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag): """ diff --git a/tests/core/pyspec/eth2spec/test/helpers/constants.py b/tests/core/pyspec/eth2spec/test/helpers/constants.py index 05e5ee19b..cd103337f 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/constants.py +++ b/tests/core/pyspec/eth2spec/test/helpers/constants.py @@ -38,8 +38,11 @@ ALL_PRE_POST_FORKS = ALL_FORK_UPGRADES.items() AFTER_BELLATRIX_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() if key != PHASE0} AFTER_BELLATRIX_PRE_POST_FORKS = AFTER_BELLATRIX_UPGRADES.items() AFTER_CAPELLA_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() - if key not in [PHASE0, ALTAIR, BELLATRIX]} + if key not in [PHASE0, ALTAIR]} AFTER_CAPELLA_PRE_POST_FORKS = AFTER_CAPELLA_UPGRADES.items() +AFTER_DENEB_UPGRADES = {key: value for key, value in ALL_FORK_UPGRADES.items() + if key not in [PHASE0, ALTAIR, BELLATRIX]} +AFTER_DENEB_PRE_POST_FORKS = AFTER_DENEB_UPGRADES.items() # # Config From 9ab147860c68aaf7f7d94d20d068c97e5de92520 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 27 Jan 2023 10:48:00 +0100 Subject: [PATCH 13/15] Update transtion testgen --- .../pyspec/eth2spec/test/eip4844/transition/__init__.py | 0 tests/generators/transition/main.py | 7 +++++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/eip4844/transition/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/eip4844/transition/__init__.py b/tests/core/pyspec/eth2spec/test/eip4844/transition/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/generators/transition/main.py b/tests/generators/transition/main.py index 7de7213bd..a4eba90df 100644 --- a/tests/generators/transition/main.py +++ b/tests/generators/transition/main.py @@ -16,6 +16,9 @@ from eth2spec.test.altair.transition import ( test_slashing as test_altair_slashing, test_operations as test_altair_operations, ) +from eth2spec.test.eip4844.transition import ( + test_operations as test_eip4844_operations, +) def create_provider(tests_src, preset_name: str, pre_fork_name: str, post_fork_name: str) -> gen_typing.TestProvider: @@ -37,14 +40,14 @@ def create_provider(tests_src, preset_name: str, pre_fork_name: str, post_fork_n if __name__ == "__main__": - altair_tests = ( + all_tests = ( test_altair_transition, test_altair_activations_and_exits, test_altair_leaking, test_altair_slashing, test_altair_operations, + test_eip4844_operations, ) - all_tests = altair_tests for transition_test_module in all_tests: for pre_fork, post_fork in ALL_PRE_POST_FORKS: gen_runner.run_generator("transition", [ From a2b3cd33ef850f39ca56d97e1a6957963abb75b7 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 27 Jan 2023 18:54:09 +0800 Subject: [PATCH 14/15] bump VERSION.txt to 1.3.0-rc.2 --- tests/core/pyspec/eth2spec/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index bf16dded0..1d074f43e 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.3.0-rc.1 +1.3.0-rc.2 From 366e3b64c4a26b58922d356b0871fc172cf9a472 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 27 Jan 2023 15:37:12 +0100 Subject: [PATCH 15/15] hotfix: `transition_to_slot_via_block` only return unsigned block --- .../pyspec/eth2spec/test/capella/sanity/test_blocks.py | 7 ++++--- tests/core/pyspec/eth2spec/test/helpers/state.py | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py index 808f1b581..079990e3e 100644 --- a/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py @@ -9,7 +9,6 @@ from eth2spec.test.helpers.state import ( next_epoch_via_block, state_transition_and_sign_block, transition_to, - transition_to_slot_via_block, next_slot, ) from eth2spec.test.helpers.block import ( @@ -341,7 +340,8 @@ def test_top_up_to_fully_withdrawn_validator(spec, state): ) # Apply an empty block - signed_block_2 = transition_to_slot_via_block(spec, state, state.slot + 1) + block = build_empty_block_for_next_slot(spec, state) + signed_block_2 = state_transition_and_sign_block(spec, state, block) # With mainnet preset, it holds if len(state.validators) <= spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: @@ -387,7 +387,8 @@ def _run_activate_and_partial_withdrawal(spec, state, initial_balance): blocks = [] # To activate - signed_block = transition_to_slot_via_block(spec, state, state.slot + 1) + block = build_empty_block_for_next_slot(spec, state) + signed_block = state_transition_and_sign_block(spec, state, block) blocks.append(signed_block) assert spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state)) diff --git a/tests/core/pyspec/eth2spec/test/helpers/state.py b/tests/core/pyspec/eth2spec/test/helpers/state.py index 9d01b11ae..0dc17b00f 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/state.py +++ b/tests/core/pyspec/eth2spec/test/helpers/state.py @@ -38,9 +38,8 @@ def transition_to_slot_via_block(spec, state, slot): Transition to ``slot`` via an empty block transition """ assert state.slot < slot - signed_block = apply_empty_block(spec, state, slot) + apply_empty_block(spec, state, slot) assert state.slot == slot - return signed_block def transition_to_valid_shard_slot(spec, state):