parent
c64cd2f275
commit
1269e001ad
|
@ -444,7 +444,7 @@ when isMainModule:
|
|||
stateSlot = humaneSlotNum(node.beaconState.slot),
|
||||
SHARD_COUNT,
|
||||
EPOCH_LENGTH,
|
||||
SLOT_DURATION,
|
||||
SECONDS_PER_SLOT,
|
||||
SPEC_VERSION
|
||||
|
||||
node.addLocalValidators()
|
||||
|
|
|
@ -22,7 +22,7 @@ func sum_effective_balances*(
|
|||
for index in validator_indices:
|
||||
result += get_effective_balance(state, index)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#validate_proof_of_possession<F12>
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#validate_proof_of_possession
|
||||
func validate_proof_of_possession(state: BeaconState,
|
||||
pubkey: ValidatorPubKey,
|
||||
proof_of_possession: ValidatorSig,
|
||||
|
@ -67,8 +67,8 @@ func process_deposit(state: var BeaconState,
|
|||
withdrawal_credentials: withdrawal_credentials,
|
||||
activation_epoch: FAR_FUTURE_EPOCH,
|
||||
exit_epoch: FAR_FUTURE_EPOCH,
|
||||
withdrawal_epoch: FAR_FUTURE_EPOCH,
|
||||
penalized_epoch: FAR_FUTURE_EPOCH,
|
||||
withdrawable_epoch: FAR_FUTURE_EPOCH,
|
||||
slashed_epoch: FAR_FUTURE_EPOCH,
|
||||
status_flags: 0,
|
||||
)
|
||||
|
||||
|
@ -88,7 +88,7 @@ func process_deposit(state: var BeaconState,
|
|||
func get_entry_exit_effect_epoch*(epoch: EpochNumber): EpochNumber =
|
||||
## An entry or exit triggered in the ``epoch`` given by the input takes effect at
|
||||
## the epoch given by the output.
|
||||
epoch + 1 + ENTRY_EXIT_DELAY
|
||||
epoch + 1 + ACTIVATION_EXIT_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#activate_validator
|
||||
func activate_validator(state: var BeaconState,
|
||||
|
@ -136,11 +136,11 @@ func process_penalties_and_exits(state: var BeaconState) =
|
|||
total_balance += get_effective_balance(state, i)
|
||||
|
||||
for index, validator in state.validator_registry:
|
||||
if current_epoch == validator.penalized_epoch + LATEST_PENALIZED_EXIT_LENGTH div 2:
|
||||
if current_epoch == validator.slashed_epoch + LATEST_SLASHED_EXIT_LENGTH div 2:
|
||||
let
|
||||
e = (current_epoch mod LATEST_PENALIZED_EXIT_LENGTH).int
|
||||
total_at_start = state.latest_penalized_exit_balances[(e + 1) mod LATEST_PENALIZED_EXIT_LENGTH]
|
||||
total_at_end = state.latest_penalized_exit_balances[e]
|
||||
e = (current_epoch mod LATEST_SLASHED_EXIT_LENGTH).int
|
||||
total_at_start = state.latest_slashed_balances[(e + 1) mod LATEST_SLASHED_EXIT_LENGTH]
|
||||
total_at_end = state.latest_slashed_balances[e]
|
||||
total_penalties = total_at_end - total_at_start
|
||||
penalty = get_effective_balance(state, index.ValidatorIndex) * min(total_penalties * 3, total_balance) div total_balance
|
||||
state.validator_balances[index] -= penalty
|
||||
|
@ -193,12 +193,12 @@ func get_initial_beacon_state*(
|
|||
validator_registry_delta_chain_tip: ZERO_HASH,
|
||||
|
||||
# Randomness and committees
|
||||
previous_epoch_start_shard: GENESIS_START_SHARD,
|
||||
current_epoch_start_shard: GENESIS_START_SHARD,
|
||||
previous_calculation_epoch: GENESIS_EPOCH,
|
||||
current_calculation_epoch: GENESIS_EPOCH,
|
||||
previous_epoch_seed: ZERO_HASH,
|
||||
current_epoch_seed: ZERO_HASH,
|
||||
previous_shuffling_start_shard: GENESIS_START_SHARD,
|
||||
current_shuffling_start_shard: GENESIS_START_SHARD,
|
||||
previous_shuffling_epoch: GENESIS_EPOCH,
|
||||
current_shuffling_epoch: GENESIS_EPOCH,
|
||||
previous_shuffling_seed: ZERO_HASH,
|
||||
current_shuffling_seed: ZERO_HASH,
|
||||
|
||||
# Finality
|
||||
previous_justified_epoch: GENESIS_EPOCH,
|
||||
|
@ -326,9 +326,9 @@ func update_validator_registry*(state: var BeaconState) =
|
|||
state.validator_registry_update_epoch = current_epoch
|
||||
|
||||
# Perform additional updates
|
||||
state.current_calculation_epoch = next_epoch
|
||||
state.current_epoch_start_shard = (state.current_epoch_start_shard + get_current_epoch_committee_count(state)) mod SHARD_COUNT
|
||||
state.current_epoch_seed = generate_seed(state, state.current_calculation_epoch)
|
||||
state.current_shuffling_epoch = next_epoch
|
||||
state.current_shuffling_start_shard = (state.current_shuffling_start_shard + get_current_epoch_committee_count(state)) mod SHARD_COUNT
|
||||
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch)
|
||||
|
||||
# TODO "If a validator registry update does not happen do the following: ..."
|
||||
|
||||
|
@ -463,4 +463,5 @@ func prepare_validator_for_withdrawal(state: var BeaconState, index: ValidatorIn
|
|||
## Set the validator with the given ``index`` with ``WITHDRAWABLE`` flag.
|
||||
## Note that this function mutates ``state``.
|
||||
var validator = addr state.validator_registry[index]
|
||||
# TODO rm WITHDRAWABLE, since gone in 0.3.0
|
||||
validator.status_flags = validator.status_flags or WITHDRAWABLE
|
||||
|
|
|
@ -45,7 +45,7 @@ const
|
|||
## TODO: improve this scheme once we can negotiate versions in protocol
|
||||
|
||||
# Misc
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#misc
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#misc
|
||||
SHARD_COUNT* {.intdefine.} = 1024 ##\
|
||||
## Number of shards supported by the network - validators will jump around
|
||||
## between these shards and provide attestations to their state.
|
||||
|
@ -73,14 +73,16 @@ const
|
|||
|
||||
MAX_WITHDRAWALS_PER_EPOCH* = 4 # withdrawals
|
||||
|
||||
MAX_EXIT_DEQUEUES_PER_EPOCH* = 4
|
||||
|
||||
SHUFFLE_ROUND_COUNT* = 90
|
||||
|
||||
# Deposit contract
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#deposit-contract
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#deposit-contract
|
||||
DEPOSIT_CONTRACT_TREE_DEPTH* = 2^5
|
||||
|
||||
# Gwei values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#gwei-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#gwei-values
|
||||
MIN_DEPOSIT_AMOUNT* = 2'u64^0 * 10'u64^9 ##\
|
||||
## Minimum amounth of ETH that can be deposited in one call - deposits can
|
||||
## be used either to top up an existing validator or commit to a new one
|
||||
|
@ -101,7 +103,7 @@ const
|
|||
## Compile with -d:EPOCH_LENGTH=4 for shorter epochs
|
||||
|
||||
# Initial values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#initial-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#initial-values
|
||||
GENESIS_FORK_VERSION* = 0'u64
|
||||
GENESIS_SLOT* = 2'u64^63
|
||||
GENESIS_EPOCH* = GENESIS_SLOT div EPOCH_LENGTH # slot_to_epoch(GENESIS_SLOT)
|
||||
|
@ -112,8 +114,8 @@ const
|
|||
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
|
||||
|
||||
# Time parameters
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#time-parameters
|
||||
SLOT_DURATION*{.intdefine.} = 6'u64 # Compile with -d:SLOT_DURATION=1 for 6x faster slots
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#time-parameters
|
||||
SECONDS_PER_SLOT*{.intdefine.} = 6'u64 # Compile with -d:SECONDS_PER_SLOT=1 for 6x faster slots
|
||||
## TODO consistent time unit across projects, similar to C++ chrono?
|
||||
|
||||
MIN_ATTESTATION_INCLUSION_DELAY* = 2'u64^2 ##\
|
||||
|
@ -128,47 +130,53 @@ const
|
|||
## wait towards the end of the slot and still have time to publish the
|
||||
## attestation.
|
||||
|
||||
SEED_LOOKAHEAD* = 1 ##\
|
||||
SLOTS_PER_EPOCH* = 2^6 ##\
|
||||
## 6.4 minutes
|
||||
|
||||
MIN_SEED_LOOKAHEAD* = 1 ##\
|
||||
## epochs (~6.4 minutes)
|
||||
|
||||
ENTRY_EXIT_DELAY* = 4 ##\
|
||||
ACTIVATION_EXIT_DELAY* = 4 ##\
|
||||
## epochs (~25.6 minutes)
|
||||
|
||||
ETH1_DATA_VOTING_PERIOD* = 2'u64^4 ##\
|
||||
EPOCHS_PER_ETH1_VOTING_PERIOD* = 2'u64^4 ##\
|
||||
## epochs (~1.7 hours)
|
||||
|
||||
MIN_VALIDATOR_WITHDRAWAL_EPOCHS* = 2'u64^8 ##\
|
||||
MIN_VALIDATOR_WITHDRAWAL_DELAY* = 2'u64^8 ##\
|
||||
## epochs (~27 hours)
|
||||
|
||||
# State list lengths
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
LATEST_BLOCK_ROOTS_LENGTH* = 2'u64^13
|
||||
LATEST_RANDAO_MIXES_LENGTH* = 2'u64^13
|
||||
LATEST_INDEX_ROOTS_LENGTH* = 2'u64^13
|
||||
LATEST_PENALIZED_EXIT_LENGTH* = 8192 # epochs
|
||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 2'u64^13
|
||||
LATEST_SLASHED_EXIT_LENGTH* = 8192 # epochs
|
||||
|
||||
# Reward and penalty quotients
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
BASE_REWARD_QUOTIENT* = 2'u64^5 ##\
|
||||
## The `BASE_REWARD_QUOTIENT` parameter dictates the per-epoch reward. It
|
||||
## corresponds to ~2.54% annual interest assuming 10 million participating
|
||||
## ETH in every epoch.
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT* = 2'u64^9
|
||||
INCLUDER_REWARD_QUOTIENT* = 2'u64^3
|
||||
ATTESTATION_INCLUSION_REWARD_QUOTIENT* = 2'u64^3
|
||||
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^24
|
||||
MIN_PENALTY_QUOTIENT* = 2^5
|
||||
|
||||
# Status flags
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#status-flags
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#status-flags
|
||||
INITIATED_EXIT* = 1'u64
|
||||
# TODO rm WITHDRAWABLE
|
||||
WITHDRAWABLE* = 2'u64
|
||||
|
||||
# Max operations per block
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
# Max transactions per block
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#max-transactions-per-block
|
||||
MAX_PROPOSER_SLASHINGS* = 2^4
|
||||
MAX_ATTESTER_SLASHINGS* = 2^0
|
||||
MAX_ATTESTATIONS* = 2^7
|
||||
MAX_DEPOSITS* = 2^4
|
||||
MAX_EXITS* = 2^4
|
||||
MAX_VOLUNTARY_EXITS* = 2^4
|
||||
MAX_TRANSFERS* = 2^4
|
||||
|
||||
type
|
||||
ValidatorIndex* = range[0'u32 .. 0xFFFFFF'u32] # TODO: wrap-around
|
||||
|
@ -181,7 +189,7 @@ type
|
|||
EpochNumber* = uint64
|
||||
Gwei* = uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#proposerslashing
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#proposerslashing
|
||||
ProposerSlashing* = object
|
||||
proposer_index*: uint64
|
||||
proposal_data_1*: ProposalSignedData
|
||||
|
@ -189,14 +197,14 @@ type
|
|||
proposal_data_2*: ProposalSignedData
|
||||
proposal_signature_2*: ValidatorSig
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attesterslashing
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attesterslashing
|
||||
AttesterSlashing* = object
|
||||
slashable_attestation_1*: SlashableAttestation ## \
|
||||
## First batch of votes
|
||||
## First slashable attestation
|
||||
slashable_attestation_2*: SlashableAttestation ## \
|
||||
## Second batch of votes
|
||||
## Second slashable attestation
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#slashableattestation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#slashableattestation
|
||||
SlashableAttestation* = object
|
||||
validator_indices*: seq[uint64] ##\
|
||||
## Validator indices
|
||||
|
@ -210,19 +218,21 @@ type
|
|||
aggregate_signature*: ValidatorSig ## \
|
||||
## Aggregate signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#attestation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestation
|
||||
Attestation* = object
|
||||
aggregation_bitfield*: seq[byte] ##\
|
||||
## The attesters that are represented in the aggregate signature - each
|
||||
## bit represents an index in `ShardCommittee.committee`
|
||||
## Attester aggregation bitfield
|
||||
|
||||
data*: AttestationData ##\
|
||||
## Attestation data
|
||||
|
||||
data*: AttestationData
|
||||
custody_bitfield*: seq[byte] ##\
|
||||
## Custody bitfield
|
||||
aggregate_signature*: ValidatorSig ##\
|
||||
## Aggregate signature of the validators in `custody_bitfield`
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestation
|
||||
aggregate_signature*: ValidatorSig ##\
|
||||
## BLS aggregate signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestationdata
|
||||
AttestationData* = object
|
||||
slot*: uint64 ##\
|
||||
## Slot number
|
||||
|
@ -248,12 +258,12 @@ type
|
|||
justified_block_root*: Eth2Digest ##\
|
||||
## Hash of the last justified beacon block
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
||||
AttestationDataAndCustodyBit* = object
|
||||
data*: AttestationData
|
||||
custody_bit*: bool
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#deposit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#deposit
|
||||
Deposit* = object
|
||||
branch*: seq[Eth2Digest] ##\
|
||||
## Branch in the deposit tree
|
||||
|
@ -264,21 +274,21 @@ type
|
|||
deposit_data*: DepositData ##\
|
||||
## Data
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#depositdata
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#depositdata
|
||||
DepositData* = object
|
||||
amount*: uint64 ## Value in Gwei
|
||||
timestamp*: uint64 # Timestamp from deposit contract
|
||||
deposit_input*: DepositInput
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#depositinput
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#depositinput
|
||||
DepositInput* = object
|
||||
pubkey*: ValidatorPubKey
|
||||
withdrawal_credentials*: Eth2Digest
|
||||
proof_of_possession*: ValidatorSig ##\
|
||||
## BLS proof of possession (a BLS signature)
|
||||
## A BLS signature of this DepositInput
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#exit
|
||||
Exit* = object
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#voluntaryexit
|
||||
VoluntaryExit* = object
|
||||
# Minimum epoch for processing exit
|
||||
epoch*: uint64
|
||||
# Index of the exiting validator
|
||||
|
@ -286,7 +296,30 @@ type
|
|||
# Validator signature
|
||||
signature*: ValidatorSig
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#beaconblock
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#transfer
|
||||
Transfer* = object
|
||||
from_field*: uint64 ##\
|
||||
## Sender index
|
||||
|
||||
to*: uint64 ##\
|
||||
## Recipient index
|
||||
|
||||
amount*: uint64 ##\
|
||||
## Amount in Gwei
|
||||
|
||||
fee*: uint64 ##\
|
||||
## Fee in Gwei for block proposer
|
||||
|
||||
slot*: uint64 ##\
|
||||
## Inclusion slot
|
||||
|
||||
pubkey*: ValidatorPubKey ##\
|
||||
## Sender withdrawal pubkey
|
||||
|
||||
signature*: ValidatorSig ##\
|
||||
## Sender signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#beaconblock
|
||||
BeaconBlock* = object
|
||||
## For each slot, a proposer is chosen from the validator pool to propose
|
||||
## a new block. Once the block as been proposed, it is transmitted to
|
||||
|
@ -311,22 +344,23 @@ type
|
|||
|
||||
body*: BeaconBlockBody
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
BeaconBlockBody* = object
|
||||
proposer_slashings*: seq[ProposerSlashing]
|
||||
attester_slashings*: seq[AttesterSlashing]
|
||||
attestations*: seq[Attestation]
|
||||
deposits*: seq[Deposit]
|
||||
exits*: seq[Exit]
|
||||
voluntary_exits*: seq[VoluntaryExit]
|
||||
transfers*: seq[Transfer]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#proposalsigneddata
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#proposalsigneddata
|
||||
ProposalSignedData* = object
|
||||
slot*: uint64
|
||||
shard*: uint64 ##\
|
||||
## Shard number (or `BEACON_CHAIN_SHARD_NUMBER` for beacon chain)
|
||||
block_root*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#beaconstate
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
slot*: uint64
|
||||
genesis_time*: uint64
|
||||
|
@ -346,12 +380,12 @@ type
|
|||
|
||||
# Randomness and committees
|
||||
latest_randao_mixes*: array[LATEST_BLOCK_ROOTS_LENGTH.int, Eth2Digest]
|
||||
previous_epoch_start_shard*: uint64
|
||||
current_epoch_start_shard*: uint64
|
||||
previous_calculation_epoch*: uint64
|
||||
current_calculation_epoch*: uint64
|
||||
previous_epoch_seed*: Eth2Digest
|
||||
current_epoch_seed*: Eth2Digest
|
||||
previous_shuffling_start_shard*: uint64
|
||||
current_shuffling_start_shard*: uint64
|
||||
previous_shuffling_epoch*: uint64
|
||||
current_shuffling_epoch*: uint64
|
||||
previous_shuffling_seed*: Eth2Digest
|
||||
current_shuffling_seed*: Eth2Digest
|
||||
|
||||
# Finality
|
||||
previous_justified_epoch*: uint64
|
||||
|
@ -363,9 +397,9 @@ type
|
|||
latest_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
latest_block_roots*: array[LATEST_BLOCK_ROOTS_LENGTH.int, Eth2Digest] ##\
|
||||
## Needed to process attestations, older to newer
|
||||
latest_index_roots*: array[LATEST_INDEX_ROOTS_LENGTH.int, Eth2Digest]
|
||||
latest_active_index_roots*: array[LATEST_ACTIVE_INDEX_ROOTS_LENGTH.int, Eth2Digest]
|
||||
|
||||
latest_penalized_exit_balances*: seq[uint64] ##\
|
||||
latest_slashed_balances*: seq[uint64] ##\
|
||||
## Balances penalized in the current withdrawal period
|
||||
|
||||
latest_attestations*: seq[PendingAttestation]
|
||||
|
@ -374,8 +408,9 @@ type
|
|||
# Ethereum 1.0 chain data
|
||||
latest_eth1_data*: Eth1Data
|
||||
eth1_data_votes*: seq[Eth1DataVote]
|
||||
deposit_index*: uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#validator
|
||||
Validator* = object
|
||||
pubkey*: ValidatorPubKey ##\
|
||||
## BLS public key
|
||||
|
@ -389,34 +424,36 @@ type
|
|||
exit_epoch*: uint64 ##\
|
||||
## Epoch when validator exited
|
||||
|
||||
withdrawal_epoch*: uint64 ##\
|
||||
withdrawable_epoch*: uint64 ##\
|
||||
## Epoch when validator withdrew
|
||||
|
||||
penalized_epoch*: uint64 ##\
|
||||
slashed_epoch*: uint64 ##\
|
||||
## Epoch when validator penalized
|
||||
|
||||
status_flags*: uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#crosslink
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#crosslink
|
||||
Crosslink* = object
|
||||
epoch*: uint64
|
||||
shard_block_root*: Eth2Digest ##\
|
||||
## Shard chain block root
|
||||
epoch*: uint64 ##\
|
||||
## Epoch number
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#pendingattestation
|
||||
shard_block_root*: Eth2Digest ##\
|
||||
## Shard block root
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#pendingattestation
|
||||
PendingAttestation* = object
|
||||
aggregation_bitfield*: seq[byte] # Attester participation bitfield
|
||||
data*: AttestationData # Attestation data
|
||||
custody_bitfield*: seq[byte] # Custody bitfield
|
||||
inclusion_slot*: uint64 # Inclusion slot
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#fork
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#fork
|
||||
Fork* = object
|
||||
previous_version*: uint64 # Previous fork version
|
||||
current_version*: uint64 # Current fork version
|
||||
epoch*: uint64 # Fork epoch number
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#eth1data
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#eth1data
|
||||
Eth1Data* = object
|
||||
deposit_root*: Eth2Digest ##\
|
||||
## Data being voted for
|
||||
|
@ -424,10 +461,13 @@ type
|
|||
block_hash*: Eth2Digest ##\
|
||||
## Block hash
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#eth1datavote
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#eth1datavote
|
||||
Eth1DataVote* = object
|
||||
eth1_data*: Eth1Data
|
||||
vote_count*: uint64 # Vote count
|
||||
eth1_data*: Eth1Data ##\
|
||||
## Data being voted for
|
||||
|
||||
vote_count*: uint64 ##\
|
||||
## Vote count
|
||||
|
||||
## TODO remove or otherwise conditional-compile this, since it's for light
|
||||
## client but not in spec
|
||||
|
@ -444,13 +484,14 @@ type
|
|||
Activation = 0
|
||||
Exit = 1
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#signature-domains
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#signature-domains
|
||||
SignatureDomain* {.pure.} = enum
|
||||
DOMAIN_DEPOSIT = 0
|
||||
DOMAIN_ATTESTATION = 1
|
||||
DOMAIN_PROPOSAL = 2
|
||||
DOMAIN_EXIT = 3
|
||||
DOMAIN_RANDAO = 4
|
||||
DOMAIN_TRANSFER = 5
|
||||
|
||||
# TODO: not in spec
|
||||
CrosslinkCommittee* = tuple[committee: seq[ValidatorIndex], shard: uint64]
|
||||
|
|
|
@ -152,7 +152,7 @@ func get_current_epoch_committee_count*(state: BeaconState): uint64 =
|
|||
# Return the number of committees in the current epoch of the given ``state``.
|
||||
let current_active_validators = get_active_validator_indices(
|
||||
state.validator_registry,
|
||||
state.current_calculation_epoch,
|
||||
state.current_shuffling_epoch,
|
||||
)
|
||||
get_epoch_committee_count(len(current_active_validators))
|
||||
|
||||
|
@ -178,9 +178,9 @@ func get_active_index_root(state: BeaconState, epoch: EpochNumber): Eth2Digest =
|
|||
# Returns the index root at a recent ``epoch``.
|
||||
|
||||
# Cannot underflow, since GENESIS_EPOCH > LATEST_RANDAO_MIXES_LENGTH
|
||||
assert get_current_epoch(state) - LATEST_INDEX_ROOTS_LENGTH < epoch
|
||||
assert epoch <= get_current_epoch(state) + ENTRY_EXIT_DELAY
|
||||
state.latest_index_roots[epoch mod LATEST_INDEX_ROOTS_LENGTH]
|
||||
assert get_current_epoch(state) - LATEST_ACTIVE_INDEX_ROOTS_LENGTH < epoch
|
||||
assert epoch <= get_current_epoch(state) + ACTIVATION_EXIT_DELAY
|
||||
state.latest_active_index_roots[epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#bytes_to_int
|
||||
func bytes_to_int*(data: seq[byte]): uint64 =
|
||||
|
@ -219,8 +219,8 @@ func generate_seed*(state: BeaconState, epoch: EpochNumber): Eth2Digest =
|
|||
# Generate a seed for the given ``epoch``.
|
||||
|
||||
var seed_input : array[32*3, byte]
|
||||
# Cannot underflow, since GENESIS_EPOCH > SEED_LOOKAHEAD
|
||||
seed_input[0..31] = get_randao_mix(state, epoch - SEED_LOOKAHEAD).data
|
||||
# Cannot underflow, since GENESIS_EPOCH > MIN_SEED_LOOKAHEAD
|
||||
seed_input[0..31] = get_randao_mix(state, epoch - MIN_SEED_LOOKAHEAD).data
|
||||
seed_input[32..63] = get_active_index_root(state, epoch).data
|
||||
seed_input[64..95] = int_to_bytes32(epoch)
|
||||
eth2hash(seed_input)
|
||||
|
|
|
@ -107,7 +107,7 @@ func get_previous_epoch_committee_count(state: BeaconState): uint64 =
|
|||
# Return the number of committees in the previous epoch of the given ``state``.
|
||||
let previous_active_validators = get_active_validator_indices(
|
||||
state.validator_registry,
|
||||
state.previous_calculation_epoch,
|
||||
state.previous_shuffling_epoch,
|
||||
)
|
||||
get_epoch_committee_count(len(previous_active_validators))
|
||||
|
||||
|
@ -163,16 +163,16 @@ func get_crosslink_committees_at_slot*(state: BeaconState, slot: uint64,
|
|||
## Nim optimizes out both copies per. Could directly construct tuple
|
||||
## but this hews closer to spec helper code.
|
||||
committees_per_epoch = get_previous_epoch_committee_count(state)
|
||||
seed = state.previous_epoch_seed
|
||||
shuffling_epoch = state.previous_calculation_epoch
|
||||
shuffling_start_shard = state.previous_epoch_start_shard
|
||||
seed = state.previous_shuffling_seed
|
||||
shuffling_epoch = state.previous_shuffling_epoch
|
||||
shuffling_start_shard = state.previous_shuffling_start_shard
|
||||
(committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard)
|
||||
elif epoch == current_epoch:
|
||||
let
|
||||
committees_per_epoch = get_current_epoch_committee_count(state)
|
||||
seed = state.current_epoch_seed
|
||||
shuffling_epoch = state.current_calculation_epoch
|
||||
shuffling_start_shard = state.current_epoch_start_shard
|
||||
seed = state.current_shuffling_seed
|
||||
shuffling_epoch = state.current_shuffling_epoch
|
||||
shuffling_start_shard = state.current_shuffling_start_shard
|
||||
(committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard)
|
||||
else:
|
||||
assert epoch == next_epoch
|
||||
|
@ -188,13 +188,13 @@ func get_crosslink_committees_at_slot*(state: BeaconState, slot: uint64,
|
|||
seed = if registry_change or condition:
|
||||
generate_seed(state, next_epoch)
|
||||
else:
|
||||
state.current_epoch_seed
|
||||
state.current_shuffling_seed
|
||||
shuffling_start_shard =
|
||||
if registry_change:
|
||||
(state.current_epoch_start_shard +
|
||||
(state.current_shuffling_start_shard +
|
||||
current_committees_per_epoch) mod SHARD_COUNT
|
||||
else:
|
||||
state.current_epoch_start_shard
|
||||
state.current_shuffling_start_shard
|
||||
(committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard)
|
||||
|
||||
let (committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard) =
|
||||
|
|
|
@ -112,8 +112,8 @@ func penalizeValidator(state: var BeaconState, index: ValidatorIndex) =
|
|||
## Note that this function mutates ``state``.
|
||||
exit_validator(state, index)
|
||||
var validator = addr state.validator_registry[index]
|
||||
state.latest_penalized_exit_balances[(get_current_epoch(state) mod
|
||||
LATEST_PENALIZED_EXIT_LENGTH).int] += get_effective_balance(state,
|
||||
state.latest_slashed_balances[(get_current_epoch(state) mod
|
||||
LATEST_SLASHED_EXIT_LENGTH).int] += get_effective_balance(state,
|
||||
index.ValidatorIndex)
|
||||
|
||||
let
|
||||
|
@ -121,7 +121,8 @@ func penalizeValidator(state: var BeaconState, index: ValidatorIndex) =
|
|||
whistleblower_reward = get_effective_balance(state, index) div WHISTLEBLOWER_REWARD_QUOTIENT
|
||||
state.validator_balances[whistleblower_index] += whistleblower_reward
|
||||
state.validator_balances[index] -= whistleblower_reward
|
||||
validator.penalized_epoch = get_current_epoch(state)
|
||||
validator.slashed_epoch = get_current_epoch(state)
|
||||
validator.withdrawable_epoch = get_current_epoch(state) + LATEST_SLASHED_EXIT_LENGTH
|
||||
|
||||
proc processProposerSlashings(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
|
@ -169,7 +170,7 @@ proc processProposerSlashings(
|
|||
notice "PropSlash: block root mismatch"
|
||||
return false
|
||||
|
||||
if not (proposer.penalized_epoch > get_current_epoch(state)):
|
||||
if not (proposer.slashed_epoch > get_current_epoch(state)):
|
||||
notice "PropSlash: penalized slot"
|
||||
return false
|
||||
|
||||
|
@ -265,7 +266,7 @@ proc processAttesterSlashings(state: var BeaconState, blck: BeaconBlock): bool =
|
|||
return false
|
||||
|
||||
for index in slashable_indices:
|
||||
if state.validator_registry[index.int].penalized_epoch > get_current_epoch(state):
|
||||
if state.validator_registry[index.int].slashed_epoch > get_current_epoch(state):
|
||||
penalize_validator(state, index.ValidatorIndex)
|
||||
|
||||
return true
|
||||
|
@ -311,11 +312,11 @@ func initiate_validator_exit(state: var BeaconState, index: int) =
|
|||
proc processExits(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#exits-1
|
||||
if len(blck.body.exits) > MAX_EXITS:
|
||||
if len(blck.body.voluntary_exits) > MAX_VOLUNTARY_EXITS:
|
||||
notice "Exit: too many!"
|
||||
return false
|
||||
|
||||
for exit in blck.body.exits:
|
||||
for exit in blck.body.voluntary_exits:
|
||||
let validator = state.validator_registry[exit.validator_index.int]
|
||||
|
||||
if skipValidation notin flags:
|
||||
|
@ -582,9 +583,9 @@ func processEpoch(state: var BeaconState) =
|
|||
sum_effective_balances(statePtr[], crosslink_committee.committee)
|
||||
|
||||
block: # Eth1 data
|
||||
if state.slot mod ETH1_DATA_VOTING_PERIOD == 0:
|
||||
if state.slot mod EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
|
||||
for x in state.eth1_data_votes:
|
||||
if x.vote_count * 2 >= ETH1_DATA_VOTING_PERIOD:
|
||||
if x.vote_count * 2 >= EPOCHS_PER_ETH1_VOTING_PERIOD:
|
||||
state.latest_eth1_data = x.eth1_data
|
||||
break
|
||||
state.eth1_data_votes = @[]
|
||||
|
@ -716,7 +717,7 @@ func processEpoch(state: var BeaconState) =
|
|||
let proposer_index =
|
||||
get_beacon_proposer_index(state, inclusion_slot(state, v))
|
||||
state.validator_balances[proposer_index] +=
|
||||
base_reward(state, v) div INCLUDER_REWARD_QUOTIENT
|
||||
base_reward(state, v) div ATTESTATION_INCLUSION_REWARD_QUOTIENT
|
||||
|
||||
block: # Crosslinks
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#crosslinks-1
|
||||
|
@ -740,27 +741,27 @@ func processEpoch(state: var BeaconState) =
|
|||
|
||||
block: # Validator registry and shuffling seed data
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
|
||||
state.previous_calculation_epoch = state.current_calculation_epoch
|
||||
state.previous_epoch_start_shard = state.current_epoch_start_shard
|
||||
state.previous_epoch_seed = state.current_epoch_seed
|
||||
#TODO state.latest_index_roots[next_epoch mod LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root_final(get_active_validator_indices(state.validator_registry, next_epoch))
|
||||
state.previous_shuffling_epoch = state.current_shuffling_epoch
|
||||
state.previous_shuffling_start_shard = state.current_shuffling_start_shard
|
||||
state.previous_shuffling_seed = state.current_shuffling_seed
|
||||
#TODO state.latest_index_roots[next_epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = hash_tree_root_final(get_active_validator_indices(state.validator_registry, next_epoch))
|
||||
|
||||
if state.finalized_epoch > state.validator_registry_update_epoch and
|
||||
allIt(
|
||||
0 ..< get_current_epoch_committee_count(state).int * EPOCH_LENGTH,
|
||||
state.latest_crosslinks[(state.current_epoch_start_shard + it.uint64) mod SHARD_COUNT].epoch > state.validator_registry_update_epoch):
|
||||
state.latest_crosslinks[(state.current_shuffling_start_shard + it.uint64) mod SHARD_COUNT].epoch > state.validator_registry_update_epoch):
|
||||
update_validator_registry(state)
|
||||
|
||||
state.current_calculation_epoch = next_epoch
|
||||
state.current_epoch_start_shard = (state.current_epoch_start_shard + get_current_epoch_committee_count(state) * EPOCH_LENGTH) mod SHARD_COUNT
|
||||
state.current_epoch_seed = generate_seed(state, state.current_calculation_epoch)
|
||||
state.current_shuffling_epoch = next_epoch
|
||||
state.current_shuffling_start_shard = (state.current_shuffling_start_shard + get_current_epoch_committee_count(state) * EPOCH_LENGTH) mod SHARD_COUNT
|
||||
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch)
|
||||
else:
|
||||
# If a validator registry change does NOT happen
|
||||
let epochs_since_last_registry_change = current_epoch - state.validator_registry_update_epoch
|
||||
if is_power_of_2(epochs_since_last_registry_change):
|
||||
state.current_calculation_epoch = next_epoch
|
||||
state.current_epoch_seed = generate_seed(state, state.current_calculation_epoch)
|
||||
# /Note/ that state.current_epoch_start_shard is left unchanged
|
||||
state.current_shuffling_epoch = next_epoch
|
||||
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_epoch)
|
||||
# /Note/ that state.current_shuffling_start_shard is left unchanged
|
||||
# TODO run process_penalties_and_exits
|
||||
|
||||
block: # Final updates
|
||||
|
|
|
@ -18,13 +18,13 @@ proc timeSinceGenesis*(s: BeaconState): Timestamp =
|
|||
|
||||
proc getSlotFromTime*(s: BeaconState, t = now()): SlotNumber =
|
||||
GENESIS_SLOT + uint64((int64(t - s.genesis_time * 1000) - detectedClockDrift) div
|
||||
int64(SLOT_DURATION * 1000))
|
||||
int64(SECONDS_PER_SLOT * 1000))
|
||||
|
||||
func slotStart*(s: BeaconState, slot: SlotNumber): Timestamp =
|
||||
(s.genesis_time + (slot * SLOT_DURATION)) * 1000
|
||||
(s.genesis_time + (slot * SECONDS_PER_SLOT)) * 1000
|
||||
|
||||
func slotMiddle*(s: BeaconState, slot: SlotNumber): Timestamp =
|
||||
s.slotStart(slot) + SLOT_DURATION * 500
|
||||
s.slotStart(slot) + SECONDS_PER_SLOT * 500
|
||||
|
||||
func slotEnd*(s: BeaconState, slot: SlotNumber): Timestamp =
|
||||
# TODO this is actually past the end, by nim inclusive semantics (sigh)
|
||||
|
@ -36,7 +36,7 @@ proc randomTimeInSlot*(s: BeaconState,
|
|||
## Returns a random moment within the slot.
|
||||
## The interval must be a sub-interval of [0..1].
|
||||
## Zero marks the begginning of the slot and One marks the end.
|
||||
s.slotStart(slot) + Timestamp(rand(interval) * float(SLOT_DURATION * 1000))
|
||||
s.slotStart(slot) + Timestamp(rand(interval) * float(SECONDS_PER_SLOT * 1000))
|
||||
|
||||
proc slotDistanceFromNow*(s: BeaconState): int64 =
|
||||
## Returns how many slots have passed since a particular BeaconState was finalized
|
||||
|
|
|
@ -3,7 +3,7 @@ import
|
|||
spec/[datatypes, crypto, digest, beaconstate], beacon_chain_db, conf
|
||||
|
||||
const
|
||||
WEAK_SUBJECTVITY_PERIOD* = uint64(4 * 30 * 24 * 60 * 60) div SLOT_DURATION
|
||||
WEAK_SUBJECTVITY_PERIOD* = uint64(4 * 30 * 24 * 60 * 60) div SECONDS_PER_SLOT
|
||||
# TODO: This needs revisiting.
|
||||
# Why was the validator WITHDRAWAL_PERIOD altered in the spec?
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ VALIDATOR_KEYGEN_BIN=$BUILD_OUTPUTS_DIR/validator_keygen
|
|||
# Run with "SHARD_COUNT=4 ./start.sh" to change these
|
||||
DEFS="-d:SHARD_COUNT=${SHARD_COUNT:-4} " # Spec default: 1024
|
||||
DEFS+="-d:EPOCH_LENGTH=${EPOCH_LENGTH:-8} " # Spec default: 64
|
||||
DEFS+="-d:SLOT_DURATION=${SLOT_DURATION:-4} " # Spec default: 6
|
||||
DEFS+="-d:SECONDS_PER_SLOT=${SECONDS_PER_SLOT:-4} " # Spec default: 6
|
||||
|
||||
if [[ -z "$SKIP_BUILDS" ]]; then
|
||||
nim c -o:"$VALIDATOR_KEYGEN_BIN" $DEFS -d:release beacon_chain/validator_keygen
|
||||
|
|
Loading…
Reference in New Issue