subspace_farmer_components/
segment_reconstruction.rs

1use 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    /// Segment downloading failed
17    #[error("Segment downloading failed: {0}")]
18    SegmentDownloadingFailed(#[from] SegmentDownloadingError),
19
20    /// Internal piece retrieval process failed
21    #[error("Piece reconstruction failed: {0}")]
22    ReconstructionFailed(#[from] ReconstructorError),
23
24    /// Join error
25    #[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}