Skip to content

Commit 9b580c2

Browse files
authored
feat: add various new APIs for Lotus (#89)
The new APIs are: - decoding a range of an updated empty sector - generating TreeRLast - generating TreeC - running SDR
1 parent e449912 commit 9b580c2

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

src/seal.rs

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use filecoin_hashers::Hasher;
1111
use filecoin_proofs_v1::constants::{
1212
SectorShape16KiB, SectorShape16MiB, SectorShape1GiB, SectorShape2KiB, SectorShape32GiB,
1313
SectorShape32KiB, SectorShape4KiB, SectorShape512MiB, SectorShape64GiB, SectorShape8MiB,
14-
SECTOR_SIZE_16_KIB, SECTOR_SIZE_16_MIB, SECTOR_SIZE_1_GIB, SECTOR_SIZE_2_KIB,
14+
LAYERS, SECTOR_SIZE_16_KIB, SECTOR_SIZE_16_MIB, SECTOR_SIZE_1_GIB, SECTOR_SIZE_2_KIB,
1515
SECTOR_SIZE_32_GIB, SECTOR_SIZE_32_KIB, SECTOR_SIZE_4_KIB, SECTOR_SIZE_512_MIB,
1616
SECTOR_SIZE_64_GIB, SECTOR_SIZE_8_MIB,
1717
};
@@ -402,6 +402,46 @@ fn seal_pre_commit_phase1_inner<Tree: 'static + MerkleTreeTrait>(
402402
})
403403
}
404404

405+
/// Generate label layers (SDR).
406+
///
407+
/// # Arguments
408+
/// * `registered_proof` - Selected seal operation.
409+
/// * `cache_path` - Directory path to use for generation of Merkle tree on disk.
410+
/// * `output_dir` - Directory where the TreeRLast(s) are stored.
411+
pub fn sdr<R>(
412+
registered_proof: RegisteredSealProof,
413+
cache_path: R,
414+
replica_id: <filecoin_proofs_v1::constants::DefaultTreeHasher as Hasher>::Domain,
415+
) -> Result<()>
416+
where
417+
R: AsRef<Path>,
418+
{
419+
ensure!(
420+
registered_proof.major_version() == 1,
421+
"unusupported version"
422+
);
423+
424+
with_shape!(
425+
u64::from(registered_proof.sector_size()),
426+
sdr_inner,
427+
registered_proof,
428+
cache_path.as_ref(),
429+
replica_id,
430+
)?;
431+
432+
Ok(())
433+
}
434+
435+
fn sdr_inner<Tree: 'static + MerkleTreeTrait>(
436+
registered_proof: RegisteredSealProof,
437+
cache_path: &Path,
438+
replica_id: <Tree::Hasher as Hasher>::Domain,
439+
) -> Result<()> {
440+
let config = registered_proof.as_v1_config();
441+
filecoin_proofs_v1::sdr::<_, Tree>(&config, cache_path, &replica_id)?;
442+
Ok(())
443+
}
444+
405445
/// Second phase of seal precommit operation, must be called with output of
406446
/// [`seal_pre_commit_phase1`]. Generates `comm_r` replica commitment from outputs
407447
/// of previous step.
@@ -477,6 +517,96 @@ fn seal_pre_commit_phase2_inner<Tree: 'static + MerkleTreeTrait>(
477517
})
478518
}
479519

