@@ -14,7 +14,7 @@ use ethportal_api::{
14
14
finality_update:: { LightClientFinalityUpdate , LightClientFinalityUpdateElectra } ,
15
15
optimistic_update:: { LightClientOptimisticUpdate , LightClientOptimisticUpdateElectra } ,
16
16
store:: LightClientStore ,
17
- update:: { FinalizedRootProofLenElectra , LightClientUpdateElectra } ,
17
+ update:: { FinalizedRootProofLenElectra , LightClientUpdate , LightClientUpdateElectra } ,
18
18
} ,
19
19
} ;
20
20
use milagro_bls:: PublicKey ;
@@ -28,6 +28,7 @@ use crate::{
28
28
consensus:: {
29
29
constants:: MAX_REQUEST_LIGHT_CLIENT_UPDATES , rpc:: portal_rpc:: expected_current_slot,
30
30
} ,
31
+ watch:: { light_client_watch_channels, LightClientWatchReceivers , LightClientWatchSenders } ,
31
32
} ;
32
33
33
34
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md
@@ -40,6 +41,7 @@ pub struct ConsensusLightClient<R: ConsensusRpc> {
40
41
initial_checkpoint : B256 ,
41
42
pub last_checkpoint : Option < B256 > ,
42
43
pub config : Arc < Config > ,
44
+ watch_senders : LightClientWatchSenders ,
43
45
}
44
46
45
47
impl < R : ConsensusRpc > ConsensusLightClient < R > {
@@ -49,23 +51,27 @@ impl<R: ConsensusRpc> ConsensusLightClient<R> {
49
51
config : Arc < Config > ,
50
52
) -> Result < ConsensusLightClient < R > > {
51
53
let rpc = R :: new ( rpc) ;
54
+ let ( watch_senders, _watch_receivers) = light_client_watch_channels ( ) ;
52
55
53
56
Ok ( ConsensusLightClient {
54
57
rpc,
55
58
store : LightClientStore :: default ( ) ,
56
59
last_checkpoint : None ,
57
60
config,
58
61
initial_checkpoint : checkpoint_block_root,
62
+ watch_senders,
59
63
} )
60
64
}
61
65
62
66
pub fn with_custom_rpc ( rpc : R , checkpoint_block_root : B256 , config : Arc < Config > ) -> Self {
67
+ let ( watch_senders, _watch_receivers) = light_client_watch_channels ( ) ;
63
68
ConsensusLightClient {
64
69
rpc,
65
70
store : LightClientStore :: default ( ) ,
66
71
last_checkpoint : None ,
67
72
config,
68
73
initial_checkpoint : checkpoint_block_root,
74
+ watch_senders,
69
75
}
70
76
}
71
77
@@ -105,6 +111,10 @@ impl<R: ConsensusRpc> ConsensusLightClient<R> {
105
111
& self . store
106
112
}
107
113
114
+ pub fn get_watch_receivers ( & self ) -> LightClientWatchReceivers {
115
+ self . watch_senders . subscribe ( )
116
+ }
117
+
108
118
pub async fn sync ( & mut self ) -> Result < ( ) > {
109
119
self . bootstrap ( ) . await ?;
110
120
@@ -366,13 +376,35 @@ impl<R: ConsensusRpc> ConsensusLightClient<R> {
366
376
}
367
377
368
378
fn apply_update ( & mut self , update : & LightClientUpdateElectra ) {
369
- let update = GenericUpdate :: from ( update) ;
370
- self . apply_generic_update ( & update) ;
379
+ let optimistic_header_slot = self . store . optimistic_header . slot ;
380
+ let finalized_header_slot = self . store . finalized_header . slot ;
381
+
382
+ let generic_update = GenericUpdate :: from ( update) ;
383
+ self . apply_generic_update ( & generic_update) ;
384
+
385
+ if optimistic_header_slot < self . store . optimistic_header . slot
386
+ || finalized_header_slot < self . store . finalized_header . slot
387
+ {
388
+ self . watch_senders
389
+ . update
390
+ . send_replace ( Some ( LightClientUpdate :: Electra ( update. clone ( ) ) ) ) ;
391
+ }
371
392
}
372
393
373
394
fn apply_finality_update ( & mut self , update : & LightClientFinalityUpdateElectra ) {
374
- let update = GenericUpdate :: from ( update) ;
375
- self . apply_generic_update ( & update) ;
395
+ let optimistic_header_slot = self . store . optimistic_header . slot ;
396
+ let finalized_header_slot = self . store . finalized_header . slot ;
397
+
398
+ let generic_update = GenericUpdate :: from ( update) ;
399
+ self . apply_generic_update ( & generic_update) ;
400
+
401
+ if optimistic_header_slot < self . store . optimistic_header . slot
402
+ || finalized_header_slot < self . store . finalized_header . slot
403
+ {
404
+ self . watch_senders
405
+ . finality_update
406
+ . send_replace ( Some ( LightClientFinalityUpdate :: Electra ( update. clone ( ) ) ) ) ;
407
+ }
376
408
}
377
409
378
410
fn log_finality_update ( & self , update : & GenericUpdate ) {
@@ -393,8 +425,16 @@ impl<R: ConsensusRpc> ConsensusLightClient<R> {
393
425
}
394
426
395
427
fn apply_optimistic_update ( & mut self , update : & LightClientOptimisticUpdateElectra ) {
396
- let update = GenericUpdate :: from ( update) ;
397
- self . apply_generic_update ( & update) ;
428
+ let optimistic_header_slot = self . store . optimistic_header . slot ;
429
+
430
+ let generic_update = GenericUpdate :: from ( update) ;
431
+ self . apply_generic_update ( & generic_update) ;
432
+
433
+ if optimistic_header_slot < self . store . optimistic_header . slot {
434
+ self . watch_senders
435
+ . optimistic_update
436
+ . send_replace ( Some ( LightClientOptimisticUpdate :: Electra ( update. clone ( ) ) ) ) ;
437
+ }
398
438
}
399
439
400
440
fn log_optimistic_update ( & self , update : & GenericUpdate ) {
0 commit comments