18
18
19
19
//! Warp syncing strategy. Bootstraps chain by downloading warp proofs and state.
20
20
21
+ use sc_consensus:: IncomingBlock ;
22
+ use sp_consensus:: BlockOrigin ;
21
23
pub use sp_consensus_grandpa:: { AuthorityList , SetId } ;
22
24
23
25
use crate :: {
@@ -61,9 +63,9 @@ pub struct WarpProofRequest<B: BlockT> {
61
63
/// Proof verification result.
62
64
pub enum VerificationResult < Block : BlockT > {
63
65
/// Proof is valid, but the target was not reached.
64
- Partial ( SetId , AuthorityList , Block :: Hash ) ,
66
+ Partial ( SetId , AuthorityList , Block :: Hash , Vec < ( Block :: Header , Justifications ) > ) ,
65
67
/// Target finality is proved.
66
- Complete ( SetId , AuthorityList , Block :: Header ) ,
68
+ Complete ( SetId , AuthorityList , Block :: Header , Vec < ( Block :: Header , Justifications ) > ) ,
67
69
}
68
70
69
71
/// Warp sync backend. Handles retrieving and verifying warp sync proofs.
@@ -403,20 +405,43 @@ where
403
405
return
404
406
} ;
405
407
408
+ let proof_to_incoming_block =
409
+ |( header, justifications) : ( B :: Header , Justifications ) | -> IncomingBlock < B > {
410
+ IncomingBlock {
411
+ hash : header. hash ( ) ,
412
+ header : Some ( header) ,
413
+ body : None ,
414
+ indexed_body : None ,
415
+ justifications : Some ( justifications) ,
416
+ origin : Some ( * peer_id) ,
417
+ // We are still in warp sync, so we don't have the state. This means
418
+ // we also can't execute the block.
419
+ allow_missing_state : true ,
420
+ skip_execution : true ,
421
+ // Shouldn't already exist in the database.
422
+ import_existing : false ,
423
+ state : None ,
424
+ }
425
+ } ;
426
+
406
427
match warp_sync_provider. verify ( & response, * set_id, authorities. clone ( ) ) {
407
428
Err ( e) => {
408
429
debug ! ( target: LOG_TARGET , "Bad warp proof response: {}" , e) ;
409
430
self . actions
410
431
. push ( SyncingAction :: DropPeer ( BadPeer ( * peer_id, rep:: BAD_WARP_PROOF ) ) )
411
432
} ,
412
- Ok ( VerificationResult :: Partial ( new_set_id, new_authorities, new_last_hash) ) => {
433
+ Ok ( VerificationResult :: Partial ( new_set_id, new_authorities, new_last_hash, proofs ) ) => {
413
434
log:: debug!( target: LOG_TARGET , "Verified partial proof, set_id={:?}" , new_set_id) ;
414
435
* set_id = new_set_id;
415
436
* authorities = new_authorities;
416
437
* last_hash = new_last_hash;
417
438
self . total_proof_bytes += response. 0 . len ( ) as u64 ;
439
+ self . actions . push ( SyncingAction :: ImportBlocks {
440
+ origin : BlockOrigin :: NetworkInitialSync ,
441
+ blocks : proofs. into_iter ( ) . map ( proof_to_incoming_block) . collect ( ) ,
442
+ } ) ;
418
443
} ,
419
- Ok ( VerificationResult :: Complete ( new_set_id, _, header) ) => {
444
+ Ok ( VerificationResult :: Complete ( new_set_id, _, header, proofs ) ) => {
420
445
log:: debug!(
421
446
target: LOG_TARGET ,
422
447
"Verified complete proof, set_id={:?}. Continuing with target block download: {} ({})." ,
@@ -426,6 +451,10 @@ where
426
451
) ;
427
452
self . total_proof_bytes += response. 0 . len ( ) as u64 ;
428
453
self . phase = Phase :: TargetBlock ( header) ;
454
+ self . actions . push ( SyncingAction :: ImportBlocks {
455
+ origin : BlockOrigin :: NetworkInitialSync ,
456
+ blocks : proofs. into_iter ( ) . map ( proof_to_incoming_block) . collect ( ) ,
457
+ } ) ;
429
458
} ,
430
459
}
431
460
}
@@ -744,7 +773,7 @@ mod test {
744
773
use crate :: { mock:: MockBlockDownloader , service:: network:: NetworkServiceProvider } ;
745
774
use sc_block_builder:: BlockBuilderBuilder ;
746
775
use sp_blockchain:: { BlockStatus , Error as BlockchainError , HeaderBackend , Info } ;
747
- use sp_consensus_grandpa:: { AuthorityList , SetId } ;
776
+ use sp_consensus_grandpa:: { AuthorityList , SetId , GRANDPA_ENGINE_ID } ;
748
777
use sp_core:: H256 ;
749
778
use sp_runtime:: traits:: { Block as BlockT , Header as HeaderT , NumberFor } ;
750
779
use std:: { io:: ErrorKind , sync:: Arc } ;
@@ -1230,19 +1259,38 @@ mod test {
1230
1259
1231
1260
#[ test]
1232
1261
fn partial_warp_proof_doesnt_advance_phase ( ) {
1233
- let client = mock_client_without_state ( ) ;
1262
+ let client = Arc :: new ( TestClientBuilder :: new ( ) . set_no_genesis ( ) . build ( ) ) ;
1234
1263
let mut provider = MockWarpSyncProvider :: < Block > :: new ( ) ;
1235
1264
provider
1236
1265
. expect_current_authorities ( )
1237
1266
. once ( )
1238
1267
. return_const ( AuthorityList :: default ( ) ) ;
1268
+ let target_block = BlockBuilderBuilder :: new ( & * client)
1269
+ . on_parent_block ( client. chain_info ( ) . best_hash )
1270
+ . with_parent_block_number ( client. chain_info ( ) . best_number )
1271
+ . build ( )
1272
+ . unwrap ( )
1273
+ . build ( )
1274
+ . unwrap ( )
1275
+ . block ;
1276
+ let target_header = target_block. header ( ) . clone ( ) ;
1277
+ let justifications = Justifications :: new ( vec ! [ ( GRANDPA_ENGINE_ID , vec![ 1 , 2 , 3 , 4 , 5 ] ) ] ) ;
1239
1278
// Warp proof is partial.
1240
- provider. expect_verify ( ) . return_once ( |_proof, set_id, authorities| {
1241
- Ok ( VerificationResult :: Partial ( set_id, authorities, Hash :: random ( ) ) )
1242
- } ) ;
1279
+ {
1280
+ let target_header = target_header. clone ( ) ;
1281
+ let justifications = justifications. clone ( ) ;
1282
+ provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1283
+ Ok ( VerificationResult :: Partial (
1284
+ set_id,
1285
+ authorities,
1286
+ target_header. hash ( ) ,
1287
+ vec ! [ ( target_header, justifications) ] ,
1288
+ ) )
1289
+ } ) ;
1290
+ }
1243
1291
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1244
1292
let mut warp_sync = WarpSync :: new (
1245
- Arc :: new ( client) ,
1293
+ client,
1246
1294
config,
1247
1295
Some ( ProtocolName :: Static ( "" ) ) ,
1248
1296
Arc :: new ( MockBlockDownloader :: new ( ) ) ,
@@ -1267,7 +1315,29 @@ mod test {
1267
1315
1268
1316
warp_sync. on_warp_proof_response ( & request_peer_id, EncodedProof ( Vec :: new ( ) ) ) ;
1269
1317
1270
- assert ! ( warp_sync. actions. is_empty( ) , "No extra actions generated" ) ;
1318
+ assert_eq ! ( warp_sync. actions. len( ) , 1 ) ;
1319
+ let SyncingAction :: ImportBlocks { origin, mut blocks } = warp_sync. actions . pop ( ) . unwrap ( )
1320
+ else {
1321
+ panic ! ( "Expected `ImportBlocks` action." ) ;
1322
+ } ;
1323
+ assert_eq ! ( origin, BlockOrigin :: NetworkInitialSync ) ;
1324
+ assert_eq ! ( blocks. len( ) , 1 ) ;
1325
+ let import_block = blocks. pop ( ) . unwrap ( ) ;
1326
+ assert_eq ! (
1327
+ import_block,
1328
+ IncomingBlock {
1329
+ hash: target_header. hash( ) ,
1330
+ header: Some ( target_header) ,
1331
+ body: None ,
1332
+ indexed_body: None ,
1333
+ justifications: Some ( justifications) ,
1334
+ origin: Some ( request_peer_id) ,
1335
+ allow_missing_state: true ,
1336
+ skip_execution: true ,
1337
+ import_existing: false ,
1338
+ state: None ,
1339
+ }
1340
+ ) ;
1271
1341
assert ! ( matches!( warp_sync. phase, Phase :: WarpProof { .. } ) ) ;
1272
1342
}
1273
1343
@@ -1288,10 +1358,20 @@ mod test {
1288
1358
. unwrap ( )
1289
1359
. block ;
1290
1360
let target_header = target_block. header ( ) . clone ( ) ;
1361
+ let justifications = Justifications :: new ( vec ! [ ( GRANDPA_ENGINE_ID , vec![ 1 , 2 , 3 , 4 , 5 ] ) ] ) ;
1291
1362
// Warp proof is complete.
1292
- provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1293
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1294
- } ) ;
1363
+ {
1364
+ let target_header = target_header. clone ( ) ;
1365
+ let justifications = justifications. clone ( ) ;
1366
+ provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1367
+ Ok ( VerificationResult :: Complete (
1368
+ set_id,
1369
+ authorities,
1370
+ target_header. clone ( ) ,
1371
+ vec ! [ ( target_header, justifications) ] ,
1372
+ ) )
1373
+ } ) ;
1374
+ }
1295
1375
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1296
1376
let mut warp_sync = WarpSync :: new (
1297
1377
client,
@@ -1319,7 +1399,29 @@ mod test {
1319
1399
1320
1400
warp_sync. on_warp_proof_response ( & request_peer_id, EncodedProof ( Vec :: new ( ) ) ) ;
1321
1401
1322
- assert ! ( warp_sync. actions. is_empty( ) , "No extra actions generated." ) ;
1402
+ assert_eq ! ( warp_sync. actions. len( ) , 1 ) ;
1403
+ let SyncingAction :: ImportBlocks { origin, mut blocks } = warp_sync. actions . pop ( ) . unwrap ( )
1404
+ else {
1405
+ panic ! ( "Expected `ImportBlocks` action." ) ;
1406
+ } ;
1407
+ assert_eq ! ( origin, BlockOrigin :: NetworkInitialSync ) ;
1408
+ assert_eq ! ( blocks. len( ) , 1 ) ;
1409
+ let import_block = blocks. pop ( ) . unwrap ( ) ;
1410
+ assert_eq ! (
1411
+ import_block,
1412
+ IncomingBlock {
1413
+ hash: target_header. hash( ) ,
1414
+ header: Some ( target_header) ,
1415
+ body: None ,
1416
+ indexed_body: None ,
1417
+ justifications: Some ( justifications) ,
1418
+ origin: Some ( request_peer_id) ,
1419
+ allow_missing_state: true ,
1420
+ skip_execution: true ,
1421
+ import_existing: false ,
1422
+ state: None ,
1423
+ }
1424
+ ) ;
1323
1425
assert ! (
1324
1426
matches!( warp_sync. phase, Phase :: TargetBlock ( header) if header == * target_block. header( ) )
1325
1427
) ;
@@ -1372,7 +1474,7 @@ mod test {
1372
1474
let target_header = target_block. header ( ) . clone ( ) ;
1373
1475
// Warp proof is complete.
1374
1476
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1375
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1477
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1376
1478
} ) ;
1377
1479
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1378
1480
let mut warp_sync =
@@ -1446,7 +1548,7 @@ mod test {
1446
1548
let target_header = target_block. header ( ) . clone ( ) ;
1447
1549
// Warp proof is complete.
1448
1550
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1449
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1551
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1450
1552
} ) ;
1451
1553
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1452
1554
let mut warp_sync =
@@ -1485,7 +1587,7 @@ mod test {
1485
1587
let target_header = target_block. header ( ) . clone ( ) ;
1486
1588
// Warp proof is complete.
1487
1589
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1488
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1590
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1489
1591
} ) ;
1490
1592
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1491
1593
let mut warp_sync =
@@ -1540,7 +1642,7 @@ mod test {
1540
1642
let target_header = target_block. header ( ) . clone ( ) ;
1541
1643
// Warp proof is complete.
1542
1644
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1543
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1645
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1544
1646
} ) ;
1545
1647
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1546
1648
let mut warp_sync =
@@ -1618,7 +1720,7 @@ mod test {
1618
1720
let target_header = target_block. header ( ) . clone ( ) ;
1619
1721
// Warp proof is complete.
1620
1722
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1621
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1723
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1622
1724
} ) ;
1623
1725
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1624
1726
let mut warp_sync =
@@ -1672,7 +1774,7 @@ mod test {
1672
1774
let target_header = target_block. header ( ) . clone ( ) ;
1673
1775
// Warp proof is complete.
1674
1776
provider. expect_verify ( ) . return_once ( move |_proof, set_id, authorities| {
1675
- Ok ( VerificationResult :: Complete ( set_id, authorities, target_header) )
1777
+ Ok ( VerificationResult :: Complete ( set_id, authorities, target_header, Default :: default ( ) ) )
1676
1778
} ) ;
1677
1779
let config = WarpSyncConfig :: WithProvider ( Arc :: new ( provider) ) ;
1678
1780
let mut warp_sync =
0 commit comments