From 565f61dfaa520708cc83a0a593e8eb2df9e5d516 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Sun, 9 Jun 2019 20:41:21 +0100 Subject: [PATCH] Cleanup containers --- configs/constant_presets/mainnet.yaml | 6 +- configs/constant_presets/minimal.yaml | 6 +- scripts/build_spec.py | 11 +- specs/core/0_beacon-chain.md | 756 ++++++++---------- specs/core/0_deposit-contract.md | 6 +- specs/core/0_fork-choice.md | 12 +- specs/core/1_custody-game.md | 20 +- specs/core/1_shard-data-chains.md | 12 +- specs/light_client/sync_protocol.md | 8 +- specs/networking/rpc-interface.md | 8 +- specs/validator/0_beacon-chain-validator.md | 16 +- .../pyspec/eth2spec/test/helpers/block.py | 4 +- .../pyspec/eth2spec/test/helpers/deposits.py | 6 +- .../pyspec/eth2spec/test/helpers/genesis.py | 12 +- .../test/helpers/proposer_slashings.py | 2 +- .../pyspec/eth2spec/test/helpers/state.py | 2 +- .../pyspec/eth2spec/test/helpers/transfers.py | 2 +- .../test_process_attestation.py | 8 +- .../test_process_attester_slashing.py | 4 +- .../test_process_block_header.py | 2 +- .../block_processing/test_process_deposit.py | 28 +- .../test_process_proposer_slashing.py | 10 +- .../block_processing/test_process_transfer.py | 20 +- .../test_process_voluntary_exit.py | 34 +- .../test_process_crosslinks.py | 8 +- .../test_process_registry_updates.py | 26 +- ...est_process_early_derived_secret_reveal.py | 4 +- .../eth2spec/test/sanity/test_blocks.py | 46 +- 28 files changed, 515 insertions(+), 564 deletions(-) diff --git a/configs/constant_presets/mainnet.yaml b/configs/constant_presets/mainnet.yaml index 6ac3f422f..d72b276c1 100644 --- a/configs/constant_presets/mainnet.yaml +++ b/configs/constant_presets/mainnet.yaml @@ -80,11 +80,11 @@ MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4 # State list lengths # --------------------------------------------------------------- # 2**13 (= 8,192) epochs ~36 days -LATEST_RANDAO_MIXES_LENGTH: 8192 +RANDAO_MIXES_LENGTH: 8192 # 2**13 (= 8,192) epochs ~36 days -LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 +ACTIVE_INDEX_ROOTS_LENGTH: 8192 # 2**13 (= 8,192) epochs ~36 days -LATEST_SLASHED_EXIT_LENGTH: 8192 +SLASHED_EXIT_LENGTH: 8192 # Reward and penalty quotients diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index 73448c3c6..25f1e8419 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -81,11 +81,11 @@ EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS: 4096 # State list lengths # --------------------------------------------------------------- # [customized] smaller state -LATEST_RANDAO_MIXES_LENGTH: 64 +RANDAO_MIXES_LENGTH: 64 # [customized] smaller state -LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 64 +ACTIVE_INDEX_ROOTS_LENGTH: 64 # [customized] smaller state -LATEST_SLASHED_EXIT_LENGTH: 64 +SLASHED_EXIT_LENGTH: 64 # Reward and penalty quotients diff --git a/scripts/build_spec.py b/scripts/build_spec.py index 7a51970e3..e25147a7f 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -62,6 +62,7 @@ from eth2spec.utils.bls import ( from eth2spec.utils.hash_function import hash ''' +BYTE_TYPES = [4, 32, 48, 96] NEW_TYPES = { 'Slot': 'int', 'Epoch': 'int', @@ -69,7 +70,6 @@ NEW_TYPES = { 'ValidatorIndex': 'int', 'Gwei': 'int', } -BYTE_TYPES = [4, 32, 48, 96] SUNDRY_FUNCTIONS = ''' def get_ssz_type_by_name(name: str) -> Container: return globals()[name] @@ -130,9 +130,10 @@ def objects_to_spec(functions: Dict[str, str], """ Given all the objects that constitute a spec, combine them into a single pyfile. """ - new_type_definitions = \ - '\n'.join(['''%s = NewType('%s', %s)''' % (key, key, value) for key, value in new_types.items()]) - new_type_definitions += '\n' + '\n'.join(['Bytes%s = BytesN[%s]' % (n, n) for n in byte_types]) + new_type_definitions = '\n'.join(['Bytes%s = BytesN[%s]' % (n, n) for n in byte_types]) + new_type_definitions += '\n' + '\n'.join(['Hash = Bytes32', 'BLSPubkey = Bytes48', 'BLSSignature = Bytes96']) + new_type_definitions += \ + '\n' + '\n'.join(['''%s = NewType('%s', %s)''' % (key, key, value) for key, value in new_types.items()]) functions_spec = '\n\n'.join(functions.values()) constants_spec = '\n'.join(map(lambda x: '%s = %s' % (x, constants[x]), constants)) ssz_objects_instantiation_spec = '\n\n'.join(ssz_objects.values()) @@ -177,7 +178,7 @@ def dependency_order_ssz_objects(objects: Dict[str, str]) -> None: items = list(objects.items()) for key, value in items: dependencies = re.findall(r'(: [A-Z][\w[]*)', value) - dependencies = map(lambda x: re.sub(r'\W|Vector|List|Container|uint\d+|Bytes\d+|bytes', '', x), dependencies) + dependencies = map(lambda x: re.sub(r'\W|Vector|List|Container|Hash|BLSPubkey|BLSSignature|uint\d+|Bytes\d+|bytes', '', x), dependencies) for dep in dependencies: if dep in NEW_TYPES or len(dep) == 0: continue diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a6d9d23c5..9fd38d7db 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -20,7 +20,8 @@ - [Rewards and penalties](#rewards-and-penalties) - [Max operations per block](#max-operations-per-block) - [Signature domains](#signature-domains) - - [Data structures](#data-structures) + - [Custom types](#custom-types) + - [Containers](#containers) - [Misc dependencies](#misc-dependencies) - [`Fork`](#fork) - [`Validator`](#validator) @@ -45,7 +46,6 @@ - [`BeaconBlock`](#beaconblock) - [Beacon state](#beacon-state) - [`BeaconState`](#beaconstate) - - [Custom types](#custom-types) - [Helper functions](#helper-functions) - [`xor`](#xor) - [`hash`](#hash) @@ -216,9 +216,9 @@ These configurations are updated for releases, but may be out of sync during `de | Name | Value | Unit | Duration | | - | - | :-: | :-: | -| `LATEST_RANDAO_MIXES_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | -| `LATEST_ACTIVE_INDEX_ROOTS_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | -| `LATEST_SLASHED_EXIT_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | +| `RANDAO_MIXES_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | +| `ACTIVE_INDEX_ROOTS_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | +| `SLASHED_EXIT_LENGTH` | `2**13` (= 8,192) | epochs | ~36 days | ### Rewards and penalties @@ -255,314 +255,6 @@ These configurations are updated for releases, but may be out of sync during `de | `DOMAIN_VOLUNTARY_EXIT` | `4` | | `DOMAIN_TRANSFER` | `5` | -## Data structures - -The following data structures are defined as [SimpleSerialize (SSZ)](../simple-serialize.md) objects. - -The types are defined topologically to aid in facilitating an executable version of the spec. - -### Misc dependencies - -#### `Fork` - -```python -class Fork(Container): - # Previous fork version - previous_version: Bytes4 - # Current fork version - current_version: Bytes4 - # Fork epoch number - epoch: uint64 -``` - -#### `Validator` - -```python -class Validator(Container): - # BLS public key - pubkey: Bytes48 - # Withdrawal credentials - withdrawal_credentials: Bytes32 - # Epoch when became eligible for activation - activation_eligibility_epoch: uint64 - # Epoch when validator activated - activation_epoch: uint64 - # Epoch when validator exited - exit_epoch: uint64 - # Epoch when validator is eligible to withdraw - withdrawable_epoch: uint64 - # Was the validator slashed - slashed: bool - # Effective balance - effective_balance: uint64 -``` - -#### `Crosslink` - -```python -class Crosslink(Container): - # Shard number - shard: uint64 - # Crosslinking data from epochs [start....end-1] - start_epoch: uint64 - end_epoch: uint64 - # Root of the previous crosslink - parent_root: Bytes32 - # Root of the crosslinked shard data since the previous crosslink - data_root: Bytes32 -``` - -#### `AttestationData` - -```python -class AttestationData(Container): - # LMD GHOST vote - beacon_block_root: Bytes32 - - # FFG vote - source_epoch: uint64 - source_root: Bytes32 - target_epoch: uint64 - target_root: Bytes32 - - # Crosslink vote - crosslink: Crosslink -``` - -#### `AttestationDataAndCustodyBit` - -```python -class AttestationDataAndCustodyBit(Container): - # Attestation data - data: AttestationData - # Custody bit - custody_bit: bool -``` - -#### `IndexedAttestation` - -```python -class IndexedAttestation(Container): - # Validator indices - custody_bit_0_indices: List[uint64] - custody_bit_1_indices: List[uint64] - # Attestation data - data: AttestationData - # Aggregate signature - signature: Bytes96 -``` - -#### `PendingAttestation` - -```python -class PendingAttestation(Container): - # Attester aggregation bitfield - aggregation_bitfield: bytes - # Attestation data - data: AttestationData - # Inclusion delay - inclusion_delay: uint64 - # Proposer index - proposer_index: uint64 -``` - -#### `Eth1Data` - -```python -class Eth1Data(Container): - # Root of the deposit tree - deposit_root: Bytes32 - # Total number of deposits - deposit_count: uint64 - # Block hash - block_hash: Bytes32 -``` - -#### `HistoricalBatch` - -```python -class HistoricalBatch(Container): - # Block roots - block_roots: Vector[Bytes32, SLOTS_PER_HISTORICAL_ROOT] - # State roots - state_roots: Vector[Bytes32, SLOTS_PER_HISTORICAL_ROOT] -``` - -#### `DepositData` - -```python -class DepositData(Container): - # BLS pubkey - pubkey: Bytes48 - # Withdrawal credentials - withdrawal_credentials: Bytes32 - # Amount in Gwei - amount: uint64 - # Container self-signature - signature: Bytes96 -``` - -#### `BeaconBlockHeader` - -```python -class BeaconBlockHeader(Container): - slot: uint64 - parent_root: Bytes32 - state_root: Bytes32 - body_root: Bytes32 - signature: Bytes96 -``` - -### Beacon operations - -#### `ProposerSlashing` - -```python -class ProposerSlashing(Container): - # Proposer index - proposer_index: uint64 - # First block header - header_1: BeaconBlockHeader - # Second block header - header_2: BeaconBlockHeader -``` - -#### `AttesterSlashing` - -```python -class AttesterSlashing(Container): - # First attestation - attestation_1: IndexedAttestation - # Second attestation - attestation_2: IndexedAttestation -``` - -#### `Attestation` - -```python -class Attestation(Container): - # Attester aggregation bitfield - aggregation_bitfield: bytes - # Attestation data - data: AttestationData - # Custody bitfield - custody_bitfield: bytes - # BLS aggregate signature - signature: Bytes96 -``` - -#### `Deposit` - -```python -class Deposit(Container): - # Branch in the deposit tree - proof: Vector[Bytes32, DEPOSIT_CONTRACT_TREE_DEPTH] - # Data - data: DepositData -``` - -#### `VoluntaryExit` - -```python -class VoluntaryExit(Container): - # Minimum epoch for processing exit - epoch: uint64 - # Index of the exiting validator - validator_index: uint64 - # Validator signature - signature: Bytes96 -``` - -#### `Transfer` - -```python -class Transfer(Container): - # Sender index - sender: uint64 - # Recipient index - recipient: uint64 - # Amount in Gwei - amount: uint64 - # Fee in Gwei for block proposer - fee: uint64 - # Inclusion slot - slot: uint64 - # Sender withdrawal pubkey - pubkey: Bytes48 - # Sender signature - signature: Bytes96 -``` - -### Beacon blocks - -#### `BeaconBlockBody` - -```python -class BeaconBlockBody(Container): - randao_reveal: Bytes96 - eth1_data: Eth1Data - graffiti: Bytes32 - proposer_slashings: List[ProposerSlashing] - attester_slashings: List[AttesterSlashing] - attestations: List[Attestation] - deposits: List[Deposit] - voluntary_exits: List[VoluntaryExit] - transfers: List[Transfer] -``` - -#### `BeaconBlock` - -```python -class BeaconBlock(Container): - # Header - slot: uint64 - parent_root: Bytes32 - state_root: Bytes32 - body: BeaconBlockBody - signature: Bytes96 -``` - -### Beacon state - -#### `BeaconState` - -```python -class BeaconState(Container): - # Misc - slot: uint64 - genesis_time: uint64 - fork: Fork # For versioning hard forks - # Validator registry - validator_registry: List[Validator] - balances: List[uint64] - # Randomness and committees - latest_randao_mixes: Vector[Bytes32, LATEST_RANDAO_MIXES_LENGTH] - latest_start_shard: uint64 - # Finality - previous_epoch_attestations: List[PendingAttestation] - current_epoch_attestations: List[PendingAttestation] - previous_justified_epoch: uint64 - current_justified_epoch: uint64 - previous_justified_root: Bytes32 - current_justified_root: Bytes32 - justification_bitfield: uint64 - finalized_epoch: uint64 - finalized_root: Bytes32 - # Recent state - current_crosslinks: Vector[Crosslink, SHARD_COUNT] - previous_crosslinks: Vector[Crosslink, SHARD_COUNT] - latest_block_roots: Vector[Bytes32, SLOTS_PER_HISTORICAL_ROOT] - latest_state_roots: Vector[Bytes32, SLOTS_PER_HISTORICAL_ROOT] - latest_active_index_roots: Vector[Bytes32, LATEST_ACTIVE_INDEX_ROOTS_LENGTH] - latest_slashed_balances: Vector[uint64, LATEST_SLASHED_EXIT_LENGTH] - latest_block_header: BeaconBlockHeader - historical_roots: List[Bytes32] - # Ethereum 1.0 chain data - latest_eth1_data: Eth1Data - eth1_data_votes: List[Eth1Data] - deposit_index: uint64 -``` - ## Custom types We define the following Python custom types for type hinting and readability: @@ -577,6 +269,264 @@ We define the following Python custom types for type hinting and readability: | `BLSPubkey` | `Bytes48` | a BLS12-381 public key | | `BLSSignature` | `Bytes96` | a BLS12-381 signature | +## Containers + +The following types are [SimpleSerialize (SSZ)](../simple-serialize.md) containers. + +*Note*: The definitions are ordered topologically to facilitate execution of the spec. + +### Misc dependencies + +#### `Fork` + +```python +class Fork(Container): + previous_version: Bytes4 + current_version: Bytes4 + epoch: Epoch +``` + +#### `Validator` + +```python +class Validator(Container): + pubkey: BLSPubkey + withdrawal_credentials: Hash + effective_balance: Gwei + slashed: bool + # Status epochs + activation_eligibility_epoch: Epoch + activation_epoch: Epoch + exit_epoch: Epoch + withdrawable_epoch: Epoch +``` + +#### `Crosslink` + +```python +class Crosslink(Container): + shard: Shard + parent_root: Hash + # Crosslinking data + start_epoch: Epoch + end_epoch: Epoch + data_root: Hash +``` + +#### `AttestationData` + +```python +class AttestationData(Container): + # LMD GHOST vote + beacon_block_root: Hash + # FFG vote + source_epoch: Epoch + source_root: Hash + target_epoch: Epoch + target_root: Hash + # Crosslink vote + crosslink: Crosslink +``` + +#### `AttestationDataAndCustodyBit` + +```python +class AttestationDataAndCustodyBit(Container): + data: AttestationData + custody_bit: bool +``` + +#### `IndexedAttestation` + +```python +class IndexedAttestation(Container): + custody_bit_0_indices: List[ValidatorIndex] # Indices with custody bit equal to 0 + custody_bit_1_indices: List[ValidatorIndex] # Indices with custody bit equal to 1 + data: AttestationData + signature: BLSSignature +``` + +#### `PendingAttestation` + +```python +class PendingAttestation(Container): + aggregation_bitfield: bytes + data: AttestationData + inclusion_delay: Slot + proposer_index: ValidatorIndex +``` + +#### `Eth1Data` + +```python +class Eth1Data(Container): + deposit_root: Hash + deposit_count: uint64 + block_hash: Hash +``` + +#### `HistoricalBatch` + +```python +class HistoricalBatch(Container): + block_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT] + state_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT] +``` + +#### `DepositData` + +```python +class DepositData(Container): + pubkey: BLSPubkey + withdrawal_credentials: Hash + amount: Gwei + signature: BLSSignature +``` + +#### `BeaconBlockHeader` + +```python +class BeaconBlockHeader(Container): + slot: Slot + parent_root: Hash + state_root: Hash + body_root: Hash + signature: BLSSignature +``` + +### Beacon operations + +#### `ProposerSlashing` + +```python +class ProposerSlashing(Container): + proposer_index: ValidatorIndex + header_1: BeaconBlockHeader + header_2: BeaconBlockHeader +``` + +#### `AttesterSlashing` + +```python +class AttesterSlashing(Container): + attestation_1: IndexedAttestation + attestation_2: IndexedAttestation +``` + +#### `Attestation` + +```python +class Attestation(Container): + aggregation_bitfield: bytes + data: AttestationData + custody_bitfield: bytes + signature: BLSSignature +``` + +#### `Deposit` + +```python +class Deposit(Container): + proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH] + data: DepositData +``` + +#### `VoluntaryExit` + +```python +class VoluntaryExit(Container): + epoch: Epoch + validator_index: ValidatorIndex + signature: BLSSignature +``` + +#### `Transfer` + +```python +class Transfer(Container): + sender: ValidatorIndex + recipient: ValidatorIndex + amount: Gwei + fee: Gwei + slot: Slot + pubkey: BLSPubkey + signature: BLSSignature +``` + +### Beacon blocks + +#### `BeaconBlockBody` + +```python +class BeaconBlockBody(Container): + randao_reveal: BLSSignature + eth1_data: Eth1Data + graffiti: Bytes32 + # Operations + proposer_slashings: List[ProposerSlashing] + attester_slashings: List[AttesterSlashing] + attestations: List[Attestation] + deposits: List[Deposit] + voluntary_exits: List[VoluntaryExit] + transfers: List[Transfer] +``` + +#### `BeaconBlock` + +```python +class BeaconBlock(Container): + slot: Slot + parent_root: Hash + state_root: Hash + body: BeaconBlockBody + signature: BLSSignature +``` + +### Beacon state + +#### `BeaconState` + +```python +class BeaconState(Container): + # Versioning + genesis_time: uint64 + slot: Slot + fork: Fork + # History + block_header: BeaconBlockHeader + block_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT] + state_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT] + historical_roots: List[Hash] + # Eth1 + eth1_data: Eth1Data + eth1_data_votes: List[Eth1Data] + eth1_deposit_index: uint64 + # Registry + validators: List[Validator] + balances: List[Gwei] + # Shuffling + start_shard: Shard + randao_mixes: Vector[Hash, RANDAO_MIXES_LENGTH] + active_index_roots: Vector[Hash, ACTIVE_INDEX_ROOTS_LENGTH] + # Slashings + slashed_balances: Vector[Gwei, SLASHED_EXIT_LENGTH] + # Attestations + previous_attestations: List[PendingAttestation] + current_attestations: List[PendingAttestation] + # Crosslinks + previous_crosslinks: Vector[Crosslink, SHARD_COUNT] + current_crosslinks: Vector[Crosslink, SHARD_COUNT] + # Justification + previous_justified_epoch: Epoch + previous_justified_root: Hash + current_justified_epoch: Epoch + current_justified_root: Hash + justification_bitfield: uint64 + # Finality + finalized_epoch: Epoch + finalized_root: Hash +``` + ## Helper functions *Note*: The definitions below are for specification purposes and are not necessarily optimal implementations. @@ -596,11 +546,11 @@ The `hash` function is SHA256. ### `hash_tree_root` -`def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](../simple-serialize.md#merkleization). +`def hash_tree_root(object: SSZSerializable) -> Hash` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](../simple-serialize.md#merkleization). ### `signing_root` -`def signing_root(object: Container) -> Bytes32` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages. +`def signing_root(object: Container) -> Hash` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages. ### `bls_domain` @@ -681,7 +631,7 @@ def get_active_validator_indices(state: BeaconState, epoch: Epoch) -> List[Valid """ Get active validator indices at ``epoch``. """ - return [i for i, v in enumerate(state.validator_registry) if is_active_validator(v, epoch)] + return [i for i, v in enumerate(state.validators) if is_active_validator(v, epoch)] ``` ### `increase_balance` @@ -726,7 +676,7 @@ def get_epoch_committee_count(state: BeaconState, epoch: Epoch) -> int: ```python def get_shard_delta(state: BeaconState, epoch: Epoch) -> int: """ - Return the number of shards to increment ``state.latest_start_shard`` during ``epoch``. + Return the number of shards to increment ``state.start_shard`` during ``epoch``. """ return min(get_epoch_committee_count(state, epoch), SHARD_COUNT - SHARD_COUNT // SLOTS_PER_EPOCH) ``` @@ -737,7 +687,7 @@ def get_shard_delta(state: BeaconState, epoch: Epoch) -> int: def get_epoch_start_shard(state: BeaconState, epoch: Epoch) -> Shard: assert epoch <= get_current_epoch(state) + 1 check_epoch = get_current_epoch(state) + 1 - shard = (state.latest_start_shard + get_shard_delta(state, get_current_epoch(state))) % SHARD_COUNT + shard = (state.start_shard + get_shard_delta(state, get_current_epoch(state))) % SHARD_COUNT while check_epoch > epoch: check_epoch -= 1 shard = (shard + SHARD_COUNT - get_shard_delta(state, check_epoch)) % SHARD_COUNT @@ -757,19 +707,19 @@ def get_attestation_data_slot(state: BeaconState, data: AttestationData) -> Slot ```python def get_block_root_at_slot(state: BeaconState, - slot: Slot) -> Bytes32: + slot: Slot) -> Hash: """ Return the block root at a recent ``slot``. """ assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT - return state.latest_block_roots[slot % SLOTS_PER_HISTORICAL_ROOT] + return state.block_roots[slot % SLOTS_PER_HISTORICAL_ROOT] ``` ### `get_block_root` ```python def get_block_root(state: BeaconState, - epoch: Epoch) -> Bytes32: + epoch: Epoch) -> Hash: """ Return the block root at a recent ``epoch``. """ @@ -780,37 +730,37 @@ def get_block_root(state: BeaconState, ```python def get_randao_mix(state: BeaconState, - epoch: Epoch) -> Bytes32: + epoch: Epoch) -> Hash: """ Return the randao mix at a recent ``epoch``. - ``epoch`` expected to be between (current_epoch - LATEST_RANDAO_MIXES_LENGTH, current_epoch]. + ``epoch`` expected to be between (current_epoch - RANDAO_MIXES_LENGTH, current_epoch]. """ - return state.latest_randao_mixes[epoch % LATEST_RANDAO_MIXES_LENGTH] + return state.randao_mixes[epoch % RANDAO_MIXES_LENGTH] ``` ### `get_active_index_root` ```python def get_active_index_root(state: BeaconState, - epoch: Epoch) -> Bytes32: + epoch: Epoch) -> Hash: """ Return the index root at a recent ``epoch``. ``epoch`` expected to be between - (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch + ACTIVATION_EXIT_DELAY]. + (current_epoch - ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch + ACTIVATION_EXIT_DELAY]. """ - return state.latest_active_index_roots[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] + return state.active_index_roots[epoch % ACTIVE_INDEX_ROOTS_LENGTH] ``` ### `generate_seed` ```python def generate_seed(state: BeaconState, - epoch: Epoch) -> Bytes32: + epoch: Epoch) -> Hash: """ Generate a seed for the given ``epoch``. """ return hash( - get_randao_mix(state, epoch + LATEST_RANDAO_MIXES_LENGTH - MIN_SEED_LOOKAHEAD) + + get_randao_mix(state, epoch + RANDAO_MIXES_LENGTH - MIN_SEED_LOOKAHEAD) + get_active_index_root(state, epoch) + int_to_bytes(epoch, length=32) ) @@ -834,7 +784,7 @@ def get_beacon_proposer_index(state: BeaconState) -> ValidatorIndex: while True: candidate_index = first_committee[(epoch + i) % len(first_committee)] random_byte = hash(seed + int_to_bytes(i // 32, length=8))[i % 32] - effective_balance = state.validator_registry[candidate_index].effective_balance + effective_balance = state.validators[candidate_index].effective_balance if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte: return candidate_index i += 1 @@ -843,7 +793,7 @@ def get_beacon_proposer_index(state: BeaconState) -> ValidatorIndex: ### `verify_merkle_branch` ```python -def verify_merkle_branch(leaf: Bytes32, proof: List[Bytes32], depth: int, index: int, root: Bytes32) -> bool: +def verify_merkle_branch(leaf: Hash, proof: List[Hash], depth: int, index: int, root: Hash) -> bool: """ Verify that the given ``leaf`` is on the merkle branch ``proof`` starting with the given ``root``. @@ -860,7 +810,7 @@ def verify_merkle_branch(leaf: Bytes32, proof: List[Bytes32], depth: int, index: ### `get_shuffled_index` ```python -def get_shuffled_index(index: ValidatorIndex, index_count: int, seed: Bytes32) -> ValidatorIndex: +def get_shuffled_index(index: ValidatorIndex, index_count: int, seed: Hash) -> ValidatorIndex: """ Return the shuffled validator index corresponding to ``seed`` (and ``index_count``). """ @@ -884,7 +834,7 @@ def get_shuffled_index(index: ValidatorIndex, index_count: int, seed: Bytes32) - ### `compute_committee` ```python -def compute_committee(indices: List[ValidatorIndex], seed: Bytes32, index: int, count: int) -> List[ValidatorIndex]: +def compute_committee(indices: List[ValidatorIndex], seed: Hash, index: int, count: int) -> List[ValidatorIndex]: start = (len(indices) * index) // count end = (len(indices) * (index + 1)) // count return [indices[get_shuffled_index(i, len(indices), seed)] for i in range(start, end)] @@ -937,7 +887,7 @@ def get_total_balance(state: BeaconState, indices: List[ValidatorIndex]) -> Gwei """ Return the combined effective balance of the ``indices``. (1 Gwei minimum to avoid divisions by zero.) """ - return max(sum([state.validator_registry[index].effective_balance for index in indices]), 1) + return max(sum([state.validators[index].effective_balance for index in indices]), 1) ``` ### `get_domain` @@ -1022,8 +972,8 @@ def validate_indexed_attestation(state: BeaconState, indexed_attestation: Indexe # Verify aggregate signature assert bls_verify_multiple( pubkeys=[ - bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in bit_0_indices]), - bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in bit_1_indices]), + bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_0_indices]), + bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_1_indices]), ], message_hashes=[ hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b0)), @@ -1112,14 +1062,14 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: Initiate the exit of the validator of the given ``index``. """ # Return if validator already initiated exit - validator = state.validator_registry[index] + validator = state.validators[index] if validator.exit_epoch != FAR_FUTURE_EPOCH: return # Compute exit queue epoch - exit_epochs = [v.exit_epoch for v in state.validator_registry if v.exit_epoch != FAR_FUTURE_EPOCH] + exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH] exit_queue_epoch = max(exit_epochs + [get_delayed_activation_exit_epoch(get_current_epoch(state))]) - exit_queue_churn = len([v for v in state.validator_registry if v.exit_epoch == exit_queue_epoch]) + exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch]) if exit_queue_churn >= get_churn_limit(state): exit_queue_epoch += 1 @@ -1139,10 +1089,10 @@ def slash_validator(state: BeaconState, """ current_epoch = get_current_epoch(state) initiate_validator_exit(state, slashed_index) - state.validator_registry[slashed_index].slashed = True - state.validator_registry[slashed_index].withdrawable_epoch = current_epoch + LATEST_SLASHED_EXIT_LENGTH - slashed_balance = state.validator_registry[slashed_index].effective_balance - state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH] += slashed_balance + state.validators[slashed_index].slashed = True + state.validators[slashed_index].withdrawable_epoch = current_epoch + SLASHED_EXIT_LENGTH + slashed_balance = state.validators[slashed_index].effective_balance + state.slashed_balances[current_epoch % SLASHED_EXIT_LENGTH] += slashed_balance proposer_index = get_beacon_proposer_index(state) if whistleblower_index is None: @@ -1175,8 +1125,8 @@ Let `genesis_state = get_genesis_beacon_state(genesis_deposits, eth2genesis.gene def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis_eth1_data: Eth1Data) -> BeaconState: state = BeaconState( genesis_time=genesis_time, - latest_eth1_data=genesis_eth1_data, - latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), + eth1_data=genesis_eth1_data, + block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) # Process genesis deposits @@ -1184,15 +1134,15 @@ def get_genesis_beacon_state(deposits: List[Deposit], genesis_time: int, genesis process_deposit(state, deposit) # Process genesis activations - for validator in state.validator_registry: + for validator in state.validators: if validator.effective_balance >= MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - # Populate latest_active_index_roots + # Populate active_index_roots genesis_active_index_root = hash_tree_root(get_active_validator_indices(state, GENESIS_EPOCH)) - for index in range(LATEST_ACTIVE_INDEX_ROOTS_LENGTH): - state.latest_active_index_roots[index] = genesis_active_index_root + for index in range(ACTIVE_INDEX_ROOTS_LENGTH): + state.active_index_roots[index] = genesis_active_index_root return state ``` @@ -1233,15 +1183,15 @@ def process_slots(state: BeaconState, slot: Slot) -> None: def process_slot(state: BeaconState) -> None: # Cache state root previous_state_root = hash_tree_root(state) - state.latest_state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root + state.state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root # Cache latest block header state root - if state.latest_block_header.state_root == ZERO_HASH: - state.latest_block_header.state_root = previous_state_root + if state.block_header.state_root == ZERO_HASH: + state.block_header.state_root = previous_state_root # Cache block root - previous_block_root = signing_root(state.latest_block_header) - state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root + previous_block_root = signing_root(state.block_header) + state.block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root ``` ### Epoch processing @@ -1271,7 +1221,7 @@ def get_total_active_balance(state: BeaconState) -> Gwei: ```python def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]: assert epoch in (get_current_epoch(state), get_previous_epoch(state)) - return state.current_epoch_attestations if epoch == get_current_epoch(state) else state.previous_epoch_attestations + return state.current_attestations if epoch == get_current_epoch(state) else state.previous_attestations ``` ```python @@ -1296,7 +1246,7 @@ def get_unslashed_attesting_indices(state: BeaconState, output = set() for a in attestations: output = output.union(get_attesting_indices(state, a.data, a.aggregation_bitfield)) - return sorted(filter(lambda index: not state.validator_registry[index].slashed, list(output))) + return sorted(filter(lambda index: not state.validators[index].slashed, list(output))) ``` ```python @@ -1391,7 +1341,7 @@ def process_crosslinks(state: BeaconState) -> None: ```python def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei: total_balance = get_total_active_balance(state) - effective_balance = state.validator_registry[index].effective_balance + effective_balance = state.validators[index].effective_balance return effective_balance * BASE_REWARD_FACTOR // integer_squareroot(total_balance) // BASE_REWARDS_PER_EPOCH ``` @@ -1399,10 +1349,10 @@ def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei: def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: previous_epoch = get_previous_epoch(state) total_balance = get_total_active_balance(state) - rewards = [0 for _ in range(len(state.validator_registry))] - penalties = [0 for _ in range(len(state.validator_registry))] + rewards = [0 for _ in range(len(state.validators))] + penalties = [0 for _ in range(len(state.validators))] eligible_validator_indices = [ - index for index, v in enumerate(state.validator_registry) + index for index, v in enumerate(state.validators) if is_active_validator(v, previous_epoch) or (v.slashed and previous_epoch + 1 < v.withdrawable_epoch) ] @@ -1436,7 +1386,7 @@ def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: penalties[index] += BASE_REWARDS_PER_EPOCH * get_base_reward(state, index) if index not in matching_target_attesting_indices: penalties[index] += ( - state.validator_registry[index].effective_balance * finality_delay // INACTIVITY_PENALTY_QUOTIENT + state.validators[index].effective_balance * finality_delay // INACTIVITY_PENALTY_QUOTIENT ) return rewards, penalties @@ -1444,8 +1394,8 @@ def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: ```python def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: - rewards = [0 for index in range(len(state.validator_registry))] - penalties = [0 for index in range(len(state.validator_registry))] + rewards = [0 for index in range(len(state.validators))] + penalties = [0 for index in range(len(state.validators))] epoch = get_previous_epoch(state) for offset in range(get_epoch_committee_count(state, epoch)): shard = (get_epoch_start_shard(state, epoch) + offset) % SHARD_COUNT @@ -1469,7 +1419,7 @@ def process_rewards_and_penalties(state: BeaconState) -> None: rewards1, penalties1 = get_attestation_deltas(state) rewards2, penalties2 = get_crosslink_deltas(state) - for i in range(len(state.validator_registry)): + for i in range(len(state.validators)): increase_balance(state, i, rewards1[i] + rewards2[i]) decrease_balance(state, i, penalties1[i] + penalties2[i]) ``` @@ -1479,7 +1429,7 @@ def process_rewards_and_penalties(state: BeaconState) -> None: ```python def process_registry_updates(state: BeaconState) -> None: # Process activation eligibility and ejections - for index, validator in enumerate(state.validator_registry): + for index, validator in enumerate(state.validators): if ( validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and validator.effective_balance >= MAX_EFFECTIVE_BALANCE @@ -1491,13 +1441,13 @@ def process_registry_updates(state: BeaconState) -> None: # Queue validators eligible for activation and not dequeued for activation prior to finalized epoch activation_queue = sorted([ - index for index, validator in enumerate(state.validator_registry) if + index for index, validator in enumerate(state.validators) if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch) - ], key=lambda index: state.validator_registry[index].activation_eligibility_epoch) + ], key=lambda index: state.validators[index].activation_eligibility_epoch) # Dequeued validators for activation up to churn limit (without resetting activation epoch) for index in activation_queue[:get_churn_limit(state)]: - validator = state.validator_registry[index] + validator = state.validators[index] if validator.activation_epoch == FAR_FUTURE_EPOCH: validator.activation_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state)) ``` @@ -1510,12 +1460,12 @@ def process_slashings(state: BeaconState) -> None: total_balance = get_total_active_balance(state) # Compute slashed balances in the current epoch - total_at_start = state.latest_slashed_balances[(current_epoch + 1) % LATEST_SLASHED_EXIT_LENGTH] - total_at_end = state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH] + total_at_start = state.slashed_balances[(current_epoch + 1) % SLASHED_EXIT_LENGTH] + total_at_end = state.slashed_balances[current_epoch % SLASHED_EXIT_LENGTH] total_penalties = total_at_end - total_at_start - for index, validator in enumerate(state.validator_registry): - if validator.slashed and current_epoch == validator.withdrawable_epoch - LATEST_SLASHED_EXIT_LENGTH // 2: + for index, validator in enumerate(state.validators): + if validator.slashed and current_epoch == validator.withdrawable_epoch - SLASHED_EXIT_LENGTH // 2: penalty = max( validator.effective_balance * min(total_penalties * 3, total_balance) // total_balance, validator.effective_balance // MIN_SLASHING_PENALTY_QUOTIENT @@ -1533,34 +1483,34 @@ def process_final_updates(state: BeaconState) -> None: if (state.slot + 1) % SLOTS_PER_ETH1_VOTING_PERIOD == 0: state.eth1_data_votes = [] # Update effective balances with hysteresis - for index, validator in enumerate(state.validator_registry): + for index, validator in enumerate(state.validators): balance = state.balances[index] HALF_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // 2 if balance < validator.effective_balance or validator.effective_balance + 3 * HALF_INCREMENT < balance: validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE) # Update start shard - state.latest_start_shard = (state.latest_start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT + state.start_shard = (state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT # Set active index root - index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH - state.latest_active_index_roots[index_root_position] = hash_tree_root( + index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % ACTIVE_INDEX_ROOTS_LENGTH + state.active_index_roots[index_root_position] = hash_tree_root( get_active_validator_indices(state, next_epoch + ACTIVATION_EXIT_DELAY) ) # Set total slashed balances - state.latest_slashed_balances[next_epoch % LATEST_SLASHED_EXIT_LENGTH] = ( - state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH] + state.slashed_balances[next_epoch % SLASHED_EXIT_LENGTH] = ( + state.slashed_balances[current_epoch % SLASHED_EXIT_LENGTH] ) # Set randao mix - state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = get_randao_mix(state, current_epoch) + state.randao_mixes[next_epoch % RANDAO_MIXES_LENGTH] = get_randao_mix(state, current_epoch) # Set historical root accumulator if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0: historical_batch = HistoricalBatch( - block_roots=state.latest_block_roots, - state_roots=state.latest_state_roots, + block_roots=state.block_roots, + state_roots=state.state_roots, ) state.historical_roots.append(hash_tree_root(historical_batch)) # Rotate current/previous epoch attestations - state.previous_epoch_attestations = state.current_epoch_attestations - state.current_epoch_attestations = [] + state.previous_attestations = state.current_attestations + state.current_attestations = [] ``` ### Block processing @@ -1580,15 +1530,15 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None: # Verify that the slots match assert block.slot == state.slot # Verify that the parent matches - assert block.parent_root == signing_root(state.latest_block_header) + assert block.parent_root == signing_root(state.block_header) # Save current block as the new latest block - state.latest_block_header = BeaconBlockHeader( + state.block_header = BeaconBlockHeader( slot=block.slot, parent_root=block.parent_root, body_root=hash_tree_root(block.body), ) # Verify proposer is not slashed - proposer = state.validator_registry[get_beacon_proposer_index(state)] + proposer = state.validators[get_beacon_proposer_index(state)] assert not proposer.slashed # Verify proposer signature assert bls_verify(proposer.pubkey, signing_root(block), block.signature, get_domain(state, DOMAIN_BEACON_PROPOSER)) @@ -1598,7 +1548,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None: ```python def process_randao(state: BeaconState, body: BeaconBlockBody) -> None: - proposer = state.validator_registry[get_beacon_proposer_index(state)] + proposer = state.validators[get_beacon_proposer_index(state)] # Verify that the provided randao value is valid assert bls_verify( proposer.pubkey, @@ -1607,7 +1557,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None: get_domain(state, DOMAIN_RANDAO), ) # Mix it in - state.latest_randao_mixes[get_current_epoch(state) % LATEST_RANDAO_MIXES_LENGTH] = ( + state.randao_mixes[get_current_epoch(state) % RANDAO_MIXES_LENGTH] = ( xor(get_randao_mix(state, get_current_epoch(state)), hash(body.randao_reveal)) ) @@ -1619,7 +1569,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None: def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None: state.eth1_data_votes.append(body.eth1_data) if state.eth1_data_votes.count(body.eth1_data) * 2 > SLOTS_PER_ETH1_VOTING_PERIOD: - state.latest_eth1_data = body.eth1_data + state.eth1_data = body.eth1_data ``` #### Operations @@ -1627,7 +1577,7 @@ def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None: ```python def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: # Verify that outstanding deposits are processed up to the maximum number of deposits - assert len(body.deposits) == min(MAX_DEPOSITS, state.latest_eth1_data.deposit_count - state.deposit_index) + assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index) # Verify that there are no duplicate transfers assert len(body.transfers) == len(set(body.transfers)) @@ -1651,7 +1601,7 @@ def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSla """ Process ``ProposerSlashing`` operation. """ - proposer = state.validator_registry[proposer_slashing.proposer_index] + proposer = state.validators[proposer_slashing.proposer_index] # Verify that the epoch is the same assert slot_to_epoch(proposer_slashing.header_1.slot) == slot_to_epoch(proposer_slashing.header_2.slot) # But the headers are different @@ -1683,7 +1633,7 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla attesting_indices_1 = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices attesting_indices_2 = attestation_2.custody_bit_0_indices + attestation_2.custody_bit_1_indices for index in sorted(set(attesting_indices_1).intersection(attesting_indices_2)): - if is_slashable_validator(state.validator_registry[index], get_current_epoch(state)): + if is_slashable_validator(state.validators[index], get_current_epoch(state)): slash_validator(state, index) slashed_any = True assert slashed_any @@ -1711,11 +1661,11 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: if data.target_epoch == get_current_epoch(state): ffg_data = (state.current_justified_epoch, state.current_justified_root, get_current_epoch(state)) parent_crosslink = state.current_crosslinks[data.crosslink.shard] - state.current_epoch_attestations.append(pending_attestation) + state.current_attestations.append(pending_attestation) else: ffg_data = (state.previous_justified_epoch, state.previous_justified_root, get_previous_epoch(state)) parent_crosslink = state.previous_crosslinks[data.crosslink.shard] - state.previous_epoch_attestations.append(pending_attestation) + state.previous_attestations.append(pending_attestation) # Check FFG data, crosslink data, and signature assert ffg_data == (data.source_epoch, data.source_root, data.target_epoch) @@ -1738,16 +1688,16 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: leaf=hash_tree_root(deposit.data), proof=deposit.proof, depth=DEPOSIT_CONTRACT_TREE_DEPTH, - index=state.deposit_index, - root=state.latest_eth1_data.deposit_root, + index=state.eth1_deposit_index, + root=state.eth1_data.deposit_root, ) # Deposits must be processed in order - state.deposit_index += 1 + state.eth1_deposit_index += 1 pubkey = deposit.data.pubkey amount = deposit.data.amount - validator_pubkeys = [v.pubkey for v in state.validator_registry] + validator_pubkeys = [v.pubkey for v in state.validators] if pubkey not in validator_pubkeys: # Verify the deposit signature (proof of possession). # Invalid signatures are allowed by the deposit contract, @@ -1759,7 +1709,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: return # Add validator and balance entries - state.validator_registry.append(Validator( + state.validators.append(Validator( pubkey=pubkey, withdrawal_credentials=deposit.data.withdrawal_credentials, activation_eligibility_epoch=FAR_FUTURE_EPOCH, @@ -1782,7 +1732,7 @@ def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None: """ Process ``VoluntaryExit`` operation. """ - validator = state.validator_registry[exit.validator_index] + validator = state.validators[exit.validator_index] # Verify the validator is active assert is_active_validator(validator, get_current_epoch(state)) # Verify the validator has not yet exited @@ -1811,13 +1761,13 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None: assert state.slot == transfer.slot # Sender must be not yet eligible for activation, withdrawn, or transfer balance over MAX_EFFECTIVE_BALANCE assert ( - state.validator_registry[transfer.sender].activation_eligibility_epoch == FAR_FUTURE_EPOCH or - get_current_epoch(state) >= state.validator_registry[transfer.sender].withdrawable_epoch or + state.validators[transfer.sender].activation_eligibility_epoch == FAR_FUTURE_EPOCH or + get_current_epoch(state) >= state.validators[transfer.sender].withdrawable_epoch or transfer.amount + transfer.fee + MAX_EFFECTIVE_BALANCE <= state.balances[transfer.sender] ) # Verify that the pubkey is valid assert ( - state.validator_registry[transfer.sender].withdrawal_credentials == + state.validators[transfer.sender].withdrawal_credentials == int_to_bytes(BLS_WITHDRAWAL_PREFIX, length=1) + hash(transfer.pubkey)[1:] ) # Verify that the signature is valid diff --git a/specs/core/0_deposit-contract.md b/specs/core/0_deposit-contract.md index e80dad1c5..d40553f43 100644 --- a/specs/core/0_deposit-contract.md +++ b/specs/core/0_deposit-contract.md @@ -75,9 +75,9 @@ Every Ethereum 1.0 deposit, of size at least `MIN_DEPOSIT_AMOUNT`, emits a `Depo When `CHAIN_START_FULL_DEPOSIT_THRESHOLD` of full deposits have been made, the deposit contract emits the `Eth2Genesis` log. The beacon chain state may then be initialized by calling the `get_genesis_beacon_state` function (defined [here](./0_beacon-chain.md#genesis-state)) where: * `genesis_time` equals `time` in the `Eth2Genesis` log -* `latest_eth1_data.deposit_root` equals `deposit_root` in the `Eth2Genesis` log -* `latest_eth1_data.deposit_count` equals `deposit_count` in the `Eth2Genesis` log -* `latest_eth1_data.block_hash` equals the hash of the block that included the log +* `eth1_data.deposit_root` equals `deposit_root` in the `Eth2Genesis` log +* `eth1_data.deposit_count` equals `deposit_count` in the `Eth2Genesis` log +* `eth1_data.block_hash` equals the hash of the block that included the log * `genesis_validator_deposits` is a list of `Deposit` objects built according to the `Deposit` logs up to the deposit that triggered the `Eth2Genesis` log, processed in the order in which they were emitted (oldest to newest) ## Vyper code diff --git a/specs/core/0_fork-choice.md b/specs/core/0_fork-choice.md index 91c3e27ee..739c06d59 100644 --- a/specs/core/0_fork-choice.md +++ b/specs/core/0_fork-choice.md @@ -39,7 +39,7 @@ All terminology, constants, functions, and protocol mechanics defined in the [Ph Processing the beacon chain is similar to processing the Ethereum 1.0 chain. Clients download and process blocks and maintain a view of what is the current "canonical chain", terminating at the current "head". For a beacon block, `block`, to be processed by a node, the following conditions must be met: * The parent block with root `block.parent_root` has been processed and accepted. -* An Ethereum 1.0 block pointed to by the `state.latest_eth1_data.block_hash` has been processed and accepted. +* An Ethereum 1.0 block pointed to by the `state.eth1_data.block_hash` has been processed and accepted. * The node's Unix time is greater than or equal to `state.genesis_time + block.slot * SECONDS_PER_SLOT`. *Note*: Leap seconds mean that slots will occasionally last `SECONDS_PER_SLOT + 1` or `SECONDS_PER_SLOT - 1` seconds, possibly several times a year. @@ -68,8 +68,8 @@ def get_ancestor(store: Store, block: BeaconBlock, slot: Slot) -> BeaconBlock: return get_ancestor(store, store.get_parent(block), slot) ``` -* Let `get_latest_attestation(store: Store, index: ValidatorIndex) -> Attestation` be the attestation with the highest slot number in `store` from the validator with the given `index`. If several such attestations exist, use the one the validator `v` observed first. -* Let `get_latest_attestation_target(store: Store, index: ValidatorIndex) -> BeaconBlock` be the target block in the attestation `get_latest_attestation(store, index)`. +* Let `get_attestation(store: Store, index: ValidatorIndex) -> Attestation` be the attestation with the highest slot number in `store` from the validator with the given `index`. If several such attestations exist, use the one the validator `v` observed first. +* Let `get_attestation_target(store: Store, index: ValidatorIndex) -> BeaconBlock` be the target block in the attestation `get_attestation(store, index)`. * Let `get_children(store: Store, block: BeaconBlock) -> List[BeaconBlock]` return the child blocks of the given `block`. * Let `justified_head_state` be the resulting `BeaconState` object from processing the chain up to the `justified_head`. * The `head` is `lmd_ghost(store, justified_head_state, justified_head)` where the function `lmd_ghost` is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count. @@ -79,16 +79,16 @@ def lmd_ghost(store: Store, start_state: BeaconState, start_block: BeaconBlock) """ Execute the LMD-GHOST algorithm to find the head ``BeaconBlock``. """ - validators = start_state.validator_registry + validators = start_state.validators active_validator_indices = get_active_validator_indices(validators, slot_to_epoch(start_state.slot)) - attestation_targets = [(i, get_latest_attestation_target(store, i)) for i in active_validator_indices] + attestation_targets = [(i, get_attestation_target(store, i)) for i in active_validator_indices] # Use the rounded-balance-with-hysteresis supplied by the protocol for fork # choice voting. This reduces the number of recomputations that need to be # made for optimized implementations that precompute and save data def get_vote_count(block: BeaconBlock) -> int: return sum( - start_state.validator_registry[validator_index].effective_balance + start_state.validators[validator_index].effective_balance for validator_index, target in attestation_targets if get_ancestor(store, target, block.slot) == block ) diff --git a/specs/core/1_custody-game.md b/specs/core/1_custody-game.md index 6c89ef853..75ab36609 100644 --- a/specs/core/1_custody-game.md +++ b/specs/core/1_custody-game.md @@ -339,7 +339,7 @@ def process_custody_key_reveal(state: BeaconState, Note that this function mutates ``state``. """ - revealer = state.validator_registry[reveal.revealer_index] + revealer = state.validators[reveal.revealer_index] epoch_to_sign = get_randao_epoch_for_custody_period(revealer.next_custody_reveal_period, reveal.revealed_index) assert revealer.next_custody_reveal_period < get_validators_custody_reveal_period(state, reveal.revealed_index) @@ -389,8 +389,8 @@ def process_early_derived_secret_reveal(state: BeaconState, Note that this function mutates ``state``. """ - revealed_validator = state.validator_registry[reveal.revealed_index] - masker = state.validator_registry[reveal.masker_index] + revealed_validator = state.validators[reveal.revealed_index] + masker = state.validators[reveal.masker_index] derived_secret_location = reveal.epoch % EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS assert reveal.epoch >= get_current_epoch(state) + RANDAO_PENALTY_EPOCHS @@ -399,7 +399,7 @@ def process_early_derived_secret_reveal(state: BeaconState, assert reveal.revealed_index not in state.exposed_derived_secrets[derived_secret_location] # Verify signature correctness - masker = state.validator_registry[reveal.masker_index] + masker = state.validators[reveal.masker_index] pubkeys = [revealed_validator.pubkey, masker.pubkey] message_hashes = [ hash_tree_root(reveal.epoch), @@ -465,7 +465,7 @@ def process_chunk_challenge(state: BeaconState, validate_indexed_attestation(state, convert_to_indexed(state, challenge.attestation)) # Verify it is not too late to challenge assert slot_to_epoch(challenge.attestation.data.slot) >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY - responder = state.validator_registry[challenge.responder_index] + responder = state.validators[challenge.responder_index] assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY # Verify the responder participated in the attestation attesters = get_attesting_indices(state, challenge.attestation.data, challenge.attestation.aggregation_bitfield) @@ -507,7 +507,7 @@ def process_bit_challenge(state: BeaconState, challenge: CustodyBitChallenge) -> None: # Verify challenge signature - challenger = state.validator_registry[challenge.challenger_index] + challenger = state.validators[challenge.challenger_index] assert bls_verify( pubkey=challenger.pubkey, message_hash=signing_root(challenge), @@ -520,7 +520,7 @@ def process_bit_challenge(state: BeaconState, attestation = challenge.attestation validate_indexed_attestation(state, convert_to_indexed(state, attestation)) # Verify the attestation is eligible for challenging - responder = state.validator_registry[challenge.responder_index] + responder = state.validators[challenge.responder_index] assert (slot_to_epoch(attestation.data.slot) + responder.max_reveal_lateness <= get_validators_custody_reveal_period(state, challenge.responder_index)) @@ -630,7 +630,7 @@ def process_bit_challenge_response(state: BeaconState, # Verify chunk index assert response.chunk_index < challenge.chunk_count # Verify responder has not been slashed - responder = state.validator_registry[challenge.responder_index] + responder = state.validators[challenge.responder_index] assert not responder.slashed # Verify the chunk matches the crosslink data root assert verify_merkle_branch( @@ -669,7 +669,7 @@ Run `process_reveal_deadlines(state)` immediately after `process_registry_update process_reveal_deadlines(state) # end insert @process_reveal_deadlines def process_reveal_deadlines(state: BeaconState) -> None: - for index, validator in enumerate(state.validator_registry): + for index, validator in enumerate(state.validators): deadline = validator.next_custody_reveal_period + (CUSTODY_RESPONSE_DEADLINE // EPOCHS_PER_CUSTODY_PERIOD) if get_validators_custody_reveal_period(state, index) > deadline: slash_validator(state, index) @@ -710,7 +710,7 @@ def after_process_final_updates(state: BeaconState) -> None: validator_indices_in_records = set( [record.challenger_index for record in records] + [record.responder_index for record in records] ) - for index, validator in enumerate(state.validator_registry): + for index, validator in enumerate(state.validators): if index not in validator_indices_in_records: if validator.exit_epoch != FAR_FUTURE_EPOCH and validator.withdrawable_epoch == FAR_FUTURE_EPOCH: validator.withdrawable_epoch = validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 21e08e7c9..a895b3c38 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -158,9 +158,9 @@ def get_persistent_committee(state: BeaconState, later_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD committee_count = max( - len(get_active_validator_indices(state.validator_registry, earlier_start_epoch)) // + len(get_active_validator_indices(state.validators, earlier_start_epoch)) // (SHARD_COUNT * TARGET_COMMITTEE_SIZE), - len(get_active_validator_indices(state.validator_registry, later_start_epoch)) // + len(get_active_validator_indices(state.validators, later_start_epoch)) // (SHARD_COUNT * TARGET_COMMITTEE_SIZE), ) + 1 @@ -190,7 +190,7 @@ def get_shard_proposer_index(state: BeaconState, # Search for an active proposer for index in persistent_committee: - if is_active_validator(state.validator_registry[index], get_current_epoch(state)): + if is_active_validator(state.validators[index], get_current_epoch(state)): return index # No block can be proposed if no validator is active @@ -224,7 +224,7 @@ def verify_shard_attestation_signature(state: BeaconState, pubkeys = [] for i, index in enumerate(persistent_committee): if get_bitfield_bit(attestation.aggregation_bitfield, i) == 0b1: - validator = state.validator_registry[index] + validator = state.validators[index] assert is_active_validator(validator, get_current_epoch(state)) pubkeys.append(validator.pubkey) assert bls_verify( @@ -325,7 +325,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock], proposer_index = get_shard_proposer_index(beacon_state, candidate.shard, candidate.slot) assert proposer_index is not None assert bls_verify( - pubkey=beacon_state.validator_registry[proposer_index].pubkey, + pubkey=beacon_state.validators[proposer_index].pubkey, message_hash=signing_root(block), signature=candidate.signature, domain=get_domain(beacon_state, slot_to_epoch(candidate.slot), DOMAIN_SHARD_PROPOSER), @@ -395,7 +395,7 @@ def is_valid_beacon_attestation(shard: Shard, assert candidate.data.previous_attestation.epoch < slot_to_epoch(candidate.data.slot) # Check crosslink data root - start_epoch = beacon_state.latest_crosslinks[shard].epoch + start_epoch = beacon_state.crosslinks[shard].epoch end_epoch = min(slot_to_epoch(candidate.data.slot) - CROSSLINK_LOOKBACK, start_epoch + MAX_EPOCHS_PER_CROSSLINK) blocks = [] for slot in range(start_epoch * SLOTS_PER_EPOCH, end_epoch * SLOTS_PER_EPOCH): diff --git a/specs/light_client/sync_protocol.md b/specs/light_client/sync_protocol.md index 8501c5869..eb4bf09eb 100644 --- a/specs/light_client/sync_protocol.md +++ b/specs/light_client/sync_protocol.md @@ -31,7 +31,7 @@ We define an "expansion" of an object as an object where a field in an object th We define two expansions: -* `ExtendedBeaconState`, which is identical to a `BeaconState` except `latest_active_index_roots: List[Bytes32]` is replaced by `latest_active_indices: List[List[ValidatorIndex]]`, where `BeaconState.latest_active_index_roots[i] = hash_tree_root(ExtendedBeaconState.latest_active_indices[i])`. +* `ExtendedBeaconState`, which is identical to a `BeaconState` except `active_index_roots: List[Bytes32]` is replaced by `active_indices: List[List[ValidatorIndex]]`, where `BeaconState.active_index_roots[i] = hash_tree_root(ExtendedBeaconState.active_indices[i])`. * `ExtendedBeaconBlock`, which is identical to a `BeaconBlock` except `state_root` is replaced with the corresponding `state: ExtendedBeaconState`. ### `get_active_validator_indices` @@ -40,10 +40,10 @@ Note that there is now a new way to compute `get_active_validator_indices`: ```python def get_active_validator_indices(state: ExtendedBeaconState, epoch: Epoch) -> List[ValidatorIndex]: - return state.latest_active_indices[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] + return state.active_indices[epoch % ACTIVE_INDEX_ROOTS_LENGTH] ``` -Note that it takes `state` instead of `state.validator_registry` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments. +Note that it takes `state` instead of `state.validators` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments. ### `MerklePartial` @@ -85,7 +85,7 @@ def get_period_data(block: ExtendedBeaconBlock, shard_id: Shard, later: bool) -> return PeriodData( validator_count, generate_seed(block.state, period_start), - [block.state.validator_registry[i] for i in indices], + [block.state.validators[i] for i in indices], ) ``` diff --git a/specs/networking/rpc-interface.md b/specs/networking/rpc-interface.md index b81f78408..be154075c 100644 --- a/specs/networking/rpc-interface.md +++ b/specs/networking/rpc-interface.md @@ -95,8 +95,8 @@ Since some clients are waiting for `libp2p` implementations in their respective ( network_id: uint8 chain_id: uint64 - latest_finalized_root: bytes32 - latest_finalized_epoch: uint64 + finalized_root: bytes32 + finalized_epoch: uint64 best_root: bytes32 best_slot: uint64 ) @@ -107,7 +107,7 @@ Clients exchange `hello` messages upon connection, forming a two-phase handshake Clients SHOULD immediately disconnect from one another following the handshake above under the following conditions: 1. If `network_id` belongs to a different chain, since the client definitionally cannot sync with this client. -2. If the `latest_finalized_root` shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 in the diagram below has `(root, epoch)` of `(A, 5)` and Peer 2 has `(B, 3)`, Peer 1 would disconnect because it knows that `B` is not the root in their chain at epoch 3: +2. If the `finalized_root` shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 in the diagram below has `(root, epoch)` of `(A, 5)` and Peer 2 has `(B, 3)`, Peer 1 would disconnect because it knows that `B` is not the root in their chain at epoch 3: ``` Root A @@ -136,7 +136,7 @@ Root B ^ +---+ ``` -Once the handshake completes, the client with the higher `latest_finalized_epoch` or `best_slot` (if the clients have equal `latest_finalized_epoch`s) SHOULD request beacon block roots from its counterparty via `beacon_block_roots` (i.e. RPC method `10`). +Once the handshake completes, the client with the higher `finalized_epoch` or `best_slot` (if the clients have equal `finalized_epoch`s) SHOULD request beacon block roots from its counterparty via `beacon_block_roots` (i.e. RPC method `10`). ### Goodbye diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 2f5aa4264..d062e1d3b 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -101,15 +101,15 @@ To submit a deposit: * Let `signature` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=bls_domain(DOMAIN_DEPOSIT)`. (Deposits are valid regardless of fork version, `bls_domain` will default to zeroes there). * Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `def deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96])` along with a deposit of `amount` Gwei. -*Note*: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validator_registry` with each additional deposit amount added to the validator's balance. A validator can only be activated when total deposits for the validator pubkey meet or exceed `MAX_EFFECTIVE_BALANCE`. +*Note*: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validators` with each additional deposit amount added to the validator's balance. A validator can only be activated when total deposits for the validator pubkey meet or exceed `MAX_EFFECTIVE_BALANCE`. ### Process deposit -Deposits cannot be processed into the beacon chain until the Eth 1.0 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth 1.0 blocks (~4 hours) plus `ETH1_DATA_VOTING_PERIOD` epochs (~1.7 hours). Once the requisite Eth 1.0 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validator_registry` within an epoch or two. The validator is then in a queue to be activated. +Deposits cannot be processed into the beacon chain until the Eth 1.0 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth 1.0 blocks (~4 hours) plus `ETH1_DATA_VOTING_PERIOD` epochs (~1.7 hours). Once the requisite Eth 1.0 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validators` within an epoch or two. The validator is then in a queue to be activated. ### Validator index -Once a validator has been processed and added to the beacon state's `validator_registry`, the validator's `validator_index` is defined by the index into the registry at which the [`ValidatorRecord`](../core/0_beacon-chain.md#validator) contains the `pubkey` specified in the validator's deposit. A validator's `validator_index` is guaranteed to not change from the time of initial deposit until the validator exits and fully withdraws. This `validator_index` is used throughout the specification to dictate validator roles and responsibilities at any point and should be stored locally. +Once a validator has been processed and added to the beacon state's `validators`, the validator's `validator_index` is defined by the index into the registry at which the [`ValidatorRecord`](../core/0_beacon-chain.md#validator) contains the `pubkey` specified in the validator's deposit. A validator's `validator_index` is guaranteed to not change from the time of initial deposit until the validator exits and fully withdraws. This `validator_index` is used throughout the specification to dictate validator roles and responsibilities at any point and should be stored locally. ### Activation @@ -118,7 +118,7 @@ In normal operation, the validator is quickly activated at which point the valid The function [`is_active_validator`](../core/0_beacon-chain.md#is_active_validator) can be used to check if a validator is active during a given epoch. Usage is as follows: ```python -validator = state.validator_registry[validator_index] +validator = state.validators[validator_index] is_active = is_active_validator(validator, get_current_epoch(state)) ``` @@ -221,10 +221,10 @@ epoch_signature = bls_sign( ##### Eth1 Data -`block.eth1_data` is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed, `state.latest_eth1_data` is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling the `get_deposit_root()` function of the deposit contract using the post-state of the block hash. +`block.eth1_data` is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed, `state.eth1_data` is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling the `get_deposit_root()` function of the deposit contract using the post-state of the block hash. * Let `D` be the list of `Eth1DataVote` objects `vote` in `state.eth1_data_votes` where: - * `vote.eth1_data.block_hash` is the hash of an Eth 1.0 block that is (i) part of the canonical chain, (ii) >= `ETH1_FOLLOW_DISTANCE` blocks behind the head, and (iii) newer than `state.latest_eth1_data.block_hash`. + * `vote.eth1_data.block_hash` is the hash of an Eth 1.0 block that is (i) part of the canonical chain, (ii) >= `ETH1_FOLLOW_DISTANCE` blocks behind the head, and (iii) newer than `state.eth1_data.block_hash`. * `vote.eth1_data.deposit_count` is the deposit count of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`. * `vote.eth1_data.deposit_root` is the deposit root of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`. * If `D` is empty: @@ -267,9 +267,9 @@ Up to `MAX_ATTESTATIONS` aggregate attestations can be included in the `block`. ##### Deposits -If there are any unprocessed deposits for the existing `state.latest_eth1_data` (i.e. `state.latest_eth1_data.deposit_count > state.deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, latest_eth1_data.deposit_count - state.deposit_index)`. These [`deposits`](../core/0_beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [Eth 1.0 deposit contract](../core/0_deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](../core/0_beacon-chain.md#deposits). +If there are any unprocessed deposits for the existing `state.eth1_data` (i.e. `state.eth1_data.deposit_count > state.eth1_deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, eth1_data.deposit_count - state.eth1_deposit_index)`. These [`deposits`](../core/0_beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [Eth 1.0 deposit contract](../core/0_deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](../core/0_beacon-chain.md#deposits). -The `proof` for each deposit must be constructed against the deposit root contained in `state.latest_eth1_data` rather than the deposit root at the time the deposit was initially logged from the 1.0 chain. This entails storing a full deposit merkle tree locally and computing updated proofs against the `latest_eth1_data.deposit_root` as needed. See [`minimal_merkle.py`](https://github.com/ethereum/research/blob/master/spec_pythonizer/utils/merkle_minimal.py) for a sample implementation. +The `proof` for each deposit must be constructed against the deposit root contained in `state.eth1_data` rather than the deposit root at the time the deposit was initially logged from the 1.0 chain. This entails storing a full deposit merkle tree locally and computing updated proofs against the `eth1_data.deposit_root` as needed. See [`minimal_merkle.py`](https://github.com/ethereum/research/blob/master/spec_pythonizer/utils/merkle_minimal.py) for a sample implementation. ##### Voluntary exits diff --git a/test_libs/pyspec/eth2spec/test/helpers/block.py b/test_libs/pyspec/eth2spec/test/helpers/block.py index 5c7cb02a0..ebd20f1b5 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/block.py +++ b/test_libs/pyspec/eth2spec/test/helpers/block.py @@ -57,8 +57,8 @@ def build_empty_block(spec, state, slot=None, signed=False): slot = state.slot empty_block = spec.BeaconBlock() empty_block.slot = slot - empty_block.body.eth1_data.deposit_count = state.deposit_index - previous_block_header = deepcopy(state.latest_block_header) + empty_block.body.eth1_data.deposit_count = state.eth1_deposit_index + previous_block_header = deepcopy(state.block_header) if previous_block_header.state_root == spec.ZERO_HASH: previous_block_header.state_root = state.hash_tree_root() empty_block.parent_root = signing_root(previous_block_header) diff --git a/test_libs/pyspec/eth2spec/test/helpers/deposits.py b/test_libs/pyspec/eth2spec/test/helpers/deposits.py index c85d265eb..e3bd839aa 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/deposits.py +++ b/test_libs/pyspec/eth2spec/test/helpers/deposits.py @@ -58,7 +58,7 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c """ Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. """ - pre_validator_count = len(state.validator_registry) + pre_validator_count = len(state.validators) # fill previous deposits with zero-hash deposit_data_leaves = [spec.ZERO_HASH] * pre_validator_count @@ -80,6 +80,6 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c signed ) - state.latest_eth1_data.deposit_root = root - state.latest_eth1_data.deposit_count = len(deposit_data_leaves) + state.eth1_data.deposit_root = root + state.eth1_data.deposit_count = len(deposit_data_leaves) return deposit diff --git a/test_libs/pyspec/eth2spec/test/helpers/genesis.py b/test_libs/pyspec/eth2spec/test/helpers/genesis.py index 83af56621..241706957 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/genesis.py +++ b/test_libs/pyspec/eth2spec/test/helpers/genesis.py @@ -22,8 +22,8 @@ def create_genesis_state(spec, num_validators): state = spec.BeaconState( genesis_time=0, - deposit_index=num_validators, - latest_eth1_data=spec.Eth1Data( + eth1_deposit_index=num_validators, + eth1_data=spec.Eth1Data( deposit_root=deposit_root, deposit_count=num_validators, block_hash=spec.ZERO_HASH, @@ -32,16 +32,16 @@ def create_genesis_state(spec, num_validators): # We "hack" in the initial validators, # as it is much faster than creating and processing genesis deposits for every single test case. state.balances = [spec.MAX_EFFECTIVE_BALANCE] * num_validators - state.validator_registry = [build_mock_validator(spec, i, state.balances[i]) for i in range(num_validators)] + state.validators = [build_mock_validator(spec, i, state.balances[i]) for i in range(num_validators)] # Process genesis activations - for validator in state.validator_registry: + for validator in state.validators: if validator.effective_balance >= spec.MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = spec.GENESIS_EPOCH validator.activation_epoch = spec.GENESIS_EPOCH genesis_active_index_root = hash_tree_root(spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)) - for index in range(spec.LATEST_ACTIVE_INDEX_ROOTS_LENGTH): - state.latest_active_index_roots[index] = genesis_active_index_root + for index in range(spec.ACTIVE_INDEX_ROOTS_LENGTH): + state.active_index_roots[index] = genesis_active_index_root return state diff --git a/test_libs/pyspec/eth2spec/test/helpers/proposer_slashings.py b/test_libs/pyspec/eth2spec/test/helpers/proposer_slashings.py index 86c6acf47..d5b7f7b7f 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/proposer_slashings.py +++ b/test_libs/pyspec/eth2spec/test/helpers/proposer_slashings.py @@ -7,7 +7,7 @@ from eth2spec.test.helpers.keys import pubkey_to_privkey def get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=False): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] slot = state.slot header_1 = spec.BeaconBlockHeader( diff --git a/test_libs/pyspec/eth2spec/test/helpers/state.py b/test_libs/pyspec/eth2spec/test/helpers/state.py index 63aa27d70..19a04b04f 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/state.py +++ b/test_libs/pyspec/eth2spec/test/helpers/state.py @@ -22,4 +22,4 @@ def get_state_root(spec, state, slot) -> bytes: Return the state root at a recent ``slot``. """ assert slot < state.slot <= slot + spec.SLOTS_PER_HISTORICAL_ROOT - return state.latest_state_roots[slot % spec.SLOTS_PER_HISTORICAL_ROOT] + return state.state_roots[slot % spec.SLOTS_PER_HISTORICAL_ROOT] diff --git a/test_libs/pyspec/eth2spec/test/helpers/transfers.py b/test_libs/pyspec/eth2spec/test/helpers/transfers.py index e619c5569..f7397ca38 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/transfers.py +++ b/test_libs/pyspec/eth2spec/test/helpers/transfers.py @@ -31,7 +31,7 @@ def get_valid_transfer(spec, state, slot=None, sender_index=None, amount=None, f sign_transfer(spec, state, transfer, transfer_privkey) # ensure withdrawal_credentials reproducible - state.validator_registry[transfer.sender].withdrawal_credentials = ( + state.validators[transfer.sender].withdrawal_credentials = ( spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:] ) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index 2b34ab405..6cd2d1194 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -31,17 +31,17 @@ def run_attestation_processing(spec, state, attestation, valid=True): yield 'post', None return - current_epoch_count = len(state.current_epoch_attestations) - previous_epoch_count = len(state.previous_epoch_attestations) + current_epoch_count = len(state.current_attestations) + previous_epoch_count = len(state.previous_attestations) # process attestation spec.process_attestation(state, attestation) # Make sure the attestation has been processed if attestation.data.target_epoch == spec.get_current_epoch(state): - assert len(state.current_epoch_attestations) == current_epoch_count + 1 + assert len(state.current_attestations) == current_epoch_count + 1 else: - assert len(state.previous_epoch_attestations) == previous_epoch_count + 1 + assert len(state.previous_attestations) == previous_epoch_count + 1 # yield post-state yield 'post', state diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py index 6c7637d59..c51f5a8a9 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py @@ -34,7 +34,7 @@ def run_attester_slashing_processing(spec, state, attester_slashing, valid=True) # Process slashing spec.process_attester_slashing(state, attester_slashing) - slashed_validator = state.validator_registry[slashed_index] + slashed_validator = state.validators[slashed_index] # Check slashing assert slashed_validator.slashed @@ -135,7 +135,7 @@ def test_participants_already_slashed(spec, state): attestation_1 = attester_slashing.attestation_1 validator_indices = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices for index in validator_indices: - state.validator_registry[index].slashed = True + state.validators[index].slashed = True yield from run_attester_slashing_processing(spec, state, attester_slashing, False) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py index f3c017982..a2306ef4d 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py @@ -78,7 +78,7 @@ def test_proposer_slashed(spec, state): proposer_index = spec.get_beacon_proposer_index(stub_state) # set proposer to slashed - state.validator_registry[proposer_index].slashed = True + state.validators[proposer_index].slashed = True block = build_empty_block_for_next_slot(spec, state, signed=True) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py index c50b11f2e..7efb57871 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py @@ -16,7 +16,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef - post-state ('post'). If ``valid == False``, run expecting ``AssertionError`` """ - pre_validator_count = len(state.validator_registry) + pre_validator_count = len(state.validators) pre_balance = 0 if validator_index < pre_validator_count: pre_balance = get_balance(state, validator_index) @@ -34,29 +34,29 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef yield 'post', state if not effective: - assert len(state.validator_registry) == pre_validator_count + assert len(state.validators) == pre_validator_count assert len(state.balances) == pre_validator_count if validator_index < pre_validator_count: assert get_balance(state, validator_index) == pre_balance else: if validator_index < pre_validator_count: # top-up - assert len(state.validator_registry) == pre_validator_count + assert len(state.validators) == pre_validator_count assert len(state.balances) == pre_validator_count else: # new validator - assert len(state.validator_registry) == pre_validator_count + 1 + assert len(state.validators) == pre_validator_count + 1 assert len(state.balances) == pre_validator_count + 1 assert get_balance(state, validator_index) == pre_balance + deposit.data.amount - assert state.deposit_index == state.latest_eth1_data.deposit_count + assert state.eth1_deposit_index == state.eth1_data.deposit_count @with_all_phases @spec_state_test def test_new_deposit(spec, state): # fresh deposit = next validator index = validator appended to registry - validator_index = len(state.validator_registry) + validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) @@ -68,7 +68,7 @@ def test_new_deposit(spec, state): @spec_state_test def test_invalid_sig_new_deposit(spec, state): # fresh deposit = next validator index = validator appended to registry - validator_index = len(state.validator_registry) + validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE deposit = prepare_state_and_deposit(spec, state, validator_index, amount) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=False) @@ -117,12 +117,12 @@ def test_invalid_withdrawal_credentials_top_up(spec, state): @with_all_phases @spec_state_test def test_wrong_index(spec, state): - validator_index = len(state.validator_registry) + validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE deposit = prepare_state_and_deposit(spec, state, validator_index, amount) - # mess up deposit_index - deposit.index = state.deposit_index + 1 + # mess up eth1_deposit_index + deposit.index = state.eth1_deposit_index + 1 sign_deposit_data(spec, state, deposit.data, privkeys[validator_index]) @@ -132,7 +132,7 @@ def test_wrong_index(spec, state): @with_all_phases @spec_state_test def test_wrong_deposit_for_deposit_count(spec, state): - deposit_data_leaves = [spec.ZERO_HASH] * len(state.validator_registry) + deposit_data_leaves = [spec.ZERO_HASH] * len(state.validators) # build root for deposit_1 index_1 = len(deposit_data_leaves) @@ -166,8 +166,8 @@ def test_wrong_deposit_for_deposit_count(spec, state): ) # state has root for deposit_2 but is at deposit_count for deposit_1 - state.latest_eth1_data.deposit_root = root_2 - state.latest_eth1_data.deposit_count = deposit_count_1 + state.eth1_data.deposit_root = root_2 + state.eth1_data.deposit_count = deposit_count_1 yield from run_deposit_processing(spec, state, deposit_2, index_2, valid=False) @@ -178,7 +178,7 @@ def test_wrong_deposit_for_deposit_count(spec, state): @with_all_phases @spec_state_test def test_bad_merkle_proof(spec, state): - validator_index = len(state.validator_registry) + validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE deposit = prepare_state_and_deposit(spec, state, validator_index, amount) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py index b35241859..af34ea709 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py @@ -28,7 +28,7 @@ def run_proposer_slashing_processing(spec, state, proposer_slashing, valid=True) yield 'post', state # check if slashed - slashed_validator = state.validator_registry[proposer_slashing.proposer_index] + slashed_validator = state.validators[proposer_slashing.proposer_index] assert slashed_validator.slashed assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH @@ -77,7 +77,7 @@ def test_invalid_sig_1_and_2(spec, state): def test_invalid_proposer_index(spec, state): proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) # Index just too high (by 1) - proposer_slashing.proposer_index = len(state.validator_registry) + proposer_slashing.proposer_index = len(state.validators) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) @@ -111,7 +111,7 @@ def test_proposer_is_not_activated(spec, state): proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) # set proposer to be not active yet - state.validator_registry[proposer_slashing.proposer_index].activation_epoch = spec.get_current_epoch(state) + 1 + state.validators[proposer_slashing.proposer_index].activation_epoch = spec.get_current_epoch(state) + 1 yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) @@ -122,7 +122,7 @@ def test_proposer_is_slashed(spec, state): proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) # set proposer to slashed - state.validator_registry[proposer_slashing.proposer_index].slashed = True + state.validators[proposer_slashing.proposer_index].slashed = True yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) @@ -137,6 +137,6 @@ def test_proposer_is_withdrawn(spec, state): # set proposer withdrawable_epoch in past current_epoch = spec.get_current_epoch(state) proposer_index = proposer_slashing.proposer_index - state.validator_registry[proposer_index].withdrawable_epoch = current_epoch - 1 + state.validators[proposer_index].withdrawable_epoch = current_epoch - 1 yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_transfer.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_transfer.py index 1294ca84a..e9d282b3a 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_transfer.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_transfer.py @@ -41,7 +41,7 @@ def run_transfer_processing(spec, state, transfer, valid=True): def test_success_non_activated(spec, state): transfer = get_valid_transfer(spec, state, signed=True) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer) @@ -55,7 +55,7 @@ def test_success_withdrawable(spec, state): transfer = get_valid_transfer(spec, state, signed=True) # withdrawable_epoch in past so can transfer - state.validator_registry[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1 + state.validators[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1 yield from run_transfer_processing(spec, state, transfer) @@ -86,7 +86,7 @@ def test_success_active_above_max_effective_fee(spec, state): def test_invalid_signature(spec, state): transfer = get_valid_transfer(spec, state) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -107,7 +107,7 @@ def test_active_but_transfer_past_effective_balance(spec, state): def test_incorrect_slot(spec, state): transfer = get_valid_transfer(spec, state, slot=state.slot + 1, signed=True) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -120,7 +120,7 @@ def test_insufficient_balance_for_fee(spec, state): transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=0, fee=1, signed=True) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -133,7 +133,7 @@ def test_insufficient_balance(spec, state): transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -153,7 +153,7 @@ def test_no_dust_sender(spec, state): ) # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -167,7 +167,7 @@ def test_no_dust_recipient(spec, state): state.balances[transfer.recipient] = 0 # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) @@ -176,9 +176,9 @@ def test_no_dust_recipient(spec, state): @spec_state_test def test_invalid_pubkey(spec, state): transfer = get_valid_transfer(spec, state, signed=True) - state.validator_registry[transfer.sender].withdrawal_credentials = spec.ZERO_HASH + state.validators[transfer.sender].withdrawal_credentials = spec.ZERO_HASH # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH yield from run_transfer_processing(spec, state, transfer, False) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py index 3359c5e78..33cacc4e2 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py @@ -21,14 +21,14 @@ def run_voluntary_exit_processing(spec, state, voluntary_exit, valid=True): yield 'post', None return - pre_exit_epoch = state.validator_registry[validator_index].exit_epoch + pre_exit_epoch = state.validators[validator_index].exit_epoch spec.process_voluntary_exit(state, voluntary_exit) yield 'post', state assert pre_exit_epoch == spec.FAR_FUTURE_EPOCH - assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH + assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH @with_all_phases @@ -39,7 +39,7 @@ def test_success(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey, signed=True) @@ -55,7 +55,7 @@ def test_invalid_signature(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey) @@ -76,7 +76,7 @@ def test_success_exit_queue(spec, state): # Prepare a bunch of exits, based on the current state exit_queue = [] for index in initial_indices: - privkey = pubkey_to_privkey[state.validator_registry[index].pubkey] + privkey = pubkey_to_privkey[state.validators[index].pubkey] exit_queue.append(build_voluntary_exit( spec, state, @@ -94,7 +94,7 @@ def test_success_exit_queue(spec, state): # exit an additional validator validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit( spec, state, @@ -109,8 +109,8 @@ def test_success_exit_queue(spec, state): yield from run_voluntary_exit_processing(spec, state, voluntary_exit) assert ( - state.validator_registry[validator_index].exit_epoch == - state.validator_registry[initial_indices[0]].exit_epoch + 1 + state.validators[validator_index].exit_epoch == + state.validators[initial_indices[0]].exit_epoch + 1 ) @@ -122,7 +122,7 @@ def test_validator_exit_in_future(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit( spec, @@ -146,7 +146,7 @@ def test_validator_invalid_validator_index(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit( spec, @@ -156,7 +156,7 @@ def test_validator_invalid_validator_index(spec, state): privkey, signed=False, ) - voluntary_exit.validator_index = len(state.validator_registry) + voluntary_exit.validator_index = len(state.validators) sign_voluntary_exit(spec, state, voluntary_exit, privkey) yield from run_voluntary_exit_processing(spec, state, voluntary_exit, False) @@ -167,9 +167,9 @@ def test_validator_invalid_validator_index(spec, state): def test_validator_not_active(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] - state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH # build and test voluntary exit voluntary_exit = build_voluntary_exit( @@ -192,10 +192,10 @@ def test_validator_already_exited(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] # but validator already has exited - state.validator_registry[validator_index].exit_epoch = current_epoch + 2 + state.validators[validator_index].exit_epoch = current_epoch + 2 voluntary_exit = build_voluntary_exit( spec, @@ -214,7 +214,7 @@ def test_validator_already_exited(spec, state): def test_validator_not_active_long_enough(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] + privkey = pubkey_to_privkey[state.validators[validator_index].pubkey] voluntary_exit = build_voluntary_exit( spec, @@ -226,7 +226,7 @@ def test_validator_not_active_long_enough(spec, state): ) assert ( - current_epoch - state.validator_registry[validator_index].activation_epoch < + current_epoch - state.validators[validator_index].activation_epoch < spec.PERSISTENT_COMMITTEE_PERIOD ) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py index 65d958678..cd4532457 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py @@ -56,7 +56,7 @@ def test_single_crosslink_update_from_current_epoch(spec, state): fill_aggregate_attestation(spec, state, attestation) add_attestation_to_state(spec, state, attestation, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) - assert len(state.current_epoch_attestations) == 1 + assert len(state.current_attestations) == 1 shard = attestation.data.crosslink.shard pre_crosslink = deepcopy(state.current_crosslinks[shard]) @@ -77,7 +77,7 @@ def test_single_crosslink_update_from_previous_epoch(spec, state): fill_aggregate_attestation(spec, state, attestation) add_attestation_to_state(spec, state, attestation, state.slot + spec.SLOTS_PER_EPOCH) - assert len(state.previous_epoch_attestations) == 1 + assert len(state.previous_attestations) == 1 shard = attestation.data.crosslink.shard pre_crosslink = deepcopy(state.current_crosslinks[shard]) @@ -130,8 +130,8 @@ def test_double_late_crosslink(spec, state): next_epoch(spec, state) add_attestation_to_state(spec, state, attestation_2, state.slot + 1) - assert len(state.previous_epoch_attestations) == 1 - assert len(state.current_epoch_attestations) == 0 + assert len(state.previous_attestations) == 1 + assert len(state.current_attestations) == 0 crosslink_deltas = spec.get_crosslink_deltas(state) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py index e6679f844..6863af3b1 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py @@ -35,23 +35,23 @@ def run_process_registry_updates(spec, state, valid=True): @spec_state_test def test_activation(spec, state): index = 0 - assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) + assert spec.is_active_validator(state.validators[index], spec.get_current_epoch(state)) # Mock a new deposit - state.validator_registry[index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH - state.validator_registry[index].activation_epoch = spec.FAR_FUTURE_EPOCH - state.validator_registry[index].effective_balance = spec.MAX_EFFECTIVE_BALANCE - assert not spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) + state.validators[index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH + state.validators[index].activation_epoch = spec.FAR_FUTURE_EPOCH + state.validators[index].effective_balance = spec.MAX_EFFECTIVE_BALANCE + assert not spec.is_active_validator(state.validators[index], spec.get_current_epoch(state)) for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): next_epoch(spec, state) yield from run_process_registry_updates(spec, state) - assert state.validator_registry[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH - assert state.validator_registry[index].activation_epoch != spec.FAR_FUTURE_EPOCH + assert state.validators[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH + assert state.validators[index].activation_epoch != spec.FAR_FUTURE_EPOCH assert spec.is_active_validator( - state.validator_registry[index], + state.validators[index], spec.get_current_epoch(state), ) @@ -60,19 +60,19 @@ def test_activation(spec, state): @spec_state_test def test_ejection(spec, state): index = 0 - assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) - assert state.validator_registry[index].exit_epoch == spec.FAR_FUTURE_EPOCH + assert spec.is_active_validator(state.validators[index], spec.get_current_epoch(state)) + assert state.validators[index].exit_epoch == spec.FAR_FUTURE_EPOCH # Mock an ejection - state.validator_registry[index].effective_balance = spec.EJECTION_BALANCE + state.validators[index].effective_balance = spec.EJECTION_BALANCE for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): next_epoch(spec, state) yield from run_process_registry_updates(spec, state) - assert state.validator_registry[index].exit_epoch != spec.FAR_FUTURE_EPOCH + assert state.validators[index].exit_epoch != spec.FAR_FUTURE_EPOCH assert not spec.is_active_validator( - state.validator_registry[index], + state.validators[index], spec.get_current_epoch(state), ) diff --git a/test_libs/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py b/test_libs/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py index 110231d77..87297d443 100644 --- a/test_libs/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py +++ b/test_libs/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py @@ -24,7 +24,7 @@ def run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, v spec.process_early_derived_secret_reveal(state, randao_key_reveal) - slashed_validator = state.validator_registry[randao_key_reveal.revealed_index] + slashed_validator = state.validators[randao_key_reveal.revealed_index] if randao_key_reveal.epoch >= spec.get_current_epoch(state) + spec.CUSTODY_PERIOD_TO_RANDAO_PADDING: assert slashed_validator.slashed @@ -111,7 +111,7 @@ def test_double_reveal(spec, state): @spec_state_test def test_revealer_is_slashed(spec, state): randao_key_reveal = get_valid_early_derived_secret_reveal(spec, state, spec.get_current_epoch(state)) - state.validator_registry[randao_key_reveal.revealed_index].slashed = True + state.validators[randao_key_reveal.revealed_index].slashed = True yield from run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, False) diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py index 587c37742..a5079b901 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py @@ -91,7 +91,7 @@ def test_empty_epoch_transition(spec, state): # assert state.slot == block.slot # assert state.finalized_epoch < spec.get_current_epoch(state) - 4 -# for index in range(len(state.validator_registry)): +# for index in range(len(state.validators)): # assert get_balance(state, index) < get_balance(pre_state, index) @@ -103,7 +103,7 @@ def test_proposer_slashing(spec, state): proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) validator_index = proposer_slashing.proposer_index - assert not state.validator_registry[validator_index].slashed + assert not state.validators[validator_index].slashed yield 'pre', state @@ -119,7 +119,7 @@ def test_proposer_slashing(spec, state): yield 'post', state # check if slashed - slashed_validator = state.validator_registry[validator_index] + slashed_validator = state.validators[validator_index] assert slashed_validator.slashed assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH @@ -137,7 +137,7 @@ def test_attester_slashing(spec, state): validator_index = (attester_slashing.attestation_1.custody_bit_0_indices + attester_slashing.attestation_1.custody_bit_1_indices)[0] - assert not state.validator_registry[validator_index].slashed + assert not state.validators[validator_index].slashed yield 'pre', state @@ -152,7 +152,7 @@ def test_attester_slashing(spec, state): spec.state_transition(state, block) yield 'post', state - slashed_validator = state.validator_registry[validator_index] + slashed_validator = state.validators[validator_index] assert slashed_validator.slashed assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH @@ -172,10 +172,10 @@ def test_attester_slashing(spec, state): @with_all_phases @spec_state_test def test_deposit_in_block(spec, state): - initial_registry_len = len(state.validator_registry) + initial_registry_len = len(state.validators) initial_balances_len = len(state.balances) - validator_index = len(state.validator_registry) + validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) @@ -190,10 +190,10 @@ def test_deposit_in_block(spec, state): spec.state_transition(state, block) yield 'post', state - assert len(state.validator_registry) == initial_registry_len + 1 + assert len(state.validators) == initial_registry_len + 1 assert len(state.balances) == initial_balances_len + 1 assert get_balance(state, validator_index) == spec.MAX_EFFECTIVE_BALANCE - assert state.validator_registry[validator_index].pubkey == pubkeys[validator_index] + assert state.validators[validator_index].pubkey == pubkeys[validator_index] @with_all_phases @@ -203,7 +203,7 @@ def test_deposit_top_up(spec, state): amount = spec.MAX_EFFECTIVE_BALANCE // 4 deposit = prepare_state_and_deposit(spec, state, validator_index, amount) - initial_registry_len = len(state.validator_registry) + initial_registry_len = len(state.validators) initial_balances_len = len(state.balances) validator_pre_balance = get_balance(state, validator_index) @@ -218,7 +218,7 @@ def test_deposit_top_up(spec, state): spec.state_transition(state, block) yield 'post', state - assert len(state.validator_registry) == initial_registry_len + assert len(state.validators) == initial_registry_len assert len(state.balances) == initial_balances_len assert get_balance(state, validator_index) == validator_pre_balance + amount @@ -233,17 +233,17 @@ def test_attestation(spec, state): attestation = get_valid_attestation(spec, state, signed=True) # Add to state via block transition - pre_current_attestations_len = len(state.current_epoch_attestations) + pre_current_attestations_len = len(state.current_attestations) attestation_block = build_empty_block_for_next_slot(spec, state) attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY attestation_block.body.attestations.append(attestation) sign_block(spec, state, attestation_block) spec.state_transition(state, attestation_block) - assert len(state.current_epoch_attestations) == pre_current_attestations_len + 1 + assert len(state.current_attestations) == pre_current_attestations_len + 1 - # Epoch transition should move to previous_epoch_attestations - pre_current_attestations_root = spec.hash_tree_root(state.current_epoch_attestations) + # Epoch transition should move to previous_attestations + pre_current_attestations_root = spec.hash_tree_root(state.current_attestations) epoch_block = build_empty_block_for_next_slot(spec, state) epoch_block.slot += spec.SLOTS_PER_EPOCH @@ -253,8 +253,8 @@ def test_attestation(spec, state): yield 'blocks', [attestation_block, epoch_block], List[spec.BeaconBlock] yield 'post', state - assert len(state.current_epoch_attestations) == 0 - assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root + assert len(state.current_attestations) == 0 + assert spec.hash_tree_root(state.previous_attestations) == pre_current_attestations_root @with_all_phases @@ -289,7 +289,7 @@ def test_voluntary_exit(spec, state): sign_block(spec, state, initiate_exit_block) spec.state_transition(state, initiate_exit_block) - assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH + assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH # Process within epoch transition exit_block = build_empty_block_for_next_slot(spec, state) @@ -300,7 +300,7 @@ def test_voluntary_exit(spec, state): yield 'blocks', [initiate_exit_block, exit_block], List[spec.BeaconBlock] yield 'post', state - assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH + assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH @with_all_phases @@ -317,7 +317,7 @@ def test_transfer(spec, state): pre_transfer_recipient_balance = get_balance(state, recipient_index) # un-activate so validator can transfer - state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH + state.validators[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH yield 'pre', state @@ -343,10 +343,10 @@ def test_balance_driven_status_transitions(spec, state): current_epoch = spec.get_current_epoch(state) validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH + assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH # set validator balance to below ejection threshold - state.validator_registry[validator_index].effective_balance = spec.EJECTION_BALANCE + state.validators[validator_index].effective_balance = spec.EJECTION_BALANCE yield 'pre', state @@ -359,7 +359,7 @@ def test_balance_driven_status_transitions(spec, state): yield 'blocks', [block], List[spec.BeaconBlock] yield 'post', state - assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH + assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH @with_all_phases