From 7e3aa4dda2efe9e5f8f7e23f71e498cd5d0b9ded Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Wed, 16 Jan 2019 05:39:34 -0800 Subject: [PATCH] initial process_penalties_and_exits --- beacon_chain/spec/beaconstate.nim | 38 +++++++++++++++++++++++++++++++ beacon_chain/spec/datatypes.nim | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 62656e53d..1667958b5 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -178,6 +178,44 @@ func exit_validator*(state: var BeaconState, committee.delete(i) break +func process_penalties_and_exits_eligible(state: BeaconState, index: int): bool = + let validator = state.validator_registry[index] + if validator.penalized_slot <= state.slot: + # strangely uppercase variable-ish name + let PENALIZED_WITHDRAWAL_TIME = (LATEST_PENALIZED_EXIT_LENGTH * EPOCH_LENGTH div 2).uint64 + return state.slot >= validator.penalized_slot + PENALIZED_WITHDRAWAL_TIME + else: + return state.slot >= validator.exit_slot + MIN_VALIDATOR_WITHDRAWAL_TIME + +func process_penalties_and_exits(state: var BeaconState) = + # The active validators + let active_validator_indices = get_active_validator_indices(state.validator_registry, state.slot) + # The total effective balance of active validators + var total_balance : uint64 = 0 + for i in active_validator_indices: + total_balance += get_effective_balance(state, i) + + for index, validator in state.validator_registry: + if (state.slot div EPOCH_LENGTH) == (validator.penalized_slot div EPOCH_LENGTH) + LATEST_PENALIZED_EXIT_LENGTH div 2: + let + e = ((state.slot div EPOCH_LENGTH) mod LATEST_PENALIZED_EXIT_LENGTH).int + total_at_start = state.latest_penalized_exit_balances[(e + 1) mod LATEST_PENALIZED_EXIT_LENGTH] + total_at_end = state.latest_penalized_exit_balances[e] + total_penalties = total_at_end - total_at_start + penalty = get_effective_balance(state, index.Uint24) * min(total_penalties * 3, total_balance) div total_balance + state.validator_balances[index] -= penalty + + ## 'state' is of type which cannot be captured as it + ## would violate memory safety, when using nested function approach in + ## spec directly. That said, the spec approach evidently is not meant, + ## based on its abundant and pointless memory copies, for production. + var eligible_indices : seq[Uint24] = @[] + for i in 0 ..< len(state.validator_registry): + eligible_indices.add i.Uint24 + + ## TODO figure out that memory safety issue, which would come up again when + ## sorting, and then actually do withdrawals + func get_initial_beacon_state*( initial_validator_deposits: openArray[Deposit], genesis_time: uint64, diff --git a/beacon_chain/spec/datatypes.nim b/beacon_chain/spec/datatypes.nim index 3cf8b13a4..045df9b6e 100644 --- a/beacon_chain/spec/datatypes.nim +++ b/beacon_chain/spec/datatypes.nim @@ -78,7 +78,7 @@ const LATEST_BLOCK_ROOTS_LENGTH* = 2'u64^13 LATEST_RANDAO_MIXES_LENGTH* = 2'u64^13 LATEST_PENALIZED_EXIT_LENGTH* = 8192 # epochs - MAX_WITHDRAWALS_PER_EPOCHS* = 4 # withdrawals + MAX_WITHDRAWALS_PER_EPOCH* = 4 # withdrawals # Deposit contract DEPOSIT_CONTRACT_TREE_DEPTH* = 2^5