@@ -12,7 +12,6 @@ use sc_consensus_subspace::archiver::{decode_block, SegmentHeadersStore};
1212use sc_network:: { NetworkBlock , PeerId } ;
1313use sc_network_sync:: service:: network:: NetworkServiceHandle ;
1414use sc_network_sync:: SyncingService ;
15- use sc_service:: Error ;
1615use sp_api:: ProvideRuntimeApi ;
1716use sp_blockchain:: HeaderBackend ;
1817use sp_consensus:: BlockOrigin ;
@@ -31,6 +30,35 @@ use subspace_networking::Node;
3130use tokio:: time:: sleep;
3231use tracing:: { debug, error} ;
3332
33+ /// Error type for snap sync.
34+ #[ derive( thiserror:: Error , Debug ) ]
35+ pub enum Error {
36+ /// A fatal snap sync error which requires user intervention.
37+ /// Most snap sync errors are non-fatal, because we can just continue with regular sync.
38+ #[ error( "Snap Sync requires user action: {0}" ) ]
39+ SnapSyncImpossible ( String ) ,
40+
41+ /// Substrate service error.
42+ #[ error( transparent) ]
43+ Sub ( #[ from] sc_service:: Error ) ,
44+
45+ /// Substrate blockchain client error.
46+ #[ error( transparent) ]
47+ Client ( #[ from] sp_blockchain:: Error ) ,
48+
49+ /// Other.
50+ #[ error( "Snap sync error: {0}" ) ]
51+ Other ( String ) ,
52+ }
53+
54+ impl From < String > for Error {
55+ fn from ( error : String ) -> Self {
56+ Error :: Other ( error)
57+ }
58+ }
59+
60+ /// Run a snap sync, return an error if snap sync is impossible and user intervention is required.
61+ /// Otherwise, just log the error and return `Ok(())` so that regular sync continues.
3462#[ allow( clippy:: too_many_arguments) ]
3563pub ( crate ) async fn snap_sync < Block , AS , Client , PG > (
3664 segment_headers_store : SegmentHeadersStore < AS > ,
@@ -43,7 +71,8 @@ pub(crate) async fn snap_sync<Block, AS, Client, PG>(
4371 sync_service : Arc < SyncingService < Block > > ,
4472 network_service_handle : NetworkServiceHandle ,
4573 erasure_coding : ErasureCoding ,
46- ) where
74+ ) -> Result < ( ) , Error >
75+ where
4776 Block : BlockT ,
4877 AS : AuxStore ,
4978 Client : HeaderBackend < Block >
@@ -81,6 +110,13 @@ pub(crate) async fn snap_sync<Block, AS, Client, PG>(
81110 debug ! ( "Snap sync finished successfully" ) ;
82111 }
83112 Err ( error) => {
113+ // A fatal snap sync error requiring user intervention. The caller will log this error,
114+ // so just return it to terminate the task.
115+ if matches ! ( error, Error :: SnapSyncImpossible ( _) ) {
116+ return Err ( error) ;
117+ }
118+
119+ // Other errors are non-fatal
84120 error ! ( %error, "Snap sync failed" ) ;
85121 }
86122 }
@@ -95,6 +131,8 @@ pub(crate) async fn snap_sync<Block, AS, Client, PG>(
95131 } else {
96132 debug ! ( "Snap sync can only work with genesis state, skipping" ) ;
97133 }
134+
135+ Ok ( ( ) )
98136}
99137
100138// Get blocks from the last segment or from the segment containing the target block.
@@ -166,11 +204,12 @@ where
166204
167205 // We don't have the genesis state when we choose to snap sync.
168206 if target_segment_index <= SegmentIndex :: ONE {
169- error ! (
207+ // The caller logs this error
208+ return Err ( Error :: SnapSyncImpossible (
170209 "Snap sync is impossible - not enough archived history: \
171210 wipe the DB folder and rerun with --sync=full"
172- ) ;
173- return Err ( "Snap sync is impossible - not enough archived history" . into ( ) ) ;
211+ . into ( ) ,
212+ ) ) ;
174213 }
175214
176215 // Identify all segment headers that would need to be reconstructed in order to get first
0 commit comments