nimbus-eth2/tests/spec_block_processing/test_process_deposits.nim
Etan Kissling 7bbe0258d0
allow testing genesis with Altair (#2866)
The mocking framework was limited to chain configurations that do not
include Altair at genesis. This patch extends it so that genesis states
can be generated that are already upgraded to Altair. This is useful for
tests such as eth2spec/test/altair/unittests/test_sync_protocol.py.
2021-09-13 22:56:37 +00:00

149 lines
5.4 KiB
Nim

# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# process_deposit (beaconstate.nim)
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#deposits
# ---------------------------------------------------------------
{.used.}
import
# Standard library
std/math,
# Specs
../../beacon_chain/spec/[forks, state_transition_block],
../../beacon_chain/spec/datatypes/base,
# Internals
# Mock helpers
../mocking/[mock_deposits, mock_genesis],
../testutil, ../helpers/math_helpers
suite "[Unit - Spec - Block processing] Deposits " & preset():
const NumValidators = uint64 5 * SLOTS_PER_EPOCH
let genesisState = newClone(initGenesisState(NumValidators).hbsPhase0)
doAssert genesisState.data.validators.lenu64 == NumValidators
template valid_deposit(deposit_amount: uint64, name: string): untyped =
test "Deposit " & name & " MAX_EFFECTIVE_BALANCE balance (" &
$(MAX_EFFECTIVE_BALANCE div 10'u64^9) & " ETH)":
var state = assignClone(genesisState[])
# Test configuration
# ----------------------------------------
let validator_index = state.data.validators.len
let deposit = mockUpdateStateForNewDeposit(
state.data,
uint64 validator_index,
deposit_amount,
flags = {}
)
# Params for sanity checks
# ----------------------------------------
let pre_val_count = state.data.validators.len
let pre_balance = if validator_index < pre_val_count:
state.data.balances[validator_index]
else:
0
# State transition
# ----------------------------------------
check: process_deposit(defaultRuntimeConfig, state.data, deposit, {}).isOk
# Check invariants
# ----------------------------------------
check:
state.data.validators.len == pre_val_count + 1
state.data.balances.len == pre_val_count + 1
state.data.balances[validator_index] == pre_balance + deposit.data.amount
state.data.validators[validator_index].effective_balance ==
round_multiple_down(
min(MAX_EFFECTIVE_BALANCE, state.data.balances[validator_index]),
EFFECTIVE_BALANCE_INCREMENT
)
valid_deposit(MAX_EFFECTIVE_BALANCE - 1, "under")
valid_deposit(MAX_EFFECTIVE_BALANCE, "at")
valid_deposit(MAX_EFFECTIVE_BALANCE + 1, "over")
test "Validator top-up":
var state = assignClone(genesisState[])
# Test configuration
# ----------------------------------------
let validator_index = 0
let deposit_amount = MAX_EFFECTIVE_BALANCE div 4
let deposit = mockUpdateStateForNewDeposit(
state.data,
uint64 validator_index,
deposit_amount,
flags = {}
)
# Params for sanity checks
# ----------------------------------------
let pre_val_count = state.data.validators.len
let pre_balance = if validator_index < pre_val_count:
state.data.balances[validator_index]
else:
0
# State transition
# ----------------------------------------
check: process_deposit(defaultRuntimeConfig, state.data, deposit, {}).isOk
# Check invariants
# ----------------------------------------
check:
state.data.validators.len == pre_val_count
state.data.balances.len == pre_val_count
state.data.balances[validator_index] == pre_balance + deposit.data.amount
state.data.validators[validator_index].effective_balance ==
round_multiple_down(
min(MAX_EFFECTIVE_BALANCE, state.data.balances[validator_index]),
EFFECTIVE_BALANCE_INCREMENT
)
template invalid_signature(deposit_amount: uint64, name: string): untyped =
test "Invalid deposit " & name & " MAX_EFFECTIVE_BALANCE balance (" &
$(MAX_EFFECTIVE_BALANCE div 10'u64^9) & " ETH)":
var state = assignClone(genesisState[])
# Test configuration
# ----------------------------------------
let validator_index = state.data.validators.len
var deposit = mockUpdateStateForNewDeposit(
state.data,
uint64 validator_index,
deposit_amount,
flags = {skipBlsValidation}
)
# Params for sanity checks
# ----------------------------------------
let pre_val_count = state.data.validators.len
# State transition
# ----------------------------------------
check:
process_deposit(defaultRuntimeConfig, state.data, deposit, {}).isOk
# Check invariants
# ----------------------------------------
check:
state.data.validators.len == pre_val_count
state.data.balances.len == pre_val_count
invalid_signature(MAX_EFFECTIVE_BALANCE, "at")
# TODO, tests with:
# - invalid withdrawal credential
# - invalid deposit root
# - invalid merkle proof