@@ -266,6 +266,16 @@ pub enum Error {
266
266
attestation : Hash256 ,
267
267
expected : Option < Hash256 > ,
268
268
} ,
269
+ /// The attestation conflicts with finalization, no need to propagate.
270
+ ///
271
+ /// ## Peer scoring
272
+ ///
273
+ /// It's unclear if this attestation is valid, but it conflicts with finality and shouldn't be
274
+ /// propogated.
275
+ NotFinalizedDescendant {
276
+ attestation_block_root : Hash256 ,
277
+ attestation_slot : Slot ,
278
+ } ,
269
279
/// There was an error whilst processing the attestation. It is not known if it is valid or invalid.
270
280
///
271
281
/// ## Peer scoring
@@ -848,6 +858,9 @@ impl<'a, T: BeaconChainTypes> IndexedUnaggregatedAttestation<'a, T> {
848
858
// [New in Electra:EIP7549]
849
859
verify_committee_index ( attestation) ?;
850
860
861
+ // Do not process an attestation that doesn't descend from the finalized root.
862
+ verify_attestation_is_finalized_checkpoint_or_descendant ( attestation, chain) ?;
863
+
851
864
// Attestations must be for a known block. If the block is unknown, we simply drop the
852
865
// attestation and do not delay consideration for later.
853
866
//
@@ -1361,6 +1374,30 @@ pub fn verify_committee_index<E: EthSpec>(attestation: AttestationRef<E>) -> Res
1361
1374
Ok ( ( ) )
1362
1375
}
1363
1376
1377
+ fn verify_attestation_is_finalized_checkpoint_or_descendant < T : BeaconChainTypes > (
1378
+ attestation : AttestationRef < T :: EthSpec > ,
1379
+ chain : & BeaconChain < T > ,
1380
+ ) -> Result < ( ) , Error > {
1381
+ // If we have a split block newer than finalization then we also ban attestations which are not
1382
+ // descended from that split block.
1383
+ let fork_choice = chain. canonical_head . fork_choice_read_lock ( ) ;
1384
+ let split = chain. store . get_split_info ( ) ;
1385
+ let attestation_block_root = attestation. data ( ) . beacon_block_root ;
1386
+ let is_descendant_from_split_block =
1387
+ split. slot == 0 || fork_choice. is_descendant ( split. block_root , attestation_block_root) ;
1388
+
1389
+ if fork_choice. is_finalized_checkpoint_or_descendant ( attestation_block_root)
1390
+ && is_descendant_from_split_block
1391
+ {
1392
+ Ok ( ( ) )
1393
+ } else {
1394
+ Err ( Error :: NotFinalizedDescendant {
1395
+ attestation_block_root,
1396
+ attestation_slot : attestation. data ( ) . slot ,
1397
+ } )
1398
+ }
1399
+ }
1400
+
1364
1401
/// Assists in readability.
1365
1402
type CommitteesPerSlot = u64 ;
1366
1403
0 commit comments