small 0.3.0 adjustments; comment updates/clarifications; add Transfer processing
This commit is contained in:
parent
a62d25ab98
commit
fb3bbfccaa
|
@ -106,8 +106,8 @@ func activate_validator(state: var BeaconState,
|
|||
get_entry_exit_effect_epoch(get_current_epoch(state))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#initiate_validator_exit
|
||||
func initiate_validator_exit(state: var BeaconState,
|
||||
index: ValidatorIndex) =
|
||||
func initiate_validator_exit*(state: var BeaconState,
|
||||
index: ValidatorIndex) =
|
||||
## Initiate exit for the validator with the given ``index``.
|
||||
## Note that this function mutates ``state``.
|
||||
var validator = addr state.validator_registry[index]
|
||||
|
@ -352,7 +352,7 @@ func update_validator_registry*(state: var BeaconState) =
|
|||
|
||||
# TODO "If a validator registry update does not happen do the following: ..."
|
||||
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestations-1
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestations-1
|
||||
proc checkAttestation*(
|
||||
state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool =
|
||||
## Check that an attestation follows the rules of being included in the state
|
||||
|
@ -365,6 +365,7 @@ proc checkAttestation*(
|
|||
attestation_slot = attestation.data.slot, state_slot = state.slot)
|
||||
return
|
||||
|
||||
# Can't underflow, because GENESIS_SLOT > MIN_ATTESTATION_INCLUSION_DELAY
|
||||
if not (state.slot - MIN_ATTESTATION_INCLUSION_DELAY <
|
||||
attestation.data.slot + SLOTS_PER_EPOCH):
|
||||
warn("Attestation too old",
|
||||
|
@ -372,8 +373,7 @@ proc checkAttestation*(
|
|||
return
|
||||
|
||||
let expected_justified_epoch =
|
||||
# https://github.com/ethereum/eth2.0-specs/issues/618
|
||||
if attestation.data.slot + 1 >= get_epoch_start_slot(get_current_epoch(state)):
|
||||
if slot_to_epoch(attestation.data.slot + 1) >= get_current_epoch(state):
|
||||
state.justified_epoch
|
||||
else:
|
||||
state.previous_justified_epoch
|
||||
|
@ -443,7 +443,6 @@ proc checkAttestation*(
|
|||
group_public_key = bls_aggregate_pubkeys(
|
||||
participants.mapIt(state.validator_registry[it].pubkey))
|
||||
|
||||
## the rest; turns into expensive NOP until then.
|
||||
if skipValidation notin flags:
|
||||
# Verify that aggregate_signature verifies using the group pubkey.
|
||||
assert bls_verify_multiple(
|
||||
|
|
|
@ -277,6 +277,7 @@ proc processAttesterSlashings(state: var BeaconState, blck: BeaconBlock): bool =
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#attestations-1
|
||||
proc processAttestations(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
## Each block includes a number of attestations that the proposer chose. Each
|
||||
|
@ -285,8 +286,6 @@ proc processAttestations(
|
|||
## Here we make sanity checks for each attestation and it to the state - most
|
||||
## updates will happen at the epoch boundary where state updates happen in
|
||||
## bulk.
|
||||
##
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestations-1
|
||||
if blck.body.attestations.len > MAX_ATTESTATIONS:
|
||||
notice "Attestation: too many!", attestations = blck.body.attestations.len
|
||||
return false
|
||||
|
@ -304,20 +303,16 @@ proc processAttestations(
|
|||
)
|
||||
)
|
||||
|
||||
return true
|
||||
|
||||
proc processDeposits(state: var BeaconState, blck: BeaconBlock): bool =
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposits-1
|
||||
# TODO! Spec writing in progress
|
||||
true
|
||||
|
||||
func initiate_validator_exit(state: var BeaconState, index: int) =
|
||||
var validator = state.validator_registry[index]
|
||||
validator.status_flags = validator.status_flags or INITIATED_EXIT
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#deposits-1
|
||||
func processDeposits(state: var BeaconState, blck: BeaconBlock): bool =
|
||||
# TODO! Spec writing in progress as of v0.3.0
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#voluntary-exits-1
|
||||
proc processExits(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#exits-1
|
||||
if len(blck.body.voluntary_exits) > MAX_VOLUNTARY_EXITS:
|
||||
notice "Exit: too many!"
|
||||
return false
|
||||
|
@ -325,13 +320,6 @@ proc processExits(
|
|||
for exit in blck.body.voluntary_exits:
|
||||
let validator = state.validator_registry[exit.validator_index.int]
|
||||
|
||||
if skipValidation notin flags:
|
||||
if not bls_verify(
|
||||
validator.pubkey, ZERO_HASH.data, exit.signature,
|
||||
get_domain(state.fork, exit.epoch, DOMAIN_EXIT)):
|
||||
notice "Exit: invalid signature"
|
||||
return false
|
||||
|
||||
if not (validator.exit_epoch > get_entry_exit_effect_epoch(get_current_epoch(state))):
|
||||
notice "Exit: exit/entry too close"
|
||||
return false
|
||||
|
@ -340,9 +328,82 @@ proc processExits(
|
|||
notice "Exit: bad epoch"
|
||||
return false
|
||||
|
||||
initiate_validator_exit(state, exit.validator_index.int)
|
||||
if skipValidation notin flags:
|
||||
let exit_message = hash_tree_root(
|
||||
# In 0.3.0 spec, this is "Exit", but that's a renaming mismatch
|
||||
VoluntaryExit(
|
||||
epoch: exit.epoch, validator_index: exit.validator_index,
|
||||
signature: EMPTY_SIGNATURE))
|
||||
if not bls_verify(
|
||||
validator.pubkey, exit_message, exit.signature,
|
||||
get_domain(state.fork, exit.epoch, DOMAIN_EXIT)):
|
||||
notice "Exit: invalid signature"
|
||||
return false
|
||||
|
||||
return true
|
||||
initiate_validator_exit(state, exit.validator_index.ValidatorIndex)
|
||||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#transfers-1
|
||||
proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
||||
flags: UpdateFlags): bool =
|
||||
## Note: Transfers are a temporary functionality for phases 0 and 1, to be
|
||||
## removed in phase 2.
|
||||
if not (len(blck.body.transfers) <= MAX_TRANSFERS):
|
||||
notice "Transfer: too many transfers"
|
||||
return false
|
||||
|
||||
for transfer in blck.body.transfers:
|
||||
let from_balance = state.validator_balances[transfer.from_field.int]
|
||||
|
||||
if not (from_balance >= transfer.amount):
|
||||
notice "Transfer: source balance too low for amount"
|
||||
return false
|
||||
|
||||
if not (from_balance >= transfer.fee):
|
||||
notice "Transfer: source balance too low for fee"
|
||||
return false
|
||||
|
||||
if not (from_balance == transfer.amount + transfer.fee or from_balance >=
|
||||
transfer.amount + transfer.fee + MIN_DEPOSIT_AMOUNT):
|
||||
notice "Transfer: source balance too low for amount + fee"
|
||||
return false
|
||||
|
||||
if not (state.slot == transfer.slot):
|
||||
notice "Transfer: slot mismatch"
|
||||
return false
|
||||
|
||||
if not (get_current_epoch(state) >=
|
||||
state.validator_registry[transfer.from_field.int].withdrawable_epoch):
|
||||
notice "Transfer: epoch mismatch"
|
||||
return false
|
||||
|
||||
let wc = state.validator_registry[transfer.from_field.int].
|
||||
withdrawal_credentials
|
||||
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX_BYTE and
|
||||
wc.data[1..^1] == eth2hash(transfer.pubkey.getBytes).data[1..^1]):
|
||||
notice "Transfer: incorrect withdrawal credentials"
|
||||
return false
|
||||
|
||||
if skipValidation notin flags:
|
||||
let transfer_message = hash_tree_root(
|
||||
Transfer(
|
||||
from_field: transfer.from_field, to: transfer.to,
|
||||
amount: transfer.amount, fee: transfer.fee, slot: transfer.slot,
|
||||
signature: EMPTY_SIGNATURE))
|
||||
if bls_verify(
|
||||
pubkey=transfer.pubkey, transfer_message, transfer.signature,
|
||||
get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)):
|
||||
notice "Transfer: incorrect signature"
|
||||
return false
|
||||
|
||||
state.validator_balances[
|
||||
transfer.from_field.int] -= transfer.amount + transfer.fee
|
||||
state.validator_balances[transfer.to.int] += transfer.amount
|
||||
state.validator_balances[
|
||||
get_beacon_proposer_index(state, state.slot)] += transfer.fee
|
||||
|
||||
true
|
||||
|
||||
proc process_ejections(state: var BeaconState) =
|
||||
## Iterate through the validator registry and eject active validators with
|
||||
|
@ -427,9 +488,10 @@ proc processBlock(
|
|||
if not processExits(state, blck, flags):
|
||||
return false
|
||||
|
||||
process_ejections(state)
|
||||
if not processTransfers(state, blck, flags):
|
||||
return false
|
||||
|
||||
return true
|
||||
true
|
||||
|
||||
func get_attester_indices(
|
||||
state: BeaconState,
|
||||
|
@ -460,12 +522,11 @@ func lowerThan(candidate, current: Eth2Digest): bool =
|
|||
return false
|
||||
|
||||
func processEpoch(state: var BeaconState) =
|
||||
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#per-epoch-processing
|
||||
|
||||
# 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
|
||||
|
||||
# Precomputation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#helper-variables
|
||||
let
|
||||
active_validator_indices =
|
||||
get_active_validator_indices(state.validator_registry, state.slot)
|
||||
|
|
Loading…
Reference in New Issue