@@ -9,12 +9,15 @@ use crate::sync::manager::{BlockProcessType, SyncMessage};
9
9
use crate :: sync:: { BatchProcessResult , ChainId } ;
10
10
use beacon_chain:: CountUnrealized ;
11
11
use beacon_chain:: {
12
- observed_block_producers:: Error as ObserveError , BeaconChainError , BeaconChainTypes ,
13
- BlockError , ChainSegmentResult , HistoricalBlockError , NotifyExecutionLayer ,
12
+ observed_block_producers:: Error as ObserveError , validator_monitor:: get_block_delay_ms,
13
+ BeaconChainError , BeaconChainTypes , BlockError , ChainSegmentResult , HistoricalBlockError ,
14
+ NotifyExecutionLayer ,
14
15
} ;
15
16
use lighthouse_network:: PeerAction ;
16
17
use slog:: { debug, error, info, warn} ;
18
+ use slot_clock:: SlotClock ;
17
19
use std:: sync:: Arc ;
20
+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
18
21
use tokio:: sync:: mpsc;
19
22
use types:: { Epoch , Hash256 , SignedBeaconBlock } ;
20
23
@@ -83,21 +86,38 @@ impl<T: BeaconChainTypes> Worker<T> {
83
86
return ;
84
87
}
85
88
} ;
86
- // Check if a block from this proposer is already known. If so, defer processing until later
87
- // to avoid wasting time processing duplicates.
88
- let proposal_already_known = match self
89
- . chain
90
- . observed_block_producers
91
- . read ( )
92
- . proposer_has_been_observed ( block. message ( ) )
93
- {
94
- Ok ( is_observed) => is_observed,
95
- // Both of these blocks will be rejected, so reject them now rather
96
- // than re-queuing them.
97
- Err ( ObserveError :: FinalizedBlock { .. } )
98
- | Err ( ObserveError :: ValidatorIndexTooHigh { .. } ) => false ,
89
+
90
+ // Returns `true` if the time now is after the 4s attestation deadline.
91
+ let block_is_late = SystemTime :: now ( )
92
+ . duration_since ( UNIX_EPOCH )
93
+ // If we can't read the system time clock then indicate that the
94
+ // block is late (and therefore should *not* be requeued). This
95
+ // avoids infinite loops.
96
+ . map_or ( true , |now| {
97
+ get_block_delay_ms ( now, block. message ( ) , & self . chain . slot_clock )
98
+ > self . chain . slot_clock . unagg_attestation_production_delay ( )
99
+ } ) ;
100
+
101
+ // Checks if a block from this proposer is already known.
102
+ let proposal_already_known = || {
103
+ match self
104
+ . chain
105
+ . observed_block_producers
106
+ . read ( )
107
+ . proposer_has_been_observed ( block. message ( ) )
108
+ {
109
+ Ok ( is_observed) => is_observed,
110
+ // Both of these blocks will be rejected, so reject them now rather
111
+ // than re-queuing them.
112
+ Err ( ObserveError :: FinalizedBlock { .. } )
113
+ | Err ( ObserveError :: ValidatorIndexTooHigh { .. } ) => false ,
114
+ }
99
115
} ;
100
- if proposal_already_known {
116
+
117
+ // If we've already seen a block from this proposer *and* the block
118
+ // arrived before the attestation deadline, requeue it to ensure it is
119
+ // imported late enough that it won't receive a proposer boost.
120
+ if !block_is_late && proposal_already_known ( ) {
101
121
debug ! (
102
122
self . log,
103
123
"Delaying processing of duplicate RPC block" ;
0 commit comments