fix crosslink epoch refs to begin with GENESIS_EPOCH; more minor epoch processing tweaks/unstubbed-code (#137)

* fix crosslink epoch refs to begin with GENESIS_EPOCH; more minor epoch processing tweaks/unstubbed-code

* remove obsolete TODO and use humanEpochNum
This commit is contained in:
Dustin Brody 2019-02-27 13:58:07 +00:00 committed by GitHub
parent 0305432a87
commit 34e6149f89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 48 deletions

View File

@ -202,7 +202,7 @@ proc makeAttestation(node: BeaconNode,
beacon_block_root: node.headBlockRoot,
epoch_boundary_root: Eth2Digest(), # TODO
shard_block_root: Eth2Digest(), # TODO
latest_crosslink: Crosslink(), # TODO
latest_crosslink: Crosslink(epoch: state.latest_crosslinks[shard].epoch),
justified_epoch: state.justified_epoch,
justified_block_root: justifiedBlockRoot)

View File

@ -204,11 +204,14 @@ func get_genesis_beacon_state*(
latest_eth1_data: latest_eth1_data,
# Recent state
# TODO properly initialize latest_crosslinks
# latest_block_roots, latest_active_index_roots, latest_slashed_balances,
# latest_attestations, and batched_block_roots automatically initialized.
)
for i in 0 ..< SHARD_COUNT:
state.latest_crosslinks[i] = Crosslink(
epoch: GENESIS_EPOCH, shard_block_root: ZERO_HASH)
# Process initial deposits
for deposit in initial_validator_deposits:
process_deposit(
@ -398,7 +401,12 @@ proc checkAttestation*(
Crosslink(
shard_block_root: attestation.data.shard_block_root,
epoch: slot_to_epoch(attestation.data.slot))]):
warn("Unexpected crosslink shard")
warn("Unexpected crosslink shard",
state_latest_crosslinks_attestation_data_shard =
state.latest_crosslinks[attestation.data.shard],
attestation_data_latest_crosslink = attestation.data.latest_crosslink,
epoch = humaneEpochNum(slot_to_epoch(attestation.data.slot)),
shard_block_root = attestation.data.shard_block_root)
return
assert allIt(attestation.custody_bitfield, it == 0) #TO BE REMOVED IN PHASE 1

View File

@ -405,16 +405,15 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
true
proc process_ejections(state: var BeaconState) =
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.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``
##
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#ejections
for index, validator in state.validator_registry:
if is_active_validator(validator, state.slot) and
state.validator_balances[index] < EJECTION_BALANCE:
exit_validator(state, index.ValidatorIndex)
for index in get_active_validator_indices(
# TODO minor 0.3.0 bug: it says just current_epoch(state)
state.validator_registry, get_current_epoch(state)):
if state.validator_balances[index] < EJECTION_BALANCE:
exit_validator(state, index)
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#per-slot-processing
func processSlot(state: var BeaconState, previous_block_root: Eth2Digest) =
@ -519,7 +518,6 @@ func lowerThan(candidate, current: Eth2Digest): bool =
if v > candidate.data[i]: return true
false
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
func process_slashings(state: var BeaconState) =
## Process the slashings.
@ -583,8 +581,8 @@ func process_exit_queue(state: var BeaconState) =
break
prepare_validator_for_withdrawal(state, index)
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#per-epoch-processing
func processEpoch(state: var BeaconState) =
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#per-epoch-processing
if (state.slot + 1) mod SLOTS_PER_EPOCH != 0:
return
@ -716,18 +714,18 @@ func processEpoch(state: var BeaconState) =
func total_balance_sac(crosslink_committee: CrosslinkCommittee): uint64 =
get_total_balance(statePtr[], crosslink_committee.committee)
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#eth1-data-1
block: # Eth1 data
if state.slot mod EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#eth1-data-1
block:
if next_epoch mod EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
for x in state.eth1_data_votes:
if x.vote_count * 2 >= EPOCHS_PER_ETH1_VOTING_PERIOD:
if x.vote_count * 2 >= EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
# more than half the votes in this voting period were for that value
state.latest_eth1_data = x.eth1_data
break
state.eth1_data_votes = @[]
block: # Justification
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#justification
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#justification
block:
# First, update the justification bitfield
var new_justified_epoch = state.justified_epoch
state.justification_bitfield = state.justification_bitfield shl 1
@ -752,47 +750,50 @@ func processEpoch(state: var BeaconState) =
state.previous_justified_epoch = state.justified_epoch
state.justified_epoch = new_justified_epoch
block: # Crosslinks
# https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#crosslinks
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#crosslinks
block:
for slot in get_epoch_start_slot(previous_epoch) ..< get_epoch_start_slot(next_epoch):
let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot)
#
#for crosslink_committee, shard in crosslink_committees_at_slot.items:
# if 3 * total_attesting_balance(crosslink_committee) >= 2 * total_balance(crosslink_committee):
# state.latest_crosslinks[shard] = Crosslink(
# slot=state.slot, shard_block_root=winning_root(crosslink_committee))
# Rewards and penalties helpers
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/core/0_beacon-chain.md#rewards-and-penalties
let
base_reward_quotient =
integer_squareroot(previous_total_balance) div BASE_REWARD_QUOTIENT
for crosslink_committee in crosslink_committees_at_slot:
if 3'u64 * total_attesting_balance(crosslink_committee) >=
2'u64 * get_total_balance(state, crosslink_committee.committee):
state.latest_crosslinks[crosslink_committee.shard] = Crosslink(
epoch: slot_to_epoch(slot),
shard_block_root: winning_root(crosslink_committee))
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#rewards-and-penalties
## First, we define some additional helpers
## Note: When applying penalties in the following balance recalculations
## implementers should make sure the uint64 does not underflow
let base_reward_quotient =
integer_squareroot(previous_total_balance) div BASE_REWARD_QUOTIENT
func base_reward(state: BeaconState, index: ValidatorIndex): uint64 =
get_effective_balance(state, index) div base_reward_quotient.uint64 div 4
get_effective_balance(state, index) div base_reward_quotient.uint64 div 5
func inactivity_penalty(
state: BeaconState, index: ValidatorIndex, epochs_since_finality: uint64): uint64 =
base_reward(state, index) +
get_effective_balance(state, index) *
epochs_since_finality div INACTIVITY_PENALTY_QUOTIENT div 2
get_effective_balance(state, index) * epochs_since_finality div
INACTIVITY_PENALTY_QUOTIENT div 2
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#justification-and-finalization
func inclusion_slot(state: BeaconState, v: ValidatorIndex): uint64 =
for a in previous_epoch_attestations:
if v in get_attestation_participants(state, a.data, a.aggregation_bitfield):
return a.inclusion_slot
doAssert false # shouldn't happen..
doAssert false
func inclusion_distance(state: BeaconState, v: ValidatorIndex): uint64 =
for a in previous_epoch_attestations:
if v in get_attestation_participants(state, a.data, a.aggregation_bitfield):
return a.inclusion_slot - a.data.slot
doAssert false # shouldn't happen..
doAssert false
let active_validator_indices =
get_active_validator_indices(state.validator_registry, state.slot)
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#justification-and-finalization
block: # Justification and finalization
let epochs_since_finality = next_epoch - state.finalized_epoch
@ -867,16 +868,16 @@ func processEpoch(state: var BeaconState) =
# TODO underflows?
state.validator_balances[index] -= base_reward(state, index)
block: # Ejections
process_ejections(state)
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
process_ejections(state)
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
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
block:
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))
# TODO verify this shard list
if state.finalized_epoch > state.validator_registry_update_epoch and
allIt(
0 ..< get_current_epoch_committee_count(state).int * SLOTS_PER_EPOCH,
@ -884,8 +885,11 @@ func processEpoch(state: var BeaconState) =
update_validator_registry(state)
state.current_shuffling_epoch = next_epoch
state.current_shuffling_start_shard = (state.current_shuffling_start_shard + get_current_epoch_committee_count(state) * SLOTS_PER_EPOCH) mod SHARD_COUNT
state.current_shuffling_seed = generate_seed(state, state.current_shuffling_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)
else:
# If a validator registry change does NOT happen
let epochs_since_last_registry_change = current_epoch - state.validator_registry_update_epoch
@ -893,7 +897,6 @@ func processEpoch(state: var BeaconState) =
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
## Regardless of whether or not a validator set change happens run
## process_slashings(state) and process_exit_queue(state)

View File

@ -1,5 +1,5 @@
# beacon_chain
# Copyright (c) 2018 Status Research & Development GmbH
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
@ -81,6 +81,11 @@ proc addBlock*(
let proposer_index = get_beacon_proposer_index(state, state.slot)
state.slot -= 1
# Ferret out remaining GENESIS_EPOCH == 0 assumptions in test code
doAssert allIt(
body.attestations,
it.data.latest_crosslink.epoch >= GENESIS_EPOCH)
let
# Index from the new state, but registry from the old state.. hmm...
proposer = state.validator_registry[proposer_index]
@ -168,7 +173,7 @@ proc makeAttestation*(
shard: sac.shard,
beacon_block_root: beacon_block_root,
epoch_boundary_root: Eth2Digest(), # TODO
latest_crosslink: Crosslink(), # TODO
latest_crosslink: Crosslink(epoch: state.latest_crosslinks[sac.shard].epoch), # TODO
shard_block_root: Eth2Digest(), # TODO
justified_epoch: state.justified_epoch,
justified_block_root: get_block_root(state, get_epoch_start_slot(state.justified_epoch)),