Add more deposit tests
This commit is contained in:
parent
97e6166bf1
commit
990de16c0f
|
@ -2,307 +2,383 @@ from eth2spec.test.context import spec_state_test, always_bls, with_electra_and_
|
|||
from eth2spec.test.helpers.deposits import (
|
||||
prepare_deposit_request,
|
||||
run_deposit_request_processing,
|
||||
run_deposit_request_processing_with_specific_fork_version
|
||||
)
|
||||
from eth2spec.test.helpers.state import next_epoch_via_block
|
||||
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable
|
||||
from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with
|
||||
|
||||
|
||||
def run_process_pending_deposits(spec, state):
|
||||
yield from run_epoch_processing_with(
|
||||
spec, state, 'process_pending_deposits')
|
||||
def _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_creds,
|
||||
request_creds,
|
||||
signed=True,
|
||||
effective=True
|
||||
):
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
# Minimal deposit amount
|
||||
amount=(spec.EFFECTIVE_BALANCE_INCREMENT * 1),
|
||||
withdrawal_credentials=request_creds,
|
||||
signed=signed
|
||||
)
|
||||
state.validators[validator_index].withdrawal_credentials = initial_creds
|
||||
|
||||
yield from run_deposit_request_processing(
|
||||
spec,
|
||||
state,
|
||||
deposit_request,
|
||||
validator_index,
|
||||
switches_to_compounding=effective
|
||||
)
|
||||
|
||||
if effective:
|
||||
# Withdrawal address must never be changed, the change applies to the type only
|
||||
expected_credentials = spec.COMPOUNDING_WITHDRAWAL_PREFIX + initial_creds[1:]
|
||||
assert state.validators[validator_index].withdrawal_credentials == expected_credentials
|
||||
else:
|
||||
assert state.validators[validator_index].withdrawal_credentials == initial_creds
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_new_deposit_under_max(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement.
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE - 1
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_new_deposit_max(spec, state):
|
||||
def test_process_deposit_request_min_activation(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_new_deposit_over_max(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# just 1 over the limit, effective balance should be set MAX_EFFECTIVE_BALANCE during processing
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_new_deposit_eth1_withdrawal_credentials(spec, state):
|
||||
def test_process_deposit_request_max_effective_balance_compounding(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
signed=True,
|
||||
withdrawal_credentials=withdrawal_credentials
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_top_up_min_activation(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.balances[validator_index] = spec.MIN_ACTIVATION_BALANCE
|
||||
state.validators[validator_index].effective_balance = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_top_up_max_effective_balance_compounding(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE
|
||||
state.validators[validator_index].effective_balance = spec.MAX_EFFECTIVE_BALANCE
|
||||
state.validators[validator_index].withdrawal_credentials = withdrawal_credentials
|
||||
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
signed=True,
|
||||
withdrawal_credentials=withdrawal_credentials
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_process_deposit_request_invalid_sig(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_process_deposit_request_top_up_invalid_sig(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount)
|
||||
|
||||
state.balances[validator_index] = spec.MIN_ACTIVATION_BALANCE
|
||||
state.validators[validator_index].effective_balance = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_set_start_index(spec, state):
|
||||
assert state.deposit_requests_start_index == spec.UNSET_DEPOSIT_REQUESTS_START_INDEX
|
||||
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
assert state.deposit_requests_start_index == deposit_request.index
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_set_start_index_only_once(spec, state):
|
||||
initial_start_index = 1
|
||||
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.deposit_requests_start_index = initial_start_index
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
assert state.deposit_requests_start_index == initial_start_index
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_normal(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_new_deposit_non_versioned_withdrawal_credentials(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
b'\xFF' # Non specified withdrawal credentials version
|
||||
+ b'\x02' * 31 # Garabage bytes
|
||||
)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_correct_sig_but_forked_state(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
# deposits will always be valid, regardless of the current fork
|
||||
state.fork.current_version = spec.Version('0x1234abcd')
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_incorrect_sig_new_deposit(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount)
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_top_up__max_effective_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE
|
||||
state.validators[validator_index].effective_balance = spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_top_up__less_effective_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
initial_balance = spec.MAX_EFFECTIVE_BALANCE - 1000
|
||||
initial_effective_balance = spec.MAX_EFFECTIVE_BALANCE - spec.EFFECTIVE_BALANCE_INCREMENT
|
||||
state.balances[validator_index] = initial_balance
|
||||
state.validators[validator_index].effective_balance = initial_effective_balance
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_top_up__zero_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, signed=True)
|
||||
|
||||
initial_balance = 0
|
||||
initial_effective_balance = 0
|
||||
state.balances[validator_index] = initial_balance
|
||||
state.validators[validator_index].effective_balance = initial_effective_balance
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_incorrect_sig_top_up(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount)
|
||||
|
||||
# invalid signatures, in top-ups, are allowed!
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_incorrect_withdrawal_credentials_top_up(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
|
||||
deposit_request = prepare_deposit_request(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials
|
||||
)
|
||||
|
||||
# inconsistent withdrawal credentials, in top-ups, are allowed!
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_key_validate_invalid_subgroup(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
# All-zero pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception.
|
||||
pubkey = b'\x00' * 48
|
||||
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, pubkey=pubkey, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_key_validate_invalid_decompression(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
# `deserialization_fails_infinity_with_true_b_flag` BLS G1 deserialization test case.
|
||||
# This pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception.
|
||||
pubkey_hex = 'c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
pubkey = bytes.fromhex(pubkey_hex)
|
||||
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, pubkey=pubkey, signed=True)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_ineffective_deposit_with_previous_fork_version(spec, state):
|
||||
# Since deposits are valid across forks, the domain is always set with `GENESIS_FORK_VERSION`.
|
||||
# It's an ineffective deposit because it fails at BLS sig verification.
|
||||
# NOTE: it was effective in Altair.
|
||||
assert state.fork.previous_version != state.fork.current_version
|
||||
|
||||
yield from run_deposit_request_processing_with_specific_fork_version(
|
||||
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
fork_version=state.fork.previous_version,
|
||||
effective=False,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=True
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_with_excess(spec, state):
|
||||
validator_index = 0
|
||||
# there is excess balace that will be enqueued to pending deposits
|
||||
initial_balance = initial_effective_balance = (
|
||||
spec.MIN_ACTIVATION_BALANCE + spec.EFFECTIVE_BALANCE_INCREMENT // 2)
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
state.balances[validator_index] = initial_balance
|
||||
state.validators[validator_index].effective_balance = initial_effective_balance
|
||||
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=True
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_incorrect_credentials(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
|
||||
)
|
||||
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=True
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_no_compounding(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
# credentials with ETH1 prefix
|
||||
incorrect_compounding_credentials = (
|
||||
b'\xFF'
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
incorrect_compounding_credentials,
|
||||
effective=False
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_has_bls(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = state.validators[validator_index].withdrawal_credentials.copy()
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=False
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_effective_deposit_with_genesis_fork_version(spec, state):
|
||||
assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version)
|
||||
def test_process_deposit_request_switch_to_compounding_invalid_sig(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing_with_specific_fork_version(
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
fork_version=spec.config.GENESIS_FORK_VERSION,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
signed=False,
|
||||
effective=False
|
||||
)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_success_top_up_to_withdrawn_validator(spec, state):
|
||||
def test_process_deposit_request_switch_to_compounding_inactive(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
# Fully withdraw validator
|
||||
set_validator_fully_withdrawable(spec, state, validator_index)
|
||||
assert state.balances[validator_index] > 0
|
||||
next_epoch_via_block(spec, state)
|
||||
assert state.balances[validator_index] == 0
|
||||
assert state.validators[validator_index].effective_balance > 0
|
||||
next_epoch_via_block(spec, state)
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
# Set exit_epoch to the current epoch to make validator inactive
|
||||
spec.initiate_validator_exit(state, validator_index)
|
||||
state.validators[validator_index].exit_epoch = spec.get_current_epoch(state)
|
||||
|
||||
# Make a top-up balance to validator
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
deposit_request = prepare_deposit_request(spec, validator_index, amount, len(state.validators), signed=True)
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=False
|
||||
)
|
||||
|
||||
yield from run_deposit_request_processing(spec, state, deposit_request, validator_index)
|
||||
|
||||
deposits_len = len(state.pending_deposits)
|
||||
assert state.pending_deposits[deposits_len - 1].amount == amount
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_process_deposit_request_switch_to_compounding_exited_and_active(spec, state):
|
||||
validator_index = 0
|
||||
initial_withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
|
||||
validator = state.validators[validator_index]
|
||||
# Initiate exit
|
||||
spec.initiate_validator_exit(state, validator_index)
|
||||
|
||||
pending_deposits_len = len(state.pending_deposits)
|
||||
pending_deposit = state.pending_deposits[pending_deposits_len - 1]
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator)
|
||||
is_withdrawable = validator.withdrawable_epoch <= current_epoch
|
||||
has_non_zero_balance = pending_deposit.amount > 0
|
||||
# NOTE: directly compute `is_fully_withdrawable_validator` conditions here
|
||||
# to work around how the epoch processing changed balance updates
|
||||
assert has_execution_withdrawal and is_withdrawable and has_non_zero_balance
|
||||
yield from _run_deposit_request_switching_to_compounding(
|
||||
spec,
|
||||
state,
|
||||
validator_index,
|
||||
initial_withdrawal_credentials,
|
||||
compounding_credentials,
|
||||
effective=True
|
||||
)
|
||||
|
|
|
@ -1,264 +1,467 @@
|
|||
from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with
|
||||
from eth2spec.test.context import (
|
||||
spec_state_test,
|
||||
with_electra_and_later,
|
||||
always_bls,
|
||||
)
|
||||
from tests.core.pyspec.eth2spec.test.helpers.deposits import (
|
||||
prepare_pending_deposit,
|
||||
run_pending_deposit_applying,
|
||||
)
|
||||
from eth2spec.test.helpers.keys import privkeys, pubkeys
|
||||
from tests.core.pyspec.eth2spec.test.helpers.deposits import build_deposit_data
|
||||
from eth2spec.test.helpers.state import next_epoch_via_block
|
||||
|
||||
|
||||
def run_process_pending_deposits(spec, state):
|
||||
yield from run_epoch_processing_with(
|
||||
spec, state, 'process_pending_deposits')
|
||||
from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_add_validator_to_registry(spec, state):
|
||||
def test_apply_pending_deposit_under_min_activation(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement.
|
||||
amount = spec.MIN_ACTIVATION_BALANCE - 1
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_min_activation(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_over_min_activation(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
# just 1 over the limit, effective balance should be set MIN_ACTIVATION_BALANCE during processing
|
||||
amount = spec.MIN_ACTIVATION_BALANCE + 1
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_eth1_withdrawal_credentials(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_compounding_withdrawal_credentials_under_max(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
# effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement.
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA - 1
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_compounding_withdrawal_credentials_max(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
# effective balance will be exactly the same as balance.
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_compounding_withdrawal_credentials_over_max(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
# just 1 over the limit, effective balance should be set MAX_EFFECTIVE_BALANCE_ELECTRA during processing
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA + 1
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_non_versioned_withdrawal_credentials(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
b'\xFF' # Non specified withdrawal credentials version
|
||||
+ b'\x02' * 31 # Garabage bytes
|
||||
)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_non_versioned_withdrawal_credentials_over_min_activation(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
b'\xFF' # Non specified withdrawal credentials version
|
||||
+ b'\x02' * 31 # Garabage bytes
|
||||
)
|
||||
# just 1 over the limit, effective balance should be set MIN_ACTIVATION_BALANCE during processing
|
||||
amount = spec.MIN_ACTIVATION_BALANCE + 1
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_correct_sig_but_forked_state(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
# deposits will always be valid, regardless of the current fork
|
||||
state.fork.current_version = spec.Version('0x1234abcd')
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_incorrect_sig_new_deposit(spec, state):
|
||||
# fresh deposit = next validator index = validator appended to registry
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount)
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_top_up__min_activation_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.balances[validator_index] = spec.MIN_ACTIVATION_BALANCE
|
||||
state.validators[validator_index].effective_balance = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
assert state.balances[validator_index] == spec.MIN_ACTIVATION_BALANCE + amount
|
||||
assert state.validators[validator_index].effective_balance == spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_top_up__min_activation_balance_compounding(spec, state):
|
||||
validator_index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.balances[validator_index] = spec.MIN_ACTIVATION_BALANCE
|
||||
state.validators[validator_index].withdrawal_credentials = withdrawal_credentials
|
||||
state.validators[validator_index].effective_balance = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
assert state.balances[validator_index] == spec.MIN_ACTIVATION_BALANCE + amount
|
||||
assert state.validators[validator_index].effective_balance == spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_top_up__max_effective_balance_compounding(spec, state):
|
||||
validator_index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX
|
||||
+ b'\x00' * 11 # specified 0s
|
||||
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||
)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE_ELECTRA // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
state.balances[validator_index] = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
state.validators[validator_index].withdrawal_credentials = withdrawal_credentials
|
||||
state.validators[validator_index].effective_balance = spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
assert state.balances[validator_index] == spec.MAX_EFFECTIVE_BALANCE_ELECTRA + amount
|
||||
assert state.validators[validator_index].effective_balance == spec.MAX_EFFECTIVE_BALANCE_ELECTRA
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_top_up__less_effective_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
initial_balance = spec.MIN_ACTIVATION_BALANCE - 1000
|
||||
initial_effective_balance = spec.MIN_ACTIVATION_BALANCE - spec.EFFECTIVE_BALANCE_INCREMENT
|
||||
state.balances[validator_index] = initial_balance
|
||||
state.validators[validator_index].effective_balance = initial_effective_balance
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
assert state.balances[validator_index] == initial_balance + amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_top_up__zero_balance(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
initial_balance = 0
|
||||
initial_effective_balance = 0
|
||||
state.balances[validator_index] = initial_balance
|
||||
state.validators[validator_index].effective_balance = initial_effective_balance
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
assert state.balances[validator_index] == initial_balance + amount
|
||||
# unchanged effective balance
|
||||
assert state.validators[validator_index].effective_balance == initial_effective_balance
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_incorrect_sig_top_up(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
# invalid signatures, in top-ups, are allowed!
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_incorrect_withdrawal_credentials_top_up(spec, state):
|
||||
validator_index = 0
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index,
|
||||
amount,
|
||||
signed=True,
|
||||
withdrawal_credentials=withdrawal_credentials
|
||||
)
|
||||
|
||||
# inconsistent withdrawal credentials, in top-ups, are allowed!
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_key_validate_invalid_subgroup(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
# select validator set outside of the mainnet preset of 256
|
||||
index = len(state.validators)
|
||||
withdrawal_credentials = (
|
||||
spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
withdrawal_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
old_validator_count = len(state.validators)
|
||||
state.pending_deposits.append(deposit)
|
||||
yield from run_process_pending_deposits(spec, state)
|
||||
# validator count should increase by 1
|
||||
assert len(state.validators) == old_validator_count + 1
|
||||
# All-zero pubkey would not pass `bls.KeyValidate`, but `apply_pending_deposit` would not throw exception.
|
||||
pubkey = b'\x00' * 48
|
||||
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, pubkey=pubkey, signed=True)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_increases_balance(spec, state):
|
||||
amount = 100
|
||||
# signature doesn't matter here as it's interpreted as a top-up
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=state.validators[0].pubkey,
|
||||
withdrawal_credentials=state.validators[0].withdrawal_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT
|
||||
)
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
assert state.balances[0] == amount
|
||||
def test_apply_pending_deposit_key_validate_invalid_decompression(spec, state):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MIN_ACTIVATION_BALANCE
|
||||
|
||||
# `deserialization_fails_infinity_with_true_b_flag` BLS G1 deserialization test case.
|
||||
# This pubkey would not pass `bls.KeyValidate`, but `apply_pending_deposit` would not throw exception.
|
||||
pubkey_hex = 'c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||
pubkey = bytes.fromhex(pubkey_hex)
|
||||
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, pubkey=pubkey, signed=True)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_switch_to_compounding(spec, state):
|
||||
amount = 100
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_ineffective_deposit_with_bad_fork_version(spec, state):
|
||||
validator_index=len(state.validators)
|
||||
fork_version=spec.Version('0xAaBbCcDd')
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index=validator_index,
|
||||
amount=spec.MIN_ACTIVATION_BALANCE,
|
||||
fork_version=fork_version,
|
||||
signed=True
|
||||
)
|
||||
|
||||
# choose a value public key that's in the validator set
|
||||
index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_with_previous_fork_version(spec, state):
|
||||
# Since deposits are valid across forks, the domain is always set with `GENESIS_FORK_VERSION`.
|
||||
# It's an ineffective deposit because it fails at BLS sig verification.
|
||||
# NOTE: it was effective in Altair.
|
||||
assert state.fork.previous_version != state.fork.current_version
|
||||
|
||||
validator_index=len(state.validators)
|
||||
fork_version=state.fork.previous_version
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index=validator_index,
|
||||
amount=spec.MIN_ACTIVATION_BALANCE,
|
||||
fork_version=fork_version,
|
||||
signed=True
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_ineffective_deposit_with_current_fork_version(spec, state):
|
||||
validator_index=len(state.validators)
|
||||
fork_version=state.fork.current_version
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index=validator_index,
|
||||
amount=spec.MIN_ACTIVATION_BALANCE,
|
||||
fork_version=fork_version,
|
||||
signed=True
|
||||
)
|
||||
# advance the state
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=False)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_apply_pending_deposit_effective_deposit_with_genesis_fork_version(spec, state):
|
||||
assert spec.config.GENESIS_FORK_VERSION not in (state.fork.previous_version, state.fork.current_version)
|
||||
|
||||
validator_index=len(state.validators)
|
||||
fork_version=state.fork.previous_version
|
||||
pending_deposit = prepare_pending_deposit(
|
||||
spec,
|
||||
validator_index=validator_index,
|
||||
amount=spec.MIN_ACTIVATION_BALANCE,
|
||||
fork_version=spec.config.GENESIS_FORK_VERSION,
|
||||
signed=True
|
||||
)
|
||||
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_success_top_up_to_withdrawn_validator(spec, state):
|
||||
validator_index = 0
|
||||
|
||||
# Fully withdraw validator
|
||||
set_validator_fully_withdrawable(spec, state, validator_index)
|
||||
assert state.balances[validator_index] > 0
|
||||
next_epoch_via_block(spec, state)
|
||||
state.validators[index].withdrawal_credentials = withdrawal_credentials
|
||||
# set validator to be exited by current epoch
|
||||
state.validators[index].exit_epoch = spec.get_current_epoch(state) - 1
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
compounding_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=compounding_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
state.balances[index] = 0
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
# validator balance should increase
|
||||
assert state.balances[index] == amount
|
||||
current_credentials = state.validators[0].withdrawal_credentials
|
||||
assert current_credentials == compounding_credentials
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_switch_to_compounding_no_compounding(spec, state):
|
||||
amount = 100
|
||||
|
||||
# choose a value public key that's in the validator set
|
||||
index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
# wrong compounding
|
||||
compounding_credentials = (
|
||||
spec.hash(b"wrong compounding address")[:]
|
||||
)
|
||||
# advance the state
|
||||
assert state.balances[validator_index] == 0
|
||||
assert state.validators[validator_index].effective_balance > 0
|
||||
next_epoch_via_block(spec, state)
|
||||
state.validators[index].withdrawal_credentials = withdrawal_credentials
|
||||
# set validator to be exited by current epoch
|
||||
state.validators[index].exit_epoch = spec.get_current_epoch(state) - 1
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
compounding_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=compounding_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
state.balances[index] = 0
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
# validator balance should increase
|
||||
assert state.balances[index] == amount
|
||||
current_credentials = state.validators[0].withdrawal_credentials
|
||||
assert current_credentials == withdrawal_credentials
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
|
||||
# Make a top-up balance to validator
|
||||
amount = spec.MIN_ACTIVATION_BALANCE // 4
|
||||
pending_deposit = prepare_pending_deposit(spec, validator_index, amount, signed=True)
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_switch_to_compounding_has_bls(spec, state):
|
||||
amount = 100
|
||||
yield from run_pending_deposit_applying(spec, state, pending_deposit, validator_index)
|
||||
|
||||
# choose a value public key that's in the validator set
|
||||
index = 0
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
# advance the state
|
||||
next_epoch_via_block(spec, state)
|
||||
bls_credentials = state.validators[index].withdrawal_credentials
|
||||
# set validator to be exited by current epoch
|
||||
state.validators[index].exit_epoch = spec.get_current_epoch(state) - 1
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
compounding_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=compounding_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
state.balances[index] = 0
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
# validator balance should increase
|
||||
assert state.balances[index] == amount
|
||||
current_credentials = state.validators[index].withdrawal_credentials
|
||||
# does not switch to compounding
|
||||
assert current_credentials == bls_credentials
|
||||
assert state.balances[validator_index] == amount
|
||||
assert state.validators[validator_index].effective_balance == 0
|
||||
|
||||
validator = state.validators[validator_index]
|
||||
balance = state.balances[validator_index]
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_switch_to_compounding_invalid_sig(spec, state):
|
||||
amount = 100
|
||||
|
||||
# choose a value public key that's in the validator set
|
||||
index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX +
|
||||
spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
# advance the state
|
||||
next_epoch_via_block(spec, state)
|
||||
state.validators[index].withdrawal_credentials = withdrawal_credentials
|
||||
# set validator to be exited by current epoch
|
||||
state.validators[index].exit_epoch = spec.get_current_epoch(state) - 1
|
||||
# creates wrong signature
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
withdrawal_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=compounding_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
state.balances[index] = 0
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
# validator balance should increase
|
||||
assert state.balances[index] == amount
|
||||
current_credentials = state.validators[0].withdrawal_credentials
|
||||
assert current_credentials == withdrawal_credentials
|
||||
|
||||
|
||||
@with_electra_and_later
|
||||
@spec_state_test
|
||||
def test_apply_pending_deposit_switch_to_compounding_not_exited(spec, state):
|
||||
amount = 100
|
||||
|
||||
# choose a value public key that's in the validator set
|
||||
index = 0
|
||||
withdrawal_credentials = (
|
||||
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
compounding_credentials = (
|
||||
spec.COMPOUNDING_WITHDRAWAL_PREFIX + spec.hash(pubkeys[index])[1:]
|
||||
)
|
||||
state.validators[index].withdrawal_credentials = withdrawal_credentials
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkeys[index],
|
||||
privkeys[index],
|
||||
amount,
|
||||
compounding_credentials,
|
||||
signed=True)
|
||||
deposit = spec.PendingDeposit(
|
||||
pubkey=pubkeys[index],
|
||||
withdrawal_credentials=compounding_credentials,
|
||||
amount=amount,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
signature=deposit_data.signature,
|
||||
)
|
||||
state.balances[index] = 0
|
||||
# run test
|
||||
spec.apply_pending_deposit(state, deposit)
|
||||
# validator balance should increase
|
||||
assert state.balances[index] == amount
|
||||
# make sure validator did not switch to compounding if not exited
|
||||
current_credentials = state.validators[0].withdrawal_credentials
|
||||
assert current_credentials == withdrawal_credentials
|
||||
# postpone pending_deposit
|
||||
assert len(state.pending_deposits) == 0
|
||||
assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch)
|
||||
|
|
|
@ -4,6 +4,7 @@ from eth2spec.test.context import expect_assertion_error
|
|||
from eth2spec.test.helpers.forks import is_post_altair, is_post_electra
|
||||
from eth2spec.test.helpers.keys import pubkeys, privkeys
|
||||
from eth2spec.test.helpers.state import get_balance
|
||||
from eth2spec.test.helpers.epoch_processing import run_epoch_processing_to
|
||||
from eth2spec.utils import bls
|
||||
from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merkle_proof
|
||||
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
||||
|
@ -23,7 +24,7 @@ def mock_deposit(spec, state, index):
|
|||
assert not spec.is_active_validator(state.validators[index], spec.get_current_epoch(state))
|
||||
|
||||
|
||||
def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, fork_version, signed=False):
|
||||
def build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, fork_version=None, signed=False):
|
||||
deposit_data = spec.DepositData(
|
||||
pubkey=pubkey,
|
||||
withdrawal_credentials=withdrawal_credentials,
|
||||
|
@ -276,6 +277,47 @@ def build_pending_deposit(spec, validator_index, amount,
|
|||
pending_deposit.signature = deposit_data.signature
|
||||
return pending_deposit
|
||||
|
||||
|
||||
def prepare_pending_deposit(spec, validator_index, amount,
|
||||
pubkey=None,
|
||||
privkey=None,
|
||||
withdrawal_credentials=None,
|
||||
fork_version=None,
|
||||
signed=False,
|
||||
slot=None):
|
||||
"""
|
||||
Create a pending deposit for the given validator, depositing the given amount.
|
||||
"""
|
||||
if pubkey is None:
|
||||
pubkey = pubkeys[validator_index]
|
||||
|
||||
if privkey is None:
|
||||
privkey = privkeys[validator_index]
|
||||
|
||||
# insecurely use pubkey as withdrawal key if no credentials provided
|
||||
if withdrawal_credentials is None:
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
|
||||
|
||||
# use GENESIS_SLOT which is always finalized if no slot provided
|
||||
if slot is None:
|
||||
slot = spec.GENESIS_SLOT
|
||||
|
||||
deposit_data = build_deposit_data(spec,
|
||||
pubkey,
|
||||
privkey,
|
||||
amount,
|
||||
withdrawal_credentials,
|
||||
fork_version,
|
||||
signed)
|
||||
|
||||
return spec.PendingDeposit(
|
||||
pubkey=deposit_data.pubkey,
|
||||
amount=deposit_data.amount,
|
||||
withdrawal_credentials=deposit_data.withdrawal_credentials,
|
||||
signature=deposit_data.signature,
|
||||
slot=slot,
|
||||
)
|
||||
|
||||
#
|
||||
# Run processing
|
||||
#
|
||||
|
@ -381,14 +423,24 @@ def run_deposit_processing_with_specific_fork_version(
|
|||
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=valid, effective=effective)
|
||||
|
||||
|
||||
def run_deposit_request_processing(spec, state, deposit_request, validator_index, valid=True, effective=True):
|
||||
def run_deposit_request_processing(
|
||||
spec,
|
||||
state,
|
||||
deposit_request,
|
||||
validator_index,
|
||||
effective=True,
|
||||
switches_to_compounding=False):
|
||||
|
||||
"""
|
||||
Run ``process_deposit_request``, yielding:
|
||||
- pre-state ('pre')
|
||||
- deposit_request ('deposit_request')
|
||||
- post-state ('post').
|
||||
If ``valid == False``, run expecting ``AssertionError``
|
||||
"""
|
||||
assert is_post_electra(spec)
|
||||
if switches_to_compounding:
|
||||
assert effective
|
||||
|
||||
pre_validator_count = len(state.validators)
|
||||
pre_balance = 0
|
||||
is_top_up = False
|
||||
|
@ -403,71 +455,103 @@ def run_deposit_request_processing(spec, state, deposit_request, validator_index
|
|||
yield 'pre', state
|
||||
yield 'deposit_request', deposit_request
|
||||
|
||||
if not valid:
|
||||
expect_assertion_error(lambda: spec.process_deposit_request(state, deposit_request))
|
||||
yield 'post', None
|
||||
return
|
||||
|
||||
spec.process_deposit_request(state, deposit_request)
|
||||
|
||||
yield 'post', state
|
||||
|
||||
if not effective or not bls.KeyValidate(deposit_request.pubkey):
|
||||
# New validator is only created after the pending_deposits processing
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
|
||||
if is_top_up:
|
||||
assert state.validators[validator_index].effective_balance == pre_effective_balance
|
||||
if switches_to_compounding and pre_balance > spec.MIN_ACTIVATION_BALANCE:
|
||||
assert state.balances[validator_index] == spec.MIN_ACTIVATION_BALANCE
|
||||
else:
|
||||
assert state.balances[validator_index] == pre_balance
|
||||
|
||||
pending_deposit = spec.PendingDeposit(
|
||||
pubkey=deposit_request.pubkey,
|
||||
withdrawal_credentials=deposit_request.withdrawal_credentials,
|
||||
amount=deposit_request.amount,
|
||||
signature=deposit_request.signature,
|
||||
slot=state.slot,
|
||||
)
|
||||
|
||||
if switches_to_compounding and pre_balance > spec.MIN_ACTIVATION_BALANCE:
|
||||
validator = state.validators[validator_index]
|
||||
excess_amount = pre_balance - spec.MIN_ACTIVATION_BALANCE
|
||||
pending_excess = spec.PendingDeposit(
|
||||
pubkey=validator.pubkey,
|
||||
withdrawal_credentials=validator.withdrawal_credentials,
|
||||
amount=excess_amount,
|
||||
signature=spec.bls.G2_POINT_AT_INFINITY,
|
||||
slot=spec.GENESIS_SLOT,
|
||||
)
|
||||
assert state.pending_deposits == [pending_deposit, pending_excess]
|
||||
else:
|
||||
assert state.pending_deposits == [pending_deposit]
|
||||
|
||||
|
||||
def run_pending_deposit_applying(spec, state, pending_deposit, validator_index, effective=True):
|
||||
"""
|
||||
Enqueue ``pending_deposit`` and run epoch processing with ``process_pending_deposits``, yielding:
|
||||
- pre-state ('pre')
|
||||
- post-state ('post').
|
||||
"""
|
||||
assert is_post_electra(spec)
|
||||
|
||||
# ensure the transition from eth1 bridge is complete
|
||||
state.deposit_requests_start_index = state.eth1_deposit_index
|
||||
|
||||
# ensure there is enough churn to apply the deposit
|
||||
if pending_deposit.amount > spec.get_activation_exit_churn_limit(state):
|
||||
state.deposit_balance_to_consume = pending_deposit.amount - spec.get_activation_exit_churn_limit(state)
|
||||
|
||||
# append pending deposit
|
||||
state.pending_deposits.append(pending_deposit)
|
||||
|
||||
# run to the very beginning of the epoch processing to avoid
|
||||
# any updates to the validator registry (e.g. ejections)
|
||||
run_epoch_processing_to(spec, state, "process_justification_and_finalization")
|
||||
|
||||
pre_validator_count = len(state.validators)
|
||||
pre_balance = 0
|
||||
pre_effective_balance = 0
|
||||
is_top_up = False
|
||||
# is a top-up
|
||||
if validator_index < pre_validator_count:
|
||||
is_top_up = True
|
||||
pre_balance = get_balance(state, validator_index)
|
||||
pre_effective_balance = state.validators[validator_index].effective_balance
|
||||
|
||||
yield 'pre', state
|
||||
|
||||
spec.process_pending_deposits(state)
|
||||
|
||||
yield 'post', state
|
||||
|
||||
if effective:
|
||||
if is_top_up:
|
||||
# Top-ups don't add validators
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
# Top-ups do not change effective balance
|
||||
assert state.validators[validator_index].effective_balance == pre_effective_balance
|
||||
else:
|
||||
# new validator is added
|
||||
assert len(state.validators) == pre_validator_count + 1
|
||||
assert len(state.balances) == pre_validator_count + 1
|
||||
# effective balance is set correctly
|
||||
max_effective_balace = spec.get_validator_max_effective_balance(state.validators[validator_index])
|
||||
effective_balance = min(max_effective_balace, pending_deposit.amount)
|
||||
effective_balance -= effective_balance % spec.EFFECTIVE_BALANCE_INCREMENT
|
||||
assert state.validators[validator_index].effective_balance == effective_balance
|
||||
assert get_balance(state, validator_index) == pre_balance + pending_deposit.amount
|
||||
else:
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
if is_top_up:
|
||||
assert get_balance(state, validator_index) == pre_balance
|
||||
else:
|
||||
if is_top_up:
|
||||
# Top-ups do not change effective balance
|
||||
assert state.validators[validator_index].effective_balance == pre_effective_balance
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
else:
|
||||
# new validator is only created after the pending_deposits processing
|
||||
assert len(state.validators) == pre_validator_count
|
||||
assert len(state.balances) == pre_validator_count
|
||||
|
||||
assert len(state.pending_deposits) == pre_pending_deposits + 1
|
||||
assert state.pending_deposits[pre_pending_deposits].pubkey == deposit_request.pubkey
|
||||
assert state.pending_deposits[
|
||||
pre_pending_deposits].withdrawal_credentials == deposit_request.withdrawal_credentials
|
||||
assert state.pending_deposits[pre_pending_deposits].amount == deposit_request.amount
|
||||
assert state.pending_deposits[pre_pending_deposits].signature == deposit_request.signature
|
||||
assert state.pending_deposits[pre_pending_deposits].slot == state.slot
|
||||
|
||||
|
||||
def run_deposit_request_processing_with_specific_fork_version(
|
||||
spec,
|
||||
state,
|
||||
fork_version,
|
||||
valid=True,
|
||||
effective=True):
|
||||
validator_index = len(state.validators)
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
pubkey = pubkeys[validator_index]
|
||||
privkey = privkeys[validator_index]
|
||||
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
|
||||
|
||||
deposit_message = spec.DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount)
|
||||
domain = spec.compute_domain(domain_type=spec.DOMAIN_DEPOSIT, fork_version=fork_version)
|
||||
deposit_data = spec.DepositData(
|
||||
pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount,
|
||||
signature=bls.Sign(privkey, spec.compute_signing_root(deposit_message, domain))
|
||||
)
|
||||
deposit_request = spec.DepositRequest(
|
||||
pubkey=deposit_data.pubkey,
|
||||
withdrawal_credentials=deposit_data.withdrawal_credentials,
|
||||
amount=deposit_data.amount,
|
||||
signature=deposit_data.signature,
|
||||
index=validator_index)
|
||||
|
||||
yield from run_deposit_request_processing(
|
||||
spec,
|
||||
state,
|
||||
deposit_request,
|
||||
validator_index,
|
||||
valid=valid,
|
||||
effective=effective
|
||||
)
|
||||
|
||||
assert len(state.pending_deposits) == 0
|
||||
|
|
|
@ -22,7 +22,7 @@ def get_process_calls(spec):
|
|||
'charge_confirmed_header_fees', # sharding
|
||||
'reset_pending_headers', # sharding
|
||||
'process_eth1_data_reset',
|
||||
'process_pending_balance_deposits', # electra
|
||||
'process_pending_deposits', # electra
|
||||
'process_pending_consolidations', # electra
|
||||
'process_effective_balance_updates',
|
||||
'process_slashings_reset',
|
||||
|
@ -38,8 +38,6 @@ def get_process_calls(spec):
|
|||
'process_sync_committee_updates', # altair
|
||||
'process_full_withdrawals', # capella
|
||||
'process_partial_withdrawals', # capella
|
||||
'process_pending_deposits', # electra
|
||||
'process_pending_consolidations', # electra
|
||||
# TODO: add sharding processing functions when spec stabilizes.
|
||||
]
|
||||
|
||||
|
|
|
@ -41,6 +41,20 @@ def run_test_effective_balance_hysteresis(spec, state, with_compounding_credenti
|
|||
(min, min + (hys_inc * div * 2), min + (2 * inc), "exact two step balance increment"),
|
||||
(min, min + (hys_inc * div * 2) + 1, min + (2 * inc), "over two steps, round down"),
|
||||
]
|
||||
|
||||
if with_compounding_credentials:
|
||||
min = spec.MIN_ACTIVATION_BALANCE
|
||||
cases = cases + [
|
||||
(min, min + (hys_inc * up), min, "bigger balance, but not high enough"),
|
||||
(min, min + (hys_inc * up) + 1, min + inc, "bigger balance, high enough, but small step"),
|
||||
(min, min + (hys_inc * div * 2) - 1, min + inc, "bigger balance, high enough, close to double step"),
|
||||
(min, min + (hys_inc * div * 2), min + (2 * inc), "exact two step balance increment"),
|
||||
(min, min + (hys_inc * div * 2) + 1, min + (2 * inc), "over two steps, round down"),
|
||||
(min, min * 2 + 1, min * 2, "top up or consolidation doubling the balance"),
|
||||
(min, min * 2 - 1, min * 2 - spec.EFFECTIVE_BALANCE_INCREMENT,
|
||||
"top up or consolidation almost doubling the balance"),
|
||||
]
|
||||
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
for i, (pre_eff, bal, _, _) in enumerate(cases):
|
||||
assert spec.is_active_validator(state.validators[i], current_epoch)
|
||||
|
|
Loading…
Reference in New Issue