/ test_libs / pyspec / eth2spec / test / block_processing / test_process_attestation.py
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)