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
This commit is contained in:
parent
16fb9e8d11
commit
2e1515b107
|
@ -39,7 +39,8 @@ proc lmdGhost*(
|
|||
if get_ancestor(target, blck.slot) == blck:
|
||||
# The div on the balance is to chop off the insignification bits that
|
||||
# fluctuate a lot epoch to epoch to have a more stable fork choice
|
||||
res += get_effective_balance(start_state, validator_index) div
|
||||
res +=
|
||||
start_state.validator_registry[validator_index].effective_balance div
|
||||
FORK_CHOICE_BALANCE_INCREMENT
|
||||
res
|
||||
|
||||
|
|
|
@ -6,17 +6,11 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
chronicles, math, options, sequtils,
|
||||
algorithm, chronicles, math, options, sequtils,
|
||||
../extras, ../ssz, ../beacon_node_types,
|
||||
./bitfield, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
|
||||
tables
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_effective_balance
|
||||
func get_effective_balance*(state: BeaconState, index: ValidatorIndex): Gwei =
|
||||
## Return the effective balance (also known as "balance at stake") for a
|
||||
## validator with the given ``index``.
|
||||
min(state.balances[index], MAX_EFFECTIVE_BALANCE)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#verify_merkle_branch
|
||||
func verify_merkle_branch(leaf: Eth2Digest, proof: openarray[Eth2Digest], depth: uint64, index: uint64, root: Eth2Digest): bool =
|
||||
## Verify that the given ``leaf`` is on the merkle branch ``proof``
|
||||
|
@ -35,13 +29,13 @@ func verify_merkle_branch(leaf: Eth2Digest, proof: openarray[Eth2Digest], depth:
|
|||
value = eth2hash(buf)
|
||||
value == root
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#increase_balance
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#increase_balance
|
||||
func increase_balance*(
|
||||
state: var BeaconState, index: ValidatorIndex, delta: Gwei) =
|
||||
# Increase validator balance by ``delta``.
|
||||
state.balances[index] += delta
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#decrease_balance
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#decrease_balance
|
||||
func decrease_balance*(
|
||||
state: var BeaconState, index: ValidatorIndex, delta: Gwei) =
|
||||
# Decrease validator balance by ``delta`` with underflow protection.
|
||||
|
@ -51,7 +45,7 @@ func decrease_balance*(
|
|||
else:
|
||||
state.balances[index] - delta
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#deposits
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#deposits
|
||||
func process_deposit*(
|
||||
state: var BeaconState, deposit: Deposit, flags: UpdateFlags = {}): bool =
|
||||
# Process an Eth1 deposit, registering a validator or increasing its balance.
|
||||
|
@ -114,13 +108,13 @@ func process_deposit*(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#get_delayed_activation_exit_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_delayed_activation_exit_epoch
|
||||
func get_delayed_activation_exit_epoch*(epoch: Epoch): Epoch =
|
||||
## Return the epoch at which an activation or exit triggered in ``epoch``
|
||||
## takes effect.
|
||||
epoch + 1 + ACTIVATION_EXIT_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_churn_limit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_churn_limit
|
||||
func get_churn_limit(state: BeaconState): uint64 =
|
||||
max(
|
||||
MIN_PER_EPOCH_CHURN_LIMIT,
|
||||
|
@ -128,7 +122,7 @@ func get_churn_limit(state: BeaconState): uint64 =
|
|||
CHURN_LIMIT_QUOTIENT
|
||||
).uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#initiate_validator_exit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#initiate_validator_exit
|
||||
func initiate_validator_exit*(state: var BeaconState,
|
||||
index: ValidatorIndex) =
|
||||
# Initiate the validator of the given ``index``.
|
||||
|
@ -139,6 +133,7 @@ func initiate_validator_exit*(state: var BeaconState,
|
|||
return
|
||||
|
||||
# Compute exit queue epoch
|
||||
# TODO try zero-functional here
|
||||
let exit_epochs = mapIt(
|
||||
filterIt(state.validator_registry, it.exit_epoch != FAR_FUTURE_EPOCH),
|
||||
it.exit_epoch)
|
||||
|
@ -158,23 +153,6 @@ func initiate_validator_exit*(state: var BeaconState,
|
|||
validator.withdrawable_epoch =
|
||||
validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#exit_validator
|
||||
func exit_validator*(state: var BeaconState,
|
||||
index: ValidatorIndex) =
|
||||
## Exit the validator with the given ``index``.
|
||||
## Note that this function mutates ``state``.
|
||||
|
||||
let
|
||||
validator = addr state.validator_registry[index]
|
||||
delayed_activation_exit_epoch =
|
||||
get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||
|
||||
# The following updates only occur if not previous exited
|
||||
if validator.exit_epoch <= delayed_activation_exit_epoch:
|
||||
return
|
||||
|
||||
validator.exit_epoch = delayed_activation_exit_epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#slash_validator
|
||||
func slash_validator*(state: var BeaconState, slashed_index: ValidatorIndex) =
|
||||
# Slash the validator with index ``index``.
|
||||
|
@ -247,18 +225,10 @@ func get_genesis_beacon_state*(
|
|||
epoch: GENESIS_EPOCH,
|
||||
),
|
||||
|
||||
validator_registry_update_epoch: GENESIS_EPOCH,
|
||||
|
||||
# validator_registry and balances automatically initalized
|
||||
|
||||
# Randomness and committees
|
||||
# latest_randao_mixes automatically initialized
|
||||
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_epoch_attestations and current_epoch_attestations automatically
|
||||
|
@ -282,7 +252,7 @@ func get_genesis_beacon_state*(
|
|||
)
|
||||
|
||||
for i in 0 ..< SHARD_COUNT:
|
||||
state.latest_crosslinks[i] = Crosslink(
|
||||
state.current_crosslinks[i] = Crosslink(
|
||||
epoch: GENESIS_EPOCH, crosslink_data_root: ZERO_HASH)
|
||||
|
||||
# Process genesis deposits
|
||||
|
@ -300,7 +270,6 @@ func get_genesis_beacon_state*(
|
|||
get_active_validator_indices(state, GENESIS_EPOCH))
|
||||
for index in 0 ..< LATEST_ACTIVE_INDEX_ROOTS_LENGTH:
|
||||
state.latest_active_index_roots[index] = genesis_active_index_root
|
||||
state.current_shuffling_seed = generate_seed(state, GENESIS_EPOCH)
|
||||
|
||||
state
|
||||
|
||||
|
@ -314,7 +283,7 @@ func get_initial_beacon_block*(state: BeaconState): BeaconBlock =
|
|||
# initialized to default values.
|
||||
)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_attestation_slot
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_attestation_slot
|
||||
func get_attestation_slot*(state: BeaconState,
|
||||
attestation: Attestation|PendingAttestation,
|
||||
committee_count: uint64): Slot =
|
||||
|
@ -331,7 +300,7 @@ func get_attestation_slot*(state: BeaconState,
|
|||
get_attestation_slot(
|
||||
state, attestation, get_epoch_committee_count(state, epoch))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_block_root_at_slot
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_block_root_at_slot
|
||||
func get_block_root_at_slot*(state: BeaconState,
|
||||
slot: Slot): Eth2Digest =
|
||||
# Return the block root at a recent ``slot``.
|
||||
|
@ -340,7 +309,7 @@ func get_block_root_at_slot*(state: BeaconState,
|
|||
doAssert slot < state.slot
|
||||
state.latest_block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_block_root
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_block_root
|
||||
func get_block_root*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||
# Return the block root at a recent ``epoch``.
|
||||
get_block_root_at_slot(state, get_epoch_start_slot(epoch))
|
||||
|
@ -405,7 +374,7 @@ iterator get_attestation_participants_cached*(state: BeaconState,
|
|||
|
||||
var found = false
|
||||
for crosslink_committee in get_crosslink_committees_at_slot_cached(
|
||||
state, attestation_data.slot, false, cache):
|
||||
state, attestation_data.slot, cache):
|
||||
if crosslink_committee.shard == attestation_data.shard:
|
||||
# TODO this and other attestation-based fields need validation so we don't
|
||||
# crash on a malicious attestation!
|
||||
|
@ -420,75 +389,48 @@ iterator get_attestation_participants_cached*(state: BeaconState,
|
|||
break
|
||||
doAssert found, "Couldn't find crosslink committee"
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#ejections
|
||||
func process_ejections*(state: var BeaconState) =
|
||||
## Iterate through the validator registry and eject active validators with
|
||||
## balance below ``EJECTION_BALANCE``
|
||||
for index in get_active_validator_indices(
|
||||
state, get_current_epoch(state)):
|
||||
if state.balances[index] < EJECTION_BALANCE:
|
||||
exit_validator(state, index)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_total_balance
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_total_balance
|
||||
func get_total_balance*(state: BeaconState, validators: auto): Gwei =
|
||||
# Return the combined effective balance of an array of validators.
|
||||
foldl(validators, a + get_effective_balance(state, b), 0'u64)
|
||||
# Return the combined effective balance of an array of ``validators``.
|
||||
foldl(validators, a + state.validator_registry[b].effective_balance, 0'u64)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
|
||||
func should_update_validator_registry*(state: BeaconState): bool =
|
||||
# Must have finalized a new block
|
||||
if state.finalized_epoch <= state.validator_registry_update_epoch:
|
||||
return false
|
||||
# Must have processed new crosslinks on all shards of the current epoch
|
||||
allIt(0 ..< get_epoch_committee_count(state, get_current_epoch(state)).int,
|
||||
not (state.latest_crosslinks[
|
||||
((state.current_shuffling_start_shard + it.uint64) mod
|
||||
SHARD_COUNT).int].epoch <= state.validator_registry_update_epoch))
|
||||
|
||||
func update_validator_registry*(state: var BeaconState) =
|
||||
## Update validator registry.
|
||||
## Note that this function mutates ``state``.
|
||||
let
|
||||
current_epoch = get_current_epoch(state)
|
||||
# The active validators
|
||||
active_validator_indices =
|
||||
get_active_validator_indices(state, current_epoch)
|
||||
# The total effective balance of active validators
|
||||
total_balance = get_total_balance(state, active_validator_indices)
|
||||
|
||||
# The maximum balance churn in Gwei (for deposits and exits separately)
|
||||
max_balance_churn = max(
|
||||
MAX_EFFECTIVE_BALANCE,
|
||||
total_balance div (2 * MAX_BALANCE_CHURN_QUOTIENT)
|
||||
)
|
||||
|
||||
# Activate validators within the allowable balance churn
|
||||
var balance_churn = 0'u64
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#registry-updates
|
||||
func process_registry_updates*(state: var BeaconState) =
|
||||
# Process activation eligibility and ejections
|
||||
for index, validator in state.validator_registry:
|
||||
if validator.activation_epoch == FAR_FUTURE_EPOCH and
|
||||
state.balances[index] >= MAX_EFFECTIVE_BALANCE:
|
||||
# Check the balance churn would be within the allowance
|
||||
balance_churn += get_effective_balance(state, index.ValidatorIndex)
|
||||
if balance_churn > max_balance_churn:
|
||||
break
|
||||
|
||||
# Activate validator
|
||||
if validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
||||
validator.effective_balance >= MAX_EFFECTIVE_BALANCE:
|
||||
state.validator_registry[index].activation_eligibility_epoch =
|
||||
get_current_epoch(state)
|
||||
|
||||
# Exit validators within the allowable balance churn
|
||||
balance_churn = 0
|
||||
if is_active_validator(validator, get_current_epoch(state)) and
|
||||
validator.effective_balance <= EJECTION_BALANCE:
|
||||
initiate_validator_exit(state, index.ValidatorIndex)
|
||||
|
||||
## Queue validators eligible for activation and not dequeued for activation
|
||||
## prior to finalized epoch
|
||||
var activation_queue : seq[tuple[a: Epoch, b: int]] = @[]
|
||||
for index, validator in state.validator_registry:
|
||||
if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and
|
||||
validator.activation_epoch >=
|
||||
get_delayed_activation_exit_epoch(state.finalized_epoch):
|
||||
activation_queue.add (
|
||||
state.validator_registry[index].activation_eligibility_epoch, index)
|
||||
|
||||
activation_queue.sort(system.cmp)
|
||||
|
||||
## Dequeued validators for activation up to churn limit (without resetting
|
||||
## activation epoch)
|
||||
let churn_limit = get_churn_limit(state)
|
||||
for i, epoch_and_index in activation_queue:
|
||||
if i.uint64 >= churn_limit:
|
||||
break
|
||||
let
|
||||
(epoch, index) = epoch_and_index
|
||||
validator = addr state.validator_registry[index]
|
||||
if validator.activation_epoch == FAR_FUTURE_EPOCH:
|
||||
# Check the balance churn would be within the allowance
|
||||
balance_churn += get_effective_balance(state, index.ValidatorIndex)
|
||||
if balance_churn > max_balance_churn:
|
||||
break
|
||||
|
||||
# Exit validator
|
||||
exit_validator(state, index.ValidatorIndex)
|
||||
|
||||
state.validator_registry_update_epoch = current_epoch
|
||||
validator.activation_epoch =
|
||||
get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#attestations
|
||||
proc checkAttestation*(
|
||||
|
@ -562,11 +504,11 @@ proc checkAttestation*(
|
|||
epoch: slot_to_epoch(attestation.data.slot)
|
||||
)
|
||||
]
|
||||
if not (state.latest_crosslinks[attestation.data.shard] in
|
||||
if not (state.current_crosslinks[attestation.data.shard] in
|
||||
acceptable_crosslink_data):
|
||||
warn("Unexpected crosslink shard",
|
||||
state_latest_crosslinks_attestation_data_shard =
|
||||
state.latest_crosslinks[attestation.data.shard],
|
||||
state.current_crosslinks[attestation.data.shard],
|
||||
attestation_data_previous_crosslink = attestation.data.previous_crosslink,
|
||||
epoch = humaneEpochNum(slot_to_epoch(attestation.data.slot)),
|
||||
actual_epoch = slot_to_epoch(attestation.data.slot),
|
||||
|
@ -658,7 +600,7 @@ proc makeAttestationData*(
|
|||
beacon_block_root: beacon_block_root,
|
||||
target_root: target_root,
|
||||
crosslink_data_root: Eth2Digest(), # Stub in phase0
|
||||
previous_crosslink: state.latest_crosslinks[shard],
|
||||
previous_crosslink: state.current_crosslinks[shard],
|
||||
source_epoch: state.current_justified_epoch,
|
||||
source_root: state.current_justified_root,
|
||||
target_epoch: slot_to_epoch(epoch_start_slot)
|
||||
|
|
|
@ -17,14 +17,14 @@ func init*(T: type BitField, bits: int): BitField =
|
|||
#proc readValue*(r: var JsonReader, a: var BitField) {.inline.} =
|
||||
# a.bits = r.readValue(string).hexToSeqByte()
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#get_bitfield_bit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_bitfield_bit
|
||||
func get_bitfield_bit*(bitfield: BitField, i: int): bool =
|
||||
# Extract the bit in ``bitfield`` at position ``i``.
|
||||
doAssert 0 <= i div 8, "i: " & $i & " i div 8: " & $(i div 8)
|
||||
doAssert i div 8 < bitfield.bits.len, "i: " & $i & " i div 8: " & $(i div 8)
|
||||
((bitfield.bits[i div 8] shr (i mod 8)) mod 2) > 0'u8
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#verify_bitfield
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#verify_bitfield
|
||||
func verify_bitfield*(bitfield: BitField, committee_size: int): bool =
|
||||
# Verify ``bitfield`` against the ``committee_size``.
|
||||
if len(bitfield.bits) != (committee_size + 7) div 8:
|
||||
|
|
|
@ -69,7 +69,7 @@ template hash*(k: ValidatorPubKey|ValidatorPrivKey): Hash =
|
|||
|
||||
func pubKey*(pk: ValidatorPrivKey): ValidatorPubKey = pk.getKey()
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/bls_signature.md#bls_aggregate_pubkeys
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/bls_signature.md#bls_aggregate_pubkeys
|
||||
func bls_aggregate_pubkeys*(keys: openArray[ValidatorPubKey]): ValidatorPubKey =
|
||||
var empty = true
|
||||
for key in keys:
|
||||
|
@ -79,14 +79,14 @@ func bls_aggregate_pubkeys*(keys: openArray[ValidatorPubKey]): ValidatorPubKey =
|
|||
else:
|
||||
result.combine(key)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/bls_signature.md#bls_verify
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/bls_signature.md#bls_verify
|
||||
func bls_verify*(
|
||||
pubkey: ValidatorPubKey, msg: openArray[byte], sig: ValidatorSig,
|
||||
domain: uint64): bool =
|
||||
# name from spec!
|
||||
sig.verify(msg, domain, pubkey)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/bls_signature.md#bls_verify_multiple
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/bls_signature.md#bls_verify_multiple
|
||||
func bls_verify_multiple*(
|
||||
pubkeys: seq[ValidatorPubKey], message_hashes: openArray[Eth2Digest],
|
||||
sig: ValidatorSig, domain: uint64): bool =
|
||||
|
|
|
@ -40,7 +40,7 @@ import
|
|||
|
||||
|
||||
# Constant presets
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/configs/constant_presets/
|
||||
# https://github.com/ethereum/eth2.0-specs/tree/v0.6.2/configs/constant_presets/
|
||||
const const_preset*{.strdefine.} = "mainnet"
|
||||
|
||||
when const_preset == "mainnet":
|
||||
|
@ -53,17 +53,10 @@ else:
|
|||
{.fatal: "Preset \"" & const_preset ".nim\" is not supported.".}
|
||||
|
||||
const
|
||||
SPEC_VERSION* = "0.6.1" ## \
|
||||
SPEC_VERSION* = "0.6.2" ## \
|
||||
## Spec version we're aiming to be compatible with, right now
|
||||
## TODO: improve this scheme once we can negotiate versions in protocol
|
||||
|
||||
# Misc
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#misc
|
||||
|
||||
# TODO remove, not in post-0.5.1
|
||||
MAX_BALANCE_CHURN_QUOTIENT* = 2^5 ##\
|
||||
|
||||
# Gwei values
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#gwei-values
|
||||
|
@ -86,7 +79,7 @@ type
|
|||
Shard* = uint64
|
||||
Gwei* = uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#proposerslashing
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#proposerslashing
|
||||
ProposerSlashing* = object
|
||||
proposer_index*: uint64 ##\
|
||||
## Proposer index
|
||||
|
@ -97,7 +90,7 @@ type
|
|||
header_2*: BeaconBlockHeader ##\
|
||||
# Second block header
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#attesterslashing
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#attesterslashing
|
||||
AttesterSlashing* = object
|
||||
attestation_1*: IndexedAttestation ## \
|
||||
## First attestation
|
||||
|
@ -118,7 +111,7 @@ type
|
|||
aggregate_signature*: ValidatorSig ## \
|
||||
## Aggregate signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#attestation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#attestation
|
||||
Attestation* = object
|
||||
aggregation_bitfield*: BitField ##\
|
||||
## Attester aggregation bitfield
|
||||
|
@ -149,12 +142,12 @@ type
|
|||
previous_crosslink*: Crosslink
|
||||
crosslink_data_root*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
||||
AttestationDataAndCustodyBit* = object
|
||||
data*: AttestationData
|
||||
custody_bit*: bool
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#deposit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#deposit
|
||||
Deposit* = object
|
||||
proof*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] ##\
|
||||
## Branch in the deposit tree
|
||||
|
@ -165,7 +158,7 @@ type
|
|||
data*: DepositData ##\
|
||||
## Data
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#depositdata
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#depositdata
|
||||
DepositData* = object
|
||||
pubkey*: ValidatorPubKey ##\
|
||||
## BLS pubkey
|
||||
|
@ -181,7 +174,7 @@ type
|
|||
signature*: ValidatorSig ##\
|
||||
## Container self-signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#voluntaryexit
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#voluntaryexit
|
||||
VoluntaryExit* = object
|
||||
# Minimum epoch for processing exit
|
||||
epoch*: Epoch
|
||||
|
@ -190,7 +183,7 @@ type
|
|||
# Validator signature
|
||||
signature*: ValidatorSig
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#transfer
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#transfer
|
||||
Transfer* = object
|
||||
sender*: uint64 ##\
|
||||
## Sender index
|
||||
|
@ -213,7 +206,7 @@ type
|
|||
signature*: ValidatorSig ##\
|
||||
## Sender signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#beaconblock
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/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
|
||||
|
@ -234,7 +227,7 @@ type
|
|||
signature*: ValidatorSig ##\
|
||||
## Proposer signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#beaconblockheader
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#beaconblockheader
|
||||
BeaconBlockHeader* = object
|
||||
slot*: Slot
|
||||
previous_block_root*: Eth2Digest
|
||||
|
@ -257,7 +250,7 @@ type
|
|||
signature*: ValidatorSig
|
||||
body*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
BeaconBlockBody* = object
|
||||
randao_reveal*: ValidatorSig
|
||||
eth1_data*: Eth1Data
|
||||
|
@ -269,7 +262,7 @@ type
|
|||
voluntary_exits*: seq[VoluntaryExit]
|
||||
transfers*: seq[Transfer]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#beaconstate
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
slot*: Slot
|
||||
genesis_time*: uint64
|
||||
|
@ -281,17 +274,9 @@ type
|
|||
balances*: seq[uint64] ##\
|
||||
## Validator balances in Gwei!
|
||||
|
||||
validator_registry_update_epoch*: Epoch
|
||||
|
||||
# Randomness and committees
|
||||
latest_randao_mixes*: array[LATEST_RANDAO_MIXES_LENGTH, Eth2Digest]
|
||||
latest_start_shard*: Shard
|
||||
previous_shuffling_start_shard*: uint64
|
||||
current_shuffling_start_shard*: uint64
|
||||
previous_shuffling_epoch*: Epoch
|
||||
current_shuffling_epoch*: Epoch
|
||||
previous_shuffling_seed*: Eth2Digest
|
||||
current_shuffling_seed*: Eth2Digest
|
||||
|
||||
# Finality
|
||||
previous_epoch_attestations*: seq[PendingAttestation]
|
||||
|
@ -305,7 +290,8 @@ type
|
|||
finalized_root*: Eth2Digest
|
||||
|
||||
# Recent state
|
||||
latest_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
current_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
previous_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
latest_block_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
|
||||
## Needed to process attestations, older to newer
|
||||
latest_state_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
|
||||
|
@ -323,7 +309,7 @@ type
|
|||
eth1_data_votes*: seq[Eth1Data]
|
||||
deposit_index*: uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#validator
|
||||
Validator* = object
|
||||
pubkey*: ValidatorPubKey ##\
|
||||
## BLS public key
|
||||
|
@ -349,7 +335,7 @@ type
|
|||
effective_balance*: uint64 ##\
|
||||
## Effective balance
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#crosslink
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#crosslink
|
||||
Crosslink* = object
|
||||
epoch*: Epoch ##\
|
||||
## Epoch number
|
||||
|
@ -360,18 +346,14 @@ type
|
|||
crosslink_data_root*: Eth2Digest ##\
|
||||
## Shard data since the previous crosslink
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#pendingattestation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#pendingattestation
|
||||
PendingAttestation* = object
|
||||
aggregation_bitfield*: BitField ## Attester participation bitfield
|
||||
data*: AttestationData ## Attestation data
|
||||
|
||||
# TODO remove
|
||||
inclusion_slot*: Slot ## Inclusion slot
|
||||
|
||||
inclusion_delay*: uint64 ## Inclusion delay
|
||||
proposer_index*: ValidatorIndex ## Proposer index
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#historicalbatch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#historicalbatch
|
||||
HistoricalBatch* = object
|
||||
block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
|
||||
## Block roots
|
||||
|
@ -379,7 +361,7 @@ type
|
|||
state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
|
||||
## State roots
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#fork
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#fork
|
||||
Fork* = object
|
||||
previous_version*: array[4, byte] ##\
|
||||
## Previous fork version
|
||||
|
@ -390,10 +372,10 @@ type
|
|||
epoch*: Epoch ##\
|
||||
## Fork epoch number
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#eth1data
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#eth1data
|
||||
Eth1Data* = object
|
||||
deposit_root*: Eth2Digest ##\
|
||||
## Data being voted for
|
||||
## Root of the deposit tree
|
||||
|
||||
deposit_count*: uint64 ##\
|
||||
## Total number of deposits
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
# Serenity hash function / digest
|
||||
#
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#hash
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#hash
|
||||
#
|
||||
# In Phase 0 the beacon chain is deployed with SHA256 (SHA2-256).
|
||||
# Note that is is different from Keccak256 (often mistakenly called SHA3-256)
|
||||
|
|
|
@ -9,18 +9,10 @@
|
|||
|
||||
import ./datatypes, ./digest, sequtils, math
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#split
|
||||
func split*[T](lst: openArray[T], N: Positive): seq[seq[T]] =
|
||||
## split lst in N pieces, with each piece having `len(lst) div N` or
|
||||
## `len(lst) div N + 1` pieces
|
||||
# TODO: implement as an iterator
|
||||
result = newSeq[seq[T]](N)
|
||||
for i in 0 ..< N:
|
||||
result[i] = lst[lst.len * i div N ..< lst.len * (i+1) div N] # TODO: avoid alloc via toOpenArray
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#integer_squareroot
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#integer_squareroot
|
||||
func integer_squareroot*(n: SomeInteger): SomeInteger =
|
||||
## The largest integer ``x`` such that ``x**2`` is less than ``n``.
|
||||
## The largest integer ``x`` such that ``x**2`` is less than or equal to
|
||||
## ``n``.
|
||||
doAssert n >= 0'u64
|
||||
|
||||
var
|
||||
|
@ -31,9 +23,6 @@ func integer_squareroot*(n: SomeInteger): SomeInteger =
|
|||
y = (x + n div x) div 2
|
||||
x
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#is_power_of_two
|
||||
func is_power_of_2*(v: uint64): bool = (v > 0'u64) and (v and (v-1)) == 0
|
||||
|
||||
# TODO reuse as necessary/useful for merkle proof building
|
||||
func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
||||
## Merkleize ``values`` (where ``len(values)`` is a power of two) and return
|
||||
|
@ -69,52 +58,22 @@ func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
|||
|
||||
o[1]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#slot_to_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#slot_to_epoch
|
||||
func slot_to_epoch*(slot: Slot|uint64): Epoch =
|
||||
# Return the epoch number of the given ``slot``.
|
||||
(slot div SLOTS_PER_EPOCH).Epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#get_epoch_start_slot
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_epoch_start_slot
|
||||
func get_epoch_start_slot*(epoch: Epoch): Slot =
|
||||
# Return the starting slot of the given ``epoch``.
|
||||
(epoch * SLOTS_PER_EPOCH).Slot
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#is_double_vote
|
||||
func is_double_vote*(attestation_data_1: AttestationData,
|
||||
attestation_data_2: AttestationData): bool =
|
||||
## Check if ``attestation_data_1`` and ``attestation_data_2`` have the same
|
||||
## target.
|
||||
let
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||
target_epoch_1 == target_epoch_2
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#is_surround_vote
|
||||
func is_surround_vote*(attestation_data_1: AttestationData,
|
||||
attestation_data_2: AttestationData): bool =
|
||||
## Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||
let
|
||||
source_epoch_1 = attestation_data_1.source_epoch
|
||||
source_epoch_2 = attestation_data_2.source_epoch
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||
|
||||
source_epoch_1 < source_epoch_2 and target_epoch_2 < target_epoch_1
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#is_active_validator
|
||||
func is_active_validator*(validator: Validator, epoch: Epoch): bool =
|
||||
### Check if ``validator`` is active
|
||||
validator.activation_epoch <= epoch and epoch < validator.exit_epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#get_active_validator_indices
|
||||
func get_active_validator_indices*(
|
||||
validators: openarray[Validator], epoch: Epoch): seq[ValidatorIndex] =
|
||||
## Gets indices of active validators from validators
|
||||
## TODO remove when shuffling's refactored persuant to 0.6.1
|
||||
for idx, val in validators:
|
||||
if is_active_validator(val, epoch):
|
||||
result.add idx.ValidatorIndex
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_active_validator_indices
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_active_validator_indices
|
||||
func get_active_validator_indices*(state: BeaconState, epoch: Epoch):
|
||||
seq[ValidatorIndex] =
|
||||
## Gets indices of active validators from validators
|
||||
|
@ -122,16 +81,6 @@ func get_active_validator_indices*(state: BeaconState, epoch: Epoch):
|
|||
if is_active_validator(val, epoch):
|
||||
result.add idx.ValidatorIndex
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#get_epoch_committee_count
|
||||
# Not quite the 0.5.1 version. TODO remove when shuffling refactoring complete
|
||||
func get_epoch_committee_count*(
|
||||
validators: openarray[Validator], epoch: Epoch): uint64 =
|
||||
# Return the number of committees at ``epoch``.
|
||||
let active_validator_indices = get_active_validator_indices(validators, epoch)
|
||||
clamp(
|
||||
len(active_validator_indices) div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
|
||||
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64 * SLOTS_PER_EPOCH
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_epoch_committee_count
|
||||
func get_epoch_committee_count*(state: BeaconState, epoch: Epoch): uint64 =
|
||||
# Return the number of committees at ``epoch``.
|
||||
|
@ -140,7 +89,7 @@ func get_epoch_committee_count*(state: BeaconState, epoch: Epoch): uint64 =
|
|||
len(active_validator_indices) div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
|
||||
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64 * SLOTS_PER_EPOCH
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#get_current_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_current_epoch
|
||||
func get_current_epoch*(state: BeaconState): Epoch =
|
||||
# Return the current epoch of the given ``state``.
|
||||
doAssert state.slot >= GENESIS_SLOT, $state.slot
|
||||
|
@ -155,14 +104,16 @@ func get_randao_mix*(state: BeaconState,
|
|||
## current_epoch + ACTIVATION_EXIT_DELAY].
|
||||
state.latest_randao_mixes[epoch mod LATEST_RANDAO_MIXES_LENGTH]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_active_index_root
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_active_index_root
|
||||
func get_active_index_root(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||
# Returns the index root at a recent ``epoch``.
|
||||
## ``epoch`` expected to be between
|
||||
## (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch + ACTIVATION_EXIT_DELAY].
|
||||
## TODO maybe assert this, but omission of such seems conspicuously
|
||||
## intentional
|
||||
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
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#bytes_to_int
|
||||
func bytes_to_int*(data: openarray[byte]): uint64 =
|
||||
doAssert data.len == 8
|
||||
|
||||
|
@ -171,7 +122,7 @@ func bytes_to_int*(data: openarray[byte]): uint64 =
|
|||
for i in countdown(7, 0):
|
||||
result = result * 256 + data[i]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#int_to_bytes1-int_to_bytes2-
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#int_to_bytes1-int_to_bytes2-
|
||||
# Have 1, 4, 8, and 32-byte versions. 1+ more and maybe worth metaprogramming.
|
||||
func int_to_bytes32*(x: uint64): array[32, byte] =
|
||||
## Little-endian data representation
|
||||
|
@ -220,12 +171,15 @@ func get_domain*(
|
|||
func get_domain*(state: BeaconState, domain_type: SignatureDomain): uint64 =
|
||||
get_domain(state, domain_type, get_current_epoch(state))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#generate_seed
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#generate_seed
|
||||
func generate_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||
# Generate a seed for the given ``epoch``.
|
||||
|
||||
var seed_input : array[32*3, byte]
|
||||
|
||||
# Detect potential underflow
|
||||
doAssert LATEST_RANDAO_MIXES_LENGTH >= MIN_SEED_LOOKAHEAD
|
||||
|
||||
seed_input[0..31] =
|
||||
get_randao_mix(state,
|
||||
epoch + LATEST_RANDAO_MIXES_LENGTH - MIN_SEED_LOOKAHEAD).data
|
||||
|
|
|
@ -57,7 +57,7 @@ const
|
|||
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#deposit-contract
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#deposit-contract
|
||||
|
||||
DEPOSIT_CONTRACT_ADDRESS = "0x1234567890123456789012345678901234567890"
|
||||
# TODO
|
||||
|
@ -66,7 +66,7 @@ const
|
|||
|
||||
# Gwei values
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#gwei-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/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
|
||||
|
@ -141,23 +141,23 @@ const
|
|||
|
||||
# State list lengths
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
LATEST_RANDAO_MIXES_LENGTH* = 8192
|
||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 8192 # 2'u64^13, epochs
|
||||
LATEST_SLASHED_EXIT_LENGTH* = 8192 # epochs
|
||||
|
||||
# Reward and penalty quotients
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
BASE_REWARD_QUOTIENT* = 2'u64^5
|
||||
WHISTLEBLOWING_REWARD_QUOTIENT* = 2'u64^9
|
||||
PROPOSER_REWARD_QUOTIENT* = 2'u64^3
|
||||
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^25
|
||||
MIN_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
MIN_SLASHING_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
|
||||
# Max operations per block
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
MAX_PROPOSER_SLASHINGS* = 2^4
|
||||
MAX_ATTESTER_SLASHINGS* = 2^0
|
||||
MAX_ATTESTATIONS* = 2^7
|
||||
|
@ -168,7 +168,7 @@ const
|
|||
type
|
||||
# Signature domains
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#signature-domains
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#signature-domains
|
||||
SignatureDomain* {.pure.} = enum
|
||||
DOMAIN_BEACON_PROPOSER = 0
|
||||
DOMAIN_RANDAO = 1
|
||||
|
|
|
@ -22,7 +22,7 @@ type
|
|||
|
||||
{.experimental: "codeReordering".} # SLOTS_PER_EPOCH is use before being defined in spec
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/configs/constant_presets/minimal.yaml
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/configs/constant_presets/minimal.yaml
|
||||
const
|
||||
# Misc
|
||||
# ---------------------------------------------------------------
|
||||
|
@ -43,7 +43,7 @@ const
|
|||
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#deposit-contract
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#deposit-contract
|
||||
|
||||
# Unchanged
|
||||
DEPOSIT_CONTRACT_ADDRESS = "0x1234567890123456789012345678901234567890"
|
||||
|
@ -51,7 +51,7 @@ const
|
|||
|
||||
# Gwei values
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#gwei-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#gwei-values
|
||||
|
||||
# Unchanged
|
||||
MIN_DEPOSIT_AMOUNT* = 2'u64^0 * 10'u64^9
|
||||
|
@ -71,10 +71,13 @@ const
|
|||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_fork-choice.md#time-parameters
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_fork-choice.md#time-parameters
|
||||
|
||||
# Unchanged
|
||||
SECONDS_PER_SLOT*{.intdefine.} = 6'u64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#time-parameters
|
||||
# Unchanged
|
||||
MIN_ATTESTATION_INCLUSION_DELAY* = 2'u64^2
|
||||
|
||||
# Changed
|
||||
|
@ -96,7 +99,7 @@ const
|
|||
|
||||
# State list lengths
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
|
||||
# Changed
|
||||
LATEST_RANDAO_MIXES_LENGTH* = 64
|
||||
|
@ -105,18 +108,18 @@ const
|
|||
|
||||
# Reward and penalty quotients
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
|
||||
|
||||
# Unchanged
|
||||
BASE_REWARD_QUOTIENT* = 2'u64^5
|
||||
WHISTLEBLOWING_REWARD_QUOTIENT* = 2'u64^9
|
||||
PROPOSER_REWARD_QUOTIENT* = 2'u64^3
|
||||
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^25
|
||||
MIN_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
MIN_SLASHING_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
|
||||
# Max operations per block
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
|
||||
# Unchanged
|
||||
MAX_PROPOSER_SLASHINGS* = 2^4
|
||||
|
@ -129,7 +132,7 @@ const
|
|||
type
|
||||
# Signature domains
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#signature-domains
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#signature-domains
|
||||
SignatureDomain* {.pure.} = enum
|
||||
DOMAIN_BEACON_PROPOSER = 0
|
||||
DOMAIN_RANDAO = 1
|
||||
|
|
|
@ -118,26 +118,6 @@ func get_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Eth2Di
|
|||
if bit != 0:
|
||||
result = flip
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#get_shuffling
|
||||
func get_shuffling*(seed: Eth2Digest,
|
||||
validators: openArray[Validator],
|
||||
epoch: Epoch,
|
||||
): seq[seq[ValidatorIndex]] =
|
||||
## This function is factored to facilitate testing with
|
||||
## https://github.com/ethereum/eth2.0-test-generators/tree/master/permutated_index
|
||||
## test vectors, which the split of get_shuffling obfuscates.
|
||||
|
||||
let
|
||||
active_validator_indices = get_active_validator_indices(validators, epoch)
|
||||
list_size = active_validator_indices.len.uint64
|
||||
committees_per_epoch = get_epoch_committee_count(
|
||||
validators, epoch).int
|
||||
shuffled_seq = get_shuffled_seq(seed, list_size)
|
||||
|
||||
# Split the shuffled list into committees_per_epoch pieces
|
||||
result = split(shuffled_seq, committees_per_epoch)
|
||||
doAssert result.len() == committees_per_epoch # what split should do..
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_previous_epoch
|
||||
func get_previous_epoch*(state: BeaconState): Epoch =
|
||||
## Return the previous epoch of the given ``state``.
|
||||
|
@ -148,114 +128,14 @@ func get_previous_epoch*(state: BeaconState): Epoch =
|
|||
else:
|
||||
current_epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_crosslink_committees_at_slot
|
||||
func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot|uint64,
|
||||
registry_change: bool = false):
|
||||
seq[CrosslinkCommittee] =
|
||||
## Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||
##
|
||||
## Note: There are two possible shufflings for crosslink committees for a
|
||||
## ``slot`` in the next epoch -- with and without a `registry_change`
|
||||
|
||||
let
|
||||
epoch = slot_to_epoch(slot) # TODO, enforce slot to be a Slot
|
||||
current_epoch = get_current_epoch(state)
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
next_epoch = current_epoch + 1
|
||||
|
||||
doAssert previous_epoch <= epoch,
|
||||
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
|
||||
", epoch: " & $humaneEpochNum(epoch) &
|
||||
" (slot: " & $humaneSlotNum(slot.Slot) & ")" &
|
||||
", Next epoch: " & $humaneEpochNum(next_epoch)
|
||||
|
||||
doAssert epoch <= next_epoch,
|
||||
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
|
||||
", epoch: " & $humaneEpochNum(epoch) &
|
||||
" (slot: " & $humaneSlotNum(slot.Slot) & ")" &
|
||||
", Next epoch: " & $humaneEpochNum(next_epoch)
|
||||
|
||||
template get_epoch_specific_params(): auto =
|
||||
if epoch == current_epoch:
|
||||
let
|
||||
committees_per_epoch = get_epoch_committee_count(state, current_epoch)
|
||||
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)
|
||||
elif epoch == previous_epoch:
|
||||
let
|
||||
committees_per_epoch = get_epoch_committee_count(state, previous_epoch)
|
||||
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)
|
||||
else:
|
||||
doAssert epoch == next_epoch
|
||||
|
||||
let
|
||||
shuffling_epoch = next_epoch
|
||||
|
||||
epochs_since_last_registry_update =
|
||||
current_epoch - state.validator_registry_update_epoch
|
||||
condition = epochs_since_last_registry_update > 1'u64 and
|
||||
is_power_of_2(epochs_since_last_registry_update)
|
||||
use_next = registry_change or condition
|
||||
committees_per_epoch =
|
||||
if use_next:
|
||||
get_epoch_committee_count(state, next_epoch)
|
||||
else:
|
||||
get_epoch_committee_count(state, current_epoch)
|
||||
seed =
|
||||
if use_next:
|
||||
generate_seed(state, next_epoch)
|
||||
else:
|
||||
state.current_shuffling_seed
|
||||
shuffling_epoch =
|
||||
if use_next: next_epoch else: state.current_shuffling_epoch
|
||||
shuffling_start_shard =
|
||||
if registry_change:
|
||||
(state.current_shuffling_start_shard +
|
||||
get_epoch_committee_count(state, current_epoch)) mod SHARD_COUNT
|
||||
else:
|
||||
state.current_shuffling_start_shard
|
||||
(committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard)
|
||||
|
||||
let (committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard) =
|
||||
get_epoch_specific_params()
|
||||
|
||||
let
|
||||
shuffling = get_shuffling(seed, state.validator_registry, shuffling_epoch)
|
||||
offset = slot mod SLOTS_PER_EPOCH
|
||||
committees_per_slot = committees_per_epoch div SLOTS_PER_EPOCH
|
||||
slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) mod SHARD_COUNT
|
||||
|
||||
for i in 0 ..< committees_per_slot.int:
|
||||
result.add (
|
||||
shuffling[(committees_per_slot * offset + i.uint64).int],
|
||||
(slot_start_shard + i.uint64) mod SHARD_COUNT
|
||||
)
|
||||
|
||||
iterator get_crosslink_committees_at_slot_cached*(
|
||||
state: BeaconState, slot: Slot|uint64,
|
||||
registry_change: bool = false, cache: var StateCache):
|
||||
CrosslinkCommittee =
|
||||
let key = (slot.uint64, registry_change)
|
||||
if key in cache.crosslink_committee_cache:
|
||||
for v in cache.crosslink_committee_cache[key]: yield v
|
||||
#debugEcho "get_crosslink_committees_at_slot_cached: MISS"
|
||||
let result = get_crosslink_committees_at_slot(state, slot, registry_change)
|
||||
cache.crosslink_committee_cache[key] = result
|
||||
for v in result: yield v
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_shard_delta
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_shard_delta
|
||||
func get_shard_delta(state: BeaconState, epoch: Epoch): uint64 =
|
||||
## Return the number of shards to increment ``state.latest_start_shard``
|
||||
## during ``epoch``.
|
||||
min(get_epoch_committee_count(state, epoch),
|
||||
(SHARD_COUNT - SHARD_COUNT div SLOTS_PER_EPOCH).uint64)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_epoch_start_shard
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_epoch_start_shard
|
||||
func get_epoch_start_shard*(state: BeaconState, epoch: Epoch): Shard =
|
||||
doAssert epoch <= get_current_epoch(state) + 1
|
||||
var
|
||||
|
@ -281,7 +161,7 @@ func compute_committee(indices: seq[ValidatorIndex], seed: Eth2Digest,
|
|||
indices[
|
||||
get_shuffled_index(it.ValidatorIndex, len(indices).uint64, seed).int])
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_crosslink_committee
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_crosslink_committee
|
||||
func get_crosslink_committee*(state: BeaconState, epoch: Epoch, shard: Shard):
|
||||
seq[ValidatorIndex] =
|
||||
compute_committee(
|
||||
|
@ -291,6 +171,47 @@ func get_crosslink_committee*(state: BeaconState, epoch: Epoch, shard: Shard):
|
|||
get_epoch_committee_count(state, epoch),
|
||||
)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_crosslink_committees_at_slot
|
||||
func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot|uint64):
|
||||
seq[CrosslinkCommittee] =
|
||||
## Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||
|
||||
let
|
||||
epoch = slot_to_epoch(slot) # TODO, enforce slot to be a Slot
|
||||
current_epoch = get_current_epoch(state)
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
next_epoch = current_epoch + 1
|
||||
|
||||
doAssert previous_epoch <= epoch,
|
||||
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
|
||||
", epoch: " & $humaneEpochNum(epoch) &
|
||||
" (slot: " & $humaneSlotNum(slot.Slot) & ")" &
|
||||
", Next epoch: " & $humaneEpochNum(next_epoch)
|
||||
|
||||
doAssert epoch <= next_epoch,
|
||||
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
|
||||
", epoch: " & $humaneEpochNum(epoch) &
|
||||
" (slot: " & $humaneSlotNum(slot.Slot) & ")" &
|
||||
", Next epoch: " & $humaneEpochNum(next_epoch)
|
||||
|
||||
for i in 0'u64 ..< get_epoch_committee_count(state, epoch):
|
||||
let shard = i mod SHARD_COUNT
|
||||
result.add (
|
||||
get_crosslink_committee(state, epoch, shard),
|
||||
shard
|
||||
)
|
||||
|
||||
iterator get_crosslink_committees_at_slot_cached*(
|
||||
state: BeaconState, slot: Slot|uint64, cache: var StateCache):
|
||||
CrosslinkCommittee =
|
||||
let key = (slot_to_epoch(slot).uint64, false)
|
||||
if key in cache.crosslink_committee_cache:
|
||||
for v in cache.crosslink_committee_cache[key]: yield v
|
||||
#debugEcho "get_crosslink_committees_at_slot_cached: MISS"
|
||||
let result = get_crosslink_committees_at_slot(state, slot)
|
||||
cache.crosslink_committee_cache[key] = result
|
||||
for v in result: yield v
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#get_beacon_proposer_index
|
||||
func get_beacon_proposer_index*(state: BeaconState): ValidatorIndex =
|
||||
# Return the current beacon proposer index.
|
||||
|
|
|
@ -263,7 +263,7 @@ proc readValue*(r: var SszReader, result: var auto) =
|
|||
# ################### Hashing ###################################
|
||||
|
||||
# Sample hash_tree_root implementation based on:
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/simple-serialize.md
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/simple-serialize.md
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/test_libs/pyspec/eth2spec/utils/minimal_ssz.py
|
||||
# TODO Probably wrong - the spec is pretty bare-bones and no test vectors yet
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ proc processBlockHeader(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#randao
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#randao
|
||||
proc processRandao(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
let
|
||||
|
@ -94,7 +94,7 @@ proc processRandao(
|
|||
proposer.pubkey,
|
||||
hash_tree_root(get_current_epoch(state).uint64).data,
|
||||
blck.body.randao_reveal,
|
||||
get_domain(state, DOMAIN_RANDAO, get_current_epoch(state))):
|
||||
get_domain(state, DOMAIN_RANDAO)):
|
||||
|
||||
notice "Randao mismatch", proposer_pubkey = proposer.pubkey,
|
||||
message = get_current_epoch(state),
|
||||
|
@ -113,7 +113,7 @@ proc processRandao(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#eth1-data
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#eth1-data
|
||||
func processEth1Data(state: var BeaconState, blck: BeaconBlock) =
|
||||
state.eth1_data_votes.add blck.body.eth1_data
|
||||
if state.eth1_data_votes.count(blck.body.eth1_data) * 2 >
|
||||
|
@ -221,42 +221,49 @@ func verify_slashable_attestation(state: BeaconState, slashable_attestation: Ind
|
|||
),
|
||||
)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#is_slashable_attestation_data
|
||||
func is_slashable_attestation_data(
|
||||
data_1: AttestationData, data_2: AttestationData): bool =
|
||||
## Check if ``data_1`` and ``data_2`` are slashable according to Casper FFG
|
||||
## rules.
|
||||
|
||||
# Double vote
|
||||
(data_1 != data_2 and data_1.target_epoch == data_2.target_epoch) or
|
||||
# Surround vote
|
||||
(data_1.source_epoch < data_2.source_epoch and
|
||||
data_2.target_epoch < data_1.target_epoch)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attester-slashings
|
||||
proc processAttesterSlashings(state: var BeaconState, blck: BeaconBlock): bool =
|
||||
## Process ``AttesterSlashing`` transaction.
|
||||
## Note that this function mutates ``state``.
|
||||
# Process ``AttesterSlashing`` operation.
|
||||
if len(blck.body.attester_slashings) > MAX_ATTESTER_SLASHINGS:
|
||||
notice "CaspSlash: too many!"
|
||||
return false
|
||||
|
||||
for attester_slashing in blck.body.attester_slashings:
|
||||
let
|
||||
slashable_attestation_1 = attester_slashing.attestation_1
|
||||
slashable_attestation_2 = attester_slashing.attestation_2
|
||||
attestation_1 = attester_slashing.attestation_1
|
||||
attestation_2 = attester_slashing.attestation_2
|
||||
|
||||
# Check that the attestations are conflicting
|
||||
if not (slashable_attestation_1.data != slashable_attestation_2.data):
|
||||
notice "CaspSlash: invalid data"
|
||||
return false
|
||||
|
||||
if not (
|
||||
is_double_vote(slashable_attestation_1.data, slashable_attestation_2.data) or
|
||||
is_surround_vote(slashable_attestation_1.data, slashable_attestation_2.data)):
|
||||
if not is_slashable_attestation_data(
|
||||
attestation_1.data, attestation_2.data):
|
||||
notice "CaspSlash: surround or double vote check failed"
|
||||
return false
|
||||
|
||||
if not verify_slashable_attestation(state, slashable_attestation_1):
|
||||
if not verify_slashable_attestation(state, attestation_1):
|
||||
notice "CaspSlash: invalid votes 1"
|
||||
return false
|
||||
|
||||
if not verify_slashable_attestation(state, slashable_attestation_2):
|
||||
if not verify_slashable_attestation(state, attestation_2):
|
||||
notice "CaspSlash: invalid votes 2"
|
||||
return false
|
||||
|
||||
var slashed_any = false
|
||||
|
||||
let
|
||||
indices2 = toSet(slashable_attestation_2.validator_indices)
|
||||
indices2 = toSet(attestation_2.validator_indices)
|
||||
slashable_indices =
|
||||
slashable_attestation_1.validator_indices.filterIt(
|
||||
attestation_1.validator_indices.filterIt(
|
||||
it in indices2 and not state.validator_registry[it.int].slashed)
|
||||
|
||||
if not (len(slashable_indices) >= 1):
|
||||
|
@ -301,7 +308,6 @@ proc processAttestations(
|
|||
let pending_attestation = PendingAttestation(
|
||||
data: attestation.data,
|
||||
aggregation_bitfield: attestation.aggregation_bitfield,
|
||||
inclusion_slot: state.slot,
|
||||
inclusion_delay: state.slot - attestation_slot,
|
||||
proposer_index: get_beacon_proposer_index(state),
|
||||
)
|
||||
|
@ -326,7 +332,7 @@ proc processDeposits(state: var BeaconState, blck: BeaconBlock): bool =
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#voluntary-exits
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#voluntary-exits
|
||||
proc processVoluntaryExits(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
# Process ``VoluntaryExit`` transaction.
|
||||
|
@ -354,6 +360,7 @@ proc processVoluntaryExits(
|
|||
return false
|
||||
|
||||
# Verify the validator has been active long enough
|
||||
# TODO detect underflow
|
||||
if not (get_current_epoch(state) - validator.activation_epoch >=
|
||||
PERSISTENT_COMMITTEE_PERIOD):
|
||||
notice "Exit: not in validator set long enough"
|
||||
|
@ -372,40 +379,7 @@ proc processVoluntaryExits(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
|
||||
func update_registry_and_shuffling_data(state: var BeaconState) =
|
||||
# First set previous shuffling data to current shuffling data
|
||||
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
|
||||
|
||||
let
|
||||
current_epoch = get_current_epoch(state)
|
||||
next_epoch = current_epoch + 1
|
||||
|
||||
# Check if we should update, and if so, update
|
||||
if should_update_validator_registry(state):
|
||||
update_validator_registry(state)
|
||||
# If we update the registry, update the shuffling data and shards as well
|
||||
state.current_shuffling_epoch = next_epoch
|
||||
state.current_shuffling_start_shard = (
|
||||
state.current_shuffling_start_shard +
|
||||
get_epoch_committee_count(state, current_epoch) mod SHARD_COUNT
|
||||
) mod SHARD_COUNT
|
||||
state.current_shuffling_seed =
|
||||
generate_seed(state, state.current_shuffling_epoch)
|
||||
else:
|
||||
## If processing at least one crosslink keeps failing, then reshuffle every
|
||||
## power of two, but don't update the current_shuffling_start_shard
|
||||
let epochs_since_last_registry_update =
|
||||
current_epoch - state.validator_registry_update_epoch
|
||||
if epochs_since_last_registry_update > 1'u64 and
|
||||
is_power_of_2(epochs_since_last_registry_update):
|
||||
state.current_shuffling_epoch = next_epoch
|
||||
state.current_shuffling_seed =
|
||||
generate_seed(state, state.current_shuffling_epoch)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#transfers
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#transfers
|
||||
proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
||||
flags: UpdateFlags): bool =
|
||||
if not (len(blck.body.transfers) <= MAX_TRANSFERS):
|
||||
|
@ -486,7 +460,7 @@ func advance_slot(state: var BeaconState) =
|
|||
|
||||
state.slot += 1
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#state-caching
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#state-caching
|
||||
func cacheState(state: var BeaconState) =
|
||||
let previous_slot_state_root = hash_tree_root(state)
|
||||
|
||||
|
@ -593,18 +567,8 @@ func get_attesting_indices(state: BeaconState,
|
|||
if get_bitfield_bit(bitfield, i):
|
||||
result.incl index
|
||||
|
||||
# TODO remove this 0.5ish one when callers disappear
|
||||
func get_attesting_indices(
|
||||
state: BeaconState,
|
||||
attestations: openArray[PendingAttestation]): HashSet[ValidatorIndex] =
|
||||
# Union of attesters that participated in some attestations
|
||||
result = initSet[ValidatorIndex]()
|
||||
for attestation in attestations:
|
||||
for validator_index in get_attestation_participants(
|
||||
state, attestation.data, attestation.aggregation_bitfield):
|
||||
result.incl validator_index
|
||||
|
||||
# TODO this cached version corresponds to the 0.5ish get_attesting_indices
|
||||
# TODO this cached version corresponds to the blob/v0.5.1ish get_attesting_indices
|
||||
# rm/make consistent with 0.6 version above
|
||||
func get_attesting_indices_cached(
|
||||
state: BeaconState,
|
||||
attestations: openArray[PendingAttestation], cache: var StateCache):
|
||||
|
@ -629,15 +593,9 @@ func get_unslashed_attesting_indices(
|
|||
if state.validator_registry[index].slashed:
|
||||
result.excl index
|
||||
|
||||
# TODO check for blob/v0.5.0 removal
|
||||
func get_previous_total_balance(state: BeaconState): Gwei =
|
||||
get_total_balance(
|
||||
state,
|
||||
get_active_validator_indices(state, get_previous_epoch(state)))
|
||||
|
||||
func get_attesting_balance(state: BeaconState,
|
||||
attestations: seq[PendingAttestation]): Gwei =
|
||||
get_total_balance(state, get_attesting_indices(state, attestations))
|
||||
get_total_balance(state, get_unslashed_attesting_indices(state, attestations))
|
||||
|
||||
func get_attesting_balance_cached(
|
||||
state: BeaconState, attestations: seq[PendingAttestation],
|
||||
|
@ -645,26 +603,6 @@ func get_attesting_balance_cached(
|
|||
get_total_balance(state, get_attesting_indices_cached(
|
||||
state, attestations, cache))
|
||||
|
||||
func get_current_epoch_boundary_attestations(state: BeaconState):
|
||||
seq[PendingAttestation] =
|
||||
filterIt(
|
||||
state.current_epoch_attestations,
|
||||
it.data.target_root == get_block_root_at_slot(
|
||||
state, get_epoch_start_slot(get_current_epoch(state))))
|
||||
|
||||
func get_previous_epoch_boundary_attestations(state: BeaconState):
|
||||
seq[PendingAttestation] =
|
||||
filterIt(
|
||||
state.previous_epoch_attestations,
|
||||
it.data.target_root ==
|
||||
get_block_root_at_slot(state, get_epoch_start_slot(get_previous_epoch(state))))
|
||||
|
||||
func get_previous_epoch_matching_head_attestations(state: BeaconState):
|
||||
seq[PendingAttestation] =
|
||||
filterIt(
|
||||
state.previous_epoch_attestations,
|
||||
it.data.beacon_block_root == get_block_root_at_slot(state, it.data.slot))
|
||||
|
||||
# Not exactly in spec, but for get_winning_root_and_participants
|
||||
func lowerThan(candidate, current: Eth2Digest): bool =
|
||||
# return true iff candidate is "lower" than current, per spec rule:
|
||||
|
@ -683,7 +621,7 @@ func get_winning_root_and_participants(
|
|||
valid_attestations =
|
||||
filterIt(
|
||||
all_attestations,
|
||||
it.data.previous_crosslink == state.latest_crosslinks[shard])
|
||||
it.data.previous_crosslink == state.current_crosslinks[shard])
|
||||
all_roots = mapIt(valid_attestations, it.data.crosslink_data_root)
|
||||
|
||||
# handle when no attestations for shard available
|
||||
|
@ -720,74 +658,70 @@ func get_winning_root_and_participants(
|
|||
state,
|
||||
attestations_for.getOrDefault(winning_root), cache))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#justification
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#justification-and-finalization
|
||||
func process_justification_and_finalization(state: var BeaconState) =
|
||||
var
|
||||
new_justified_epoch = state.current_justified_epoch
|
||||
new_finalized_epoch = state.finalized_epoch
|
||||
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
||||
return
|
||||
|
||||
## Rotate the justification bitfield up one epoch to make room for the
|
||||
## current epoch
|
||||
state.justification_bitfield = state.justification_bitfield shl 1
|
||||
|
||||
# If the previous epoch gets justified, fill the second last bit
|
||||
let previous_boundary_attesting_balance =
|
||||
get_attesting_balance(
|
||||
state, get_previous_epoch_boundary_attestations(state))
|
||||
if previous_boundary_attesting_balance * 3'u64 >=
|
||||
get_previous_total_balance(state) * 2'u64:
|
||||
new_justified_epoch = get_current_epoch(state) - 1
|
||||
state.justification_bitfield = state.justification_bitfield or 2
|
||||
|
||||
# If the current epoch gets justified, fill the last bit
|
||||
let current_boundary_attesting_balance =
|
||||
get_attesting_balance(
|
||||
state, get_current_epoch_boundary_attestations(state))
|
||||
if current_boundary_attesting_balance * 3'u64 >=
|
||||
get_total_active_balance(state) * 2'u64:
|
||||
new_justified_epoch = get_current_epoch(state)
|
||||
state.justification_bitfield = state.justification_bitfield or 1
|
||||
|
||||
# Process finalizations
|
||||
let
|
||||
bitfield = state.justification_bitfield
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
current_epoch = get_current_epoch(state)
|
||||
old_previous_justified_epoch = state.previous_justified_epoch
|
||||
old_current_justified_epoch = state.current_justified_epoch
|
||||
|
||||
## The 2nd/3rd/4th most recent epochs are all justified, the 2nd using the
|
||||
## 4th as source
|
||||
if (bitfield shr 1) mod 8 == 0b111 and
|
||||
state.previous_justified_epoch == current_epoch - 3:
|
||||
new_finalized_epoch = state.previous_justified_epoch
|
||||
|
||||
## The 2nd/3rd most recent epochs are both justified, the 2nd using the 3rd
|
||||
## as source
|
||||
if (bitfield shr 1) mod 4 == 0b11 and
|
||||
state.previous_justified_epoch == current_epoch - 2:
|
||||
new_finalized_epoch = state.previous_justified_epoch
|
||||
|
||||
## The 1st/2nd/3rd most recent epochs are all justified, the 1st using the
|
||||
## 3rd as source
|
||||
if (bitfield shr 0) mod 8 == 0b111 and
|
||||
state.current_justified_epoch == current_epoch - 2:
|
||||
new_finalized_epoch = state.current_justified_epoch
|
||||
|
||||
## The 1st/2nd most recent epochs are both justified, the 1st using the 2nd
|
||||
## as source
|
||||
if (bitfield shr 0) mod 4 == 0b11 and
|
||||
state.current_justified_epoch == current_epoch - 1:
|
||||
new_finalized_epoch = state.current_justified_epoch
|
||||
|
||||
# Update state jusification/finality fields
|
||||
# Process justifications
|
||||
state.previous_justified_epoch = state.current_justified_epoch
|
||||
state.previous_justified_root = state.current_justified_root
|
||||
if new_justified_epoch != state.current_justified_epoch:
|
||||
state.current_justified_epoch = new_justified_epoch
|
||||
state.justification_bitfield = (state.justification_bitfield shl 1)
|
||||
let previous_epoch_matching_target_balance =
|
||||
get_attesting_balance(state,
|
||||
get_matching_target_attestations(state, previous_epoch))
|
||||
if previous_epoch_matching_target_balance * 3 >=
|
||||
get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = previous_epoch
|
||||
state.current_justified_root =
|
||||
get_block_root_at_slot(state, get_epoch_start_slot(new_justified_epoch))
|
||||
if new_finalized_epoch != state.finalized_epoch:
|
||||
state.finalized_epoch = new_finalized_epoch
|
||||
state.finalized_root =
|
||||
get_block_root_at_slot(state, get_epoch_start_slot(new_finalized_epoch))
|
||||
get_block_root(state, state.current_justified_epoch)
|
||||
state.justification_bitfield = state.justification_bitfield or (1 shl 1)
|
||||
let current_epoch_matching_target_balance =
|
||||
get_attesting_balance(state,
|
||||
get_matching_target_attestations(state, current_epoch))
|
||||
if current_epoch_matching_target_balance * 3 >=
|
||||
get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = current_epoch
|
||||
state.current_justified_root =
|
||||
get_block_root(state, state.current_justified_epoch)
|
||||
state.justification_bitfield = state.justification_bitfield or (1 shl 0)
|
||||
|
||||
# Process finalizations
|
||||
let bitfield = state.justification_bitfield
|
||||
|
||||
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
|
||||
## as source
|
||||
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch ==
|
||||
current_epoch - 3:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
|
||||
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
|
||||
## source
|
||||
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch ==
|
||||
current_epoch - 2:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
|
||||
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
|
||||
## source
|
||||
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch ==
|
||||
current_epoch - 2:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
|
||||
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
|
||||
## source
|
||||
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch ==
|
||||
current_epoch - 1:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#crosslinks
|
||||
func process_crosslinks(
|
||||
|
@ -797,7 +731,7 @@ func process_crosslinks(
|
|||
previous_epoch = current_epoch - 1
|
||||
next_epoch = current_epoch + 1
|
||||
|
||||
## TODO is it actually correct to be setting state.latest_crosslinks[shard]
|
||||
## TODO is it actually correct to be setting state.current_crosslinks[shard]
|
||||
## to something pre-GENESIS_EPOCH, ever? I guess the intent is if there are
|
||||
## a quorum of participants for get_epoch_start_slot(previous_epoch), when
|
||||
## state.slot == GENESIS_SLOT, then there will be participants for a quorum
|
||||
|
@ -807,7 +741,7 @@ func process_crosslinks(
|
|||
GENESIS_SLOT.uint64, get_epoch_start_slot(previous_epoch).uint64) ..<
|
||||
get_epoch_start_slot(next_epoch).uint64:
|
||||
for cas in get_crosslink_committees_at_slot_cached(
|
||||
state, slot, false, per_epoch_cache):
|
||||
state, slot, per_epoch_cache):
|
||||
let
|
||||
(crosslink_committee, shard) = cas
|
||||
# In general, it'll loop over the same shards twice, and
|
||||
|
@ -827,7 +761,7 @@ func process_crosslinks(
|
|||
# Check not from spec; seems kludgy
|
||||
doAssert slot >= GENESIS_SLOT
|
||||
|
||||
state.latest_crosslinks[shard] = Crosslink(
|
||||
state.current_crosslinks[shard] = Crosslink(
|
||||
epoch: slot_to_epoch(slot),
|
||||
crosslink_data_root: winning_root
|
||||
)
|
||||
|
@ -925,7 +859,7 @@ func get_crosslink_deltas(state: BeaconState, cache: var StateCache):
|
|||
get_epoch_start_slot(get_current_epoch(state))
|
||||
for slot in previous_epoch_start_slot.uint64 ..<
|
||||
current_epoch_start_slot.uint64:
|
||||
for cas in get_crosslink_committees_at_slot_cached(state, slot, false, cache):
|
||||
for cas in get_crosslink_committees_at_slot_cached(state, slot, cache):
|
||||
let
|
||||
(crosslink_committee, shard) = cas
|
||||
(winning_root, participants) =
|
||||
|
@ -976,25 +910,42 @@ func process_slashings(state: var BeaconState) =
|
|||
LATEST_SLASHED_EXIT_LENGTH div 2:
|
||||
let
|
||||
penalty = max(
|
||||
get_effective_balance(state, index.ValidatorIndex) *
|
||||
validator.effective_balance *
|
||||
min(total_penalties * 3, total_balance) div total_balance,
|
||||
get_effective_balance(state, index.ValidatorIndex) div
|
||||
MIN_PENALTY_QUOTIENT)
|
||||
validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT)
|
||||
decrease_balance(state, index.ValidatorIndex, penalty)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#final-updates
|
||||
func finish_epoch_update(state: var BeaconState) =
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#get_shard_delta
|
||||
func get_shard_delta(state: BeaconState, epoch: Epoch): uint64 =
|
||||
# Return the number of shards to increment ``state.latest_start_shard`` during ``epoch``.
|
||||
min(get_epoch_committee_count(state, epoch),
|
||||
(SHARD_COUNT - SHARD_COUNT div SLOTS_PER_EPOCH).uint64)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#final-updates
|
||||
func process_final_updates(state: var BeaconState) =
|
||||
let
|
||||
current_epoch = get_current_epoch(state)
|
||||
next_epoch = current_epoch + 1
|
||||
|
||||
# Set active index root
|
||||
let index_root_position =
|
||||
(next_epoch + ACTIVATION_EXIT_DELAY) mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH
|
||||
state.latest_active_index_roots[index_root_position] =
|
||||
hash_tree_root(get_active_validator_indices(
|
||||
state, next_epoch + ACTIVATION_EXIT_DELAY)
|
||||
)
|
||||
# Reset eth1 data votes
|
||||
if (state.slot + 1) mod SLOTS_PER_ETH1_VOTING_PERIOD == 0:
|
||||
state.eth1_data_votes = @[]
|
||||
|
||||
# Update effective balances with hysteresis
|
||||
for index, validator in state.validator_registry:
|
||||
let balance = state.balances[index]
|
||||
const HALF_INCREMENT = EFFECTIVE_BALANCE_INCREMENT div 2
|
||||
if balance < validator.effective_balance or
|
||||
validator.effective_balance + 3'u64 * HALF_INCREMENT < balance:
|
||||
state.validator_registry[index].effective_balance =
|
||||
min(
|
||||
balance - balance mod EFFECTIVE_BALANCE_INCREMENT,
|
||||
MAX_EFFECTIVE_BALANCE)
|
||||
|
||||
# Update start shard
|
||||
state.latest_start_shard =
|
||||
(state.latest_start_shard + get_shard_delta(state, current_epoch)) mod
|
||||
SHARD_COUNT
|
||||
|
||||
# Set total slashed balances
|
||||
state.latest_slashed_balances[next_epoch mod LATEST_SLASHED_EXIT_LENGTH] = (
|
||||
|
@ -1017,7 +968,7 @@ func finish_epoch_update(state: var BeaconState) =
|
|||
state.previous_epoch_attestations = state.current_epoch_attestations
|
||||
state.current_epoch_attestations = @[]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#per-epoch-processing
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#per-epoch-processing
|
||||
func get_empty_per_epoch_cache(): StateCache =
|
||||
result.crosslink_committee_cache =
|
||||
initTable[tuple[a: uint64, b: bool], seq[CrosslinkCommittee]]()
|
||||
|
@ -1034,26 +985,22 @@ func processEpoch(state: var BeaconState) =
|
|||
|
||||
var per_epoch_cache = get_empty_per_epoch_cache()
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.1/specs/core/0_beacon-chain.md#crosslinks
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#crosslinks
|
||||
process_crosslinks(state, per_epoch_cache)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#rewards-and-penalties
|
||||
process_rewards_and_penalties(state, per_epoch_cache)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#ejections
|
||||
process_ejections(state)
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#registry-updates
|
||||
process_registry_updates(state)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
|
||||
update_registry_and_shuffling_data(state)
|
||||
|
||||
## Regardless of whether or not a validator set change happens run
|
||||
## process_slashings(state) and process_exit_queue(state)
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#slashings
|
||||
process_slashings(state)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#final-updates
|
||||
finish_epoch_update(state)
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#final-updates
|
||||
process_final_updates(state)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_beacon-chain.md#state-root-verification
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#state-root-verification
|
||||
proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool =
|
||||
let state_root = hash_tree_root(state)
|
||||
if state_root != blck.state_root:
|
||||
|
@ -1068,7 +1015,7 @@ proc advanceState*(state: var BeaconState) =
|
|||
## hand - this happens for example when a block proposer fails to produce a
|
||||
## a block.
|
||||
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
|
||||
## We now define the state transition function. At a high level the state
|
||||
## transition is made up of four parts:
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ type
|
|||
## which blocks are valid - in particular, blocks are not valid if they
|
||||
## come from the future as seen from the local clock.
|
||||
##
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/v0.6.0/specs/core/0_fork-choice.md#beacon-chain-processing
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_fork-choice.md#beacon-chain-processing
|
||||
##
|
||||
# TODO replace time in chronos with a proper unit type, then this code can
|
||||
# follow:
|
||||
|
|
|
@ -55,7 +55,7 @@ type
|
|||
WHISTLEBLOWING_REWARD_QUOTIENT*: uint64
|
||||
PROPOSER_REWARD_QUOTIENT*: uint64
|
||||
INACTIVITY_PENALTY_QUOTIENT*: uint64
|
||||
MIN_PENALTY_QUOTIENT*: int
|
||||
MIN_SLASHING_PENALTY_QUOTIENT*: int
|
||||
MAX_PROPOSER_SLASHINGS*: int
|
||||
MAX_ATTESTER_SLASHINGS*: int
|
||||
MAX_ATTESTATIONS*: int
|
||||
|
|
|
@ -10,10 +10,11 @@ import
|
|||
../beacon_chain/spec/[helpers]
|
||||
|
||||
suite "Spec helpers":
|
||||
test "is_power_of_2 should do its job":
|
||||
test "integer_squareroot":
|
||||
check:
|
||||
is_power_of_2(1) == true
|
||||
is_power_of_2(2) == true
|
||||
is_power_of_2(3) == false
|
||||
is_power_of_2(4) == true
|
||||
is_power_of_2(not 0'u64) == false
|
||||
integer_squareroot(0'u64) == 0'u64
|
||||
integer_squareroot(1'u64) == 1'u64
|
||||
integer_squareroot(2'u64) == 1'u64
|
||||
integer_squareroot(3'u64) == 1'u64
|
||||
integer_squareroot(4'u64) == 2'u64
|
||||
integer_squareroot(5'u64) == 2'u64
|
||||
|
|
Loading…
Reference in New Issue