More safe 0.7.0 updates (#283)

* complete marking unchanged-in-0.7.0 beaconstate functions

* complete marking unchanged-in-0.7.0 spec refs functions in helpers.nim and time.nim: get_randao_mix(...), bytes_to_int(...), and description of beacon chain processing apropos time

* complete remaining feasible 0.7.0 updates which lack externally visible effect
This commit is contained in:
Dustin Brody 2019-06-14 07:50:14 +00:00 committed by Mamy Ratsimbazafy
parent 22f518ae65
commit e2496567b3
4 changed files with 64 additions and 64 deletions

View File

@ -11,7 +11,7 @@ import
./bitfield, ./crypto, ./datatypes, ./digest, ./helpers, ./validator,
tables
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#verify_merkle_branch
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.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``
## starting with the given ``root``.
@ -45,7 +45,7 @@ func decrease_balance*(
else:
state.balances[index] - delta
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#deposits
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/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.
@ -322,7 +322,7 @@ func get_total_balance*(state: BeaconState, validators: auto): Gwei =
# 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.6.3/specs/core/0_beacon-chain.md#registry-updates
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/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:
@ -360,38 +360,42 @@ func process_registry_updates*(state: var BeaconState) =
validator.activation_epoch =
get_delayed_activation_exit_epoch(get_current_epoch(state))
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#verify_indexed_attestation
func verify_indexed_attestation*(
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#validate_indexed_attestation
func validate_indexed_attestation*(
state: BeaconState, indexed_attestation: IndexedAttestation): bool =
# Verify validity of ``indexed_attestation`` fields.
let
custody_bit_0_indices = indexed_attestation.custody_bit_0_indices
custody_bit_1_indices = indexed_attestation.custody_bit_1_indices
bit_0_indices = indexed_attestation.custody_bit_0_indices
bit_1_indices = indexed_attestation.custody_bit_1_indices
# Ensure no duplicate indices across custody bits
if len(intersection(toSet(custody_bit_0_indices), toSet(custody_bit_1_indices))) != 0:
return false
if len(custody_bit_1_indices) > 0: # [TO BE REMOVED IN PHASE 1]
# Verify no index has custody bit equal to 1 [to be removed in phase 1]
if len(bit_1_indices) != 0:
return false
let combined_len = len(custody_bit_0_indices) + len(custody_bit_1_indices)
# Verify max number of indices
let combined_len = len(bit_0_indices) + len(bit_1_indices)
if not (1 <= combined_len and combined_len <= MAX_INDICES_PER_ATTESTATION):
return false
if custody_bit_0_indices != sorted(custody_bit_0_indices, system.cmp):
# Verify index sets are disjoint
if len(intersection(toSet(bit_0_indices), toSet(bit_1_indices))) != 0:
return false
if custody_bit_1_indices != sorted(custody_bit_1_indices, system.cmp):
# Verify indices are sorted
if bit_0_indices != sorted(bit_0_indices, system.cmp):
return false
if bit_1_indices != sorted(bit_1_indices, system.cmp):
return false
# Verify aggregate signature
bls_verify_multiple(
@[
bls_aggregate_pubkeys(
mapIt(custody_bit_0_indices, state.validator_registry[it.int].pubkey)),
mapIt(bit_0_indices, state.validator_registry[it.int].pubkey)),
bls_aggregate_pubkeys(
mapIt(custody_bit_1_indices, state.validator_registry[it.int].pubkey)),
mapIt(bit_1_indices, state.validator_registry[it.int].pubkey)),
],
@[
hash_tree_root(AttestationDataAndCustodyBit(
@ -529,7 +533,7 @@ proc checkAttestation*(
return
# Check signature and bitfields
if not verify_indexed_attestation(
if not validate_indexed_attestation(
state, convert_to_indexed(state, attestation)):
warn("checkAttestation: signature or bitfields incorrect")
return

View File

@ -95,7 +95,7 @@ func get_current_epoch*(state: BeaconState): Epoch =
doAssert state.slot >= GENESIS_SLOT, $state.slot
slot_to_epoch(state.slot)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#get_randao_mix
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#get_randao_mix
func get_randao_mix*(state: BeaconState,
epoch: Epoch): Eth2Digest =
## Returns the randao mix at a recent ``epoch``.
@ -112,7 +112,7 @@ func get_active_index_root(state: BeaconState, epoch: Epoch): Eth2Digest =
## intentional
state.latest_active_index_roots[epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH]
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#bytes_to_int
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#bytes_to_int
func bytes_to_int*(data: openarray[byte]): uint64 =
doAssert data.len == 8

View File

@ -81,9 +81,9 @@ proc processBlockHeader(
true
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#randao
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#randao
proc processRandao(
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
state: var BeaconState, body: BeaconBlockBody, flags: UpdateFlags): bool =
let
proposer_index = get_beacon_proposer_index(state)
proposer = addr state.validator_registry[proposer_index]
@ -93,32 +93,31 @@ proc processRandao(
if not bls_verify(
proposer.pubkey,
hash_tree_root(get_current_epoch(state).uint64).data,
blck.body.randao_reveal,
body.randao_reveal,
get_domain(state, DOMAIN_RANDAO)):
notice "Randao mismatch", proposer_pubkey = proposer.pubkey,
message = get_current_epoch(state),
signature = blck.body.randao_reveal,
slot = state.slot,
blck_slot = blck.slot
signature = body.randao_reveal,
slot = state.slot
return false
# Mix it in
let
mix = get_current_epoch(state) mod LATEST_RANDAO_MIXES_LENGTH
rr = eth2hash(blck.body.randao_reveal.getBytes()).data
rr = eth2hash(body.randao_reveal.getBytes()).data
for i, b in state.latest_randao_mixes[mix].data:
state.latest_randao_mixes[mix].data[i] = b xor rr[i]
true
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/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 >
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#eth1-data
func processEth1Data(state: var BeaconState, body: BeaconBlockBody) =
state.eth1_data_votes.add body.eth1_data
if state.eth1_data_votes.count(body.eth1_data) * 2 >
SLOTS_PER_ETH1_VOTING_PERIOD:
state.latest_eth1_data = blck.body.eth1_data
state.latest_eth1_data = body.eth1_data
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#is_slashable_validator
func is_slashable_validator(validator: Validator, epoch: Epoch): bool =
@ -201,11 +200,11 @@ proc processAttesterSlashings(state: var BeaconState, blck: BeaconBlock): bool =
notice "CaspSlash: surround or double vote check failed"
return false
if not verify_indexed_attestation(state, attestation_1):
if not validate_indexed_attestation(state, attestation_1):
notice "CaspSlash: invalid votes 1"
return false
if not verify_indexed_attestation(state, attestation_2):
if not validate_indexed_attestation(state, attestation_2):
notice "CaspSlash: invalid votes 2"
return false
@ -414,19 +413,18 @@ func advance_slot(state: var BeaconState) =
state.slot += 1
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#state-caching
func cacheState(state: var BeaconState) =
let previous_slot_state_root = hash_tree_root(state)
# store the previous slot's post state transition root
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
func process_slot(state: var BeaconState) =
# Cache state root
let previous_state_root = hash_tree_root(state)
state.latest_state_roots[state.slot mod SLOTS_PER_HISTORICAL_ROOT] =
previous_slot_state_root
previous_state_root
# cache state root in stored latest_block_header if empty
# Cache latest block header state root
if state.latest_block_header.state_root == ZERO_HASH:
state.latest_block_header.state_root = previous_slot_state_root
state.latest_block_header.state_root = previous_state_root
# store latest known block for previous slot
# Cache block root
state.latest_block_roots[state.slot mod SLOTS_PER_HISTORICAL_ROOT] =
signing_root(state.latest_block_header)
@ -442,11 +440,11 @@ proc processBlock(
notice "Block header not valid", slot = humaneSlotNum(state.slot)
return false
if not processRandao(state, blck, flags):
if not processRandao(state, blck.body, flags):
debug "[Block processing] Randao failure", slot = humaneSlotNum(state.slot)
return false
processEth1Data(state, blck)
processEth1Data(state, blck.body)
if not processProposerSlashings(state, blck, flags):
debug "[Block processing] Proposer slashing failure", slot = humaneSlotNum(state.slot)
@ -825,13 +823,11 @@ func process_rewards_and_penalties(
increase_balance(state, i.ValidatorIndex, rewards1[i] + rewards2[i])
decrease_balance(state, i.ValidatorIndex, penalties1[i] + penalties2[i])
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#slashings
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#slashings
func process_slashings(state: var BeaconState) =
let
current_epoch = get_current_epoch(state)
active_validator_indices = get_active_validator_indices(
state, current_epoch)
total_balance = get_total_balance(state, active_validator_indices)
total_balance = get_total_active_balance(state)
# Compute `total_penalties`
total_at_start = state.latest_slashed_balances[
@ -910,24 +906,24 @@ func processEpoch(state: var BeaconState) =
(state.slot + 1) mod SLOTS_PER_EPOCH == 0):
return
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#justification-and-finalization
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#justification-and-finalization
process_justification_and_finalization(state)
var per_epoch_cache = get_empty_per_epoch_cache()
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#crosslinks
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#crosslinks
process_crosslinks(state, per_epoch_cache)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#rewards-and-penalties
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#rewards-and-penalties-1
process_rewards_and_penalties(state, per_epoch_cache)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#registry-updates
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#registry-updates
process_registry_updates(state)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#slashings
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#slashings
process_slashings(state)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#final-updates
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#final-updates
process_final_updates(state)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#state-root-verification
@ -951,7 +947,7 @@ proc advanceState*(state: var BeaconState) =
## 1. State caching, which happens at the start of every slot.
## The state caching, caches the state root of the previous slot
cacheState(state)
process_slot(state)
## 2. The per-epoch transitions, which happens at the start of the first
## slot of every epoch.
@ -1035,24 +1031,24 @@ proc skipSlots*(state: var BeaconState, slot: Slot,
# TODO hashed versions of above - not in spec
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#state-caching
func cacheState(state: var HashedBeaconState) =
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
func process_slot(state: var HashedBeaconState) =
# Cache state root
let previous_slot_state_root = state.root
# store the previous slot's post state transition root
state.data.latest_state_roots[state.data.slot mod SLOTS_PER_HISTORICAL_ROOT] =
previous_slot_state_root
# cache state root in stored latest_block_header if empty
# Cache latest block header state root
if state.data.latest_block_header.state_root == ZERO_HASH:
state.data.latest_block_header.state_root = previous_slot_state_root
# store latest known block for previous slot
# Cache block root
state.data.latest_block_roots[state.data.slot mod SLOTS_PER_HISTORICAL_ROOT] =
signing_root(state.data.latest_block_header)
# Not covered by above 0.7 marking
proc advanceState*(state: var HashedBeaconState) =
cacheState(state)
process_slot(state)
processEpoch(state.data)
advance_slot(state.data)

View File

@ -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.3/specs/core/0_fork-choice.md#beacon-chain-processing
## https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_fork-choice.md#beacon-chain-processing
##
# TODO replace time in chronos with a proper unit type, then this code can
# follow: