subspace_farmer_components/
segment_reconstruction.rs1use subspace_archiving::piece_reconstructor::{PiecesReconstructor, ReconstructorError};
2use subspace_core_primitives::pieces::{Piece, PieceIndex};
3use subspace_data_retrieval::piece_getter::PieceGetter;
4use subspace_data_retrieval::segment_downloading::{
5 SEGMENT_DOWNLOAD_RETRIES, SEGMENT_DOWNLOAD_RETRY_DELAY, SegmentDownloadingError,
6 download_segment_pieces,
7};
8use subspace_erasure_coding::ErasureCoding;
9use subspace_kzg::Kzg;
10use thiserror::Error;
11use tokio::task::JoinError;
12use tracing::{error, info};
13
14#[derive(Debug, Error)]
15pub(crate) enum SegmentReconstructionError {
16 #[error("Segment downloading failed: {0}")]
18 SegmentDownloadingFailed(#[from] SegmentDownloadingError),
19
20 #[error("Piece reconstruction failed: {0}")]
22 ReconstructionFailed(#[from] ReconstructorError),
23
24 #[error("Join error: {0}")]
26 JoinError(#[from] JoinError),
27}
28
29pub(crate) async fn recover_missing_piece<PG>(
30 piece_getter: &PG,
31 kzg: Kzg,
32 erasure_coding: ErasureCoding,
33 missing_piece_index: PieceIndex,
34) -> Result<Piece, SegmentReconstructionError>
35where
36 PG: PieceGetter + Send + Sync,
37{
38 info!(%missing_piece_index, "Recovering missing piece...");
39 let segment_index = missing_piece_index.segment_index();
40 let position = missing_piece_index.position();
41
42 let segment_pieces = download_segment_pieces(
43 segment_index,
44 piece_getter,
45 SEGMENT_DOWNLOAD_RETRIES,
46 Some(SEGMENT_DOWNLOAD_RETRY_DELAY),
47 )
48 .await?;
49
50 let result = tokio::task::spawn_blocking(move || {
51 let reconstructor = PiecesReconstructor::new(kzg, erasure_coding);
52
53 reconstructor.reconstruct_piece(&segment_pieces, position as usize)
54 })
55 .await??;
56
57 info!(%missing_piece_index, "Recovering missing piece succeeded.");
58
59 Ok(result)
60}