More 0.8.0 updates (#311)
* replace BeaconState.finalized_{epoch,root} with BeaconState.finalized_checkpoint; rename get_delayed_activation_exit_epoch(...) to compute_activation_exit_epoch(...) and mark as 0.8.0; update get_churn_limit(...)/get_validator_churn_limit(...) to 0.8.0; update process_registry_updates(...) to 0.8.0 * update process_crosslinks(...) to 0.8.0; mark compute_start_slot_of_epoch(...) and get_committee_count(...) as 0.8.0 * mark Fork, is_slashable_validator(...), and get_beacon_proposer_index(...) as 0.8.0 * rename LATEST_SLASHED_EXIT_LENGTH to EPOCHS_PER_SLASHINGS_VECTOR; update process_slashings(...) to 0.8.0; remove pointless type conversion warning in get_previous_epoch(...) * convert remaining references to finalized_epoch to finalized_checkpoint.epoch * update slash_validator(...) to 0.8.0; mark inital value, Gwei, and time constants as 0.8.0; mark hash(...) and processBlockHeader(...) as 0.8.0 * rename WHISTLEBLOWING_REWARD_QUOTIENT to WHISTLEBLOWER_REWARD_QUOTIENT; rename LATEST_ACTIVE_INDEX_ROOTS_LENGTH to EPOCHS_PER_HISTORICAL_VECTOR (randao will also get merged into this); remove get_active_index_root(...); mark time parameter, signature domain types, and max operations per block constants as 0.8.0; update rewards and penalties constants to 0.8.0 * update is_valid_indexed_attestation(...) to 0.8.0; mark process_slot(...) as 0.8.0 * replace BeaconState.{current,previous}_justified_{epoch,root} with BeaconState.{current,previous}_justified_checkpoint
This commit is contained in:
parent
5d22f5e730
commit
68be98cafa
|
@ -40,12 +40,13 @@ proc validate(
|
|||
|
||||
let attestationSlot = get_attestation_data_slot(state, attestation.data)
|
||||
|
||||
if attestationSlot < state.finalized_epoch.compute_start_slot_of_epoch():
|
||||
if attestationSlot <
|
||||
state.finalized_checkpoint.epoch.compute_start_slot_of_epoch():
|
||||
debug "Old attestation",
|
||||
attestationSlot = humaneSlotNum(attestationSlot),
|
||||
attestationEpoch = humaneEpochNum(attestationSlot.compute_epoch_of_slot),
|
||||
stateSlot = humaneSlotNum(state.slot),
|
||||
finalizedEpoch = humaneEpochNum(state.finalized_epoch)
|
||||
finalizedEpoch = humaneEpochNum(state.finalized_checkpoint.epoch)
|
||||
|
||||
return
|
||||
|
||||
|
@ -57,7 +58,7 @@ proc validate(
|
|||
attestationSlot = humaneSlotNum(attestationSlot),
|
||||
attestationEpoch = humaneEpochNum(attestationSlot.compute_epoch_of_slot),
|
||||
stateSlot = humaneSlotNum(state.slot),
|
||||
finalizedEpoch = humaneEpochNum(state.finalized_epoch)
|
||||
finalizedEpoch = humaneEpochNum(state.finalized_checkpoint.epoch)
|
||||
return
|
||||
|
||||
if not allIt(attestation.custody_bits.bits, it == 0):
|
||||
|
@ -130,7 +131,8 @@ proc slotIndex(
|
|||
# earlier than that is thrown out by the above check
|
||||
info "First attestation!",
|
||||
attestationSlot = $humaneSlotNum(attestationSlot)
|
||||
pool.startingSlot = state.finalized_epoch.compute_start_slot_of_epoch()
|
||||
pool.startingSlot =
|
||||
state.finalized_checkpoint.epoch.compute_start_slot_of_epoch()
|
||||
|
||||
if pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
|
||||
debug "Growing attestation pool",
|
||||
|
@ -141,14 +143,17 @@ proc slotIndex(
|
|||
while pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
|
||||
pool.slots.addLast(SlotData())
|
||||
|
||||
if pool.startingSlot < state.finalized_epoch.compute_start_slot_of_epoch():
|
||||
if pool.startingSlot <
|
||||
state.finalized_checkpoint.epoch.compute_start_slot_of_epoch():
|
||||
debug "Pruning attestation pool",
|
||||
startingSlot = $humaneSlotNum(pool.startingSlot),
|
||||
finalizedSlot =
|
||||
$humaneSlotNum(state.finalized_epoch.compute_start_slot_of_epoch())
|
||||
$humaneSlotNum(
|
||||
state.finalized_checkpoint.epoch.compute_start_slot_of_epoch())
|
||||
|
||||
# TODO there should be a better way to remove a whole epoch of stuff..
|
||||
while pool.startingSlot < state.finalized_epoch.compute_start_slot_of_epoch():
|
||||
while pool.startingSlot <
|
||||
state.finalized_checkpoint.epoch.compute_start_slot_of_epoch():
|
||||
pool.slots.popFirst()
|
||||
pool.startingSlot += 1
|
||||
|
||||
|
|
|
@ -107,8 +107,10 @@ proc init*(T: type BlockPool, db: BeaconChainDB): BlockPool =
|
|||
# will need revisiting however
|
||||
headState = db.getState(headStateRoot).get()
|
||||
finalizedHead =
|
||||
headRef.findAncestorBySlot(headState.finalized_epoch.compute_start_slot_of_epoch())
|
||||
justifiedSlot = headState.current_justified_epoch.compute_start_slot_of_epoch()
|
||||
headRef.findAncestorBySlot(
|
||||
headState.finalized_checkpoint.epoch.compute_start_slot_of_epoch())
|
||||
justifiedSlot =
|
||||
headState.current_justified_checkpoint.epoch.compute_start_slot_of_epoch()
|
||||
justifiedHead = headRef.findAncestorBySlot(justifiedSlot)
|
||||
head = Head(blck: headRef, justified: justifiedHead)
|
||||
|
||||
|
@ -163,7 +165,8 @@ proc addResolvedBlock(
|
|||
|
||||
# This block *might* have caused a justification - make sure we stow away
|
||||
# that information:
|
||||
let justifiedSlot = state.data.data.current_justified_epoch.compute_start_slot_of_epoch()
|
||||
let justifiedSlot =
|
||||
state.data.data.current_justified_checkpoint.epoch.compute_start_slot_of_epoch()
|
||||
|
||||
var foundHead: Option[Head]
|
||||
for head in pool.heads.mitems():
|
||||
|
@ -515,7 +518,8 @@ proc updateHead*(pool: BlockPool, state: var StateData, blck: BlockRef) =
|
|||
|
||||
# Start off by making sure we have the right state
|
||||
updateStateData(pool, state, BlockSlot(blck: blck, slot: blck.slot))
|
||||
let justifiedSlot = state.data.data.current_justified_epoch.compute_start_slot_of_epoch()
|
||||
let justifiedSlot =
|
||||
state.data.data.current_justified_checkpoint.epoch.compute_start_slot_of_epoch()
|
||||
pool.head = Head(blck: blck, justified: blck.findAncestorBySlot(justifiedSlot))
|
||||
|
||||
if lastHead.blck != blck.parent:
|
||||
|
@ -525,20 +529,25 @@ proc updateHead*(pool: BlockPool, state: var StateData, blck: BlockRef) =
|
|||
stateRoot = shortLog(state.data.root),
|
||||
headBlockRoot = shortLog(state.blck.root),
|
||||
stateSlot = humaneSlotNum(state.data.data.slot),
|
||||
justifiedEpoch = humaneEpochNum(state.data.data.current_justified_epoch),
|
||||
finalizedEpoch = humaneEpochNum(state.data.data.finalized_epoch)
|
||||
justifiedEpoch =
|
||||
humaneEpochNum(state.data.data.current_justified_checkpoint.epoch),
|
||||
finalizedEpoch =
|
||||
humaneEpochNum(state.data.data.finalized_checkpoint.epoch)
|
||||
else:
|
||||
info "Updated head",
|
||||
stateRoot = shortLog(state.data.root),
|
||||
headBlockRoot = shortLog(state.blck.root),
|
||||
stateSlot = humaneSlotNum(state.data.data.slot),
|
||||
justifiedEpoch = humaneEpochNum(state.data.data.current_justified_epoch),
|
||||
finalizedEpoch = humaneEpochNum(state.data.data.finalized_epoch)
|
||||
justifiedEpoch =
|
||||
humaneEpochNum(state.data.data.current_justified_checkpoint.epoch),
|
||||
finalizedEpoch =
|
||||
humaneEpochNum(state.data.data.finalized_checkpoint.epoch)
|
||||
|
||||
let
|
||||
# TODO there might not be a block at the epoch boundary - what then?
|
||||
finalizedHead =
|
||||
blck.findAncestorBySlot(state.data.data.finalized_epoch.compute_start_slot_of_epoch())
|
||||
blck.findAncestorBySlot(
|
||||
state.data.data.finalized_checkpoint.epoch.compute_start_slot_of_epoch())
|
||||
|
||||
doAssert (not finalizedHead.blck.isNil),
|
||||
"Block graph should always lead to a finalized block"
|
||||
|
|
|
@ -103,19 +103,19 @@ func process_deposit*(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_delayed_activation_exit_epoch
|
||||
func get_delayed_activation_exit_epoch*(epoch: Epoch): Epoch =
|
||||
## Return the epoch at which an activation or exit triggered in ``epoch``
|
||||
## takes effect.
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#compute_activation_exit_epoch
|
||||
func compute_activation_exit_epoch*(epoch: Epoch): Epoch =
|
||||
## Return the epoch during which validator activations and exits initiated in
|
||||
## ``epoch`` take effect.
|
||||
epoch + 1 + ACTIVATION_EXIT_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_churn_limit
|
||||
func get_churn_limit(state: BeaconState): uint64 =
|
||||
max(
|
||||
MIN_PER_EPOCH_CHURN_LIMIT,
|
||||
len(get_active_validator_indices(state, get_current_epoch(state))) div
|
||||
CHURN_LIMIT_QUOTIENT
|
||||
).uint64
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_validator_churn_limit
|
||||
func get_validator_churn_limit(state: BeaconState): uint64 =
|
||||
# Return the validator churn limit for the current epoch.
|
||||
let active_validator_indices =
|
||||
get_active_validator_indices(state, get_current_epoch(state))
|
||||
max(MIN_PER_EPOCH_CHURN_LIMIT,
|
||||
len(active_validator_indices) div CHURN_LIMIT_QUOTIENT).uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#initiate_validator_exit
|
||||
func initiate_validator_exit*(state: var BeaconState,
|
||||
|
@ -134,13 +134,13 @@ func initiate_validator_exit*(state: var BeaconState,
|
|||
it.exit_epoch)
|
||||
var exit_queue_epoch =
|
||||
max(max(exit_epochs),
|
||||
get_delayed_activation_exit_epoch(get_current_epoch(state)))
|
||||
compute_activation_exit_epoch(get_current_epoch(state)))
|
||||
let exit_queue_churn = foldl(
|
||||
state.validators,
|
||||
a + (if b.exit_epoch == exit_queue_epoch: 1'u64 else: 0'u64),
|
||||
0'u64)
|
||||
|
||||
if exit_queue_churn >= get_churn_limit(state):
|
||||
if exit_queue_churn >= get_validator_churn_limit(state):
|
||||
exit_queue_epoch += 1
|
||||
|
||||
# Set validator exit epoch and withdrawable epoch
|
||||
|
@ -148,32 +148,32 @@ func initiate_validator_exit*(state: var BeaconState,
|
|||
validator.withdrawable_epoch =
|
||||
validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#slash_validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#slash_validator
|
||||
func slash_validator*(state: var BeaconState, slashed_index: ValidatorIndex,
|
||||
stateCache: var StateCache) =
|
||||
# Slash the validator with index ``index``.
|
||||
let current_epoch = get_current_epoch(state)
|
||||
let epoch = get_current_epoch(state)
|
||||
initiate_validator_exit(state, slashed_index)
|
||||
state.validators[slashed_index].slashed = true
|
||||
state.validators[slashed_index].withdrawable_epoch =
|
||||
current_epoch + LATEST_SLASHED_EXIT_LENGTH
|
||||
let slashed_balance =
|
||||
state.validators[slashed_index].effective_balance
|
||||
state.slashings[current_epoch mod LATEST_SLASHED_EXIT_LENGTH] +=
|
||||
slashed_balance
|
||||
let validator = addr state.validators[slashed_index]
|
||||
validator.slashed = true
|
||||
validator.withdrawable_epoch =
|
||||
max(validator.withdrawable_epoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR)
|
||||
state.slashings[epoch mod EPOCHS_PER_SLASHINGS_VECTOR] +=
|
||||
validator.effective_balance
|
||||
decrease_balance(state, slashed_index,
|
||||
validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT)
|
||||
|
||||
let
|
||||
proposer_index = get_beacon_proposer_index(state, stateCache)
|
||||
# Spec has whistleblower_index as optional param, but it's never used.
|
||||
whistleblower_index = proposer_index
|
||||
whistleblowing_reward = slashed_balance div WHISTLEBLOWING_REWARD_QUOTIENT
|
||||
whistleblowing_reward =
|
||||
(validator.effective_balance div WHISTLEBLOWER_REWARD_QUOTIENT).Gwei
|
||||
proposer_reward = whistleblowing_reward div PROPOSER_REWARD_QUOTIENT
|
||||
increase_balance(state, proposer_index, proposer_reward)
|
||||
increase_balance(
|
||||
state, whistleblower_index, whistleblowing_reward - proposer_reward)
|
||||
decrease_balance(state, slashed_index, whistleblowing_reward)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#on-genesis
|
||||
func get_temporary_block_header(blck: BeaconBlock): BeaconBlockHeader =
|
||||
## Return the block header corresponding to a block with ``state_root`` set
|
||||
## to ``ZERO_HASH``.
|
||||
|
@ -240,7 +240,7 @@ func get_genesis_beacon_state*(
|
|||
|
||||
let genesis_active_index_root = hash_tree_root(
|
||||
get_active_validator_indices(state, GENESIS_EPOCH))
|
||||
for index in 0 ..< LATEST_ACTIVE_INDEX_ROOTS_LENGTH:
|
||||
for index in 0 ..< EPOCHS_PER_HISTORICAL_VECTOR:
|
||||
state.active_index_roots[index] = genesis_active_index_root
|
||||
|
||||
state
|
||||
|
@ -292,14 +292,14 @@ func get_total_balance*(state: BeaconState, validators: auto): Gwei =
|
|||
foldl(validators, a + state.validators[b].effective_balance, 0'u64)
|
||||
)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#registry-updates
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#registry-updates
|
||||
func process_registry_updates*(state: var BeaconState) =
|
||||
## Process activation eligibility and ejections
|
||||
## Try to avoid caching here, since this could easily become undefined
|
||||
|
||||
for index, validator in state.validators:
|
||||
if validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
||||
validator.effective_balance >= MAX_EFFECTIVE_BALANCE:
|
||||
validator.effective_balance == MAX_EFFECTIVE_BALANCE:
|
||||
state.validators[index].activation_eligibility_epoch =
|
||||
get_current_epoch(state)
|
||||
|
||||
|
@ -313,7 +313,7 @@ func process_registry_updates*(state: var BeaconState) =
|
|||
for index, validator in state.validators:
|
||||
if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and
|
||||
validator.activation_epoch >=
|
||||
get_delayed_activation_exit_epoch(state.finalized_epoch):
|
||||
compute_activation_exit_epoch(state.finalized_checkpoint.epoch):
|
||||
activation_queue.add (
|
||||
state.validators[index].activation_eligibility_epoch, index)
|
||||
|
||||
|
@ -321,7 +321,7 @@ func process_registry_updates*(state: var BeaconState) =
|
|||
|
||||
## Dequeued validators for activation up to churn limit (without resetting
|
||||
## activation epoch)
|
||||
let churn_limit = get_churn_limit(state)
|
||||
let churn_limit = get_validator_churn_limit(state)
|
||||
for i, epoch_and_index in activation_queue:
|
||||
if i.uint64 >= churn_limit:
|
||||
break
|
||||
|
@ -330,9 +330,9 @@ func process_registry_updates*(state: var BeaconState) =
|
|||
validator = addr state.validators[index]
|
||||
if validator.activation_epoch == FAR_FUTURE_EPOCH:
|
||||
validator.activation_epoch =
|
||||
get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||
compute_activation_exit_epoch(get_current_epoch(state))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#is_valid_indexed_attestation
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#is_valid_indexed_attestation
|
||||
func is_valid_indexed_attestation*(
|
||||
state: BeaconState, indexed_attestation: IndexedAttestation): bool =
|
||||
# Verify validity of ``indexed_attestation`` fields.
|
||||
|
@ -347,7 +347,7 @@ func is_valid_indexed_attestation*(
|
|||
|
||||
# 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_VALIDATORS_PER_COMMITTEE):
|
||||
if not (combined_len <= MAX_VALIDATORS_PER_COMMITTEE):
|
||||
return false
|
||||
|
||||
# Verify index sets are disjoint
|
||||
|
@ -510,8 +510,8 @@ proc process_attestation*(
|
|||
let ffg_check_data = (data.source.epoch, data.source.root, data.target.epoch)
|
||||
|
||||
if data.target.epoch == get_current_epoch(state):
|
||||
if not (ffg_check_data == (state.current_justified_epoch,
|
||||
state.current_justified_root, get_current_epoch(state))):
|
||||
if not (ffg_check_data == (state.current_justified_checkpoint.epoch,
|
||||
state.current_justified_checkpoint.root, get_current_epoch(state))):
|
||||
warn("FFG data not matching current justified epoch")
|
||||
return
|
||||
|
||||
|
@ -522,8 +522,8 @@ proc process_attestation*(
|
|||
|
||||
#state.current_epoch_attestations.add(pending_attestation)
|
||||
else:
|
||||
if not (ffg_check_data == (state.previous_justified_epoch,
|
||||
state.previous_justified_root, get_previous_epoch(state))):
|
||||
if not (ffg_check_data == (state.previous_justified_checkpoint.epoch,
|
||||
state.previous_justified_checkpoint.root, get_previous_epoch(state))):
|
||||
warn("FFG data not matching current justified epoch")
|
||||
return
|
||||
|
||||
|
@ -586,10 +586,7 @@ proc makeAttestationData*(
|
|||
|
||||
AttestationData(
|
||||
beacon_block_root: beacon_block_root,
|
||||
source: Checkpoint(
|
||||
epoch: state.current_justified_epoch,
|
||||
root: state.current_justified_root
|
||||
),
|
||||
source: state.current_justified_checkpoint,
|
||||
target: Checkpoint(
|
||||
root: target_root,
|
||||
epoch: target_epoch
|
||||
|
|
|
@ -53,7 +53,7 @@ else:
|
|||
{.fatal: "Preset \"" & const_preset ".nim\" is not supported.".}
|
||||
|
||||
const
|
||||
SPEC_VERSION* = "0.7.1" ## \
|
||||
SPEC_VERSION* = "0.8.0" ## \
|
||||
## Spec version we're aiming to be compatible with, right now
|
||||
## TODO: improve this scheme once we can negotiate versions in protocol
|
||||
|
||||
|
@ -62,9 +62,11 @@ const
|
|||
|
||||
# Initial values
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#initial-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#initial-values
|
||||
GENESIS_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
|
||||
## compute_epoch_of_slot(GENESIS_SLOT)
|
||||
|
||||
# Not part of spec. Still useful, pending removing usage if appropriate.
|
||||
ZERO_HASH* = Eth2Digest()
|
||||
|
||||
type
|
||||
|
@ -254,25 +256,38 @@ type
|
|||
## Needed to process attestations, older to newer
|
||||
|
||||
state_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
|
||||
historical_roots*: seq[Eth2Digest]
|
||||
|
||||
historical_roots*: seq[Eth2Digest] ##\
|
||||
## model List with HISTORICAL_ROOTS_LIMIT limit as seq
|
||||
## TODO bound explicitly somewhere
|
||||
|
||||
# Eth1
|
||||
eth1_data*: Eth1Data
|
||||
eth1_data_votes*: seq[Eth1Data]
|
||||
|
||||
eth1_data_votes*: seq[Eth1Data] ##\
|
||||
## As with `hitorical_roots`, this is a `List`. TODO bound explicitly.
|
||||
|
||||
eth1_deposit_index*: uint64
|
||||
|
||||
# Registry
|
||||
validators*: seq[Validator]
|
||||
balances*: seq[uint64] ##\
|
||||
## Validator balances in Gwei!
|
||||
## Also more `List`s which need to be bounded explicitly at
|
||||
## VALIDATOR_REGISTRY_LIMIT
|
||||
|
||||
# Shuffling
|
||||
start_shard*: Shard
|
||||
randao_mixes*: array[LATEST_RANDAO_MIXES_LENGTH, Eth2Digest]
|
||||
active_index_roots*: array[LATEST_ACTIVE_INDEX_ROOTS_LENGTH, Eth2Digest]
|
||||
|
||||
active_index_roots*: array[EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest] ##\
|
||||
## Active index digests for light clients
|
||||
|
||||
compact_committees_roots*: array[EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest] ##\
|
||||
## Committee digests for light clients
|
||||
|
||||
# Slashings
|
||||
slashings*: array[LATEST_SLASHED_EXIT_LENGTH, uint64] ##\
|
||||
slashings*: array[EPOCHS_PER_SLASHINGS_VECTOR, uint64] ##\
|
||||
## Per-epoch sums of slashed effective balances
|
||||
|
||||
# Attestations
|
||||
|
@ -284,13 +299,14 @@ type
|
|||
current_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint64
|
||||
previous_justified_epoch*: Epoch
|
||||
current_justified_epoch*: Epoch
|
||||
previous_justified_root*: Eth2Digest
|
||||
current_justified_root*: Eth2Digest
|
||||
finalized_epoch*: Epoch
|
||||
finalized_root*: Eth2Digest
|
||||
justification_bits*: uint64 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
||||
current_justified_checkpoint*: Checkpoint
|
||||
finalized_checkpoint*: Checkpoint
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#validator
|
||||
Validator* = object
|
||||
|
@ -338,16 +354,13 @@ type
|
|||
block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
|
||||
state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#fork
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#fork
|
||||
Fork* = object
|
||||
previous_version*: array[4, byte] ##\
|
||||
## Previous fork version
|
||||
|
||||
current_version*: array[4, byte] ##\
|
||||
## Current fork version
|
||||
previous_version*: array[4, byte]
|
||||
current_version*: array[4, byte]
|
||||
|
||||
epoch*: Epoch ##\
|
||||
## Fork epoch number
|
||||
## Epoch of latest fork
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#eth1data
|
||||
Eth1Data* = object
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
# Serenity hash function / digest
|
||||
#
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#hash
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#hash
|
||||
#
|
||||
# In Phase 0 the beacon chain is deployed with SHA256 (SHA2-256).
|
||||
# Note that is is different from Keccak256 (often mistakenly called SHA3-256)
|
||||
|
|
|
@ -62,9 +62,9 @@ func compute_epoch_of_slot*(slot: Slot|uint64): Epoch =
|
|||
# Return the epoch number of the given ``slot``.
|
||||
(slot div SLOTS_PER_EPOCH).Epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#compute_start_slot_of_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#compute_start_slot_of_epoch
|
||||
func compute_start_slot_of_epoch*(epoch: Epoch): Slot =
|
||||
# Return the starting slot of the given ``epoch``.
|
||||
# Return the start slot of ``epoch``.
|
||||
(epoch * SLOTS_PER_EPOCH).Slot
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#is_active_validator
|
||||
|
@ -80,13 +80,14 @@ func get_active_validator_indices*(state: BeaconState, epoch: Epoch):
|
|||
if is_active_validator(val, epoch):
|
||||
result.add idx.ValidatorIndex
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_committee_count
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_committee_count
|
||||
func get_committee_count*(state: BeaconState, epoch: Epoch): uint64 =
|
||||
# Return the number of committees at ``epoch``.
|
||||
let active_validator_indices = get_active_validator_indices(state, epoch)
|
||||
clamp(
|
||||
let committees_per_slot = clamp(
|
||||
len(active_validator_indices) div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
|
||||
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64 * SLOTS_PER_EPOCH
|
||||
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64
|
||||
committees_per_slot * SLOTS_PER_EPOCH
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_current_epoch
|
||||
func get_current_epoch*(state: BeaconState): Epoch =
|
||||
|
@ -102,15 +103,6 @@ func get_randao_mix*(state: BeaconState,
|
|||
## LATEST_RANDAO_MIXES_LENGTH, current_epoch].
|
||||
state.randao_mixes[epoch mod LATEST_RANDAO_MIXES_LENGTH]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_active_index_root
|
||||
func get_active_index_root(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||
# Returns the index root at a recent ``epoch``.
|
||||
## ``epoch`` expected to be between
|
||||
## (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch + ACTIVATION_EXIT_DELAY].
|
||||
## TODO maybe assert this, but omission of such seems conspicuously
|
||||
## intentional
|
||||
state.active_index_roots[epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#bytes_to_int
|
||||
func bytes_to_int*(data: openarray[byte]): uint64 =
|
||||
doAssert data.len == 8
|
||||
|
@ -186,6 +178,7 @@ func get_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
|||
seed_input[0..31] =
|
||||
get_randao_mix(state,
|
||||
epoch + LATEST_RANDAO_MIXES_LENGTH - MIN_SEED_LOOKAHEAD).data
|
||||
seed_input[32..63] = get_active_index_root(state, epoch).data
|
||||
seed_input[32..63] =
|
||||
state.active_index_roots[epoch mod EPOCHS_PER_HISTORICAL_VECTOR].data
|
||||
seed_input[64..95] = int_to_bytes32(epoch)
|
||||
eth2hash(seed_input)
|
||||
|
|
|
@ -87,11 +87,12 @@ const
|
|||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_fork-choice.md#time-parameters
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_fork-choice.md#time-parameters
|
||||
|
||||
SECONDS_PER_SLOT*{.intdefine.} = 6'u64 # Compile with -d:SECONDS_PER_SLOT=1 for 6x faster slots
|
||||
## TODO consistent time unit across projects, similar to C++ chrono?
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#time-parameters
|
||||
MIN_ATTESTATION_INCLUSION_DELAY* = 2'u64^2 ##\
|
||||
## (24 seconds)
|
||||
## Number of slots that attestations stay in the attestation
|
||||
|
@ -138,14 +139,14 @@ const
|
|||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#state-list-lengths
|
||||
LATEST_RANDAO_MIXES_LENGTH* = 8192
|
||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 8192 # 2'u64^13, epochs
|
||||
LATEST_SLASHED_EXIT_LENGTH* = 8192 # epochs
|
||||
EPOCHS_PER_HISTORICAL_VECTOR* = 8192 # 2'u64^13, epochs
|
||||
EPOCHS_PER_SLASHINGS_VECTOR* = 8192 # epochs
|
||||
|
||||
# Reward and penalty quotients
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#rewards-and-penalties
|
||||
BASE_REWARD_FACTOR* = 2'u64^5
|
||||
WHISTLEBLOWING_REWARD_QUOTIENT* = 2'u64^9
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#rewards-and-penalties
|
||||
BASE_REWARD_FACTOR* = 2'u64^6
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT* = 2'u64^9
|
||||
PROPOSER_REWARD_QUOTIENT* = 2'u64^3
|
||||
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^25
|
||||
MIN_SLASHING_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
|
@ -163,7 +164,7 @@ const
|
|||
type
|
||||
# Signature domains
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#signature-domains
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#signature-domain-types
|
||||
DomainType* {.pure.} = enum
|
||||
DOMAIN_BEACON_PROPOSER = 0
|
||||
DOMAIN_RANDAO = 1
|
||||
|
|
|
@ -50,7 +50,7 @@ const
|
|||
|
||||
# Gwei values
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#gwei-values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#gwei-values
|
||||
|
||||
# Unchanged
|
||||
MIN_DEPOSIT_AMOUNT* = 2'u64^0 * 10'u64^9
|
||||
|
@ -70,7 +70,7 @@ const
|
|||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_fork-choice.md#time-parameters
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_fork-choice.md#time-parameters
|
||||
|
||||
# Unchanged
|
||||
SECONDS_PER_SLOT*{.intdefine.} = 6'u64
|
||||
|
@ -102,23 +102,23 @@ const
|
|||
|
||||
# Changed
|
||||
LATEST_RANDAO_MIXES_LENGTH* = 64
|
||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 64
|
||||
LATEST_SLASHED_EXIT_LENGTH* = 64
|
||||
EPOCHS_PER_HISTORICAL_VECTOR* = 64
|
||||
EPOCHS_PER_SLASHINGS_VECTOR* = 64
|
||||
|
||||
# Reward and penalty quotients
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#rewards-and-penalties
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#rewards-and-penalties
|
||||
|
||||
# Unchanged
|
||||
BASE_REWARD_FACTOR* = 2'u64^5
|
||||
WHISTLEBLOWING_REWARD_QUOTIENT* = 2'u64^9
|
||||
BASE_REWARD_FACTOR* = 2'u64^6
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT* = 2'u64^9
|
||||
PROPOSER_REWARD_QUOTIENT* = 2'u64^3
|
||||
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^25
|
||||
MIN_SLASHING_PENALTY_QUOTIENT* = 32 # 2^5
|
||||
|
||||
# Max operations per block
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#max-operations-per-block
|
||||
|
||||
# Unchanged
|
||||
MAX_PROPOSER_SLASHINGS* = 2^4
|
||||
|
@ -131,7 +131,7 @@ const
|
|||
type
|
||||
# Signature domains
|
||||
# ---------------------------------------------------------------
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#signature-domains
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#signature-domain-types
|
||||
DomainType* {.pure.} = enum
|
||||
DOMAIN_BEACON_PROPOSER = 0
|
||||
DOMAIN_RANDAO = 1
|
||||
|
|
|
@ -37,7 +37,7 @@ import # TODO - cleanup imports
|
|||
../extras, ../ssz, ../beacon_node_types,
|
||||
beaconstate, bitfield, crypto, datatypes, digest, helpers, validator
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#block-header
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#block-header
|
||||
proc processBlockHeader(
|
||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags,
|
||||
stateCache: var StateCache): bool =
|
||||
|
@ -61,6 +61,7 @@ proc processBlockHeader(
|
|||
state.latest_block_header = BeaconBlockHeader(
|
||||
slot: blck.slot,
|
||||
parent_root: blck.parent_root,
|
||||
state_root: Eth2Digest(), # Overwritten in the next `process_slot` call
|
||||
body_root: hash_tree_root(blck.body),
|
||||
)
|
||||
|
||||
|
@ -124,7 +125,7 @@ func processEth1Data(state: var BeaconState, body: BeaconBlockBody) =
|
|||
SLOTS_PER_ETH1_VOTING_PERIOD:
|
||||
state.eth1_data = body.eth1_data
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#is_slashable_validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#is_slashable_validator
|
||||
func is_slashable_validator(validator: Validator, epoch: Epoch): bool =
|
||||
# Check if ``validator`` is slashable.
|
||||
(not validator.slashed) and
|
||||
|
|
|
@ -148,21 +148,23 @@ func process_justification_and_finalization(
|
|||
let
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
current_epoch = get_current_epoch(state)
|
||||
old_previous_justified_epoch = state.previous_justified_epoch
|
||||
old_current_justified_epoch = state.current_justified_epoch
|
||||
old_previous_justified_epoch = state.previous_justified_checkpoint.epoch
|
||||
old_current_justified_epoch = state.current_justified_checkpoint.epoch
|
||||
|
||||
# Process justifications
|
||||
state.previous_justified_epoch = state.current_justified_epoch
|
||||
state.previous_justified_root = state.current_justified_root
|
||||
state.previous_justified_checkpoint.epoch =
|
||||
state.current_justified_checkpoint.epoch
|
||||
state.previous_justified_checkpoint.root =
|
||||
state.current_justified_checkpoint.root
|
||||
state.justification_bits = (state.justification_bits shl 1)
|
||||
let previous_epoch_matching_target_balance =
|
||||
get_attesting_balance(state,
|
||||
get_matching_target_attestations(state, previous_epoch), stateCache)
|
||||
if previous_epoch_matching_target_balance * 3 >=
|
||||
get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = previous_epoch
|
||||
state.current_justified_root =
|
||||
get_block_root(state, state.current_justified_epoch)
|
||||
state.current_justified_checkpoint.epoch = previous_epoch
|
||||
state.current_justified_checkpoint.root =
|
||||
get_block_root(state, state.current_justified_checkpoint.epoch)
|
||||
state.justification_bits = state.justification_bits or (1 shl 1)
|
||||
let current_epoch_matching_target_balance =
|
||||
get_attesting_balance(state,
|
||||
|
@ -170,9 +172,9 @@ func process_justification_and_finalization(
|
|||
stateCache)
|
||||
if current_epoch_matching_target_balance * 3 >=
|
||||
get_total_active_balance(state) * 2:
|
||||
state.current_justified_epoch = current_epoch
|
||||
state.current_justified_root =
|
||||
get_block_root(state, state.current_justified_epoch)
|
||||
state.current_justified_checkpoint.epoch = current_epoch
|
||||
state.current_justified_checkpoint.root =
|
||||
get_block_root(state, state.current_justified_checkpoint.epoch)
|
||||
state.justification_bits = state.justification_bits or (1 shl 0)
|
||||
|
||||
# Process finalizations
|
||||
|
@ -182,48 +184,44 @@ func process_justification_and_finalization(
|
|||
## as source
|
||||
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch + 3 ==
|
||||
current_epoch:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint.epoch = old_previous_justified_epoch
|
||||
state.finalized_checkpoint.root =
|
||||
get_block_root(state, state.finalized_checkpoint.epoch)
|
||||
|
||||
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
|
||||
## source
|
||||
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch + 2 ==
|
||||
current_epoch:
|
||||
state.finalized_epoch = old_previous_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint.epoch = old_previous_justified_epoch
|
||||
state.finalized_checkpoint.root =
|
||||
get_block_root(state, state.finalized_checkpoint.epoch)
|
||||
|
||||
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
|
||||
## source
|
||||
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch + 2 ==
|
||||
current_epoch:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint.epoch = old_current_justified_epoch
|
||||
state.finalized_checkpoint.root =
|
||||
get_block_root(state, state.finalized_checkpoint.epoch)
|
||||
|
||||
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
|
||||
## source
|
||||
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch + 1 ==
|
||||
current_epoch:
|
||||
state.finalized_epoch = old_current_justified_epoch
|
||||
state.finalized_root = get_block_root(state, state.finalized_epoch)
|
||||
state.finalized_checkpoint.epoch = old_current_justified_epoch
|
||||
state.finalized_checkpoint.root =
|
||||
get_block_root(state, state.finalized_checkpoint.epoch)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#crosslinks
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#crosslinks
|
||||
func process_crosslinks(state: var BeaconState, stateCache: var StateCache) =
|
||||
## TODO is there a semantic reason for this, or is this just a way to force
|
||||
## copying? If so, why not just `list(foo)` or similar? This is strange. In
|
||||
## this case, for type reasons, don't do weird
|
||||
## [c for c in state.current_crosslinks] from spec.
|
||||
state.previous_crosslinks = state.current_crosslinks
|
||||
|
||||
for epoch_int in get_previous_epoch(state).uint64 ..
|
||||
get_current_epoch(state).uint64:
|
||||
# This issue comes up regularly -- iterating means an int type,
|
||||
# which then needs re-conversion back to specialized type.
|
||||
let epoch = epoch_int.Epoch
|
||||
for epoch in @[get_previous_epoch(state), get_current_epoch(state)]:
|
||||
for offset in 0'u64 ..< get_committee_count(state, epoch):
|
||||
let
|
||||
shard = (get_start_shard(state, epoch) + offset) mod SHARD_COUNT
|
||||
crosslink_committee =
|
||||
get_crosslink_committee(state, epoch, shard, stateCache)
|
||||
toSet(get_crosslink_committee(state, epoch, shard, stateCache))
|
||||
# In general, it'll loop over the same shards twice, and
|
||||
# get_winning_root_and_participants is defined to return
|
||||
# the same results from the previous epoch as current.
|
||||
|
@ -302,7 +300,7 @@ func get_attestation_deltas(state: BeaconState, stateCache: var StateCache):
|
|||
attestation.inclusion_delay
|
||||
|
||||
# Inactivity penalty
|
||||
let finality_delay = previous_epoch - state.finalized_epoch
|
||||
let finality_delay = previous_epoch - state.finalized_checkpoint.epoch
|
||||
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
|
||||
let matching_target_attesting_indices =
|
||||
get_unslashed_attesting_indices(
|
||||
|
@ -359,28 +357,18 @@ 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.7.1/specs/core/0_beacon-chain.md#slashings
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#slashings
|
||||
func process_slashings(state: var BeaconState) =
|
||||
let
|
||||
current_epoch = get_current_epoch(state)
|
||||
epoch = get_current_epoch(state)
|
||||
total_balance = get_total_active_balance(state)
|
||||
|
||||
# Compute `total_penalties`
|
||||
total_at_start = state.slashings[
|
||||
(current_epoch + 1) mod LATEST_SLASHED_EXIT_LENGTH]
|
||||
total_at_end =
|
||||
state.slashings[current_epoch mod
|
||||
LATEST_SLASHED_EXIT_LENGTH]
|
||||
total_penalties = total_at_end - total_at_start
|
||||
|
||||
for index, validator in state.validators:
|
||||
if validator.slashed and current_epoch == validator.withdrawable_epoch -
|
||||
LATEST_SLASHED_EXIT_LENGTH div 2:
|
||||
let
|
||||
penalty = max(
|
||||
validator.effective_balance *
|
||||
min(total_penalties * 3, total_balance) div total_balance,
|
||||
validator.effective_balance div MIN_SLASHING_PENALTY_QUOTIENT)
|
||||
if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR div 2 ==
|
||||
validator.withdrawable_epoch:
|
||||
let penalty =
|
||||
validator.effective_balance *
|
||||
min(sum(state.slashings) * 3, total_balance) div total_balance
|
||||
decrease_balance(state, index.ValidatorIndex, penalty)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#final-updates
|
||||
|
@ -410,8 +398,8 @@ func process_final_updates(state: var BeaconState) =
|
|||
SHARD_COUNT
|
||||
|
||||
# Set total slashed balances
|
||||
state.slashings[next_epoch mod LATEST_SLASHED_EXIT_LENGTH] = (
|
||||
state.slashings[current_epoch mod LATEST_SLASHED_EXIT_LENGTH]
|
||||
state.slashings[next_epoch mod EPOCHS_PER_SLASHINGS_VECTOR] = (
|
||||
state.slashings[current_epoch mod EPOCHS_PER_SLASHINGS_VECTOR]
|
||||
)
|
||||
|
||||
# Set randao mix
|
||||
|
@ -438,13 +426,13 @@ func processEpoch*(state: var BeaconState) =
|
|||
|
||||
var per_epoch_cache = get_empty_per_epoch_cache()
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#justification-and-finalization
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#justification-and-finalization
|
||||
process_justification_and_finalization(state, per_epoch_cache)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#crosslinks
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#crosslinks
|
||||
process_crosslinks(state, per_epoch_cache)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#rewards-and-penalties-1
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.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.8.0/specs/core/0_beacon-chain.md#registry-updates
|
||||
|
@ -455,8 +443,8 @@ func processEpoch*(state: var BeaconState) =
|
|||
## get_active_validator_indices(...) usually changes.
|
||||
clear(per_epoch_cache.crosslink_committee_cache)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#slashings
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#slashings
|
||||
process_slashings(state)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#final-updates
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#final-updates
|
||||
process_final_updates(state)
|
||||
|
|
|
@ -86,7 +86,7 @@ func get_previous_epoch*(state: BeaconState): Epoch =
|
|||
if current_epoch == GENESIS_EPOCH:
|
||||
current_epoch
|
||||
else:
|
||||
(current_epoch - 1).Epoch
|
||||
current_epoch - 1
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_shard_delta
|
||||
func get_shard_delta*(state: BeaconState, epoch: Epoch): uint64 =
|
||||
|
@ -166,10 +166,10 @@ func get_empty_per_epoch_cache*(): StateCache =
|
|||
result.active_validator_indices_cache =
|
||||
initTable[Epoch, seq[ValidatorIndex]]()
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_beacon_proposer_index
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_beacon_proposer_index
|
||||
func get_beacon_proposer_index*(state: BeaconState, stateCache: var StateCache):
|
||||
ValidatorIndex =
|
||||
# Return the current beacon proposer index.
|
||||
# Return the beacon proposer index at the current slot.
|
||||
const
|
||||
MAX_RANDOM_BYTE = 255
|
||||
|
||||
|
@ -187,6 +187,7 @@ func get_beacon_proposer_index*(state: BeaconState, stateCache: var StateCache):
|
|||
buffer: array[(32+8), byte]
|
||||
buffer[0..31] = seed.data
|
||||
while true:
|
||||
# TODO update to new int_to_bytes interface
|
||||
buffer[32..39] = int_to_bytes8(i.uint64 div 32)
|
||||
let
|
||||
candidate_index = first_committee[((epoch + i.uint64) mod
|
||||
|
|
|
@ -45,7 +45,7 @@ func advance_slot(state: var BeaconState) =
|
|||
|
||||
state.slot += 1
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.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)
|
||||
|
|
|
@ -43,10 +43,10 @@ type
|
|||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY*: uint64
|
||||
PERSISTENT_COMMITTEE_PERIOD*: uint64
|
||||
LATEST_RANDAO_MIXES_LENGTH*: int
|
||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH*: int
|
||||
LATEST_SLASHED_EXIT_LENGTH*: int
|
||||
EPOCHS_PER_HISTORICAL_VECTOR*: int
|
||||
EPOCHS_PER_SLASHINGS_VECTOR*: int
|
||||
BASE_REWARD_FACTOR*: uint64
|
||||
WHISTLEBLOWING_REWARD_QUOTIENT*: uint64
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT*: uint64
|
||||
PROPOSER_REWARD_QUOTIENT*: uint64
|
||||
INACTIVITY_PENALTY_QUOTIENT*: uint64
|
||||
MIN_SLASHING_PENALTY_QUOTIENT*: int
|
||||
|
|
Loading…
Reference in New Issue