Skip to content

Commit 85e8184

Browse files
authored
Merge pull request #3187 from autonomys/propagate-snap-errors
Exit when snap sync needs user intervention
2 parents 980c71e + 6731ba9 commit 85e8184

2 files changed

Lines changed: 48 additions & 6 deletions

File tree

crates/subspace-service/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,10 @@ where
11131113
Box::pin(async move {
11141114
// Run snap-sync before DSN-sync.
11151115
if config.sync == ChainSyncMode::Snap {
1116-
snap_sync_task.await;
1116+
if let Err(error) = snap_sync_task.await {
1117+
error!(%error, "Snap sync exited with a fatal error");
1118+
return;
1119+
}
11171120
}
11181121

11191122
if let Err(error) = worker.await {

crates/subspace-service/src/sync_from_dsn/snap_sync.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use sc_consensus_subspace::archiver::{decode_block, SegmentHeadersStore};
1212
use sc_network::{NetworkBlock, PeerId};
1313
use sc_network_sync::service::network::NetworkServiceHandle;
1414
use sc_network_sync::SyncingService;
15-
use sc_service::Error;
1615
use sp_api::ProvideRuntimeApi;
1716
use sp_blockchain::HeaderBackend;
1817
use sp_consensus::BlockOrigin;
@@ -31,6 +30,35 @@ use subspace_networking::Node;
3130
use tokio::time::sleep;
3231
use 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)]
3563
pub(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

Comments
 (0)