mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-03 06:13:31 +00:00
Merge branch 'dev' into lc-eph
This commit is contained in:
commit
b0471511e5
4
Makefile
4
Makefile
@ -202,8 +202,8 @@ gen_kzg_setups:
|
||||
if ! test -d venv; then python3 -m venv venv; fi; \
|
||||
. venv/bin/activate; \
|
||||
pip3 install -r requirements.txt; \
|
||||
python3 ./gen_kzg_trusted_setups.py --secret=1337 --length=4 --output-dir ${CURRENT_DIR}/presets/minimal/trusted_setups; \
|
||||
python3 ./gen_kzg_trusted_setups.py --secret=1337 --length=4096 --output-dir ${CURRENT_DIR}/presets/mainnet/trusted_setups
|
||||
python3 ./gen_kzg_trusted_setups.py --secret=1337 --g1-length=4 --g2-length=65 --output-dir ${CURRENT_DIR}/presets/minimal/trusted_setups; \
|
||||
python3 ./gen_kzg_trusted_setups.py --secret=1337 --g1-length=4096 --g2-length=65 --output-dir ${CURRENT_DIR}/presets/mainnet/trusted_setups
|
||||
|
||||
# For any generator, build it using the run_generator function.
|
||||
# (creation of output dir is a dependency)
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -18,11 +18,18 @@ if __name__ == '__main__':
|
||||
help='the secret of trusted setup',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--length",
|
||||
dest="length",
|
||||
"--g1-length",
|
||||
dest="g1_length",
|
||||
type=int,
|
||||
required=True,
|
||||
help='the length of trusted setup',
|
||||
help='the length of G1 trusted setup',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--g2-length",
|
||||
dest="g2_length",
|
||||
type=int,
|
||||
required=True,
|
||||
help='the length of G2 trusted setup',
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
@ -33,4 +40,4 @@ if __name__ == '__main__':
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
dump_kzg_trusted_setup_files(args.secret, args.length, args.output_dir)
|
||||
dump_kzg_trusted_setup_files(args.secret, args.g1_length, args.g2_length, args.output_dir)
|
||||
|
@ -164,18 +164,19 @@ def validate_blobs_sidecar(slot: Slot,
|
||||
|
||||
#### `is_data_available`
|
||||
|
||||
The implementation of `is_data_available` is meant to change with later sharding upgrades.
|
||||
The implementation of `is_data_available` will become more sophisticated during later sharding upgrades.
|
||||
Initially, it requires every verifying actor to retrieve the matching `BlobsSidecar`,
|
||||
and validate the sidecar with `validate_blobs_sidecar`.
|
||||
|
||||
The block MUST NOT be considered valid until a valid `BlobsSidecar` has been downloaded.
|
||||
The block MUST NOT be considered valid until a valid `BlobsSidecar` has been downloaded. Blocks that have been previously validated as available SHOULD be considered available even if the associated `BlobsSidecar` has subsequently been pruned.
|
||||
|
||||
```python
|
||||
def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments: Sequence[KZGCommitment]) -> bool:
|
||||
# `retrieve_blobs_sidecar` is implementation dependent, raises an exception if not available.
|
||||
# `retrieve_blobs_sidecar` is implementation and context dependent, raises an exception if not available.
|
||||
# Note: the p2p network does not guarantee sidecar retrieval outside of `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS`
|
||||
sidecar = retrieve_blobs_sidecar(slot, beacon_block_root)
|
||||
|
||||
# For testing, `retrieve_blobs_sidecar` returns "TEST.
|
||||
# For testing, `retrieve_blobs_sidecar` returns "TEST".
|
||||
# TODO: Remove it once we have a way to inject `BlobsSidecar` into tests.
|
||||
if isinstance(sidecar, str):
|
||||
return True
|
||||
@ -347,8 +348,9 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
|
||||
```
|
||||
|
||||
### 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:
|
||||
- `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.
|
||||
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.
|
||||
|
@ -58,7 +58,7 @@ def compute_fork_version(epoch: Epoch) -> Version:
|
||||
### Fork trigger
|
||||
|
||||
TBD. This fork is defined for testing purposes, the EIP may be combined with other consensus-layer upgrade.
|
||||
For now we assume the condition will be triggered at epoch `EIP4844_FORK_EPOCH`.
|
||||
For now, we assume the condition will be triggered at epoch `EIP4844_FORK_EPOCH`.
|
||||
|
||||
Note that for the pure EIP-4844 networks, we don't apply `upgrade_to_eip4844` since it starts with EIP-4844 version logic.
|
||||
|
||||
|
@ -61,7 +61,7 @@ class SignedBeaconBlockAndBlobsSidecar(Container):
|
||||
|
||||
## The gossip domain: gossipsub
|
||||
|
||||
Some gossip meshes are upgraded in the fork of EIP4844 to support upgraded types.
|
||||
Some gossip meshes are upgraded in the fork of EIP-4844 to support upgraded types.
|
||||
|
||||
### Topics and messages
|
||||
|
||||
@ -78,10 +78,9 @@ The new topics along with the type of the `data` field of a gossipsub message ar
|
||||
| - | - |
|
||||
| `beacon_block_and_blobs_sidecar` | `SignedBeaconBlockAndBlobsSidecar` (new) |
|
||||
|
||||
|
||||
#### Global topics
|
||||
|
||||
EIP4844 introduces a new global topic for beacon block and blobs-sidecars.
|
||||
EIP-4844 introduces a new global topic for beacon block and blobs-sidecars.
|
||||
|
||||
##### `beacon_block`
|
||||
|
||||
@ -97,16 +96,18 @@ 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.
|
||||
- _[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.
|
||||
- _[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`.
|
||||
- _[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.
|
||||
- _[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)`
|
||||
|
||||
### Transitioning the gossip
|
||||
@ -147,10 +148,10 @@ Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
|
||||
|
||||
[1]: # (eth2spec: skip)
|
||||
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `fork_version` | Chunk SSZ type |
|
||||
|--------------------------|-------------------------------|
|
||||
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
|
||||
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
|
||||
| `BELLATRIX_FORK_VERSION` | `bellatrix.SignedBeaconBlock` |
|
||||
| `CAPELLA_FORK_VERSION` | `capella.SignedBeaconBlock` |
|
||||
|
||||
@ -185,7 +186,7 @@ No more than `MAX_REQUEST_BLOCKS` may be requested at a time.
|
||||
The response MUST consist of zero or more `response_chunk`.
|
||||
Each _successful_ `response_chunk` MUST contain a single `SignedBeaconBlockAndBlobsSidecar` payload.
|
||||
|
||||
Clients MUST support requesting blocks and sidecars since the latest finalized epoch.
|
||||
Clients MUST support requesting blocks and sidecars since `minimum_request_epoch`, where `minimum_request_epoch = max(finalized_epoch, current_epoch - MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS, EIP4844_FORK_EPOCH)`. If any root in the request content references a block earlier than `minimum_request_epoch`, peers SHOULD respond with error code `3: ResourceUnavailable`.
|
||||
|
||||
Clients MUST respond with at least one block and sidecar, if they have it.
|
||||
Clients MAY limit the number of blocks and sidecars in the response.
|
||||
@ -218,7 +219,7 @@ may not be available beyond the initial distribution via gossip.
|
||||
Before consuming the next response chunk, the response reader SHOULD verify the blobs sidecar is well-formatted and
|
||||
correct w.r.t. the expected KZG commitments through `validate_blobs_sidecar`.
|
||||
|
||||
`BlobsSidecarsByRange` is primarily used to sync blobs that may have been missed on gossip.
|
||||
`BlobsSidecarsByRange` is primarily used to sync blobs that may have been missed on gossip and to sync within the `MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS` window.
|
||||
|
||||
The request MUST be encoded as an SSZ-container.
|
||||
|
||||
@ -226,7 +227,7 @@ The response MUST consist of zero or more `response_chunk`.
|
||||
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(GENESIS_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS), current_epoch]`
|
||||
`[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.
|
||||
|
||||
|
@ -89,8 +89,9 @@ but reusing the `mainnet` settings in public networks is a critical security req
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `KZG_SETUP_G2_LENGTH` | `65` |
|
||||
| `KZG_SETUP_G1` | `Vector[G1Point, FIELD_ELEMENTS_PER_BLOB]`, contents TBD |
|
||||
| `KZG_SETUP_G2` | `Vector[G2Point, FIELD_ELEMENTS_PER_BLOB]`, contents TBD |
|
||||
| `KZG_SETUP_G2` | `Vector[G2Point, KZG_SETUP_G2_LENGTH]`, contents TBD |
|
||||
| `KZG_SETUP_LAGRANGE` | `Vector[KZGCommitment, FIELD_ELEMENTS_PER_BLOB]`, contents TBD |
|
||||
|
||||
## Helper functions
|
||||
@ -293,7 +294,7 @@ def compute_powers(x: BLSFieldElement, n: uint64) -> Sequence[BLSFieldElement]:
|
||||
def evaluate_polynomial_in_evaluation_form(polynomial: Polynomial,
|
||||
z: BLSFieldElement) -> BLSFieldElement:
|
||||
"""
|
||||
Evaluate a polynomial (in evaluation form) at an arbitrary point ``z``.
|
||||
Evaluate a polynomial (in evaluation form) at an arbitrary point ``z`` that is not in the domain.
|
||||
Uses the barycentric formula:
|
||||
f(z) = (z**WIDTH - 1) / WIDTH * sum_(i=0)^WIDTH (f(DOMAIN[i]) * DOMAIN[i]) / (z - DOMAIN[i])
|
||||
"""
|
||||
@ -369,8 +370,9 @@ def verify_kzg_proof_impl(polynomial_kzg: KZGCommitment,
|
||||
```python
|
||||
def compute_kzg_proof(polynomial: Polynomial, z: BLSFieldElement) -> KZGProof:
|
||||
"""
|
||||
Compute KZG proof at point `z` with `polynomial` being in evaluation form
|
||||
Do this by computing the quotient polynomial in evaluation form: q(x) = (p(x) - p(z)) / (x - z)
|
||||
Compute KZG proof at point `z` with `polynomial` being in evaluation form.
|
||||
Do this by computing the quotient polynomial in evaluation form: q(x) = (p(x) - p(z)) / (x - z).
|
||||
Public method.
|
||||
"""
|
||||
y = evaluate_polynomial_in_evaluation_form(polynomial, z)
|
||||
polynomial_shifted = [BLSFieldElement((int(p) - int(y)) % BLS_MODULUS) for p in polynomial]
|
||||
|
@ -32,7 +32,7 @@ This document represents the changes to be made in the code of an "honest valida
|
||||
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.
|
||||
All terminology, constants, functions, and protocol mechanics defined in the updated [Beacon Chain doc of EIP-4844](./beacon-chain.md) are requisite for this document and used throughout.
|
||||
Please see related Beacon Chain doc before continuing and use them as a reference throughout.
|
||||
|
||||
## Helpers
|
||||
|
@ -1 +1 @@
|
||||
1.3.0-alpha.1
|
||||
1.3.0-alpha.2
|
||||
|
@ -136,18 +136,22 @@ def test_invalid_signature_extra_participant(spec, state):
|
||||
yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
|
||||
|
||||
|
||||
def is_duplicate_sync_committee(committee_indices):
|
||||
dup = {v for v in committee_indices if committee_indices.count(v) > 1}
|
||||
return len(dup) > 0
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@with_presets([MINIMAL], reason="to create nonduplicate committee")
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_nonduplicate_committee(spec, state):
|
||||
committee_indices = compute_committee_indices(state)
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [True] * committee_size
|
||||
active_validator_count = len(spec.get_active_validator_indices(state, spec.get_current_epoch(state)))
|
||||
|
||||
# Preconditions of this test case
|
||||
assert active_validator_count > spec.SYNC_COMMITTEE_SIZE
|
||||
assert committee_size == len(set(committee_indices))
|
||||
assert not is_duplicate_sync_committee(committee_indices)
|
||||
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [True] * committee_size
|
||||
|
||||
yield from run_successful_sync_committee_test(spec, state, committee_indices, committee_bits)
|
||||
|
||||
@ -157,13 +161,12 @@ def test_sync_committee_rewards_nonduplicate_committee(spec, state):
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_no_participation(spec, state):
|
||||
committee_indices = compute_committee_indices(state)
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [False] * committee_size
|
||||
active_validator_count = len(spec.get_active_validator_indices(state, spec.get_current_epoch(state)))
|
||||
|
||||
# Preconditions of this test case
|
||||
assert active_validator_count < spec.SYNC_COMMITTEE_SIZE
|
||||
assert committee_size > len(set(committee_indices))
|
||||
assert is_duplicate_sync_committee(committee_indices)
|
||||
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [False] * committee_size
|
||||
|
||||
yield from run_successful_sync_committee_test(spec, state, committee_indices, committee_bits)
|
||||
|
||||
@ -173,14 +176,13 @@ def test_sync_committee_rewards_duplicate_committee_no_participation(spec, state
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_half_participation(spec, state):
|
||||
committee_indices = compute_committee_indices(state)
|
||||
|
||||
# Preconditions of this test case
|
||||
assert is_duplicate_sync_committee(committee_indices)
|
||||
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [True] * (committee_size // 2) + [False] * (committee_size // 2)
|
||||
assert len(committee_bits) == committee_size
|
||||
active_validator_count = len(spec.get_active_validator_indices(state, spec.get_current_epoch(state)))
|
||||
|
||||
# Preconditions of this test case
|
||||
assert active_validator_count < spec.SYNC_COMMITTEE_SIZE
|
||||
assert committee_size > len(set(committee_indices))
|
||||
|
||||
yield from run_successful_sync_committee_test(spec, state, committee_indices, committee_bits)
|
||||
|
||||
@ -190,17 +192,115 @@ def test_sync_committee_rewards_duplicate_committee_half_participation(spec, sta
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_full_participation(spec, state):
|
||||
committee_indices = compute_committee_indices(state)
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [True] * committee_size
|
||||
active_validator_count = len(spec.get_active_validator_indices(state, spec.get_current_epoch(state)))
|
||||
|
||||
# Preconditions of this test case
|
||||
assert active_validator_count < spec.SYNC_COMMITTEE_SIZE
|
||||
assert committee_size > len(set(committee_indices))
|
||||
assert is_duplicate_sync_committee(committee_indices)
|
||||
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [True] * committee_size
|
||||
|
||||
yield from run_successful_sync_committee_test(spec, state, committee_indices, committee_bits)
|
||||
|
||||
|
||||
def _run_sync_committee_selected_twice(
|
||||
spec, state,
|
||||
pre_balance, participate_first_position, participate_second_position,
|
||||
skip_reward_validation=False):
|
||||
committee_indices = compute_committee_indices(state)
|
||||
|
||||
# Preconditions of this test case
|
||||
assert is_duplicate_sync_committee(committee_indices)
|
||||
|
||||
committee_size = len(committee_indices)
|
||||
committee_bits = [False] * committee_size
|
||||
|
||||
# Find duplicate indices that get selected twice
|
||||
dup = {v for v in committee_indices if committee_indices.count(v) == 2}
|
||||
assert len(dup) > 0
|
||||
validator_index = dup.pop()
|
||||
positions = [i for i, v in enumerate(committee_indices) if v == validator_index]
|
||||
committee_bits[positions[0]] = participate_first_position
|
||||
committee_bits[positions[1]] = participate_second_position
|
||||
|
||||
# Set validator's balance
|
||||
state.balances[validator_index] = pre_balance
|
||||
state.validators[validator_index].effective_balance = min(
|
||||
pre_balance - pre_balance % spec.EFFECTIVE_BALANCE_INCREMENT,
|
||||
spec.MAX_EFFECTIVE_BALANCE,
|
||||
)
|
||||
|
||||
yield from run_successful_sync_committee_test(
|
||||
spec, state, committee_indices, committee_bits,
|
||||
skip_reward_validation=skip_reward_validation)
|
||||
|
||||
return validator_index
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@with_presets([MAINNET], reason="to create duplicate committee")
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_zero_balance_only_participate_first_one(spec, state):
|
||||
validator_index = yield from _run_sync_committee_selected_twice(
|
||||
spec,
|
||||
state,
|
||||
pre_balance=0,
|
||||
participate_first_position=True,
|
||||
participate_second_position=False,
|
||||
)
|
||||
|
||||
# The validator gets reward first (balance > 0) and then gets the same amount of penalty (balance == 0)
|
||||
assert state.balances[validator_index] == 0
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@with_presets([MAINNET], reason="to create duplicate committee")
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_zero_balance_only_participate_second_one(spec, state):
|
||||
# Skip `validate_sync_committee_rewards` because it doesn't handle the balance computation order
|
||||
# inside the for loop
|
||||
validator_index = yield from _run_sync_committee_selected_twice(
|
||||
spec,
|
||||
state,
|
||||
pre_balance=0,
|
||||
participate_first_position=False,
|
||||
participate_second_position=True,
|
||||
skip_reward_validation=True,
|
||||
)
|
||||
|
||||
# The validator gets penalty first (balance is still 0) and then gets reward (balance > 0)
|
||||
assert state.balances[validator_index] > 0
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@with_presets([MAINNET], reason="to create duplicate committee")
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_max_effective_balance_only_participate_first_one(spec, state):
|
||||
validator_index = yield from _run_sync_committee_selected_twice(
|
||||
spec,
|
||||
state,
|
||||
pre_balance=spec.MAX_EFFECTIVE_BALANCE,
|
||||
participate_first_position=True,
|
||||
participate_second_position=False,
|
||||
)
|
||||
|
||||
assert state.balances[validator_index] == spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@with_presets([MAINNET], reason="to create duplicate committee")
|
||||
@spec_state_test
|
||||
def test_sync_committee_rewards_duplicate_committee_max_effective_balance_only_participate_second_one(spec, state):
|
||||
validator_index = yield from _run_sync_committee_selected_twice(
|
||||
spec,
|
||||
state,
|
||||
pre_balance=spec.MAX_EFFECTIVE_BALANCE,
|
||||
participate_first_position=False,
|
||||
participate_second_position=True,
|
||||
)
|
||||
|
||||
assert state.balances[validator_index] == spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
|
@ -107,10 +107,11 @@ def validate_sync_committee_rewards(spec, pre_state, post_state, committee_indic
|
||||
committee_bits,
|
||||
)
|
||||
|
||||
assert post_state.balances[index] == pre_state.balances[index] + reward - penalty
|
||||
balance = pre_state.balances[index] + reward
|
||||
assert post_state.balances[index] == (0 if balance < penalty else balance - penalty)
|
||||
|
||||
|
||||
def run_sync_committee_processing(spec, state, block, expect_exception=False):
|
||||
def run_sync_committee_processing(spec, state, block, expect_exception=False, skip_reward_validation=False):
|
||||
"""
|
||||
Processes everything up to the sync committee work, then runs the sync committee work in isolation, and
|
||||
produces a pre-state and post-state (None if exception) specifically for sync-committee processing changes.
|
||||
@ -131,14 +132,15 @@ def run_sync_committee_processing(spec, state, block, expect_exception=False):
|
||||
else:
|
||||
committee_indices = compute_committee_indices(state, state.current_sync_committee)
|
||||
committee_bits = block.body.sync_aggregate.sync_committee_bits
|
||||
validate_sync_committee_rewards(
|
||||
spec,
|
||||
pre_state,
|
||||
state,
|
||||
committee_indices,
|
||||
committee_bits,
|
||||
block.proposer_index
|
||||
)
|
||||
if not skip_reward_validation:
|
||||
validate_sync_committee_rewards(
|
||||
spec,
|
||||
pre_state,
|
||||
state,
|
||||
committee_indices,
|
||||
committee_bits,
|
||||
block.proposer_index
|
||||
)
|
||||
|
||||
|
||||
def _build_block_for_next_slot_with_sync_participation(spec, state, committee_indices, committee_bits):
|
||||
@ -156,6 +158,6 @@ def _build_block_for_next_slot_with_sync_participation(spec, state, committee_in
|
||||
return block
|
||||
|
||||
|
||||
def run_successful_sync_committee_test(spec, state, committee_indices, committee_bits):
|
||||
def run_successful_sync_committee_test(spec, state, committee_indices, committee_bits, skip_reward_validation=False):
|
||||
block = _build_block_for_next_slot_with_sync_participation(spec, state, committee_indices, committee_bits)
|
||||
yield from run_sync_committee_processing(spec, state, block)
|
||||
yield from run_sync_committee_processing(spec, state, block, skip_reward_validation=skip_reward_validation)
|
||||
|
@ -93,11 +93,11 @@ def get_lagrange(setup: Sequence[Optimized_Point3D]) -> Tuple[bytes]:
|
||||
return tuple(bls.G1_to_bytes48(multiply(fft_output[-i], inv_length)) for i in range(len(fft_output)))
|
||||
|
||||
|
||||
def dump_kzg_trusted_setup_files(secret: int, length: int, output_dir: str) -> None:
|
||||
setup_g1 = generate_setup(bls.G1, secret, length)
|
||||
setup_g2 = generate_setup(bls.G2, secret, length)
|
||||
def dump_kzg_trusted_setup_files(secret: int, g1_length: int, g2_length: int, output_dir: str) -> None:
|
||||
setup_g1 = generate_setup(bls.G1, secret, g1_length)
|
||||
setup_g2 = generate_setup(bls.G2, secret, g2_length)
|
||||
setup_g1_lagrange = get_lagrange(setup_g1)
|
||||
roots_of_unity = compute_roots_of_unity(length)
|
||||
roots_of_unity = compute_roots_of_unity(g1_length)
|
||||
|
||||
serailized_setup_g1 = [encode_hex(bls.G1_to_bytes48(p)) for p in setup_g1]
|
||||
serialized_setup_g2 = [encode_hex(bls.G2_to_bytes96(p)) for p in setup_g2]
|
||||
|
Loading…
x
Reference in New Issue
Block a user