vc_processors/fil_proofs/
mod.rs

1//! This module provides types and apis re-exported from rust-fil-proofs
2//!
3
4use std::collections::BTreeMap;
5use std::fs::OpenOptions;
6use std::path::{Path, PathBuf};
7use std::{fmt, io};
8
9use anyhow::{Context, Result};
10use filecoin_proofs::{get_base_tree_leafs, get_base_tree_size, DefaultBinaryTree, DefaultPieceHasher, StoreConfig, BINARY_ARITY};
11use filecoin_proofs_api::post;
12use filecoin_proofs_api::seal;
13use forest_address::Address;
14use memmap::{Mmap, MmapOptions};
15use serde::{Deserialize, Serialize};
16use storage_proofs_core::{
17    cache_key::CacheKey,
18    merkle::{create_base_merkle_tree, BinaryMerkleTree},
19    util::default_rows_to_discard,
20};
21
22// re-exported
23pub use filecoin_proofs_api::{
24    seal::{clear_cache, Labels, SealCommitPhase1Output, SealCommitPhase2Output, SealPreCommitPhase1Output, SealPreCommitPhase2Output},
25    update::{
26        empty_sector_update_encode_into, generate_empty_sector_update_proof_with_vanilla, generate_partition_proofs,
27        verify_empty_sector_update_proof, verify_partition_proofs,
28    },
29    ChallengeSeed, Commitment, PaddedBytesAmount, PartitionProofBytes, PieceInfo, PrivateReplicaInfo, ProverId, RegisteredPoStProof,
30    RegisteredSealProof, RegisteredUpdateProof, SectorId, Ticket, UnpaddedBytesAmount,
31};
32
33/// Identifier for Actors.
34pub type ActorID = u64;
35
36pub type SnarkProof = crate::b64serde::BytesVec;
37
38#[derive(Debug)]
39pub struct PanicError {
40    pub message: String,
41}
42
43impl std::error::Error for PanicError {}
44
45impl fmt::Display for PanicError {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(f, "Panic: {}", self.message)
48    }
49}
50
51macro_rules! safe_call {
52    ($ex:expr) => {
53        match std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || $ex)) {
54            Ok(r) => r,
55            Err(p) => {
56                let error_msg = match p.downcast_ref::<&str>() {
57                    Some(message) => message.to_string(),
58                    None => p
59                        .downcast_ref::<String>()
60                        .cloned()
61                        .unwrap_or_else(|| format!("non-str unwind err: {:?}", p)),
62                };
63
64                Err(crate::fil_proofs::PanicError { message: error_msg }.into())
65            }
66        }
67    };
68}
69
70pub fn write_and_preprocess<R, W>(
71    registered_proof: RegisteredSealProof,
72    source: R,
73    target: W,
74    piece_size: UnpaddedBytesAmount,
75) -> Result<(PieceInfo, UnpaddedBytesAmount)>
76where
77    R: io::Read,
78    W: io::Read + io::Write + io::Seek,
79{
80    safe_call! {
81        seal::write_and_preprocess(registered_proof, source, target, piece_size)
82    }
83}
84
85pub fn seal_commit_phase1(
86    cache_path: PathBuf,
87    replica_path: PathBuf,
88    prover_id: ProverId,
89    sector_id: SectorId,
90    ticket: Ticket,
91    seed: Ticket,
92    pre_commit: SealPreCommitPhase2Output,
93    piece_infos: &[PieceInfo],
94) -> Result<SealCommitPhase1Output> {
95    safe_call! {
96        seal::seal_commit_phase1(
97            cache_path,
98            replica_path,
99            prover_id,
100            sector_id,
101            ticket,
102            seed,
103            pre_commit,
104            piece_infos,
105        )
106    }
107}
108
109pub fn seal_commit_phase2(
110    phase1_output: SealCommitPhase1Output,
111    prover_id: ProverId,
112    sector_id: SectorId,
113) -> Result<SealCommitPhase2Output> {
114    safe_call! {
115        seal::seal_commit_phase2(phase1_output, prover_id, sector_id)
116    }
117}
118
119pub fn seal_pre_commit_phase1(
120    registered_proof: RegisteredSealProof,
121    cache_path: PathBuf,
122    in_path: PathBuf,
123    out_path: PathBuf,
124    prover_id: ProverId,
125    sector_id: SectorId,
126    ticket: Ticket,
127    piece_infos: &[PieceInfo],
128) -> Result<SealPreCommitPhase1Output> {
129    safe_call! {
130        seal::seal_pre_commit_phase1(
131            registered_proof,
132            cache_path,
133            in_path,
134            out_path,
135            prover_id,
136            sector_id,
137            ticket,
138            piece_infos,
139        )
140    }
141}
142
143pub fn seal_pre_commit_phase2(
144    phase1_output: SealPreCommitPhase1Output,
145    cache_path: PathBuf,
146    out_path: PathBuf,
147) -> Result<SealPreCommitPhase2Output> {
148    safe_call! {
149        seal::seal_pre_commit_phase2(phase1_output, cache_path, out_path)
150    }
151}
152
153#[derive(Clone, Debug, Serialize, Deserialize)]
154pub struct SnapEncodeOutput {
155    pub comm_r_new: Commitment,
156    pub comm_r_last_new: Commitment,
157    pub comm_d_new: Commitment,
158}
159
160pub fn snap_encode_into(
161    registered_proof: RegisteredUpdateProof,
162    new_replica_path: PathBuf,
163    new_cache_path: PathBuf,
164    sector_path: PathBuf,
165    sector_cache_path: PathBuf,
166    staged_data_path: PathBuf,
167    piece_infos: &[PieceInfo],
168) -> Result<SnapEncodeOutput> {
169    safe_call! {
170        empty_sector_update_encode_into(
171            registered_proof,
172            new_replica_path,
173            new_cache_path,
174            sector_path,
175            sector_cache_path,
176            staged_data_path,
177            piece_infos,
178        )
179        .map(|out| SnapEncodeOutput {
180            comm_r_new: out.comm_r_new,
181            comm_r_last_new: out.comm_r_last_new,
182            comm_d_new: out.comm_d_new,
183        })
184    }
185}
186
187pub fn snap_generate_partition_proofs(
188    registered_proof: RegisteredUpdateProof,
189    comm_r_old: Commitment,
190    comm_r_new: Commitment,
191    comm_d_new: Commitment,
192    sector_path: PathBuf,
193    sector_cache_path: PathBuf,
194    replica_path: PathBuf,
195    replica_cache_path: PathBuf,
196) -> Result<Vec<PartitionProofBytes>> {
197    safe_call! {
198        generate_partition_proofs(
199            registered_proof,
200            comm_r_old,
201            comm_r_new,
202            comm_d_new,
203            sector_path,
204            sector_cache_path,
205            replica_path,
206            replica_cache_path,
207        )
208    }
209}
210
211pub type SnapProveOutput = Vec<u8>;
212
213pub fn snap_generate_sector_update_proof(
214    registered_proof: RegisteredUpdateProof,
215    vannilla_proofs: Vec<PartitionProofBytes>,
216    comm_r_old: Commitment,
217    comm_r_new: Commitment,
218    comm_d_new: Commitment,
219) -> Result<SnapProveOutput> {
220    safe_call! {
221        generate_empty_sector_update_proof_with_vanilla(
222            registered_proof,
223            vannilla_proofs,
224            comm_r_old,
225            comm_r_new,
226            comm_d_new,
227        ).map(|out| out.0)
228    }
229}
230
231pub fn snap_verify_sector_update_proof(
232    registered_proof: RegisteredUpdateProof,
233    proof: &[u8],
234    comm_r_old: Commitment,
235    comm_r_new: Commitment,
236    comm_d_new: Commitment,
237) -> Result<bool> {
238    safe_call! {
239        verify_empty_sector_update_proof(
240            registered_proof,
241            proof,
242            comm_r_old,
243            comm_r_new,
244            comm_d_new,
245        )
246    }
247}
248
249pub fn tree_d_path_in_dir(dir: &Path) -> PathBuf {
250    StoreConfig::data_path(dir, &CacheKey::CommDTree.to_string())
251}
252
253enum Bytes {
254    Mmap(Mmap),
255    InMem(Vec<u8>),
256}
257
258impl AsRef<[u8]> for Bytes {
259    #[inline]
260    fn as_ref(&self) -> &[u8] {
261        match self {
262            Bytes::Mmap(m) => &m[..],
263            Bytes::InMem(m) => &m[..],
264        }
265    }
266}
267
268pub fn create_tree_d(registered_proof: RegisteredSealProof, in_path: Option<PathBuf>, cache_path: PathBuf) -> Result<()> {
269    safe_call! {
270        create_tree_d_inner(
271            registered_proof,
272            in_path,
273            cache_path,
274        )
275    }
276}
277
278fn create_tree_d_inner(registered_proof: RegisteredSealProof, in_path: Option<PathBuf>, cache_path: PathBuf) -> Result<()> {
279    let sector_size = registered_proof.sector_size();
280    let tree_size = get_base_tree_size::<DefaultBinaryTree>(sector_size)?;
281    let tree_leafs = get_base_tree_leafs::<DefaultBinaryTree>(tree_size)?;
282
283    let data = match in_path {
284        Some(p) => {
285            let f = OpenOptions::new()
286                .read(true)
287                .open(&p)
288                .with_context(|| format!("open staged file {:?}", p))?;
289
290            let mapped = unsafe { MmapOptions::new().map(&f).with_context(|| format!("mmap staged file: {:?}", p))? };
291
292            Bytes::Mmap(mapped)
293        }
294
295        None => Bytes::InMem(vec![0; sector_size.0 as usize]),
296    };
297
298    let cfg = StoreConfig::new(
299        cache_path,
300        CacheKey::CommDTree.to_string(),
301        default_rows_to_discard(tree_leafs, BINARY_ARITY),
302    );
303
304    create_base_merkle_tree::<BinaryMerkleTree<DefaultPieceHasher>>(Some(cfg), tree_leafs, data.as_ref())?;
305
306    Ok(())
307}
308
309pub fn cached_filenames_for_sector(registered_proof: RegisteredSealProof) -> Vec<PathBuf> {
310    use RegisteredSealProof::*;
311    let mut trees = match registered_proof {
312        StackedDrg2KiBV1 | StackedDrg8MiBV1 | StackedDrg512MiBV1 | StackedDrg2KiBV1_1 | StackedDrg8MiBV1_1 | StackedDrg512MiBV1_1 => {
313            vec!["sc-02-data-tree-r-last.dat".into()]
314        }
315
316        StackedDrg32GiBV1 | StackedDrg32GiBV1_1 => (0..8).map(|idx| format!("sc-02-data-tree-r-last-{}.dat", idx).into()).collect(),
317
318        StackedDrg64GiBV1 | StackedDrg64GiBV1_1 => (0..16).map(|idx| format!("sc-02-data-tree-r-last-{}.dat", idx).into()).collect(),
319    };
320
321    trees.push("p_aux".into());
322    trees.push("t_aux".into());
323
324    trees
325}
326
327pub fn to_prover_id(miner_id: ActorID) -> ProverId {
328    let mut prover_id: ProverId = Default::default();
329    let actor_addr_payload = Address::new_id(miner_id).payload_bytes();
330    prover_id[..actor_addr_payload.len()].copy_from_slice(actor_addr_payload.as_ref());
331    prover_id
332}
333
334pub fn generate_window_post(
335    randomness: &ChallengeSeed,
336    replicas: &BTreeMap<SectorId, PrivateReplicaInfo>,
337    prover_id: ProverId,
338) -> Result<Vec<(RegisteredPoStProof, SnarkProof)>> {
339    safe_call! {
340        post::generate_window_post(
341            randomness,
342            replicas,
343            prover_id,
344        )
345    }
346    .map(|proofs| proofs.into_iter().map(|(r, p)| (r, p.into())).collect())
347}
348
349pub fn generate_winning_post(
350    randomness: &ChallengeSeed,
351    replicas: &BTreeMap<SectorId, PrivateReplicaInfo>,
352    prover_id: ProverId,
353) -> Result<Vec<(RegisteredPoStProof, SnarkProof)>> {
354    safe_call! {
355        post::generate_winning_post(
356            randomness,
357            replicas,
358            prover_id,
359        )
360    }
361    .map(|proofs| proofs.into_iter().map(|(r, p)| (r, p.into())).collect())
362}