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 SegmentDownloadingError, download_segment_pieces,
6};
7use subspace_erasure_coding::ErasureCoding;
8use subspace_kzg::Kzg;
9use thiserror::Error;
10use tokio::task::JoinError;
11use tracing::{error, info};
12
13#[derive(Debug, Error)]
14pub(crate) enum SegmentReconstructionError {
15 #[error("Segment downloading failed: {0}")]
17 SegmentDownloadingFailed(#[from] SegmentDownloadingError),
18
19 #[error("Piece reconstruction failed: {0}")]
21 ReconstructionFailed(#[from] ReconstructorError),
22
23 #[error("Join error: {0}")]
25 JoinError(#[from] JoinError),
26}
27
28pub(crate) async fn recover_missing_piece<PG>(
29 piece_getter: &PG,
30 kzg: Kzg,
31 erasure_coding: ErasureCoding,
32 missing_piece_index: PieceIndex,
33) -> Result<Piece, SegmentReconstructionError>
34where
35 PG: PieceGetter + Send + Sync,
36{
37 info!(%missing_piece_index, "Recovering missing piece...");
38 let segment_index = missing_piece_index.segment_index();
39 let position = missing_piece_index.position();
40
41 let segment_pieces = download_segment_pieces(segment_index, piece_getter).await?;
42
43 let result = tokio::task::spawn_blocking(move || {
44 let reconstructor = PiecesReconstructor::new(kzg, erasure_coding);
45
46 reconstructor.reconstruct_piece(&segment_pieces, position as usize)
47 })
48 .await??;
49
50 info!(%missing_piece_index, "Recovering missing piece succeeded.");
51
52 Ok(result)
53}