test_process_proposer_slashing.py
1 import eth2spec.phase0.spec as spec 2 from eth2spec.phase0.spec import ( 3 get_current_epoch, 4 process_proposer_slashing, 5 ) 6 from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls 7 from eth2spec.test.helpers.block_header import sign_block_header 8 from eth2spec.test.helpers.keys import privkeys 9 from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing 10 from eth2spec.test.helpers.state import get_balance 11 12 13 def run_proposer_slashing_processing(state, proposer_slashing, valid=True): 14 """ 15 Run ``process_proposer_slashing``, yielding: 16 - pre-state ('pre') 17 - proposer_slashing ('proposer_slashing') 18 - post-state ('post'). 19 If ``valid == False``, run expecting ``AssertionError`` 20 """ 21 22 yield 'pre', state 23 yield 'proposer_slashing', proposer_slashing 24 25 if not valid: 26 expect_assertion_error(lambda: process_proposer_slashing(state, proposer_slashing)) 27 yield 'post', None 28 return 29 30 pre_proposer_balance = get_balance(state, proposer_slashing.proposer_index) 31 32 process_proposer_slashing(state, proposer_slashing) 33 yield 'post', state 34 35 # check if slashed 36 slashed_validator = state.validator_registry[proposer_slashing.proposer_index] 37 assert slashed_validator.slashed 38 assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH 39 assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH 40 41 # lost whistleblower reward 42 assert ( 43 get_balance(state, proposer_slashing.proposer_index) < 44 pre_proposer_balance 45 ) 46 47 48 @spec_state_test 49 def test_success(state): 50 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True) 51 52 yield from run_proposer_slashing_processing(state, proposer_slashing) 53 54 55 @always_bls 56 @spec_state_test 57 def test_invalid_sig_1(state): 58 proposer_slashing = get_valid_proposer_slashing(state, signed_1=False, signed_2=True) 59 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 60 61 62 @always_bls 63 @spec_state_test 64 def test_invalid_sig_2(state): 65 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=False) 66 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 67 68 69 @always_bls 70 @spec_state_test 71 def test_invalid_sig_1_and_2(state): 72 proposer_slashing = get_valid_proposer_slashing(state, signed_1=False, signed_2=False) 73 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 74 75 76 @spec_state_test 77 def test_invalid_proposer_index(state): 78 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True) 79 # Index just too high (by 1) 80 proposer_slashing.proposer_index = len(state.validator_registry) 81 82 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 83 84 85 @spec_state_test 86 def test_epochs_are_different(state): 87 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=False) 88 89 # set slots to be in different epochs 90 proposer_slashing.header_2.slot += spec.SLOTS_PER_EPOCH 91 sign_block_header(state, proposer_slashing.header_2, privkeys[proposer_slashing.proposer_index]) 92 93 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 94 95 96 @spec_state_test 97 def test_headers_are_same(state): 98 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=False) 99 100 # set headers to be the same 101 proposer_slashing.header_2 = proposer_slashing.header_1 102 103 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 104 105 106 @spec_state_test 107 def test_proposer_is_not_activated(state): 108 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True) 109 110 # set proposer to be not active yet 111 state.validator_registry[proposer_slashing.proposer_index].activation_epoch = get_current_epoch(state) + 1 112 113 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 114 115 116 @spec_state_test 117 def test_proposer_is_slashed(state): 118 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True) 119 120 # set proposer to slashed 121 state.validator_registry[proposer_slashing.proposer_index].slashed = True 122 123 yield from run_proposer_slashing_processing(state, proposer_slashing, False) 124 125 126 @spec_state_test 127 def test_proposer_is_withdrawn(state): 128 proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True) 129 130 # move 1 epoch into future, to allow for past withdrawable epoch 131 state.slot += spec.SLOTS_PER_EPOCH 132 # set proposer withdrawable_epoch in past 133 current_epoch = get_current_epoch(state) 134 proposer_index = proposer_slashing.proposer_index 135 state.validator_registry[proposer_index].withdrawable_epoch = current_epoch - 1 136 137 yield from run_proposer_slashing_processing(state, proposer_slashing, False)