2018-11-28 19:49:03 +00:00
|
|
|
# beacon_chain
|
2020-01-15 11:42:13 +00:00
|
|
|
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
2018-11-28 19:49:03 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2018-11-28 19:49:03 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2020-04-22 05:53:02 +00:00
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
import
|
2019-12-04 10:49:59 +00:00
|
|
|
tables, algorithm, math, sequtils, options,
|
2020-06-03 13:52:02 +00:00
|
|
|
json_serialization/std/sets, chronicles,
|
|
|
|
../extras, ../ssz/merkleization,
|
2020-06-16 05:45:04 +00:00
|
|
|
./crypto, ./datatypes, ./digest, ./helpers, ./signatures, ./validator,
|
2019-12-20 16:14:43 +00:00
|
|
|
../../nbench/bench_lab
|
2018-11-28 19:49:03 +00:00
|
|
|
|
2020-06-18 13:10:25 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#is_valid_merkle_branch
|
2019-12-20 16:14:43 +00:00
|
|
|
func is_valid_merkle_branch*(leaf: Eth2Digest, branch: openarray[Eth2Digest], depth: uint64, index: uint64, root: Eth2Digest): bool {.nbench.}=
|
2019-08-26 07:57:09 +00:00
|
|
|
## Check if ``leaf`` at ``index`` verifies against the Merkle ``root`` and
|
|
|
|
## ``branch``.
|
2019-03-18 15:42:42 +00:00
|
|
|
var
|
|
|
|
value = leaf
|
|
|
|
buf: array[64, byte]
|
|
|
|
|
|
|
|
for i in 0 ..< depth.int:
|
|
|
|
if (index div (1'u64 shl i)) mod 2 != 0:
|
2019-08-26 07:57:09 +00:00
|
|
|
buf[0..31] = branch[i.int].data
|
2019-03-18 15:42:42 +00:00
|
|
|
buf[32..63] = value.data
|
|
|
|
else:
|
|
|
|
buf[0..31] = value.data
|
2019-08-26 07:57:09 +00:00
|
|
|
buf[32..63] = branch[i.int].data
|
2020-06-16 12:16:43 +00:00
|
|
|
value = eth2digest(buf)
|
2019-03-18 15:42:42 +00:00
|
|
|
value == root
|
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#increase_balance
|
2019-05-09 12:27:37 +00:00
|
|
|
func increase_balance*(
|
|
|
|
state: var BeaconState, index: ValidatorIndex, delta: Gwei) =
|
2019-07-01 07:53:42 +00:00
|
|
|
# Increase the validator balance at index ``index`` by ``delta``.
|
2019-05-09 12:27:37 +00:00
|
|
|
state.balances[index] += delta
|
2019-03-08 17:44:31 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#decrease_balance
|
2019-05-09 12:27:37 +00:00
|
|
|
func decrease_balance*(
|
|
|
|
state: var BeaconState, index: ValidatorIndex, delta: Gwei) =
|
2020-06-19 11:48:23 +00:00
|
|
|
# Decrease the validator balance at index ``index`` by ``delta``, with
|
|
|
|
# underflow protection.
|
2019-05-09 12:27:37 +00:00
|
|
|
state.balances[index] =
|
|
|
|
if delta > state.balances[index]:
|
|
|
|
0'u64
|
|
|
|
else:
|
|
|
|
state.balances[index] - delta
|
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#deposits
|
2020-07-07 23:02:14 +00:00
|
|
|
proc process_deposit*(preset: RuntimePreset,
|
|
|
|
state: var BeaconState,
|
|
|
|
deposit: Deposit,
|
2020-07-08 12:36:03 +00:00
|
|
|
flags: UpdateFlags = {}): Result[void, cstring] {.nbench.}=
|
2019-05-09 12:27:37 +00:00
|
|
|
# Process an Eth1 deposit, registering a validator or increasing its balance.
|
2019-03-18 15:42:42 +00:00
|
|
|
|
|
|
|
# Verify the Merkle branch
|
2020-06-18 05:56:47 +00:00
|
|
|
if not is_valid_merkle_branch(
|
2020-01-28 21:24:45 +00:00
|
|
|
hash_tree_root(deposit.data),
|
|
|
|
deposit.proof,
|
2020-04-06 18:18:42 +00:00
|
|
|
DEPOSIT_CONTRACT_TREE_DEPTH + 1, # Add 1 for the `List` length mix-in
|
2020-01-28 21:24:45 +00:00
|
|
|
state.eth1_deposit_index,
|
2019-07-01 09:42:37 +00:00
|
|
|
state.eth1_data.deposit_root,
|
2019-05-09 12:27:37 +00:00
|
|
|
):
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_deposit: deposit Merkle validation failed")
|
2019-05-09 12:27:37 +00:00
|
|
|
|
|
|
|
# Deposits must be processed in order
|
2019-07-01 09:42:37 +00:00
|
|
|
state.eth1_deposit_index += 1
|
2018-12-27 23:40:22 +00:00
|
|
|
|
2019-03-08 17:44:31 +00:00
|
|
|
let
|
2019-05-09 12:27:37 +00:00
|
|
|
pubkey = deposit.data.pubkey
|
|
|
|
amount = deposit.data.amount
|
2019-07-01 09:13:14 +00:00
|
|
|
validator_pubkeys = mapIt(state.validators, it.pubkey)
|
2019-05-09 12:27:37 +00:00
|
|
|
index = validator_pubkeys.find(pubkey)
|
|
|
|
|
|
|
|
if index == -1:
|
2020-04-06 18:18:42 +00:00
|
|
|
# Verify the deposit signature (proof of possession) which is not checked
|
|
|
|
# by the deposit contract
|
2020-06-16 05:45:04 +00:00
|
|
|
if skipBLSValidation notin flags:
|
2020-07-07 23:02:14 +00:00
|
|
|
if not verify_deposit_signature(preset, deposit.data):
|
2020-06-16 05:45:04 +00:00
|
|
|
# It's ok that deposits fail - they get included in blocks regardless
|
|
|
|
# TODO spec test?
|
2020-06-27 12:01:19 +00:00
|
|
|
# TODO: This is temporary set to trace level in order to deal with the
|
|
|
|
# large number of invalid deposits on Altona
|
|
|
|
trace "Skipping deposit with invalid signature",
|
2020-06-16 05:45:04 +00:00
|
|
|
deposit = shortLog(deposit.data)
|
2020-07-03 17:03:14 +00:00
|
|
|
return ok()
|
2019-05-09 12:27:37 +00:00
|
|
|
|
|
|
|
# Add validator and balance entries
|
2019-07-01 09:13:14 +00:00
|
|
|
state.validators.add(Validator(
|
2018-12-13 16:00:55 +00:00
|
|
|
pubkey: pubkey,
|
2019-05-09 12:27:37 +00:00
|
|
|
withdrawal_credentials: deposit.data.withdrawal_credentials,
|
|
|
|
activation_eligibility_epoch: FAR_FUTURE_EPOCH,
|
2019-01-29 03:22:22 +00:00
|
|
|
activation_epoch: FAR_FUTURE_EPOCH,
|
|
|
|
exit_epoch: FAR_FUTURE_EPOCH,
|
2019-02-19 23:07:56 +00:00
|
|
|
withdrawable_epoch: FAR_FUTURE_EPOCH,
|
2019-05-09 12:27:37 +00:00
|
|
|
effective_balance: min(amount - amount mod EFFECTIVE_BALANCE_INCREMENT,
|
|
|
|
MAX_EFFECTIVE_BALANCE)
|
|
|
|
))
|
2019-04-29 16:48:30 +00:00
|
|
|
state.balances.add(amount)
|
2018-12-13 16:00:55 +00:00
|
|
|
else:
|
2019-05-09 12:27:37 +00:00
|
|
|
# Increase balance by deposit amount
|
|
|
|
increase_balance(state, index.ValidatorIndex, amount)
|
2018-12-13 16:00:55 +00:00
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-03-24 18:21:23 +00:00
|
|
|
|
2020-06-12 19:37:28 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#compute_activation_exit_epoch
|
2020-07-15 10:44:18 +00:00
|
|
|
func compute_activation_exit_epoch*(epoch: Epoch): Epoch =
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
## Return the epoch during which validator activations and exits initiated in
|
|
|
|
## ``epoch`` take effect.
|
initial 0.9.0 spec sync (#509)
* rename compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* remove some unnecessary imports; remove some crosslink-related code and tests; complete renaming of compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* rm more transfer-related code and tests; rm more unnecessary strutils imports
* rm remaining unused imports
* remove useless get_empty_per_epoch_cache(...)/compute_start_slot_of_epoch(...) calls
* rename compute_start_slot_of_epoch(...) to compute_start_slot_at_epoch(...)
* rename ACTIVATION_EXIT_DELAY to MAX_SEED_LOOKAHEAD
* update domain types to 0.9.0
* mark AttesterSlashing, IndexedAttestation, AttestationDataAndCustodyBit, DepositData, BeaconBlockHeader, Fork, integer_squareroot(...), and process_voluntary_exit(...) as 0.9.0
* mark increase_balance(...), decrease_balance(...), get_block_root(...), CheckPoint, Deposit, PendingAttestation, HistoricalBatch, is_active_validator(...), and is_slashable_attestation_data(...) as 0.9.0
* mark compute_activation_exit_epoch(...), bls_verify(...), Validator, get_active_validator_indices(...), get_current_epoch(...), get_total_active_balance(...), and get_previous_epoch(...) as 0.9.0
* mark get_block_root_at_slot(...), ProposerSlashing, get_domain(...), VoluntaryExit, mainnet preset Gwei values, minimal preset max operations, process_block_header(...), and is_slashable_validator(...) as 0.9.0
* mark makeWithdrawalCredentials(...), get_validator_churn_limit(...), get_total_balance(...), is_valid_indexed_attestation(...), bls_aggregate_pubkeys(...), initial genesis value/constants, Attestation, get_randao_mix(...), mainnet preset max operations per block constants, minimal preset Gwei values and time parameters, process_eth1_data(...), get_shuffled_seq(...), compute_committee(...), and process_slots(...) as 0.9.0; partially update get_indexed_attestation(...) to 0.9.0 by removing crosslink refs and associated tests
* mark initiate_validator_exit(...), process_registry_updates(...), BeaconBlock, Eth1Data, compute_domain(...), process_randao(...), process_attester_slashing(...), get_base_reward(...), and process_slot(...) as 0.9.0
2019-10-30 19:41:19 +00:00
|
|
|
epoch + 1 + MAX_SEED_LOOKAHEAD
|
2019-01-29 03:22:22 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_validator_churn_limit
|
2020-07-13 14:44:58 +00:00
|
|
|
func get_validator_churn_limit(state: BeaconState, cache: var StateCache): uint64 =
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
# Return the validator churn limit for the current epoch.
|
|
|
|
max(MIN_PER_EPOCH_CHURN_LIMIT,
|
2020-07-13 14:44:58 +00:00
|
|
|
len(cache.shuffled_active_validator_indices).uint64 div CHURN_LIMIT_QUOTIENT)
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#initiate_validator_exit
|
2019-02-22 17:53:37 +00:00
|
|
|
func initiate_validator_exit*(state: var BeaconState,
|
2020-06-03 05:42:08 +00:00
|
|
|
index: ValidatorIndex, cache: var StateCache) =
|
2019-07-01 07:53:42 +00:00
|
|
|
# Initiate the exit of the validator with index ``index``.
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
|
|
|
# Return if validator already initiated exit
|
2019-07-01 09:13:14 +00:00
|
|
|
let validator = addr state.validators[index]
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
|
|
|
return
|
|
|
|
|
|
|
|
# Compute exit queue epoch
|
2019-09-03 18:02:21 +00:00
|
|
|
var exit_epochs = mapIt(
|
2019-07-01 09:13:14 +00:00
|
|
|
filterIt(state.validators, it.exit_epoch != FAR_FUTURE_EPOCH),
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
it.exit_epoch)
|
2019-09-03 18:02:21 +00:00
|
|
|
exit_epochs.add compute_activation_exit_epoch(get_current_epoch(state))
|
|
|
|
var exit_queue_epoch = max(exit_epochs)
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
let exit_queue_churn = foldl(
|
2019-07-01 09:13:14 +00:00
|
|
|
state.validators,
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
a + (if b.exit_epoch == exit_queue_epoch: 1'u64 else: 0'u64),
|
|
|
|
0'u64)
|
|
|
|
|
2020-06-03 05:42:08 +00:00
|
|
|
if exit_queue_churn >= get_validator_churn_limit(state, cache):
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
exit_queue_epoch += 1
|
|
|
|
|
|
|
|
# Set validator exit epoch and withdrawable epoch
|
|
|
|
validator.exit_epoch = exit_queue_epoch
|
|
|
|
validator.withdrawable_epoch =
|
2019-07-02 21:14:55 +00:00
|
|
|
validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
2018-12-13 16:00:55 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#slash_validator
|
2019-11-25 08:22:16 +00:00
|
|
|
proc slash_validator*(state: var BeaconState, slashed_index: ValidatorIndex,
|
2020-06-03 05:42:08 +00:00
|
|
|
cache: var StateCache) =
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
# Slash the validator with index ``index``.
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
let epoch = get_current_epoch(state)
|
2020-06-03 05:42:08 +00:00
|
|
|
initiate_validator_exit(state, slashed_index, cache)
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
let validator = addr state.validators[slashed_index]
|
2019-11-25 08:22:16 +00:00
|
|
|
|
|
|
|
debug "slash_validator: ejecting validator via slashing (validator_leaving)",
|
|
|
|
index = slashed_index,
|
|
|
|
num_validators = state.validators.len,
|
|
|
|
current_epoch = get_current_epoch(state),
|
|
|
|
validator_slashed = validator.slashed,
|
|
|
|
validator_withdrawable_epoch = validator.withdrawable_epoch,
|
|
|
|
validator_exit_epoch = validator.exit_epoch,
|
|
|
|
validator_effective_balance = validator.effective_balance
|
|
|
|
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
validator.slashed = true
|
|
|
|
validator.withdrawable_epoch =
|
|
|
|
max(validator.withdrawable_epoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR)
|
2020-06-12 16:43:20 +00:00
|
|
|
state.slashings[int(epoch mod EPOCHS_PER_SLASHINGS_VECTOR)] +=
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
validator.effective_balance
|
|
|
|
decrease_balance(state, slashed_index,
|
|
|
|
validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT)
|
2019-02-20 20:35:27 +00:00
|
|
|
|
2019-12-04 10:49:59 +00:00
|
|
|
# The rest doesn't make sense without there being any proposer index, so skip
|
2020-06-03 05:42:08 +00:00
|
|
|
let proposer_index = get_beacon_proposer_index(state, cache)
|
2019-12-04 10:49:59 +00:00
|
|
|
if proposer_index.isNone:
|
|
|
|
debug "No beacon proposer index and probably no active validators"
|
|
|
|
return
|
|
|
|
|
2020-07-08 08:56:25 +00:00
|
|
|
# Apply proposer and whistleblower rewards
|
2019-01-29 03:22:22 +00:00
|
|
|
let
|
2019-06-12 07:48:49 +00:00
|
|
|
# Spec has whistleblower_index as optional param, but it's never used.
|
2019-12-04 10:49:59 +00:00
|
|
|
whistleblower_index = proposer_index.get
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
whistleblowing_reward =
|
|
|
|
(validator.effective_balance div WHISTLEBLOWER_REWARD_QUOTIENT).Gwei
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
proposer_reward = whistleblowing_reward div PROPOSER_REWARD_QUOTIENT
|
2019-12-04 10:49:59 +00:00
|
|
|
increase_balance(state, proposer_index.get, proposer_reward)
|
2019-09-10 22:03:06 +00:00
|
|
|
# TODO: evaluate if spec bug / underflow can be triggered
|
|
|
|
doAssert(whistleblowing_reward >= proposer_reward, "Spec bug: underflow in slash_validator")
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
increase_balance(
|
|
|
|
state, whistleblower_index, whistleblowing_reward - proposer_reward)
|
2019-01-16 13:39:34 +00:00
|
|
|
|
2020-07-07 23:02:14 +00:00
|
|
|
func genesis_time_from_eth1_timestamp*(preset: RuntimePreset, eth1_timestamp: uint64): uint64 =
|
2020-06-27 12:01:19 +00:00
|
|
|
# TODO: remove once we switch completely to v0.12.1
|
|
|
|
when SPEC_VERSION == "0.12.1":
|
2020-07-07 23:02:14 +00:00
|
|
|
eth1_timestamp + preset.GENESIS_DELAY
|
2020-06-27 12:01:19 +00:00
|
|
|
else:
|
|
|
|
const SECONDS_PER_DAY = uint64(60*60*24)
|
|
|
|
eth1_timestamp + 2'u64 * SECONDS_PER_DAY - (eth1_timestamp mod SECONDS_PER_DAY)
|
|
|
|
|
2020-06-25 14:24:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#genesis
|
2020-04-06 18:18:42 +00:00
|
|
|
proc initialize_beacon_state_from_eth1*(
|
2020-07-07 23:02:14 +00:00
|
|
|
preset: RuntimePreset,
|
2019-09-02 10:31:14 +00:00
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[Deposit],
|
2020-06-27 12:01:19 +00:00
|
|
|
flags: UpdateFlags = {}): BeaconStateRef {.nbench.} =
|
2019-02-22 09:56:45 +00:00
|
|
|
## Get the genesis ``BeaconState``.
|
2018-11-29 05:23:40 +00:00
|
|
|
##
|
|
|
|
## Before the beacon chain starts, validators will register in the Eth1 chain
|
|
|
|
## and deposit ETH. When enough many validators have registered, a
|
|
|
|
## `ChainStart` log will be emitted and the beacon chain can start beaconing.
|
|
|
|
##
|
|
|
|
## Because the state root hash is part of the genesis block, the beacon state
|
|
|
|
## must be calculated before creating the genesis block.
|
2018-12-13 16:00:55 +00:00
|
|
|
|
2018-11-29 05:23:40 +00:00
|
|
|
# Induct validators
|
2019-02-20 01:33:58 +00:00
|
|
|
# Not in spec: the system doesn't work unless there are at least SLOTS_PER_EPOCH
|
2018-11-29 22:11:05 +00:00
|
|
|
# validators - there needs to be at least one member in each committee -
|
|
|
|
# good to know for testing, though arguably the system is not that useful at
|
|
|
|
# at that point :)
|
2020-07-13 14:44:58 +00:00
|
|
|
doAssert deposits.len >= SLOTS_PER_EPOCH.int
|
2018-11-29 05:23:40 +00:00
|
|
|
|
2020-04-23 18:58:54 +00:00
|
|
|
var state = BeaconStateRef(
|
2020-04-06 18:18:42 +00:00
|
|
|
fork: Fork(
|
2020-07-07 23:02:14 +00:00
|
|
|
previous_version: preset.GENESIS_FORK_VERSION,
|
|
|
|
current_version: preset.GENESIS_FORK_VERSION,
|
2020-04-06 18:18:42 +00:00
|
|
|
epoch: GENESIS_EPOCH),
|
2020-07-07 23:02:14 +00:00
|
|
|
genesis_time: genesis_time_from_eth1_timestamp(preset, eth1_timestamp),
|
2019-09-02 10:31:14 +00:00
|
|
|
eth1_data:
|
|
|
|
Eth1Data(block_hash: eth1_block_hash, deposit_count: uint64(len(deposits))),
|
2019-07-10 12:23:02 +00:00
|
|
|
latest_block_header:
|
2019-09-08 00:56:24 +00:00
|
|
|
BeaconBlockHeader(
|
2019-09-08 18:27:09 +00:00
|
|
|
body_root: hash_tree_root(BeaconBlockBody(
|
2020-06-25 14:24:55 +00:00
|
|
|
# This differs from the spec intentionally.
|
|
|
|
# We must specify the default value for `ValidatorSig`
|
|
|
|
# in order to get a correct `hash_tree_root`.
|
2020-03-04 21:27:11 +00:00
|
|
|
randao_reveal: ValidatorSig(kind: OpaqueBlob)
|
2019-12-16 18:08:50 +00:00
|
|
|
))
|
2019-09-08 00:56:24 +00:00
|
|
|
)
|
2018-11-29 05:23:40 +00:00
|
|
|
)
|
|
|
|
|
2019-11-21 09:15:10 +00:00
|
|
|
# Seed RANDAO with Eth1 entropy
|
|
|
|
state.randao_mixes.fill(eth1_block_hash)
|
|
|
|
|
2019-07-10 12:23:02 +00:00
|
|
|
# Process deposits
|
2019-11-25 11:46:47 +00:00
|
|
|
let
|
|
|
|
leaves = deposits.mapIt(it.data)
|
2019-11-25 13:13:12 +00:00
|
|
|
var i = 0
|
|
|
|
for prefix_root in hash_tree_roots_prefix(
|
|
|
|
leaves, 2'i64^DEPOSIT_CONTRACT_TREE_DEPTH):
|
|
|
|
state.eth1_data.deposit_root = prefix_root
|
2020-07-07 23:02:14 +00:00
|
|
|
discard process_deposit(preset, state[], deposits[i], flags)
|
2019-11-25 13:13:12 +00:00
|
|
|
i += 1
|
2019-01-16 12:20:44 +00:00
|
|
|
|
2019-07-10 12:23:02 +00:00
|
|
|
# Process activations
|
2019-07-01 09:13:14 +00:00
|
|
|
for validator_index in 0 ..< state.validators.len:
|
2019-09-02 10:31:14 +00:00
|
|
|
let
|
|
|
|
balance = state.balances[validator_index]
|
|
|
|
validator = addr state.validators[validator_index]
|
|
|
|
|
|
|
|
validator.effective_balance = min(
|
|
|
|
balance - balance mod EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE)
|
|
|
|
|
|
|
|
if validator.effective_balance == MAX_EFFECTIVE_BALANCE:
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
|
|
|
validator.activation_epoch = GENESIS_EPOCH
|
2018-12-13 16:00:55 +00:00
|
|
|
|
2020-03-14 21:54:45 +00:00
|
|
|
# Set genesis validators root for domain separation and chain versioning
|
2020-05-18 17:49:22 +00:00
|
|
|
state.genesis_validators_root = hash_tree_root(state.validators)
|
2020-03-14 21:54:45 +00:00
|
|
|
|
2018-12-13 16:00:55 +00:00
|
|
|
state
|
|
|
|
|
2020-04-30 06:44:19 +00:00
|
|
|
proc initialize_hashed_beacon_state_from_eth1*(
|
2020-07-07 23:02:14 +00:00
|
|
|
preset: RuntimePreset,
|
2020-04-30 06:44:19 +00:00
|
|
|
eth1_block_hash: Eth2Digest,
|
|
|
|
eth1_timestamp: uint64,
|
|
|
|
deposits: openArray[Deposit],
|
|
|
|
flags: UpdateFlags = {}): HashedBeaconState =
|
|
|
|
let genesisState = initialize_beacon_state_from_eth1(
|
2020-07-07 23:02:14 +00:00
|
|
|
preset, eth1_block_hash, eth1_timestamp, deposits, flags)
|
2020-04-30 09:01:55 +00:00
|
|
|
HashedBeaconState(data: genesisState[], root: hash_tree_root(genesisState[]))
|
2020-04-30 06:44:19 +00:00
|
|
|
|
2020-07-07 23:02:14 +00:00
|
|
|
func is_valid_genesis_state*(preset: RuntimePreset,
|
|
|
|
state: BeaconState,
|
|
|
|
active_validator_indices: seq[ValidatorIndex]): bool =
|
|
|
|
if state.genesis_time < preset.MIN_GENESIS_TIME:
|
2019-07-12 14:24:11 +00:00
|
|
|
return false
|
2020-06-03 05:42:08 +00:00
|
|
|
# This is an okay get_active_validator_indices(...) for the time being.
|
2020-07-07 23:02:14 +00:00
|
|
|
if active_validator_indices.len.uint64 < preset.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
2019-07-12 14:24:11 +00:00
|
|
|
return false
|
|
|
|
return true
|
|
|
|
|
2019-11-26 14:32:45 +00:00
|
|
|
# TODO this is now a non-spec helper function, and it's not really accurate
|
|
|
|
# so only usable/used in research/ and tests/
|
2019-12-16 18:08:50 +00:00
|
|
|
func get_initial_beacon_block*(state: BeaconState): SignedBeaconBlock =
|
2020-07-16 13:16:51 +00:00
|
|
|
let message = BeaconBlock(
|
2019-12-16 18:08:50 +00:00
|
|
|
slot: GENESIS_SLOT,
|
|
|
|
state_root: hash_tree_root(state),
|
|
|
|
body: BeaconBlockBody(
|
2019-09-08 18:27:09 +00:00
|
|
|
# TODO: This shouldn't be necessary if OpaqueBlob is the default
|
2020-07-16 13:16:51 +00:00
|
|
|
randao_reveal: ValidatorSig(kind: OpaqueBlob)))
|
2019-12-16 18:08:50 +00:00
|
|
|
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
|
|
|
# initialized to default values.
|
2020-07-16 13:16:51 +00:00
|
|
|
SignedBeaconBlock(message: message, root: hash_tree_root(message))
|
2019-09-08 18:27:09 +00:00
|
|
|
|
2020-06-12 19:37:28 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_block_root_at_slot
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
func get_block_root_at_slot*(state: BeaconState,
|
|
|
|
slot: Slot): Eth2Digest =
|
2019-02-13 10:26:32 +00:00
|
|
|
# Return the block root at a recent ``slot``.
|
|
|
|
|
2019-03-16 19:52:37 +00:00
|
|
|
doAssert state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
|
2018-12-14 16:12:39 +00:00
|
|
|
doAssert slot < state.slot
|
2019-07-01 07:53:42 +00:00
|
|
|
state.block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
|
2018-11-29 05:23:40 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_block_root
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
func get_block_root*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
2019-07-01 07:53:42 +00:00
|
|
|
# Return the block root at the start of a recent ``epoch``.
|
initial 0.9.0 spec sync (#509)
* rename compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* remove some unnecessary imports; remove some crosslink-related code and tests; complete renaming of compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* rm more transfer-related code and tests; rm more unnecessary strutils imports
* rm remaining unused imports
* remove useless get_empty_per_epoch_cache(...)/compute_start_slot_of_epoch(...) calls
* rename compute_start_slot_of_epoch(...) to compute_start_slot_at_epoch(...)
* rename ACTIVATION_EXIT_DELAY to MAX_SEED_LOOKAHEAD
* update domain types to 0.9.0
* mark AttesterSlashing, IndexedAttestation, AttestationDataAndCustodyBit, DepositData, BeaconBlockHeader, Fork, integer_squareroot(...), and process_voluntary_exit(...) as 0.9.0
* mark increase_balance(...), decrease_balance(...), get_block_root(...), CheckPoint, Deposit, PendingAttestation, HistoricalBatch, is_active_validator(...), and is_slashable_attestation_data(...) as 0.9.0
* mark compute_activation_exit_epoch(...), bls_verify(...), Validator, get_active_validator_indices(...), get_current_epoch(...), get_total_active_balance(...), and get_previous_epoch(...) as 0.9.0
* mark get_block_root_at_slot(...), ProposerSlashing, get_domain(...), VoluntaryExit, mainnet preset Gwei values, minimal preset max operations, process_block_header(...), and is_slashable_validator(...) as 0.9.0
* mark makeWithdrawalCredentials(...), get_validator_churn_limit(...), get_total_balance(...), is_valid_indexed_attestation(...), bls_aggregate_pubkeys(...), initial genesis value/constants, Attestation, get_randao_mix(...), mainnet preset max operations per block constants, minimal preset Gwei values and time parameters, process_eth1_data(...), get_shuffled_seq(...), compute_committee(...), and process_slots(...) as 0.9.0; partially update get_indexed_attestation(...) to 0.9.0 by removing crosslink refs and associated tests
* mark initiate_validator_exit(...), process_registry_updates(...), BeaconBlock, Eth1Data, compute_domain(...), process_randao(...), process_attester_slashing(...), get_base_reward(...), and process_slot(...) as 0.9.0
2019-10-30 19:41:19 +00:00
|
|
|
get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch))
|
More 0.6.1 updates (#274)
* implement get_churn_limit from 0.6.1; update initiate_validator_exit and get_previous_epoch to 0.6.1; remove obsoleted/non-spec reduce_balance, replaced by decrease_balance; mark BeaconBlock as 0.6.1
* rename get_block_root to get_block_root_at_slot and introduce epoch-oriented get_block_root; implement get_attestation_slot, get_matching_source_attestations, get_matching_target_attestations, get_matching_head_attestations, 0.6.1 get_attesting_indices, get_unslashed_attesting_indices, get_attestation_deltas, process_rewards_and_penalties; rm get_inactivity_penalty
* update Validator and processVoluntaryExits to 0.6.1; rm obsolete inclusion_slots/inclusion_distances
* rm removed activate_validator; mark DepositData, misc values, Gwei values, Randao processing, state caching as 0.6.1; update GENESIS_SLOT to 64, since it doesn't quite yet work at 0
* mark BeaconBlockHeader as 0.6.1; update BeaconBlockBody to 0.6.1; rename WHISTLEBLOWER_REWARD_QUOTIENT to WHISTLEBLOWING_REWARD_QUOTIENT; update slash_validator to 0.6.1
* implement 0.6.2 is_slashable_validator; update processProposerSlashings to 0.6.2; mark state caching as 0.6.2
* mark get_total_active_balance and process_slashings as 0.6.2; update get_base_reward to 0.6.2
* rm prepare_validator_for_withdrawal, process_exit_queue; mark mainnet misc constants as 0.6.2; update process block header to 0.6.2
* address mratsim's code review comment
2019-05-29 10:08:56 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_total_balance
|
2019-03-06 14:21:13 +00:00
|
|
|
func get_total_balance*(state: BeaconState, validators: auto): Gwei =
|
2020-03-30 11:31:44 +00:00
|
|
|
## Return the combined effective balance of the ``indices``.
|
|
|
|
## ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
2020-03-14 21:54:45 +00:00
|
|
|
## Math safe up to ~10B ETH, afterwhich this overflows uint64.
|
2020-03-30 11:31:44 +00:00
|
|
|
max(EFFECTIVE_BALANCE_INCREMENT,
|
2019-07-01 09:13:14 +00:00
|
|
|
foldl(validators, a + state.validators[b].effective_balance, 0'u64)
|
2019-06-14 16:21:04 +00:00
|
|
|
)
|
2019-02-22 18:46:45 +00:00
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue
|
2019-12-16 18:08:50 +00:00
|
|
|
func is_eligible_for_activation_queue(validator: Validator): bool =
|
|
|
|
# Check if ``validator`` is eligible to be placed into the activation queue.
|
|
|
|
validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
|
|
|
validator.effective_balance == MAX_EFFECTIVE_BALANCE
|
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#is_eligible_for_activation
|
2019-12-16 18:08:50 +00:00
|
|
|
func is_eligible_for_activation(state: BeaconState, validator: Validator):
|
|
|
|
bool =
|
|
|
|
# Check if ``validator`` is eligible for activation.
|
|
|
|
|
|
|
|
# Placement in queue is finalized
|
|
|
|
validator.activation_eligibility_epoch <= state.finalized_checkpoint.epoch and
|
|
|
|
# Has not yet been activated
|
|
|
|
validator.activation_epoch == FAR_FUTURE_EPOCH
|
|
|
|
|
2020-06-12 19:37:28 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#registry-updates
|
2020-06-03 05:42:08 +00:00
|
|
|
proc process_registry_updates*(state: var BeaconState,
|
|
|
|
cache: var StateCache) {.nbench.}=
|
2019-06-24 09:21:56 +00:00
|
|
|
## Process activation eligibility and ejections
|
|
|
|
## Try to avoid caching here, since this could easily become undefined
|
|
|
|
|
2019-12-02 15:32:53 +00:00
|
|
|
# Make visible, e.g.,
|
|
|
|
# https://github.com/status-im/nim-beacon-chain/pull/608
|
|
|
|
# https://github.com/sigp/lighthouse/pull/657
|
2019-12-10 14:20:40 +00:00
|
|
|
let epoch {.used.} = get_current_epoch(state)
|
2019-12-02 15:32:53 +00:00
|
|
|
trace "process_registry_updates validator balances",
|
|
|
|
balances=state.balances,
|
|
|
|
active_validator_indices=get_active_validator_indices(state, epoch),
|
|
|
|
epoch=epoch
|
|
|
|
|
2020-06-03 05:42:08 +00:00
|
|
|
# is_active_validator(...) is activation_epoch <= epoch < exit_epoch,
|
|
|
|
# and changes here to either activation_epoch or exit_epoch only take
|
|
|
|
# effect with a compute_activation_exit_epoch(...) delay of, based on
|
|
|
|
# the current epoch, 1 + MAX_SEED_LOOKAHEAD epochs ahead. Thus caches
|
|
|
|
# remain valid for this epoch through though this function along with
|
|
|
|
# the rest of the epoch transition.
|
2019-07-01 09:13:14 +00:00
|
|
|
for index, validator in state.validators:
|
2019-12-16 18:08:50 +00:00
|
|
|
if is_eligible_for_activation_queue(validator):
|
2019-07-01 09:13:14 +00:00
|
|
|
state.validators[index].activation_eligibility_epoch =
|
2019-12-16 18:08:50 +00:00
|
|
|
get_current_epoch(state) + 1
|
2018-12-27 20:14:37 +00:00
|
|
|
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
if is_active_validator(validator, get_current_epoch(state)) and
|
|
|
|
validator.effective_balance <= EJECTION_BALANCE:
|
2019-11-25 08:22:16 +00:00
|
|
|
debug "Registry updating: ejecting validator due to low balance (validator_leaving)",
|
|
|
|
index = index,
|
|
|
|
num_validators = state.validators.len,
|
|
|
|
current_epoch = get_current_epoch(state),
|
|
|
|
validator_slashed = validator.slashed,
|
|
|
|
validator_withdrawable_epoch = validator.withdrawable_epoch,
|
|
|
|
validator_exit_epoch = validator.exit_epoch,
|
|
|
|
validator_effective_balance = validator.effective_balance
|
2020-06-03 05:42:08 +00:00
|
|
|
initiate_validator_exit(state, index.ValidatorIndex, cache)
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
|
|
|
|
## Queue validators eligible for activation and not dequeued for activation
|
|
|
|
var activation_queue : seq[tuple[a: Epoch, b: int]] = @[]
|
2019-07-01 09:13:14 +00:00
|
|
|
for index, validator in state.validators:
|
2019-12-16 18:08:50 +00:00
|
|
|
if is_eligible_for_activation(state, validator):
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
activation_queue.add (
|
2019-07-01 09:13:14 +00:00
|
|
|
state.validators[index].activation_eligibility_epoch, index)
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
|
|
|
|
activation_queue.sort(system.cmp)
|
|
|
|
|
|
|
|
## Dequeued validators for activation up to churn limit (without resetting
|
|
|
|
## activation epoch)
|
2020-06-03 05:42:08 +00:00
|
|
|
let churn_limit = get_validator_churn_limit(state, cache)
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
for i, epoch_and_index in activation_queue:
|
|
|
|
if i.uint64 >= churn_limit:
|
|
|
|
break
|
|
|
|
let
|
2019-11-15 11:04:49 +00:00
|
|
|
(_, index) = epoch_and_index
|
2019-07-01 09:13:14 +00:00
|
|
|
validator = addr state.validators[index]
|
2019-12-16 18:08:50 +00:00
|
|
|
validator.activation_epoch =
|
|
|
|
compute_activation_exit_epoch(get_current_epoch(state))
|
2019-01-29 03:22:22 +00:00
|
|
|
|
2020-06-22 10:37:47 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
|
|
|
|
func is_valid_indexed_attestation*(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: BeaconState, indexed_attestation: SomeIndexedAttestation,
|
2020-01-30 21:03:47 +00:00
|
|
|
flags: UpdateFlags): bool =
|
2020-06-22 10:37:47 +00:00
|
|
|
# Check if ``indexed_attestation`` is not empty, has sorted and unique
|
|
|
|
# indices and has a valid aggregate signature.
|
|
|
|
|
|
|
|
template is_sorted_and_unique(s: untyped): bool =
|
|
|
|
for i in 1 ..< s.len:
|
|
|
|
if s[i - 1].uint64 >= s[i].uint64:
|
|
|
|
return false
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
# Not from spec, but this function gets used in front-line roles, not just
|
|
|
|
# behind firewall.
|
|
|
|
let num_validators = state.validators.len.uint64
|
|
|
|
if anyIt(indexed_attestation.attesting_indices, it >= num_validators):
|
|
|
|
trace "indexed attestation: not all indices valid validators"
|
|
|
|
return false
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2020-01-30 14:03:26 +00:00
|
|
|
# Verify indices are sorted and unique
|
2020-06-22 10:37:47 +00:00
|
|
|
let indices = indexed_attestation.attesting_indices.asSeq
|
|
|
|
if len(indices) == 0 or not is_sorted_and_unique(indices):
|
|
|
|
trace "indexed attestation: indices not sorted and unique"
|
2019-06-12 07:48:49 +00:00
|
|
|
return false
|
|
|
|
|
2019-06-14 07:50:14 +00:00
|
|
|
# Verify aggregate signature
|
2020-06-16 05:45:04 +00:00
|
|
|
if skipBLSValidation notin flags:
|
|
|
|
# TODO: fuse loops with blsFastAggregateVerify
|
|
|
|
let pubkeys = mapIt(indices, state.validators[it.int].pubkey)
|
|
|
|
if not verify_attestation_signature(
|
|
|
|
state.fork, state.genesis_validators_root, indexed_attestation.data,
|
|
|
|
pubkeys, indexed_attestation.signature):
|
2020-06-22 10:37:47 +00:00
|
|
|
trace "indexed attestation: signature verification failure"
|
2020-06-16 05:45:04 +00:00
|
|
|
return false
|
2019-11-21 09:57:59 +00:00
|
|
|
|
|
|
|
true
|
2019-06-12 07:48:49 +00:00
|
|
|
|
2020-07-08 20:36:26 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_attesting_indices
|
2019-06-12 07:48:49 +00:00
|
|
|
func get_attesting_indices*(state: BeaconState,
|
2019-09-06 19:58:38 +00:00
|
|
|
data: AttestationData,
|
2019-07-03 07:35:05 +00:00
|
|
|
bits: CommitteeValidatorsBits,
|
2019-06-24 09:21:56 +00:00
|
|
|
stateCache: var StateCache):
|
|
|
|
HashSet[ValidatorIndex] =
|
2019-09-06 19:58:38 +00:00
|
|
|
# Return the set of attesting indices corresponding to ``data`` and ``bits``.
|
2019-11-15 11:04:49 +00:00
|
|
|
result = initHashSet[ValidatorIndex]()
|
2020-04-15 09:01:36 +00:00
|
|
|
let committee = get_beacon_committee(
|
|
|
|
state, data.slot, data.index.CommitteeIndex, stateCache)
|
2020-04-24 07:16:40 +00:00
|
|
|
|
|
|
|
# This shouldn't happen if one begins with a valid BeaconState and applies
|
|
|
|
# valid updates, but one can construct a BeaconState where it does. Do not
|
|
|
|
# do anything here since the PendingAttestation wouldn't have made it past
|
2020-07-09 11:43:27 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#attestations
|
2020-04-24 07:16:40 +00:00
|
|
|
# which checks len(attestation.aggregation_bits) == len(committee) that in
|
|
|
|
# nim-beacon-chain lives in check_attestation(...).
|
|
|
|
# Addresses https://github.com/status-im/nim-beacon-chain/issues/922
|
|
|
|
if bits.len != committee.len:
|
|
|
|
trace "get_attesting_indices: inconsistent aggregation and committee length"
|
|
|
|
return
|
|
|
|
|
2019-06-12 07:48:49 +00:00
|
|
|
for i, index in committee:
|
2019-07-03 07:35:05 +00:00
|
|
|
if bits[i]:
|
2019-06-12 07:48:49 +00:00
|
|
|
result.incl index
|
|
|
|
|
2020-06-19 11:48:23 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_indexed_attestation
|
2020-03-31 18:39:02 +00:00
|
|
|
func get_indexed_attestation*(state: BeaconState, attestation: Attestation,
|
2019-06-24 09:21:56 +00:00
|
|
|
stateCache: var StateCache): IndexedAttestation =
|
2019-07-01 07:53:42 +00:00
|
|
|
# Return the indexed attestation corresponding to ``attestation``.
|
2019-06-12 07:48:49 +00:00
|
|
|
let
|
|
|
|
attesting_indices =
|
|
|
|
get_attesting_indices(
|
2019-07-01 07:53:42 +00:00
|
|
|
state, attestation.data, attestation.aggregation_bits, stateCache)
|
2019-06-12 07:48:49 +00:00
|
|
|
|
|
|
|
IndexedAttestation(
|
2019-11-13 11:30:11 +00:00
|
|
|
attesting_indices:
|
2020-07-13 14:44:58 +00:00
|
|
|
List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init(
|
2020-05-18 17:49:22 +00:00
|
|
|
sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)),
|
2019-06-12 07:48:49 +00:00
|
|
|
data: attestation.data,
|
2019-11-13 11:30:11 +00:00
|
|
|
signature: attestation.signature
|
2019-06-12 07:48:49 +00:00
|
|
|
)
|
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
func get_indexed_attestation*(state: BeaconState, attestation: TrustedAttestation,
|
|
|
|
stateCache: var StateCache): TrustedIndexedAttestation =
|
|
|
|
# Return the indexed attestation corresponding to ``attestation``.
|
|
|
|
let
|
|
|
|
attesting_indices =
|
|
|
|
get_attesting_indices(
|
|
|
|
state, attestation.data, attestation.aggregation_bits, stateCache)
|
|
|
|
|
|
|
|
TrustedIndexedAttestation(
|
|
|
|
attesting_indices:
|
2020-07-13 14:44:58 +00:00
|
|
|
List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init(
|
2020-06-25 10:23:10 +00:00
|
|
|
sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)),
|
|
|
|
data: attestation.data,
|
|
|
|
signature: attestation.signature
|
|
|
|
)
|
|
|
|
|
2020-06-10 06:58:12 +00:00
|
|
|
# Attestation validation
|
|
|
|
# ------------------------------------------------------------------------------------------
|
2020-05-20 08:46:31 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#attestations
|
2020-06-10 06:58:12 +00:00
|
|
|
#
|
|
|
|
# TODO: Refactor, we need:
|
|
|
|
# - cheap validations that do not involve the fork state (to avoid unnecessary and costly rewinding which are probably a DOS vector)
|
|
|
|
# - check that must be done on the targeted state (for example beacon committee consistency)
|
|
|
|
# - check that requires easily computed data from the targeted sate (slots, epoch, justified checkpoints)
|
|
|
|
|
|
|
|
proc isValidAttestationSlot*(attestationSlot, stateSlot: Slot): bool =
|
|
|
|
## Attestation check that does not depend on the whole block state
|
|
|
|
## for cheaper prefiltering of attestations that come from the network
|
|
|
|
## to limit DOS via state rewinding
|
|
|
|
|
|
|
|
if not (attestationSlot + MIN_ATTESTATION_INCLUSION_DELAY <= stateSlot):
|
|
|
|
warn("Attestation too new",
|
|
|
|
attestation_slot = shortLog(attestationSlot),
|
|
|
|
state_slot = shortLog(stateSlot))
|
|
|
|
return false
|
|
|
|
|
|
|
|
if not (stateSlot <= attestationSlot + SLOTS_PER_EPOCH):
|
|
|
|
warn("Attestation too old",
|
|
|
|
attestation_slot = shortLog(attestationSlot),
|
|
|
|
state_slot = shortLog(stateSlot))
|
|
|
|
return false
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
# TODO remove/merge with p2p-interface validation
|
|
|
|
proc isValidAttestationTargetEpoch*(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: BeaconState, data: AttestationData): bool =
|
2020-06-10 06:58:12 +00:00
|
|
|
# TODO what constitutes a valid attestation when it's about to be added to
|
|
|
|
# the pool? we're interested in attestations that will become viable
|
|
|
|
# for inclusion in blocks in the future and on any fork, so we need to
|
|
|
|
# consider that validations might happen using the state of a different
|
|
|
|
# fork.
|
|
|
|
# Some things are always invalid (like out-of-bounds issues etc), but
|
|
|
|
# others are more subtle - how do we validate the signature for example?
|
|
|
|
# It might be valid on one fork but not another. One thing that helps
|
|
|
|
# is that committees are stable per epoch and that it should be OK to
|
|
|
|
# include an attestation in a block even if the corresponding validator
|
|
|
|
# was slashed in the same epoch - there's no penalty for doing this and
|
|
|
|
# the vote counting logic will take care of any ill effects (TODO verify)
|
|
|
|
# TODO re-enable check
|
|
|
|
#if not (data.crosslink.shard < SHARD_COUNT):
|
|
|
|
# notice "Attestation shard too high",
|
|
|
|
# attestation_shard = data.crosslink.shard
|
|
|
|
# return
|
|
|
|
|
|
|
|
# Without this check, we can't get a slot number for the attestation as
|
|
|
|
# certain helpers will assert
|
|
|
|
# TODO this could probably be avoided by being smart about the specific state
|
|
|
|
# used to validate the attestation: most likely if we pick the state of
|
|
|
|
# the beacon block being voted for and a slot in the target epoch
|
|
|
|
# of the attestation, we'll be safe!
|
|
|
|
# TODO the above state selection logic should probably live here in the
|
|
|
|
# attestation pool
|
|
|
|
if not (data.target.epoch == get_previous_epoch(state) or
|
|
|
|
data.target.epoch == get_current_epoch(state)):
|
|
|
|
warn("Target epoch not current or previous epoch")
|
|
|
|
return
|
|
|
|
|
|
|
|
if not (data.target.epoch == compute_epoch_at_slot(data.slot)):
|
|
|
|
warn("Target epoch inconsistent with epoch of data slot",
|
|
|
|
target_epoch = data.target.epoch,
|
|
|
|
data_slot_epoch = compute_epoch_at_slot(data.slot))
|
|
|
|
return
|
|
|
|
|
|
|
|
true
|
|
|
|
|
2020-07-09 11:43:27 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#attestations
|
2019-08-19 16:41:13 +00:00
|
|
|
proc check_attestation*(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: BeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
2019-06-24 09:21:56 +00:00
|
|
|
stateCache: var StateCache): bool =
|
2018-12-11 17:55:45 +00:00
|
|
|
## Check that an attestation follows the rules of being included in the state
|
2018-12-27 20:14:37 +00:00
|
|
|
## at the current slot. When acting as a proposer, the same rules need to
|
|
|
|
## be followed!
|
2018-12-11 17:55:45 +00:00
|
|
|
|
2020-06-10 06:58:12 +00:00
|
|
|
# TODO: When checking attestation from the network, currently rewinding/advancing
|
|
|
|
# a temporary state is needed.
|
|
|
|
# If this is too costly we can be DOS-ed.
|
|
|
|
# We might want to split this into "state-dependent" checks and "state-independent" checks
|
|
|
|
# The latter one should be made prior to state-rewinding.
|
|
|
|
|
2020-03-19 23:48:03 +00:00
|
|
|
let
|
|
|
|
stateSlot = state.slot
|
|
|
|
data = attestation.data
|
2019-07-02 21:14:55 +00:00
|
|
|
|
2020-07-16 13:16:51 +00:00
|
|
|
logScope:
|
|
|
|
attestation = shortLog(attestation)
|
|
|
|
trace "process_attestation: beginning"
|
2019-08-14 08:56:32 +00:00
|
|
|
|
2020-07-15 10:44:18 +00:00
|
|
|
let committee_count_at_slot =
|
|
|
|
get_committee_count_at_slot(get_shuffled_active_validator_indices(
|
|
|
|
state, stateSlot.compute_epoch_at_slot, stateCache).len.uint64).uint64
|
|
|
|
if not (data.index < committee_count_at_slot):
|
2020-07-16 13:16:51 +00:00
|
|
|
warn "Data index exceeds committee count",
|
|
|
|
committee_count = committee_count_at_slot
|
2020-01-27 21:04:26 +00:00
|
|
|
return
|
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
if not isValidAttestationTargetEpoch(state, data):
|
2020-06-10 06:58:12 +00:00
|
|
|
# Logging in isValidAttestationTargetEpoch
|
2019-07-02 21:14:55 +00:00
|
|
|
return
|
|
|
|
|
2020-06-10 06:58:12 +00:00
|
|
|
if not isValidAttestationSlot(data.slot, stateSlot):
|
|
|
|
# Logging in isValidAttestationSlot
|
2018-12-11 17:55:45 +00:00
|
|
|
return
|
|
|
|
|
2020-04-15 09:01:36 +00:00
|
|
|
let committee = get_beacon_committee(
|
|
|
|
state, data.slot, data.index.CommitteeIndex, stateCache)
|
2019-11-08 11:31:48 +00:00
|
|
|
if attestation.aggregation_bits.len != committee.len:
|
2020-07-16 13:16:51 +00:00
|
|
|
warn "Inconsistent aggregation and committee length",
|
2019-11-08 11:31:48 +00:00
|
|
|
aggregation_bits_len = attestation.aggregation_bits.len,
|
|
|
|
committee_len = committee.len
|
2020-07-16 13:16:51 +00:00
|
|
|
|
2019-11-08 11:31:48 +00:00
|
|
|
return
|
|
|
|
|
2019-07-02 21:14:55 +00:00
|
|
|
let ffg_check_data = (data.source.epoch, data.source.root, data.target.epoch)
|
2019-06-24 09:21:56 +00:00
|
|
|
|
2019-07-02 21:14:55 +00:00
|
|
|
if data.target.epoch == get_current_epoch(state):
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
if not (ffg_check_data == (state.current_justified_checkpoint.epoch,
|
|
|
|
state.current_justified_checkpoint.root, get_current_epoch(state))):
|
2020-07-16 13:16:51 +00:00
|
|
|
warn "FFG data not matching current justified epoch"
|
2019-06-24 09:21:56 +00:00
|
|
|
return
|
|
|
|
else:
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
if not (ffg_check_data == (state.previous_justified_checkpoint.epoch,
|
|
|
|
state.previous_justified_checkpoint.root, get_previous_epoch(state))):
|
2020-07-16 13:16:51 +00:00
|
|
|
warn "FFG data not matching previous justified epoch"
|
2019-06-24 09:21:56 +00:00
|
|
|
return
|
|
|
|
|
2019-07-02 21:14:55 +00:00
|
|
|
if not is_valid_indexed_attestation(
|
2020-01-30 21:03:47 +00:00
|
|
|
state, get_indexed_attestation(state, attestation, stateCache), flags):
|
2020-07-16 13:16:51 +00:00
|
|
|
warn "process_attestation: signature or bitfields incorrect"
|
2019-06-12 07:48:49 +00:00
|
|
|
return
|
|
|
|
|
2018-12-11 17:55:45 +00:00
|
|
|
true
|
2019-02-13 10:26:32 +00:00
|
|
|
|
2019-08-19 16:41:13 +00:00
|
|
|
proc process_attestation*(
|
2020-06-25 10:23:10 +00:00
|
|
|
state: var BeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
2020-07-03 17:03:14 +00:00
|
|
|
stateCache: var StateCache): Result[void, cstring] {.nbench.} =
|
2019-08-19 16:41:13 +00:00
|
|
|
# In the spec, attestation validation is mixed with state mutation, so here
|
|
|
|
# we've split it into two functions so that the validation logic can be
|
|
|
|
# reused when looking for suitable blocks to include in attestations.
|
|
|
|
# TODO don't log warnings when looking for attestations (return
|
|
|
|
# Result[void, cstring] instead of logging in check_attestation?)
|
2019-12-04 10:49:59 +00:00
|
|
|
|
|
|
|
let proposer_index = get_beacon_proposer_index(state, stateCache)
|
|
|
|
if proposer_index.isNone:
|
2020-07-03 17:03:14 +00:00
|
|
|
return err("process_attestation: no beacon proposer index and probably no active validators")
|
2019-12-04 10:49:59 +00:00
|
|
|
|
2019-08-19 16:41:13 +00:00
|
|
|
if check_attestation(state, attestation, flags, stateCache):
|
|
|
|
let
|
2019-11-12 05:35:52 +00:00
|
|
|
attestation_slot = attestation.data.slot
|
2019-08-19 16:41:13 +00:00
|
|
|
pending_attestation = PendingAttestation(
|
|
|
|
data: attestation.data,
|
|
|
|
aggregation_bits: attestation.aggregation_bits,
|
|
|
|
inclusion_delay: state.slot - attestation_slot,
|
2019-12-04 10:49:59 +00:00
|
|
|
proposer_index: proposer_index.get.uint64,
|
2019-08-19 16:41:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if attestation.data.target.epoch == get_current_epoch(state):
|
|
|
|
trace "process_attestation: current_epoch_attestations.add",
|
2020-05-09 12:43:15 +00:00
|
|
|
attestation = shortLog(attestation),
|
2019-08-19 16:41:13 +00:00
|
|
|
pending_attestation = pending_attestation,
|
|
|
|
indices = get_attesting_indices(
|
|
|
|
state, attestation.data, attestation.aggregation_bits, stateCache).len
|
|
|
|
state.current_epoch_attestations.add(pending_attestation)
|
|
|
|
else:
|
|
|
|
trace "process_attestation: previous_epoch_attestations.add",
|
2020-05-09 12:43:15 +00:00
|
|
|
attestation = shortLog(attestation),
|
2019-08-19 16:41:13 +00:00
|
|
|
pending_attestation = pending_attestation,
|
|
|
|
indices = get_attesting_indices(
|
|
|
|
state, attestation.data, attestation.aggregation_bits, stateCache).len
|
|
|
|
state.previous_epoch_attestations.add(pending_attestation)
|
|
|
|
|
2020-07-03 17:03:14 +00:00
|
|
|
ok()
|
2019-08-19 16:41:13 +00:00
|
|
|
else:
|
2020-07-03 17:03:14 +00:00
|
|
|
err("process_attestation: check_attestation failed")
|
2019-08-19 16:41:13 +00:00
|
|
|
|
2019-11-21 09:15:10 +00:00
|
|
|
func makeAttestationData*(
|
2019-11-14 17:37:51 +00:00
|
|
|
state: BeaconState, slot: Slot, committee_index: uint64,
|
2019-03-09 04:23:14 +00:00
|
|
|
beacon_block_root: Eth2Digest): AttestationData =
|
2019-08-19 16:41:13 +00:00
|
|
|
## Create an attestation / vote for the block `beacon_block_root` using the
|
|
|
|
## data in `state` to fill in the rest of the fields.
|
|
|
|
## `state` is the state corresponding to the `beacon_block_root` advanced to
|
|
|
|
## the slot we're attesting to.
|
|
|
|
|
2019-03-09 04:23:14 +00:00
|
|
|
let
|
2019-08-19 16:41:13 +00:00
|
|
|
current_epoch = get_current_epoch(state)
|
initial 0.9.0 spec sync (#509)
* rename compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* remove some unnecessary imports; remove some crosslink-related code and tests; complete renaming of compute_epoch_of_slot(...) to compute_epoch_at_slot(...)
* rm more transfer-related code and tests; rm more unnecessary strutils imports
* rm remaining unused imports
* remove useless get_empty_per_epoch_cache(...)/compute_start_slot_of_epoch(...) calls
* rename compute_start_slot_of_epoch(...) to compute_start_slot_at_epoch(...)
* rename ACTIVATION_EXIT_DELAY to MAX_SEED_LOOKAHEAD
* update domain types to 0.9.0
* mark AttesterSlashing, IndexedAttestation, AttestationDataAndCustodyBit, DepositData, BeaconBlockHeader, Fork, integer_squareroot(...), and process_voluntary_exit(...) as 0.9.0
* mark increase_balance(...), decrease_balance(...), get_block_root(...), CheckPoint, Deposit, PendingAttestation, HistoricalBatch, is_active_validator(...), and is_slashable_attestation_data(...) as 0.9.0
* mark compute_activation_exit_epoch(...), bls_verify(...), Validator, get_active_validator_indices(...), get_current_epoch(...), get_total_active_balance(...), and get_previous_epoch(...) as 0.9.0
* mark get_block_root_at_slot(...), ProposerSlashing, get_domain(...), VoluntaryExit, mainnet preset Gwei values, minimal preset max operations, process_block_header(...), and is_slashable_validator(...) as 0.9.0
* mark makeWithdrawalCredentials(...), get_validator_churn_limit(...), get_total_balance(...), is_valid_indexed_attestation(...), bls_aggregate_pubkeys(...), initial genesis value/constants, Attestation, get_randao_mix(...), mainnet preset max operations per block constants, minimal preset Gwei values and time parameters, process_eth1_data(...), get_shuffled_seq(...), compute_committee(...), and process_slots(...) as 0.9.0; partially update get_indexed_attestation(...) to 0.9.0 by removing crosslink refs and associated tests
* mark initiate_validator_exit(...), process_registry_updates(...), BeaconBlock, Eth1Data, compute_domain(...), process_randao(...), process_attester_slashing(...), get_base_reward(...), and process_slot(...) as 0.9.0
2019-10-30 19:41:19 +00:00
|
|
|
start_slot = compute_start_slot_at_epoch(current_epoch)
|
2019-08-19 16:41:13 +00:00
|
|
|
epoch_boundary_block_root =
|
|
|
|
if start_slot == state.slot: beacon_block_root
|
|
|
|
else: get_block_root_at_slot(state, start_slot)
|
2019-11-14 17:37:51 +00:00
|
|
|
|
2020-07-09 09:29:32 +00:00
|
|
|
doAssert slot.compute_epoch_at_slot == current_epoch,
|
|
|
|
"Computed epoch was " & $slot.compute_epoch_at_slot &
|
|
|
|
" while the state current_epoch was " & $current_epoch
|
2019-03-09 04:23:14 +00:00
|
|
|
|
2020-07-08 20:36:26 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#attestation-data
|
2019-03-09 04:23:14 +00:00
|
|
|
AttestationData(
|
2019-11-14 17:37:51 +00:00
|
|
|
slot: slot,
|
|
|
|
index: committee_index,
|
2019-03-09 04:23:14 +00:00
|
|
|
beacon_block_root: beacon_block_root,
|
More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0
* update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0
* mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0
* rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...)
* convert remaining references to finalized_epoch to finalized_checkpoint.epoch
* update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0
* rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0
* update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0
* replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
2019-07-05 08:30:05 +00:00
|
|
|
source: state.current_justified_checkpoint,
|
2019-07-02 21:14:55 +00:00
|
|
|
target: Checkpoint(
|
2019-08-19 16:41:13 +00:00
|
|
|
epoch: current_epoch,
|
|
|
|
root: epoch_boundary_block_root
|
2019-06-25 11:17:08 +00:00
|
|
|
)
|
2019-03-09 04:23:14 +00:00
|
|
|
)
|