test_process_attestation.py
1 from copy import deepcopy 2 3 import eth2spec.phase0.spec as spec 4 from eth2spec.phase0.spec import ( 5 get_current_epoch, 6 process_attestation 7 ) 8 from eth2spec.phase0.state_transition import ( 9 state_transition_to, 10 ) 11 from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls 12 from eth2spec.test.helpers.attestations import ( 13 get_valid_attestation, 14 sign_attestation, 15 ) 16 from eth2spec.test.helpers.state import ( 17 next_epoch, 18 next_slot, 19 ) 20 from eth2spec.test.helpers.block import apply_empty_block 21 22 23 def run_attestation_processing(state, attestation, valid=True): 24 """ 25 Run ``process_attestation``, yielding: 26 - pre-state ('pre') 27 - attestation ('attestation') 28 - post-state ('post'). 29 If ``valid == False``, run expecting ``AssertionError`` 30 """ 31 # yield pre-state 32 yield 'pre', state 33 34 yield 'attestation', attestation 35 36 # If the attestation is invalid, processing is aborted, and there is no post-state. 37 if not valid: 38 expect_assertion_error(lambda: process_attestation(state, attestation)) 39 yield 'post', None 40 return 41 42 current_epoch_count = len(state.current_epoch_attestations) 43 previous_epoch_count = len(state.previous_epoch_attestations) 44 45 # process attestation 46 process_attestation(state, attestation) 47 48 # Make sure the attestation has been processed 49 if attestation.data.target_epoch == get_current_epoch(state): 50 assert len(state.current_epoch_attestations) == current_epoch_count + 1 51 else: 52 assert len(state.previous_epoch_attestations) == previous_epoch_count + 1 53 54 # yield post-state 55 yield 'post', state 56 57 58 @spec_state_test 59 def test_success(state): 60 attestation = get_valid_attestation(state, signed=True) 61 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 62 63 yield from run_attestation_processing(state, attestation) 64 65 66 @spec_state_test 67 def test_success_previous_epoch(state): 68 attestation = get_valid_attestation(state, signed=True) 69 next_epoch(state) 70 apply_empty_block(state) 71 72 yield from run_attestation_processing(state, attestation) 73 74 75 @always_bls 76 @spec_state_test 77 def test_invalid_attestation_signature(state): 78 attestation = get_valid_attestation(state) 79 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 80 81 yield from run_attestation_processing(state, attestation, False) 82 83 84 @spec_state_test 85 def test_before_inclusion_delay(state): 86 attestation = get_valid_attestation(state, signed=True) 87 # do not increment slot to allow for inclusion delay 88 89 yield from run_attestation_processing(state, attestation, False) 90 91 92 @spec_state_test 93 def test_after_epoch_slots(state): 94 attestation = get_valid_attestation(state, signed=True) 95 # increment past latest inclusion slot 96 state_transition_to(state, state.slot + spec.SLOTS_PER_EPOCH + 1) 97 apply_empty_block(state) 98 99 yield from run_attestation_processing(state, attestation, False) 100 101 102 @spec_state_test 103 def test_old_source_epoch(state): 104 state.slot = spec.SLOTS_PER_EPOCH * 5 105 state.finalized_epoch = 2 106 state.previous_justified_epoch = 3 107 state.current_justified_epoch = 4 108 attestation = get_valid_attestation(state, slot=(spec.SLOTS_PER_EPOCH * 3) + 1) 109 110 # test logic sanity check: make sure the attestation is pointing to oldest known source epoch 111 assert attestation.data.source_epoch == state.previous_justified_epoch 112 113 # Now go beyond that, it will be invalid 114 attestation.data.source_epoch -= 1 115 116 sign_attestation(state, attestation) 117 118 yield from run_attestation_processing(state, attestation, False) 119 120 121 @spec_state_test 122 def test_wrong_shard(state): 123 attestation = get_valid_attestation(state) 124 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 125 126 attestation.data.shard += 1 127 128 sign_attestation(state, attestation) 129 130 yield from run_attestation_processing(state, attestation, False) 131 132 133 @spec_state_test 134 def test_new_source_epoch(state): 135 attestation = get_valid_attestation(state) 136 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 137 138 attestation.data.source_epoch += 1 139 140 sign_attestation(state, attestation) 141 142 yield from run_attestation_processing(state, attestation, False) 143 144 145 @spec_state_test 146 def test_source_root_is_target_root(state): 147 attestation = get_valid_attestation(state) 148 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 149 150 attestation.data.source_root = attestation.data.target_root 151 152 sign_attestation(state, attestation) 153 154 yield from run_attestation_processing(state, attestation, False) 155 156 157 @spec_state_test 158 def test_invalid_current_source_root(state): 159 state.slot = spec.SLOTS_PER_EPOCH * 5 160 state.finalized_epoch = 2 161 162 state.previous_justified_epoch = 3 163 state.previous_justified_root = b'\x01' * 32 164 165 state.current_justified_epoch = 4 166 state.current_justified_root = b'\xff' * 32 167 168 attestation = get_valid_attestation(state, slot=(spec.SLOTS_PER_EPOCH * 3) + 1) 169 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 170 171 # Test logic sanity checks: 172 assert state.current_justified_root != state.previous_justified_root 173 assert attestation.data.source_root == state.previous_justified_root 174 175 # Make attestation source root invalid: should be previous justified, not current one 176 attestation.data.source_root = state.current_justified_root 177 178 sign_attestation(state, attestation) 179 180 yield from run_attestation_processing(state, attestation, False) 181 182 183 @spec_state_test 184 def test_bad_source_root(state): 185 attestation = get_valid_attestation(state) 186 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 187 188 attestation.data.source_root = b'\x42' * 32 189 190 sign_attestation(state, attestation) 191 192 yield from run_attestation_processing(state, attestation, False) 193 194 195 @spec_state_test 196 def test_non_zero_crosslink_data_root(state): 197 attestation = get_valid_attestation(state) 198 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 199 200 attestation.data.crosslink_data_root = b'\x42' * 32 201 202 sign_attestation(state, attestation) 203 204 yield from run_attestation_processing(state, attestation, False) 205 206 207 @spec_state_test 208 def test_bad_previous_crosslink(state): 209 next_epoch(state) 210 apply_empty_block(state) 211 212 attestation = get_valid_attestation(state, signed=True) 213 for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): 214 next_slot(state) 215 apply_empty_block(state) 216 217 state.current_crosslinks[attestation.data.shard].epoch += 10 218 219 yield from run_attestation_processing(state, attestation, False) 220 221 222 @spec_state_test 223 def test_inconsistent_bitfields(state): 224 attestation = get_valid_attestation(state) 225 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 226 227 attestation.custody_bitfield = deepcopy(attestation.aggregation_bitfield) + b'\x00' 228 229 sign_attestation(state, attestation) 230 231 yield from run_attestation_processing(state, attestation, False) 232 233 234 @spec_state_test 235 def test_non_empty_custody_bitfield(state): 236 attestation = get_valid_attestation(state) 237 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 238 239 attestation.custody_bitfield = deepcopy(attestation.aggregation_bitfield) 240 241 sign_attestation(state, attestation) 242 243 yield from run_attestation_processing(state, attestation, False) 244 245 246 @spec_state_test 247 def test_empty_aggregation_bitfield(state): 248 attestation = get_valid_attestation(state) 249 state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY 250 251 attestation.aggregation_bitfield = b'\x00' * len(attestation.aggregation_bitfield) 252 253 sign_attestation(state, attestation) 254 255 yield from run_attestation_processing(state, attestation, False)