@@ -209,6 +209,57 @@ impl<P, S: Storage + Clone> Client<P, S> {
209
209
}
210
210
}
211
211
212
+ impl < P , S > Client < P , S >
213
+ where
214
+ P : LocalValidatorNodeProvider + Sync + ' static ,
215
+ S : Storage + Sync + Send + Clone + ' static ,
216
+ {
217
+ async fn download_certificates (
218
+ & self ,
219
+ nodes : & [ ( ValidatorName , P :: Node ) ] ,
220
+ chain_id : ChainId ,
221
+ height : BlockHeight ,
222
+ ) -> Result < Box < ChainInfo > , LocalNodeError > {
223
+ let mut notifications = Vec :: < Notification > :: new ( ) ;
224
+ let info = self
225
+ . local_node
226
+ . download_certificates ( nodes, chain_id, height, & mut notifications)
227
+ . await ?;
228
+ self . notifier . handle_notifications ( & notifications) ;
229
+ Ok ( info)
230
+ }
231
+
232
+ async fn try_process_certificates (
233
+ & self ,
234
+ name : & ValidatorName ,
235
+ node : & impl LocalValidatorNode ,
236
+ chain_id : ChainId ,
237
+ certificates : Vec < Certificate > ,
238
+ ) -> Option < Box < ChainInfo > > {
239
+ let mut notifications = Vec :: < Notification > :: new ( ) ;
240
+ let result = self
241
+ . local_node
242
+ . try_process_certificates ( name, node, chain_id, certificates, & mut notifications)
243
+ . await ;
244
+ self . notifier . handle_notifications ( & notifications) ;
245
+ result
246
+ }
247
+
248
+ async fn handle_certificate (
249
+ & self ,
250
+ certificate : Certificate ,
251
+ blobs : Vec < Blob > ,
252
+ ) -> Result < ChainInfoResponse , LocalNodeError > {
253
+ let mut notifications = Vec :: < Notification > :: new ( ) ;
254
+ let result = self
255
+ . local_node
256
+ . handle_certificate ( certificate, blobs, & mut notifications)
257
+ . await ;
258
+ self . notifier . handle_notifications ( & notifications) ;
259
+ result
260
+ }
261
+ }
262
+
212
263
/// Policies for automatically handling incoming messages.
213
264
#[ derive( Clone , Debug ) ]
214
265
pub struct MessagePolicy {
@@ -769,13 +820,6 @@ where
769
820
. copy ( ) )
770
821
}
771
822
772
- #[ tracing:: instrument( level = "trace" , skip( notifications) ) ]
773
- /// Notifies subscribers and clears the `notifications`.
774
- fn handle_notifications ( & self , notifications : & mut Vec < Notification > ) {
775
- self . client . notifier . handle_notifications ( notifications) ;
776
- notifications. clear ( ) ;
777
- }
778
-
779
823
#[ tracing:: instrument( level = "trace" ) ]
780
824
/// Obtains the public key associated to the current identity.
781
825
pub async fn public_key ( & self ) -> Result < PublicKey , ChainClientError > {
@@ -791,13 +835,10 @@ where
791
835
// network.
792
836
let next_block_height = self . state ( ) . next_block_height ;
793
837
let nodes = self . validator_nodes ( ) . await ?;
794
- let mut notifications = vec ! [ ] ;
795
838
let mut info = self
796
839
. client
797
- . local_node
798
- . download_certificates ( & nodes, self . chain_id , next_block_height, & mut notifications)
840
+ . download_certificates ( & nodes, self . chain_id , next_block_height)
799
841
. await ?;
800
- self . handle_notifications ( & mut notifications) ;
801
842
if info. next_block_height == next_block_height {
802
843
// Check that our local node has the expected block hash.
803
844
ensure ! (
@@ -806,17 +847,13 @@ where
806
847
) ;
807
848
}
808
849
let ownership = & info. manager . ownership ;
809
- let keys: std:: collections:: HashSet < _ > =
810
- self . state ( ) . known_key_pairs . keys ( ) . cloned ( ) . collect ( ) ;
850
+ let keys: HashSet < _ > = self . state ( ) . known_key_pairs . keys ( ) . cloned ( ) . collect ( ) ;
811
851
if ownership. all_owners ( ) . any ( |owner| !keys. contains ( owner) ) {
812
852
// For chains with any owner other than ourselves, we could be missing recent
813
853
// certificates created by other owners. Further synchronize blocks from the network.
814
854
// This is a best-effort that depends on network conditions.
815
855
let nodes = self . validator_nodes ( ) . await ?;
816
- info = self
817
- . synchronize_chain_state ( & nodes, self . chain_id , & mut notifications)
818
- . await ?;
819
- self . handle_notifications ( & mut notifications) ;
856
+ info = self . synchronize_chain_state ( & nodes, self . chain_id ) . await ?;
820
857
}
821
858
self . update_from_info ( & info) ;
822
859
Ok ( info)
@@ -1019,12 +1056,9 @@ where
1019
1056
. validator_node_provider
1020
1057
. make_nodes ( remote_committee) ?
1021
1058
. collect ( ) ;
1022
- let mut notifications = vec ! [ ] ;
1023
1059
self . client
1024
- . local_node
1025
- . download_certificates ( & nodes, block. chain_id , block. height , & mut notifications)
1060
+ . download_certificates ( & nodes, block. chain_id , block. height )
1026
1061
. await ?;
1027
- self . handle_notifications ( & mut notifications) ;
1028
1062
// Process the received operations. Download required hashed certificate values if necessary.
1029
1063
if let Err ( err) = self . process_certificate ( certificate. clone ( ) , vec ! [ ] ) . await {
1030
1064
match & err {
@@ -1186,11 +1220,9 @@ where
1186
1220
. validator_node_provider
1187
1221
. make_nodes ( & local_committee) ?
1188
1222
. collect ( ) ;
1189
- let mut notifications = vec ! [ ] ;
1190
1223
// Synchronize the state of the admin chain from the network.
1191
- self . synchronize_chain_state ( & nodes, self . admin_id ( ) , & mut notifications )
1224
+ self . synchronize_chain_state ( & nodes, self . admin_id ( ) )
1192
1225
. await ?;
1193
- self . handle_notifications ( & mut notifications) ;
1194
1226
let node_client = self . client . local_node . clone ( ) ;
1195
1227
// Now we should have a complete view of all committees in the system.
1196
1228
let ( committees, max_epoch) = self . known_committees ( ) . await ?;
@@ -1285,14 +1317,11 @@ where
1285
1317
certificate : Certificate ,
1286
1318
blobs : Vec < Blob > ,
1287
1319
) -> Result < ( ) , LocalNodeError > {
1288
- let mut notifications = vec ! [ ] ;
1289
1320
let info = self
1290
1321
. client
1291
- . local_node
1292
- . handle_certificate ( certificate, blobs, & mut notifications)
1322
+ . handle_certificate ( certificate, blobs)
1293
1323
. await ?
1294
1324
. info ;
1295
- self . handle_notifications ( & mut notifications) ;
1296
1325
self . update_from_info ( & info) ;
1297
1326
Ok ( ( ) )
1298
1327
}
@@ -1358,29 +1387,22 @@ where
1358
1387
& self ,
1359
1388
validators : & [ ( ValidatorName , impl LocalValidatorNode ) ] ,
1360
1389
chain_id : ChainId ,
1361
- notifications : & mut impl Extend < Notification > ,
1362
1390
) -> Result < Box < ChainInfo > , ChainClientError > {
1363
1391
let mut futures = vec ! [ ] ;
1364
1392
1365
1393
for ( name, node) in validators {
1366
1394
let client = self . clone ( ) ;
1367
- let mut notifications = vec ! [ ] ;
1368
1395
futures. push ( async move {
1369
- (
1370
- client
1371
- . try_synchronize_chain_state_from ( name, node, chain_id, & mut notifications)
1372
- . await ,
1373
- notifications,
1374
- )
1396
+ client
1397
+ . try_synchronize_chain_state_from ( name, node, chain_id)
1398
+ . await
1375
1399
} ) ;
1376
1400
}
1377
1401
1378
- for ( result, new_notifications ) in future:: join_all ( futures) . await {
1402
+ for result in future:: join_all ( futures) . await {
1379
1403
if let Err ( e) = result {
1380
1404
error ! ( ?e, "Error synchronizing chain state" ) ;
1381
1405
}
1382
-
1383
- notifications. extend ( new_notifications) ;
1384
1406
}
1385
1407
1386
1408
self . client
@@ -1390,15 +1412,14 @@ where
1390
1412
. map_err ( Into :: into)
1391
1413
}
1392
1414
1393
- #[ tracing:: instrument( level = "trace" , skip( self , name, node, chain_id, notifications ) ) ]
1415
+ #[ tracing:: instrument( level = "trace" , skip( self , name, node, chain_id) ) ]
1394
1416
/// Downloads any certificates from the specified validator that we are missing for the given
1395
1417
/// chain, and processes them.
1396
1418
pub async fn try_synchronize_chain_state_from (
1397
1419
& self ,
1398
1420
name : & ValidatorName ,
1399
1421
node : & impl LocalValidatorNode ,
1400
1422
chain_id : ChainId ,
1401
- notifications : & mut impl Extend < Notification > ,
1402
1423
) -> Result < ( ) , ChainClientError > {
1403
1424
let local_info = self . client . local_node . local_chain_info ( chain_id) . await ?;
1404
1425
let range = BlockHeightRange {
@@ -1431,8 +1452,7 @@ where
1431
1452
if !certificates. is_empty ( )
1432
1453
&& self
1433
1454
. client
1434
- . local_node
1435
- . try_process_certificates ( name, node, chain_id, certificates, notifications)
1455
+ . try_process_certificates ( name, node, chain_id, certificates)
1436
1456
. await
1437
1457
. is_none ( )
1438
1458
{
@@ -1485,11 +1505,7 @@ where
1485
1505
}
1486
1506
let hash = cert. hash ( ) ;
1487
1507
let mut blobs = vec ! [ ] ;
1488
- while let Err ( original_err) = self
1489
- . client
1490
- . local_node
1491
- . handle_certificate ( * cert. clone ( ) , blobs, notifications)
1492
- . await
1508
+ while let Err ( original_err) = self . client . handle_certificate ( * cert. clone ( ) , blobs) . await
1493
1509
{
1494
1510
if let LocalNodeError :: WorkerError ( WorkerError :: BlobsNotFound ( blob_ids) ) =
1495
1511
& original_err
@@ -2878,7 +2894,6 @@ where
2878
2894
}
2879
2895
}
2880
2896
Reason :: NewBlock { height, .. } => {
2881
- let mut notifications = vec ! [ ] ;
2882
2897
let chain_id = notification. chain_id ;
2883
2898
if self
2884
2899
. local_next_block_height ( chain_id, & mut local_node)
@@ -2889,13 +2904,12 @@ where
2889
2904
return ;
2890
2905
}
2891
2906
if let Err ( error) = self
2892
- . try_synchronize_chain_state_from ( & name, & node, chain_id, & mut notifications )
2907
+ . try_synchronize_chain_state_from ( & name, & node, chain_id)
2893
2908
. await
2894
2909
{
2895
2910
error ! ( "Fail to process notification: {error}" ) ;
2896
2911
return ;
2897
2912
}
2898
- self . handle_notifications ( & mut notifications) ;
2899
2913
let local_height = self
2900
2914
. local_next_block_height ( chain_id, & mut local_node)
2901
2915
. await ;
@@ -2904,7 +2918,6 @@ where
2904
2918
}
2905
2919
}
2906
2920
Reason :: NewRound { height, round } => {
2907
- let mut notifications = vec ! [ ] ;
2908
2921
let chain_id = notification. chain_id ;
2909
2922
if let Some ( info) = self . local_chain_info ( chain_id, & mut local_node) . await {
2910
2923
if ( info. next_block_height , info. manager . current_round ) >= ( height, round) {
@@ -2913,13 +2926,12 @@ where
2913
2926
}
2914
2927
}
2915
2928
if let Err ( error) = self
2916
- . try_synchronize_chain_state_from ( & name, & node, chain_id, & mut notifications )
2929
+ . try_synchronize_chain_state_from ( & name, & node, chain_id)
2917
2930
. await
2918
2931
{
2919
2932
error ! ( "Fail to process notification: {error}" ) ;
2920
2933
return ;
2921
2934
}
2922
- self . handle_notifications ( & mut notifications) ;
2923
2935
let Some ( info) = self . local_chain_info ( chain_id, & mut local_node) . await else {
2924
2936
error ! ( "Fail to read local chain info for {chain_id}" ) ;
2925
2937
return ;
0 commit comments