520+
/// Generate Merkle tree for sector replica (TreeRLast) and return the root hash (CommRLast).
521+
///
522+
/// # Arguments
523+
/// * `registered_proof` - Selected seal operation.
524+
/// * `replica_path` - File path of replica.
525+
/// * `output_dir` - Directory where the TreeRLast(s) are stored.
526+
pub fn generate_tree_r_last<O, R>(
527+
registered_proof: RegisteredSealProof,
528+
replica_path: R,
529+
output_dir: O,
530+
) -> Result<Commitment>
531+
where
532+
O: AsRef<Path>,
533+
R: AsRef<Path>,
534+
{
535+
ensure!(
536+
registered_proof.major_version() == 1,
537+
"unusupported version"
538+
);
539+
540+
let sector_size = u64::from(registered_proof.sector_size());
541+
let comm_r_last = with_shape!(
542+
sector_size,
543+
generate_tree_r_last_inner,
544+
sector_size,
545+
replica_path.as_ref(),
546+
output_dir.as_ref(),
547+
)?;
548+
549+
Ok(comm_r_last.into())
550+
}
551+
552+
fn generate_tree_r_last_inner<Tree: 'static + MerkleTreeTrait>(
553+
sector_size: u64,
554+
replica_path: &Path,
555+
output_dir: &Path,
556+
) -> Result<<Tree::Hasher as Hasher>::Domain> {
557+
filecoin_proofs_v1::generate_tree_r_last::<_, _, Tree>(sector_size, &replica_path, &output_dir)
558+
}
559+
560+
/// Generate Merkle tree for the label layers (TreeC) and return the root hash (CommC).
561+
///
562+
/// # Arguments
563+
/// * `registered_proof` - Selected seal operation.
564+
/// * `input_dir` - Directory where the label layers are stored.
565+
/// * `output_dir` - Directory where the TreeRLast(s) are stored.
566+
pub fn generate_tree_c<O, R>(
567+
registered_proof: RegisteredSealProof,
568+
input_dir: R,
569+
output_dir: O,
570+
) -> Result<Commitment>
571+
where
572+
O: AsRef<Path>,
573+
R: AsRef<Path>,
574+
{
575+
ensure!(
576+
registered_proof.major_version() == 1,
577+
"unusupported version"
578+
);
579+
580+
let sector_size = u64::from(registered_proof.sector_size());
581+
let comm_c = with_shape!(
582+
sector_size,
583+
generate_tree_c_inner,
584+
sector_size,
585+
input_dir.as_ref(),
586+
output_dir.as_ref(),
587+
)?;
588+
589+
Ok(comm_c.into())
590+
}
591+
592+
fn generate_tree_c_inner<Tree: 'static + MerkleTreeTrait>(
593+
sector_size: u64,
594+
input_dir: &Path,
595+
output_dir: &Path,
596+
) -> Result<<Tree::Hasher as Hasher>::Domain> {
597+
let num_layers = *LAYERS
598+
.read()
599+
.expect("LAYERS poisoned")
600+
.get(&sector_size)
601+
.expect("unknown sector size");
602+
filecoin_proofs_v1::generate_tree_c::<_, _, Tree>(
603+
sector_size,
604+
&input_dir,
605+
&output_dir,
606+
num_layers,
607+
)
608+
}
609+
480610
/// Computes a sectors's `comm_d` data commitment given its pieces.
481611
///
482612
/// # Arguments

src/update.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Update data within existing sealed sectors.
2+
use std::io::{Read, Write};
23
use std::path::Path;
34

45
use anyhow::{ensure, Result};
@@ -149,6 +150,58 @@ where
149150
)
150151
}
151152

153+
/// Reverses the encoding process for a certain range.
154+
///
155+
/// This function is similar to [`emptu_sector_update_decode_from`], the difference is that it
156+
/// operates directly on the given file descriptions. The current position of the file descriptors
157+
/// is where the decoding starts, i.e. you need to seek to the intended offset before you call this
158+
/// funtion.
159+
///
160+
/// # Arguments
161+
/// * `registered_proof` - Selected sector update proof.
162+
/// * `nodes_count` - Total number of nodes within the file.
163+
/// * `comm_d` - Data commitment from the updated replica.
164+
/// * `comm_r` - Replica commitment of the empty sector.
165+
/// * `input_data` - File descriptor to the encoded data.
166+
/// * `sector_key_data` - File descriptor to replica of the empty sector.
167+
/// * `output_data` - File descriptor where the decoded data is written to.
168+
/// * `nodes_offset` - Node offset relative to the beginning of the file.
169+
/// * `num_nodes` - Number of nodes to be decoded starting at the current position.
170+
pub fn empty_sector_update_decode_from_range<R, S, W>(
171+
registered_proof: RegisteredUpdateProof,
172+
comm_d: Commitment,
173+
comm_r: Commitment,
174+
input_data: R,
175+
sector_key_data: S,
176+
output_data: &mut W,
177+
nodes_offset: usize,
178+
num_nodes: usize,
179+
) -> Result<()>
180+
where
181+
R: Read,
182+
S: Read,
183+
W: Write,
184+
{
185+
ensure!(
186+
registered_proof.major_version() == 1,
187+
"unusupported version"
188+
);
189+
190+
let config = registered_proof.as_v1_config();
191+
let update_config = SectorUpdateConfig::from_porep_config(&config);
192+
193+
filecoin_proofs_v1::decode_from_range(
194+
update_config.nodes_count,
195+
comm_d,
196+
comm_r,
197+
input_data,
198+
sector_key_data,
199+
output_data,
200+
nodes_offset,
201+
num_nodes,
202+
)
203+
}
204+
152205
fn empty_sector_update_remove_encoded_data_inner<
153206
Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
154207
>(

0 commit comments

Comments
 (0)