mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-03 06:13:31 +00:00
Fix tests
This commit is contained in:
parent
c115fa9a86
commit
67809e76e1
@ -1,4 +1,3 @@
|
|||||||
from collections import Counter
|
|
||||||
import random
|
import random
|
||||||
from eth2spec.test.helpers.block import (
|
from eth2spec.test.helpers.block import (
|
||||||
build_empty_block_for_next_slot,
|
build_empty_block_for_next_slot,
|
||||||
@ -13,6 +12,9 @@ from eth2spec.test.helpers.constants import (
|
|||||||
)
|
)
|
||||||
from eth2spec.test.helpers.sync_committee import (
|
from eth2spec.test.helpers.sync_committee import (
|
||||||
compute_aggregate_sync_committee_signature,
|
compute_aggregate_sync_committee_signature,
|
||||||
|
compute_sync_committee_participant_reward_and_penalty,
|
||||||
|
compute_sync_committee_proposer_reward,
|
||||||
|
compute_committee_indices,
|
||||||
)
|
)
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
expect_assertion_error,
|
expect_assertion_error,
|
||||||
@ -61,15 +63,6 @@ def get_committee_indices(spec, state, duplicates=False):
|
|||||||
state.randao_mixes[randao_index] = hash(state.randao_mixes[randao_index])
|
state.randao_mixes[randao_index] = hash(state.randao_mixes[randao_index])
|
||||||
|
|
||||||
|
|
||||||
def compute_committee_indices(spec, state, committee):
|
|
||||||
"""
|
|
||||||
Given a ``committee``, calculate and return the related indices
|
|
||||||
"""
|
|
||||||
all_pubkeys = [v.pubkey for v in state.validators]
|
|
||||||
committee_indices = [all_pubkeys.index(pubkey) for pubkey in committee.pubkeys]
|
|
||||||
return committee_indices
|
|
||||||
|
|
||||||
|
|
||||||
@with_altair_and_later
|
@with_altair_and_later
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
@ -115,41 +108,20 @@ def test_invalid_signature_extra_participant(spec, state):
|
|||||||
yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
|
yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
|
||||||
|
|
||||||
|
|
||||||
def compute_sync_committee_inclusion_reward(spec, state):
|
|
||||||
total_active_increments = spec.get_total_active_balance(state) // spec.EFFECTIVE_BALANCE_INCREMENT
|
|
||||||
total_base_rewards = spec.Gwei(spec.get_base_reward_per_increment(state) * total_active_increments)
|
|
||||||
max_participant_rewards = spec.Gwei(total_base_rewards * spec.SYNC_REWARD_WEIGHT //
|
|
||||||
spec.WEIGHT_DENOMINATOR // spec.SLOTS_PER_EPOCH)
|
|
||||||
return spec.Gwei(max_participant_rewards // spec.SYNC_COMMITTEE_SIZE)
|
|
||||||
|
|
||||||
|
|
||||||
def compute_sync_committee_participant_reward(spec, state, participant_index, committee_indices, committee_bits):
|
|
||||||
included_indices = [index for index, bit in zip(committee_indices, committee_bits) if bit]
|
|
||||||
multiplicities = Counter(included_indices)
|
|
||||||
|
|
||||||
inclusion_reward = compute_sync_committee_inclusion_reward(spec, state)
|
|
||||||
return spec.Gwei(inclusion_reward * multiplicities[participant_index])
|
|
||||||
|
|
||||||
|
|
||||||
def compute_sync_committee_proposer_reward(spec, state, committee_indices, committee_bits):
|
|
||||||
proposer_reward_denominator = spec.WEIGHT_DENOMINATOR - spec.PROPOSER_WEIGHT
|
|
||||||
inclusion_reward = compute_sync_committee_inclusion_reward(spec, state)
|
|
||||||
participant_number = committee_bits.count(True)
|
|
||||||
participant_reward = inclusion_reward * spec.PROPOSER_WEIGHT // proposer_reward_denominator
|
|
||||||
return spec.Gwei(participant_reward * participant_number)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_sync_committee_rewards(spec, pre_state, post_state, committee_indices, committee_bits, proposer_index):
|
def validate_sync_committee_rewards(spec, pre_state, post_state, committee_indices, committee_bits, proposer_index):
|
||||||
for index in range(len(post_state.validators)):
|
for index in range(len(post_state.validators)):
|
||||||
reward = 0
|
reward = 0
|
||||||
|
penalty = 0
|
||||||
if index in committee_indices:
|
if index in committee_indices:
|
||||||
reward += compute_sync_committee_participant_reward(
|
_reward, _penalty = compute_sync_committee_participant_reward_and_penalty(
|
||||||
spec,
|
spec,
|
||||||
pre_state,
|
pre_state,
|
||||||
index,
|
index,
|
||||||
committee_indices,
|
committee_indices,
|
||||||
committee_bits,
|
committee_bits,
|
||||||
)
|
)
|
||||||
|
reward += _reward
|
||||||
|
penalty += _penalty
|
||||||
|
|
||||||
if proposer_index == index:
|
if proposer_index == index:
|
||||||
reward += compute_sync_committee_proposer_reward(
|
reward += compute_sync_committee_proposer_reward(
|
||||||
@ -159,7 +131,7 @@ def validate_sync_committee_rewards(spec, pre_state, post_state, committee_indic
|
|||||||
committee_bits,
|
committee_bits,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert post_state.balances[index] == pre_state.balances[index] + reward
|
assert post_state.balances[index] == pre_state.balances[index] + reward - penalty
|
||||||
|
|
||||||
|
|
||||||
def run_successful_sync_committee_test(spec, state, committee_indices, committee_bits):
|
def run_successful_sync_committee_test(spec, state, committee_indices, committee_bits):
|
||||||
|
@ -2,6 +2,10 @@ from eth2spec.test.context import is_post_altair
|
|||||||
from eth2spec.test.helpers.block_header import sign_block_header
|
from eth2spec.test.helpers.block_header import sign_block_header
|
||||||
from eth2spec.test.helpers.keys import pubkey_to_privkey
|
from eth2spec.test.helpers.keys import pubkey_to_privkey
|
||||||
from eth2spec.test.helpers.state import get_balance
|
from eth2spec.test.helpers.state import get_balance
|
||||||
|
from eth2spec.test.helpers.sync_committee import (
|
||||||
|
compute_committee_indices,
|
||||||
|
compute_sync_committee_participant_reward_and_penalty,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_min_slashing_penalty_quotient(spec):
|
def get_min_slashing_penalty_quotient(spec):
|
||||||
@ -11,7 +15,7 @@ def get_min_slashing_penalty_quotient(spec):
|
|||||||
return spec.MIN_SLASHING_PENALTY_QUOTIENT
|
return spec.MIN_SLASHING_PENALTY_QUOTIENT
|
||||||
|
|
||||||
|
|
||||||
def check_proposer_slashing_effect(spec, pre_state, state, slashed_index):
|
def check_proposer_slashing_effect(spec, pre_state, state, slashed_index, block=None):
|
||||||
slashed_validator = state.validators[slashed_index]
|
slashed_validator = state.validators[slashed_index]
|
||||||
assert slashed_validator.slashed
|
assert slashed_validator.slashed
|
||||||
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
|
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
|
||||||
@ -20,24 +24,51 @@ def check_proposer_slashing_effect(spec, pre_state, state, slashed_index):
|
|||||||
proposer_index = spec.get_beacon_proposer_index(state)
|
proposer_index = spec.get_beacon_proposer_index(state)
|
||||||
slash_penalty = state.validators[slashed_index].effective_balance // get_min_slashing_penalty_quotient(spec)
|
slash_penalty = state.validators[slashed_index].effective_balance // get_min_slashing_penalty_quotient(spec)
|
||||||
whistleblower_reward = state.validators[slashed_index].effective_balance // spec.WHISTLEBLOWER_REWARD_QUOTIENT
|
whistleblower_reward = state.validators[slashed_index].effective_balance // spec.WHISTLEBLOWER_REWARD_QUOTIENT
|
||||||
|
|
||||||
|
# Altair introduces sync committee (SC) reward and penalty
|
||||||
|
sc_reward_for_slashed = sc_penalty_for_slashed = sc_reward_for_proposer = sc_penalty_for_proposer = 0
|
||||||
|
if is_post_altair(spec) and block is not None:
|
||||||
|
committee_indices = compute_committee_indices(spec, state, state.current_sync_committee)
|
||||||
|
committee_bits = block.body.sync_aggregate.sync_committee_bits
|
||||||
|
sc_reward_for_slashed, sc_penalty_for_slashed = compute_sync_committee_participant_reward_and_penalty(
|
||||||
|
spec,
|
||||||
|
pre_state,
|
||||||
|
slashed_index,
|
||||||
|
committee_indices,
|
||||||
|
committee_bits,
|
||||||
|
)
|
||||||
|
sc_reward_for_proposer, sc_penalty_for_proposer = compute_sync_committee_participant_reward_and_penalty(
|
||||||
|
spec,
|
||||||
|
pre_state,
|
||||||
|
proposer_index,
|
||||||
|
committee_indices,
|
||||||
|
committee_bits,
|
||||||
|
)
|
||||||
|
|
||||||
if proposer_index != slashed_index:
|
if proposer_index != slashed_index:
|
||||||
# slashed validator lost initial slash penalty
|
# slashed validator lost initial slash penalty
|
||||||
assert (
|
assert (
|
||||||
get_balance(state, slashed_index)
|
get_balance(state, slashed_index)
|
||||||
== get_balance(pre_state, slashed_index) - slash_penalty
|
== get_balance(pre_state, slashed_index) - slash_penalty + sc_reward_for_slashed - sc_penalty_for_slashed
|
||||||
)
|
)
|
||||||
# block proposer gained whistleblower reward
|
# block proposer gained whistleblower reward
|
||||||
# >= because proposer could have reported multiple
|
# >= because proposer could have reported multiple
|
||||||
assert (
|
assert (
|
||||||
get_balance(state, proposer_index)
|
get_balance(state, proposer_index)
|
||||||
>= get_balance(pre_state, proposer_index) + whistleblower_reward
|
>= (
|
||||||
|
get_balance(pre_state, proposer_index) + whistleblower_reward
|
||||||
|
+ sc_reward_for_proposer - sc_penalty_for_proposer
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# proposer reported themself so get penalty and reward
|
# proposer reported themself so get penalty and reward
|
||||||
# >= because proposer could have reported multiple
|
# >= because proposer could have reported multiple
|
||||||
assert (
|
assert (
|
||||||
get_balance(state, slashed_index)
|
get_balance(state, slashed_index)
|
||||||
>= get_balance(pre_state, slashed_index) - slash_penalty + whistleblower_reward
|
>= (
|
||||||
|
get_balance(pre_state, slashed_index) - slash_penalty + whistleblower_reward
|
||||||
|
+ sc_reward_for_slashed - sc_penalty_for_slashed
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from collections import Counter
|
||||||
|
|
||||||
from eth2spec.test.helpers.keys import privkeys
|
from eth2spec.test.helpers.keys import privkeys
|
||||||
from eth2spec.test.helpers.block import (
|
from eth2spec.test.helpers.block import (
|
||||||
build_empty_block_for_next_slot,
|
build_empty_block_for_next_slot,
|
||||||
@ -33,3 +35,42 @@ def compute_aggregate_sync_committee_signature(spec, state, slot, participants,
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return bls.Aggregate(signatures)
|
return bls.Aggregate(signatures)
|
||||||
|
|
||||||
|
|
||||||
|
def compute_sync_committee_inclusion_reward(spec, state):
|
||||||
|
total_active_increments = spec.get_total_active_balance(state) // spec.EFFECTIVE_BALANCE_INCREMENT
|
||||||
|
total_base_rewards = spec.get_base_reward_per_increment(state) * total_active_increments
|
||||||
|
max_participant_rewards = (total_base_rewards * spec.SYNC_REWARD_WEIGHT
|
||||||
|
// spec.WEIGHT_DENOMINATOR // spec.SLOTS_PER_EPOCH)
|
||||||
|
return max_participant_rewards // spec.SYNC_COMMITTEE_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
def compute_sync_committee_participant_reward_and_penalty(
|
||||||
|
spec, state, participant_index, committee_indices, committee_bits):
|
||||||
|
inclusion_reward = compute_sync_committee_inclusion_reward(spec, state)
|
||||||
|
|
||||||
|
included_indices = [index for index, bit in zip(committee_indices, committee_bits) if bit]
|
||||||
|
not_included_indices = [index for index, bit in zip(committee_indices, committee_bits) if not bit]
|
||||||
|
included_multiplicities = Counter(included_indices)
|
||||||
|
not_included_multiplicities = Counter(not_included_indices)
|
||||||
|
return (
|
||||||
|
spec.Gwei(inclusion_reward * included_multiplicities[participant_index]),
|
||||||
|
spec.Gwei(inclusion_reward * not_included_multiplicities[participant_index])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def compute_sync_committee_proposer_reward(spec, state, committee_indices, committee_bits):
|
||||||
|
proposer_reward_denominator = spec.WEIGHT_DENOMINATOR - spec.PROPOSER_WEIGHT
|
||||||
|
inclusion_reward = compute_sync_committee_inclusion_reward(spec, state)
|
||||||
|
participant_number = committee_bits.count(True)
|
||||||
|
participant_reward = inclusion_reward * spec.PROPOSER_WEIGHT // proposer_reward_denominator
|
||||||
|
return spec.Gwei(participant_reward * participant_number)
|
||||||
|
|
||||||
|
|
||||||
|
def compute_committee_indices(spec, state, committee):
|
||||||
|
"""
|
||||||
|
Given a ``committee``, calculate and return the related indices
|
||||||
|
"""
|
||||||
|
all_pubkeys = [v.pubkey for v in state.validators]
|
||||||
|
committee_indices = [all_pubkeys.index(pubkey) for pubkey in committee.pubkeys]
|
||||||
|
return committee_indices
|
||||||
|
@ -24,6 +24,10 @@ from eth2spec.test.helpers.multi_operations import (
|
|||||||
run_slash_and_exit,
|
run_slash_and_exit,
|
||||||
run_test_full_random_operations,
|
run_test_full_random_operations,
|
||||||
)
|
)
|
||||||
|
from eth2spec.test.helpers.sync_committee import (
|
||||||
|
compute_committee_indices,
|
||||||
|
compute_sync_committee_participant_reward_and_penalty,
|
||||||
|
)
|
||||||
from eth2spec.test.helpers.constants import PHASE0, MINIMAL
|
from eth2spec.test.helpers.constants import PHASE0, MINIMAL
|
||||||
from eth2spec.test.context import (
|
from eth2spec.test.context import (
|
||||||
spec_test, spec_state_test, dump_skipping_message,
|
spec_test, spec_state_test, dump_skipping_message,
|
||||||
@ -416,7 +420,7 @@ def test_proposer_slashing(spec, state):
|
|||||||
yield 'blocks', [signed_block]
|
yield 'blocks', [signed_block]
|
||||||
yield 'post', state
|
yield 'post', state
|
||||||
|
|
||||||
check_proposer_slashing_effect(spec, pre_state, state, slashed_index)
|
check_proposer_slashing_effect(spec, pre_state, state, slashed_index, block)
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@ -491,7 +495,7 @@ def test_multiple_different_proposer_slashings_same_block(spec, state):
|
|||||||
|
|
||||||
for proposer_slashing in proposer_slashings:
|
for proposer_slashing in proposer_slashings:
|
||||||
slashed_index = proposer_slashing.signed_header_1.message.proposer_index
|
slashed_index = proposer_slashing.signed_header_1.message.proposer_index
|
||||||
check_proposer_slashing_effect(spec, pre_state, state, slashed_index)
|
check_proposer_slashing_effect(spec, pre_state, state, slashed_index, block)
|
||||||
|
|
||||||
|
|
||||||
def check_attester_slashing_effect(spec, pre_state, state, slashed_indices):
|
def check_attester_slashing_effect(spec, pre_state, state, slashed_indices):
|
||||||
@ -743,7 +747,8 @@ def test_deposit_top_up(spec, state):
|
|||||||
initial_balances_len = len(state.balances)
|
initial_balances_len = len(state.balances)
|
||||||
validator_pre_balance = get_balance(state, validator_index)
|
validator_pre_balance = get_balance(state, validator_index)
|
||||||
|
|
||||||
yield 'pre', state
|
pre_state = state.copy()
|
||||||
|
yield 'pre', pre_state
|
||||||
|
|
||||||
block = build_empty_block_for_next_slot(spec, state)
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
block.body.deposits.append(deposit)
|
block.body.deposits.append(deposit)
|
||||||
@ -755,7 +760,23 @@ def test_deposit_top_up(spec, state):
|
|||||||
|
|
||||||
assert len(state.validators) == initial_registry_len
|
assert len(state.validators) == initial_registry_len
|
||||||
assert len(state.balances) == initial_balances_len
|
assert len(state.balances) == initial_balances_len
|
||||||
assert get_balance(state, validator_index) == validator_pre_balance + amount
|
|
||||||
|
# Altair introduces sync committee (sm) reward and penalty
|
||||||
|
sync_committee_reward = sync_committee_penalty = 0
|
||||||
|
if is_post_altair(spec):
|
||||||
|
committee_indices = compute_committee_indices(spec, state, state.current_sync_committee)
|
||||||
|
committee_bits = block.body.sync_aggregate.sync_committee_bits
|
||||||
|
sync_committee_reward, sync_committee_penalty = compute_sync_committee_participant_reward_and_penalty(
|
||||||
|
spec,
|
||||||
|
pre_state,
|
||||||
|
validator_index,
|
||||||
|
committee_indices,
|
||||||
|
committee_bits,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert get_balance(state, validator_index) == (
|
||||||
|
validator_pre_balance + amount + sync_committee_reward - sync_committee_penalty
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
|
Loading…
x
Reference in New Issue
Block a user