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:
parent
22f518ae65
commit
e2496567b3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue