From 0efb8308c50a9fd9b63d0b88d7e0023650b03168 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Mon, 27 Jan 2025 18:09:00 +0100 Subject: [PATCH 01/13] feat: add 8MiB to primitives --- lib/polka-storage-proofs/src/porep/mod.rs | 30 +++++++++++++++++------ lib/polka-storage-proofs/src/post/mod.rs | 27 ++++++++++++++------ primitives/src/proofs.rs | 12 +++++++++ storagext/cli/src/cmd/storage_provider.rs | 1 + 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/lib/polka-storage-proofs/src/porep/mod.rs b/lib/polka-storage-proofs/src/porep/mod.rs index ce251c8ed..7e9c527f4 100644 --- a/lib/polka-storage-proofs/src/porep/mod.rs +++ b/lib/polka-storage-proofs/src/porep/mod.rs @@ -5,7 +5,7 @@ pub mod sealer; use bellperson::groth16; use blstrs::Bls12; -use filecoin_proofs::{DefaultPieceHasher, SectorShapeBase}; +use filecoin_proofs::{DefaultPieceHasher, SectorShapeBase, SECTOR_SIZE_2_KIB, SECTOR_SIZE_8_MIB}; use primitives::proofs::RegisteredSealProof; use rand::rngs::OsRng; use storage_proofs_core::{compound_proof::CompoundProof, proof::ProofScheme}; @@ -23,12 +23,16 @@ pub fn generate_random_groth16_parameters( ) -> Result, PoRepError> { let porep_config = seal_to_config(seal_proof); let setup_params = filecoin_proofs::parameters::setup_params(&porep_config)?; - let public_params = StackedDrg::::setup(&setup_params)?; - let circuit = storage_proofs_porep::stacked::StackedCompound::< - SectorShapeBase, - DefaultPieceHasher, - >::blank_circuit(&public_params); + let circuit = match seal_proof { + RegisteredSealProof::StackedDRG2KiBV1P1 | RegisteredSealProof::StackedDRG8MiBV1 => { + let public_params = StackedDrg::::setup(&setup_params)?; + storage_proofs_porep::stacked::StackedCompound::< + SectorShapeBase, + DefaultPieceHasher, + >::blank_circuit(&public_params) + } + }; Ok(groth16::generate_random_parameters::( circuit, &mut OsRng, @@ -64,11 +68,23 @@ fn seal_to_config(seal_proof: RegisteredSealProof) -> filecoin_proofs::PoRepConf match seal_proof { RegisteredSealProof::StackedDRG2KiBV1P1 => { // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L308 - let sector_size = 1 << 11; + let sector_size = SECTOR_SIZE_2_KIB; + // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L292 + // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L52 let porep_id = [0u8; 32]; let api_version = storage_proofs_core::api_version::ApiVersion::V1_2_0; filecoin_proofs::PoRepConfig::new_groth16(sector_size, porep_id, api_version) } + RegisteredSealProof::StackedDRG8MiBV1 => { + // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L308 + let sector_size = SECTOR_SIZE_8_MIB; + // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L292 + // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L52 + let porep_id = [1u8; 32]; + let api_version = storage_proofs_core::api_version::ApiVersion::V1_2_0; + + filecoin_proofs::PoRepConfig::new_groth16(sector_size, porep_id, api_version) + }, } } diff --git a/lib/polka-storage-proofs/src/post/mod.rs b/lib/polka-storage-proofs/src/post/mod.rs index afc49c1bd..7ea5e528a 100644 --- a/lib/polka-storage-proofs/src/post/mod.rs +++ b/lib/polka-storage-proofs/src/post/mod.rs @@ -28,13 +28,15 @@ pub fn generate_random_groth16_parameters( ) -> Result, PoStError> { let post_config = seal_to_config(seal_proof); - let public_params = - filecoin_proofs::parameters::window_post_public_params::(&post_config)?; - - let circuit = - storage_proofs_post::fallback::FallbackPoStCompound::::blank_circuit( - &public_params, - ); + let circuit = match seal_proof { + RegisteredPoStProof::StackedDRGWindow2KiBV1P1 | RegisteredPoStProof::StackedDRGWindow8MiBV1 => { + let public_params = + filecoin_proofs::parameters::window_post_public_params::(&post_config)?; + storage_proofs_post::fallback::FallbackPoStCompound::::blank_circuit( + &public_params, + ) + } + }; Ok(groth16::generate_random_parameters(circuit, &mut OsRng)?) } @@ -151,6 +153,17 @@ fn seal_to_config(seal_proof: RegisteredPoStProof) -> filecoin_proofs::PoStConfi api_version: storage_proofs_core::api_version::ApiVersion::V1_2_0, } } + RegisteredPoStProof::StackedDRGWindow8MiBV1 => { + filecoin_proofs::PoStConfig { + sector_size: filecoin_proofs::SectorSize(seal_proof.sector_size().bytes()), + challenge_count: filecoin_proofs::WINDOW_POST_CHALLENGE_COUNT, + // https://github.com/filecoin-project/rust-fil-proofs/blob/266acc39a3ebd6f3d28c6ee335d78e2b7cea06bc/filecoin-proofs/src/constants.rs#L104 + sector_count: 2, + typ: PoStType::Window, + priority: true, + api_version: storage_proofs_core::api_version::ApiVersion::V1_2_0, + } + }, } } diff --git a/primitives/src/proofs.rs b/primitives/src/proofs.rs index b0c9f8f59..4c0853f66 100644 --- a/primitives/src/proofs.rs +++ b/primitives/src/proofs.rs @@ -53,12 +53,16 @@ pub enum RegisteredSealProof { #[cfg_attr(feature = "clap", clap(name = "2KiB"))] #[cfg_attr(feature = "serde", serde(alias = "2KiB"))] StackedDRG2KiBV1P1, + #[cfg_attr(feature = "clap", clap(name = "8MiB"))] + #[cfg_attr(feature = "serde", serde(alias = "2MiB"))] + StackedDRG8MiBV1, } impl RegisteredSealProof { pub fn sector_size(&self) -> SectorSize { match self { RegisteredSealProof::StackedDRG2KiBV1P1 => SectorSize::_2KiB, + RegisteredSealProof::StackedDRG8MiBV1 => SectorSize::_8MiB, } } @@ -69,6 +73,7 @@ impl RegisteredSealProof { RegisteredSealProof::StackedDRG2KiBV1P1 => { RegisteredPoStProof::StackedDRGWindow2KiBV1P1 } + RegisteredSealProof::StackedDRG8MiBV1 => RegisteredPoStProof::StackedDRGWindow8MiBV1, } } @@ -79,6 +84,7 @@ impl RegisteredSealProof { pub fn proof_size(self) -> usize { match self { RegisteredSealProof::StackedDRG2KiBV1P1 => 192, + RegisteredSealProof::StackedDRG8MiBV1 => 192, } } @@ -104,6 +110,9 @@ pub enum RegisteredPoStProof { #[cfg_attr(feature = "clap", clap(name = "2KiB"))] #[cfg_attr(feature = "serde", serde(alias = "2KiB"))] StackedDRGWindow2KiBV1P1, + #[cfg_attr(feature = "clap", clap(name = "8KiB"))] + #[cfg_attr(feature = "serde", serde(alias = "8KiB"))] + StackedDRGWindow8MiBV1, } impl RegisteredPoStProof { @@ -111,6 +120,7 @@ impl RegisteredPoStProof { pub fn sector_size(&self) -> SectorSize { match self { RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => SectorSize::_2KiB, + RegisteredPoStProof::StackedDRGWindow8MiBV1 => SectorSize::_8MiB, } } @@ -120,6 +130,7 @@ impl RegisteredPoStProof { // Resolve to post proof and then compute size from that. match self { RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => 2, + RegisteredPoStProof::StackedDRGWindow8MiBV1 => 2, } } @@ -130,6 +141,7 @@ impl RegisteredPoStProof { pub fn sector_count(&self) -> usize { match self { RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => 2, + RegisteredPoStProof::StackedDRGWindow8MiBV1 => 2, } } diff --git a/storagext/cli/src/cmd/storage_provider.rs b/storagext/cli/src/cmd/storage_provider.rs index a974dc08d..a3d63bc60 100644 --- a/storagext/cli/src/cmd/storage_provider.rs +++ b/storagext/cli/src/cmd/storage_provider.rs @@ -23,6 +23,7 @@ use crate::{missing_keypair_error, operation_takes_a_while, OutputFormat}; fn parse_post_proof(src: &str) -> Result { match src { "2KiB" => Ok(RegisteredPoStProof::StackedDRGWindow2KiBV1P1), + "8MiB" => Ok(RegisteredPoStProof::StackedDRGWindow8MiBV1), unknown => Err(format!("Unknown PoSt Proof type: {}", unknown)), } } From b99a134d5894b5f823b79c435f795982d6a57d5c Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Mon, 27 Jan 2025 20:21:13 +0100 Subject: [PATCH 02/13] feat: add macro for constructing sealer --- lib/polka-storage-proofs/src/porep/sealer.rs | 49 +++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/lib/polka-storage-proofs/src/porep/sealer.rs b/lib/polka-storage-proofs/src/porep/sealer.rs index e6e11a1de..69cd85e35 100644 --- a/lib/polka-storage-proofs/src/porep/sealer.rs +++ b/lib/polka-storage-proofs/src/porep/sealer.rs @@ -1,25 +1,23 @@ +use core::marker::PhantomData; use std::{fs::File, path::Path}; use bellperson::groth16; use blstrs::Bls12; use filecoin_hashers::Domain; use filecoin_proofs::{ - add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, - DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, - SealPreCommitOutput, SealPreCommitPhase1Output, SectorShapeBase, UnpaddedBytesAmount, + add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, SealPreCommitOutput, SealPreCommitPhase1Output, UnpaddedBytesAmount }; use primitives::{ commitment::{ piece::{PaddedPieceSize, PieceInfo}, CommD, CommP, CommR, Commitment, }, - proofs::RegisteredSealProof, sector::SectorNumber, }; use storage_proofs_core::{compound_proof, compound_proof::CompoundProof}; use storage_proofs_porep::stacked::{self, StackedCompound, StackedDrg}; -use super::{seal_to_config, PoRepError}; +use super::PoRepError; use crate::{ types::{ProverId, Ticket}, ZeroPaddingReader, @@ -66,17 +64,32 @@ where Ok((piece_padded_file, piece_info)) } -pub struct Sealer { +pub struct Sealer { porep_config: PoRepConfig, + _sector_shape: PhantomData } -impl Sealer { - pub fn new(seal_proof: RegisteredSealProof) -> Self { - Self { - porep_config: seal_to_config(seal_proof), +#[macro_export] +macro_rules! construct_sealer { + ($seal:expr) => { + match $seal { + primitives::proofs::RegisteredSealProof::StackedDRG2KiBV1P1 => { + $crate::porep::sealer::Sealer:: { + porep_config: $crate::porep::seal_to_config($seal), + _sector_shape: PhantomData, + } + }, + primitives::proofs::RegisteredSealProof::StackedDRG8MiBV1 => { + $crate::porep::sealer::Sealer:: { + porep_config: $crate::porep::seal_to_config($seal), + _sector_shape: PhantomData, + } + } } - } + }; +} +impl Sealer { /// Adds a Piece and padding to already existing sector file and returns how many bytes were written. /// It can return more bytes than the piece size, as it adds padding so a proper Merkle Tree can be created out of the sector. /// You need to supply current pieces which are already in the sector, otherwise they'll be overwritten. @@ -213,7 +226,7 @@ impl Sealer { .map(|p| (*p).into()) .collect::>(); - let p1_output: SealPreCommitPhase1Output = + let p1_output: SealPreCommitPhase1Output = filecoin_proofs::seal_pre_commit_phase1( &self.porep_config, cache_directory, @@ -275,7 +288,7 @@ impl Sealer { .map(filecoin_proofs::PieceInfo::from) .collect::>(); - let scp1: filecoin_proofs::SealCommitPhase1Output = + let scp1: filecoin_proofs::SealCommitPhase1Output = filecoin_proofs::seal_commit_phase1_inner( &self.porep_config, cache_path, @@ -318,12 +331,12 @@ impl Sealer { }; let compound_public_params = - as CompoundProof< - StackedDrg<'_, SectorShapeBase, DefaultPieceHasher>, + as CompoundProof< + StackedDrg<'_, SectorShape, DefaultPieceHasher>, _, >>::setup(&compound_setup_params)?; - let groth_proofs = StackedCompound::::circuit_proofs( + let groth_proofs = StackedCompound::::circuit_proofs( &public_inputs, vanilla_proofs, &compound_public_params.vanilla_params, @@ -446,7 +459,9 @@ mod test { // Biggest possible piece size #[case(vec![2048])] fn padding_for_sector(#[case] piece_sizes: Vec) { - let sealer = Sealer::new(RegisteredSealProof::StackedDRG2KiBV1P1); + use primitives::proofs::RegisteredSealProof; + + let sealer = construct_sealer!(RegisteredSealProof::StackedDRG2KiBV1P1); let piece_infos: Vec<(Cursor>, PieceInfo)> = piece_sizes .into_iter() From f76da644d1e94066ec2d4d74012a1d7fe094de70 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Mon, 27 Jan 2025 23:12:05 +0100 Subject: [PATCH 03/13] fix: get rid of the macro --- lib/polka-storage-proofs/src/porep/sealer.rs | 39 +++++++++----------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/polka-storage-proofs/src/porep/sealer.rs b/lib/polka-storage-proofs/src/porep/sealer.rs index 69cd85e35..d7fe7a0a7 100644 --- a/lib/polka-storage-proofs/src/porep/sealer.rs +++ b/lib/polka-storage-proofs/src/porep/sealer.rs @@ -5,19 +5,18 @@ use bellperson::groth16; use blstrs::Bls12; use filecoin_hashers::Domain; use filecoin_proofs::{ - add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, SealPreCommitOutput, SealPreCommitPhase1Output, UnpaddedBytesAmount + add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, SealPreCommitOutput, SealPreCommitPhase1Output, SectorShape2KiB, SectorShape8MiB, UnpaddedBytesAmount }; use primitives::{ commitment::{ piece::{PaddedPieceSize, PieceInfo}, CommD, CommP, CommR, Commitment, - }, - sector::SectorNumber, + }, proofs::RegisteredSealProof, sector::SectorNumber }; use storage_proofs_core::{compound_proof, compound_proof::CompoundProof}; use storage_proofs_porep::stacked::{self, StackedCompound, StackedDrg}; -use super::PoRepError; +use super::{seal_to_config, PoRepError}; use crate::{ types::{ProverId, Ticket}, ZeroPaddingReader, @@ -69,24 +68,22 @@ pub struct Sealer { _sector_shape: PhantomData } -#[macro_export] -macro_rules! construct_sealer { - ($seal:expr) => { - match $seal { - primitives::proofs::RegisteredSealProof::StackedDRG2KiBV1P1 => { - $crate::porep::sealer::Sealer:: { - porep_config: $crate::porep::seal_to_config($seal), - _sector_shape: PhantomData, - } - }, - primitives::proofs::RegisteredSealProof::StackedDRG8MiBV1 => { - $crate::porep::sealer::Sealer:: { - porep_config: $crate::porep::seal_to_config($seal), - _sector_shape: PhantomData, - } + +pub fn select_sealer(seal: RegisteredSealProof) -> Sealer { + match seal { + RegisteredSealProof::StackedDRG2KiBV1P1 => { + Sealer:: { + porep_config: seal_to_config(seal), + _sector_shape: PhantomData, + } + }, + RegisteredSealProof::StackedDRG8MiBV1 => { + Sealer:: { + porep_config: seal_to_config(seal), + _sector_shape: PhantomData, } } - }; + } } impl Sealer { @@ -461,7 +458,7 @@ mod test { fn padding_for_sector(#[case] piece_sizes: Vec) { use primitives::proofs::RegisteredSealProof; - let sealer = construct_sealer!(RegisteredSealProof::StackedDRG2KiBV1P1); + let sealer = select_sealer(RegisteredSealProof::StackedDRG2KiBV1P1); let piece_infos: Vec<(Cursor>, PieceInfo)> = piece_sizes .into_iter() From 2dec2d447b8afb6779c40004e3f18df3841b1e1f Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Tue, 28 Jan 2025 12:33:33 +0100 Subject: [PATCH 04/13] execute PoSt dependant on the sector size --- lib/polka-storage-proofs/src/post/mod.rs | 61 ++++++++++++++++-------- pallets/proofs/src/porep/config.rs | 3 ++ 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/lib/polka-storage-proofs/src/post/mod.rs b/lib/polka-storage-proofs/src/post/mod.rs index 7ea5e528a..fc9f1a06b 100644 --- a/lib/polka-storage-proofs/src/post/mod.rs +++ b/lib/polka-storage-proofs/src/post/mod.rs @@ -3,8 +3,7 @@ use std::{collections::BTreeMap, path::PathBuf}; use bellperson::groth16; use blstrs::Bls12; use filecoin_proofs::{ - as_safe_commitment, parameters::window_post_setup_params, PoStType, PrivateReplicaInfo, - SectorShapeBase, + as_safe_commitment, parameters::window_post_setup_params, PoStType, PrivateReplicaInfo, SectorShape2KiB, SectorShape8MiB, SectorShapeBase }; use primitives::{proofs::RegisteredPoStProof, sector::SectorNumber}; use rand::rngs::OsRng; @@ -68,25 +67,14 @@ pub fn generate_window_post( prover_id: ProverId, partition_replicas: Vec, ) -> Result>, PoStError> { - type Tree = SectorShapeBase; - let post_config = seal_to_config(proof_type); - let mut replicas = BTreeMap::new(); - for replica in partition_replicas { - replicas.insert( - storage_proofs_core::sector::SectorId::from(u64::from(replica.sector_id)), - PrivateReplicaInfo::::new( - replica.replica_path, - replica.comm_r, - replica.cache_path, - )?, - ); - } + let randomness_safe = as_safe_commitment(&randomness, "randomness")?; let prover_id_safe = as_safe_commitment(&prover_id, "prover_id")?; let vanilla_params = window_post_setup_params(&post_config); - let partitions = get_partitions_for_window_post(replicas.len(), post_config.sector_count); + // ASSUMPTION: there are no duplicates in `partition_replicas`, if there are there is a heavy bug upstream. + let partitions = get_partitions_for_window_post(partition_replicas.len(), post_config.sector_count); let sector_count = vanilla_params.sector_count; let setup_params = compound_proof::SetupParams { @@ -95,8 +83,43 @@ pub fn generate_window_post( priority: post_config.priority, }; - let pub_params: compound_proof::PublicParams<'_, FallbackPoSt<'_, Tree>> = - FallbackPoStCompound::setup(&setup_params)?; + let (pub_params, replicas) = match proof_type { + RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => { + let pub_params: compound_proof::PublicParams<'_, FallbackPoSt<'_, SectorShape2KiB>> = + FallbackPoStCompound::setup(&setup_params)?; + + let mut replicas = BTreeMap::new(); + for replica in partition_replicas { + replicas.insert( + storage_proofs_core::sector::SectorId::from(u64::from(replica.sector_id)), + PrivateReplicaInfo::::new( + replica.replica_path, + replica.comm_r, + replica.cache_path, + )?, + ); + } + (pub_params, replicas) + }, + RegisteredPoStProof::StackedDRGWindow8MiBV1 => { + let pub_params: compound_proof::PublicParams<'_, FallbackPoSt<'_, SectorShape8MiB>> = + FallbackPoStCompound::setup(&setup_params)?; + + let mut replicas = BTreeMap::new(); + for replica in partition_replicas { + replicas.insert( + storage_proofs_core::sector::SectorId::from(u64::from(replica.sector_id)), + PrivateReplicaInfo::::new( + replica.replica_path, + replica.comm_r, + replica.cache_path, + )?, + ); + } + (pub_params, replicas) + } + }; + let trees: Vec<_> = replicas .values() @@ -129,7 +152,7 @@ pub fn generate_window_post( k: None, }; - let priv_inputs = fallback::PrivateInputs:: { + let priv_inputs = fallback::PrivateInputs::<_> { sectors: &priv_sectors, }; diff --git a/pallets/proofs/src/porep/config.rs b/pallets/proofs/src/porep/config.rs index 1bb57014c..d77d6a25e 100644 --- a/pallets/proofs/src/porep/config.rs +++ b/pallets/proofs/src/porep/config.rs @@ -117,6 +117,7 @@ pub fn porep_id(seal_proof: RegisteredSealProof) -> PoRepID { fn proof_id(seal_proof: RegisteredSealProof) -> u64 { match seal_proof { RegisteredSealProof::StackedDRG2KiBV1P1 => 0, + RegisteredSealProof::StackedDRG8MiBV1 => 1, } } @@ -125,6 +126,7 @@ fn proof_id(seal_proof: RegisteredSealProof) -> u64 { fn partitions(seal_proof: RegisteredSealProof) -> usize { match seal_proof { RegisteredSealProof::StackedDRG2KiBV1P1 => 1, + RegisteredSealProof::StackedDRG8MiBV1 => 1, } } @@ -133,6 +135,7 @@ fn partitions(seal_proof: RegisteredSealProof) -> usize { fn minimum_challenges(seal_proof: RegisteredSealProof) -> usize { match seal_proof { RegisteredSealProof::StackedDRG2KiBV1P1 => 2, + RegisteredSealProof::StackedDRG8MiBV1 => 2, } } From e531d8096937412a7d7a913610a09f098e3cf3d4 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Tue, 28 Jan 2025 14:04:38 +0100 Subject: [PATCH 05/13] fix: use select sealer and 8MiB sectors in real_world --- maat/tests/real_world.rs | 13 ++++++------- storage-provider/client/src/commands/proofs.rs | 4 ++-- storage-provider/common/src/sector.rs | 9 +++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/maat/tests/real_world.rs b/maat/tests/real_world.rs index d187e939b..bced8604c 100644 --- a/maat/tests/real_world.rs +++ b/maat/tests/real_world.rs @@ -7,8 +7,7 @@ use maat::*; use polka_storage_proofs::{porep, post}; use polka_storage_provider_common::{deadline::Deadline, sector::UnsealedSector}; use primitives::{ - commitment::{CommP, Commitment}, - sector::{SectorNumber, SectorSize}, + commitment::{CommP, Commitment}, proofs::RegisteredPoStProof, sector::{SectorNumber, SectorSize} }; use storagext::{ clients::ProofsClientExt, @@ -30,7 +29,7 @@ use zombienet_sdk::NetworkConfigExt; /// Network's collator name. Used for logs and so on. const COLLATOR_NAME: &str = "collator"; -async fn register_storage_provider(client: &storagext::Client, charlie: &Keypair) +async fn register_storage_provider(client: &storagext::Client, charlie: &Keypair, post_proof: RegisteredPoStProof) where Keypair: subxt::tx::Signer, { @@ -40,7 +39,7 @@ where .register_storage_provider( charlie, peer_id, - primitives::proofs::RegisteredPoStProof::StackedDRGWindow2KiBV1P1, + post_proof, true, ) .await @@ -282,7 +281,7 @@ async fn real_world_use_case() { tracing::info!("generating PoRep parameters..."); // NOTE: it can take 1-2 minutes on slower machines. can be cached someday, but I think it's good enough for now. - let seal_proof = primitives::proofs::RegisteredSealProof::StackedDRG2KiBV1P1; + let seal_proof = primitives::proofs::RegisteredSealProof::StackedDRG8MiBV1; let porep_parameters = porep::generate_random_groth16_parameters(seal_proof).unwrap(); porep_parameters.write(&mut porep_parameters_file).unwrap(); @@ -290,7 +289,7 @@ async fn real_world_use_case() { let porep_mapped_parameters = porep::load_groth16_parameters(porep_parameters_path).unwrap(); tracing::info!("generating PoSt parameters..."); - let post_proof = primitives::proofs::RegisteredPoStProof::StackedDRGWindow2KiBV1P1; + let post_proof = primitives::proofs::RegisteredPoStProof::StackedDRGWindow8MiBV1; let post_parameters = post::generate_random_groth16_parameters(post_proof).unwrap(); post_parameters.write(&mut post_parameters_file).unwrap(); // We need to read it again, as Proof Generating machine requires it in this form and that's the API of bellperson. @@ -309,7 +308,7 @@ async fn real_world_use_case() { let alice_kp = pair_signer_from_str::("//Alice"); let charlie_kp = pair_signer_from_str::("//Charlie"); - register_storage_provider(&client, &charlie_kp).await; + register_storage_provider(&client, &charlie_kp, post_proof).await; // Set PoRep VerifyingKey extrinsic only accepts scale-encoded bytes of Verifying Key in substrate form. let porep_vk = polka_storage_proofs::VerifyingKey::::try_from(porep_parameters.vk) diff --git a/storage-provider/client/src/commands/proofs.rs b/storage-provider/client/src/commands/proofs.rs index 130b6d343..083e31148 100644 --- a/storage-provider/client/src/commands/proofs.rs +++ b/storage-provider/client/src/commands/proofs.rs @@ -8,7 +8,7 @@ use std::{ use codec::Encode; use mater::CarV2Reader; use polka_storage_proofs::{ - porep::{self, sealer::Sealer}, + porep::{self, sealer::select_sealer}, post::{self, ReplicaInfo}, ZeroPaddingReader, }; @@ -314,7 +314,7 @@ impl ProofsCommand { )?; println!("Creating sector..."); - let sealer = Sealer::new(seal_proof); + let sealer = select_sealer(seal_proof); let piece_infos = sealer .create_sector(vec![(piece_file, piece_info)], unsealed_sector) .map_err(|e| UtilsCommandError::GeneratePoRepError(e))?; diff --git a/storage-provider/common/src/sector.rs b/storage-provider/common/src/sector.rs index c7b6d01f9..41629b6ee 100644 --- a/storage-provider/common/src/sector.rs +++ b/storage-provider/common/src/sector.rs @@ -1,7 +1,7 @@ use std::{path::PathBuf, sync::Arc}; use polka_storage_proofs::porep::{ - sealer::{prepare_piece, BlstrsProof, PreCommitOutput, Sealer, SubstrateProof}, + sealer::{prepare_piece, BlstrsProof, PreCommitOutput, select_sealer, SubstrateProof}, PoRepError, PoRepParameters, }; use primitives::{ @@ -106,7 +106,7 @@ impl UnsealedSector { commitment: Commitment, ) -> Result<(), SectorError> { self.deals.push((deal_id, deal)); - let sealer = Sealer::new(self.seal_proof); + let sealer = select_sealer(self.seal_proof); // would love to use something like scoped spawn blocking let pieces = self.piece_infos.clone(); @@ -138,7 +138,7 @@ impl UnsealedSector { cache_dir_path: PathBuf, sealed_path: PathBuf, ) -> Result { - let sealer: Sealer = Sealer::new(self.seal_proof); + let sealer = select_sealer(self.seal_proof); tokio::fs::create_dir_all(&cache_dir_path).await?; tokio::fs::File::create_new(&sealed_path).await?; @@ -340,7 +340,7 @@ impl PreCommittedSector { // 10 blocks = 1 minute, only testnet const PRECOMMIT_CHALLENGE_DELAY: u64 = 10; - let sealer: Sealer = Sealer::new(self.seal_proof); + let sealer = select_sealer(self.seal_proof); let seal_randomness_height = self.seal_randomness_height; let Some(digest) = xt_client.get_randomness(seal_randomness_height).await? else { @@ -429,6 +429,7 @@ impl PreCommittedSector { } }; + // TODO(@th7nder,28/01/2025): adjust proofs in PoRep for bigger sector sizes // We use sector size 2KiB only at this point, which guarantees to have 1 proof, because it has 1 partition in the config. // That's why `prove_commit` will always generate a 1 proof. let proof: SubstrateProof = proofs[0] From aec745a00eed1e190434f9fe75213ff16ce1ab31 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 29 Jan 2025 11:17:52 +0100 Subject: [PATCH 06/13] fix: update metadata and params --- maat/tests/real_world.rs | 8 ++++---- storagext/lib/artifacts/metadata.scale | Bin 168927 -> 169059 bytes 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maat/tests/real_world.rs b/maat/tests/real_world.rs index bced8604c..ed82450af 100644 --- a/maat/tests/real_world.rs +++ b/maat/tests/real_world.rs @@ -7,7 +7,7 @@ use maat::*; use polka_storage_proofs::{porep, post}; use polka_storage_provider_common::{deadline::Deadline, sector::UnsealedSector}; use primitives::{ - commitment::{CommP, Commitment}, proofs::RegisteredPoStProof, sector::{SectorNumber, SectorSize} + commitment::{CommP, Commitment}, proofs::RegisteredPoStProof, sector::SectorNumber }; use storagext::{ clients::ProofsClientExt, @@ -53,14 +53,14 @@ where let event = event.unwrap(); assert_eq!(event.owner, charlie.account_id().clone().into()); - assert_eq!(event.info.sector_size, SectorSize::_2KiB); + assert_eq!(event.info.sector_size, post_proof.sector_size()); assert_eq!( event.info.window_post_proof_type, - primitives::proofs::RegisteredPoStProof::StackedDRGWindow2KiBV1P1 + post_proof, ); assert_eq!( event.info.window_post_partition_sectors, - primitives::proofs::RegisteredPoStProof::StackedDRGWindow2KiBV1P1 + post_proof .window_post_partitions_sector() ); } diff --git a/storagext/lib/artifacts/metadata.scale b/storagext/lib/artifacts/metadata.scale index 1e1247d1e292b41f7e20556ab6e063393e1b5ec1..d83a4e1071411d9c65e91646237dfc92c917f491 100644 GIT binary patch delta 414 zcmYL@JuE|E6o&6hQKi&BiQ(HM9V8WlL>eOECuoWWgP?l9n|ssde%#wqDlr%cBgxrJ z5=M!H#AMa~)?_j;NGvuB;Wi?+bI$X;dC$|i*WmAIfHDGAmWKqFldc-13DFL>rY9W=W!41xIzQGN)%DK); z0++2>5eDyG@d>{n)`S_1m;o`w{jt@EW~yA4%53i|YrosF85MMz#1hKsD~XqKn=M1% zNwm{v3Sm@`n#L3=={k)ARM9}jGVOGl!2+u3BZGA~NXx>F8am112(`p=7IV^84%4Wk zRL%<2lRJ+9T(p~q4-J&fV*rg*S3ozK$Xh@!n#m|YK?^+=tiD$2Dq;q0v|Yr!^-Hk` M6&*MI4>-H~0mZJ7lK=n! delta 276 zcmXAiJxc-s0ET__`nt-#EDdUD3=)i{mOz4n@UlCxmLkgwMd2z74sIzL654Wj|A0^s zM9^SU8BL+ydFKyksI7vgwxWaH@p*W7UoXX%3-RVuhfpf&W4HIZ;vE$hm4noFPEF6t z3)4&4XfhIyc-+NGRXuPb8x`4rDk06gXS|PZN?Lqh+tmuGd?BGl)%f97K3mABX%B=i z`ZaHmQ#B~?^0 Date: Wed, 29 Jan 2025 13:29:46 +0100 Subject: [PATCH 07/13] fix: use proper config values --- lib/polka-storage-proofs/src/porep/mod.rs | 33 +++----- lib/polka-storage-proofs/src/porep/sealer.rs | 34 +++++---- lib/polka-storage-proofs/src/post/mod.rs | 23 +++--- maat/tests/real_world.rs | 26 +++---- pallets/proofs/src/porep/config.rs | 33 +------- pallets/proofs/src/porep/mod.rs | 80 ++++++++++++++------ primitives/src/proofs.rs | 32 ++++++++ storage-provider/common/src/sector.rs | 2 +- 8 files changed, 142 insertions(+), 121 deletions(-) diff --git a/lib/polka-storage-proofs/src/porep/mod.rs b/lib/polka-storage-proofs/src/porep/mod.rs index 7e9c527f4..9524c6343 100644 --- a/lib/polka-storage-proofs/src/porep/mod.rs +++ b/lib/polka-storage-proofs/src/porep/mod.rs @@ -5,7 +5,7 @@ pub mod sealer; use bellperson::groth16; use blstrs::Bls12; -use filecoin_proofs::{DefaultPieceHasher, SectorShapeBase, SECTOR_SIZE_2_KIB, SECTOR_SIZE_8_MIB}; +use filecoin_proofs::{DefaultPieceHasher, SectorShapeBase}; use primitives::proofs::RegisteredSealProof; use rand::rngs::OsRng; use storage_proofs_core::{compound_proof::CompoundProof, proof::ProofScheme}; @@ -26,7 +26,8 @@ pub fn generate_random_groth16_parameters( let circuit = match seal_proof { RegisteredSealProof::StackedDRG2KiBV1P1 | RegisteredSealProof::StackedDRG8MiBV1 => { - let public_params = StackedDrg::::setup(&setup_params)?; + let public_params = + StackedDrg::::setup(&setup_params)?; storage_proofs_porep::stacked::StackedCompound::< SectorShapeBase, DefaultPieceHasher, @@ -65,26 +66,10 @@ pub enum PoRepError { } fn seal_to_config(seal_proof: RegisteredSealProof) -> filecoin_proofs::PoRepConfig { - match seal_proof { - RegisteredSealProof::StackedDRG2KiBV1P1 => { - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L308 - let sector_size = SECTOR_SIZE_2_KIB; - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L292 - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L52 - let porep_id = [0u8; 32]; - let api_version = storage_proofs_core::api_version::ApiVersion::V1_2_0; - - filecoin_proofs::PoRepConfig::new_groth16(sector_size, porep_id, api_version) - } - RegisteredSealProof::StackedDRG8MiBV1 => { - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L308 - let sector_size = SECTOR_SIZE_8_MIB; - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L292 - // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L52 - let porep_id = [1u8; 32]; - let api_version = storage_proofs_core::api_version::ApiVersion::V1_2_0; - - filecoin_proofs::PoRepConfig::new_groth16(sector_size, porep_id, api_version) - }, - } + let api_version = storage_proofs_core::api_version::ApiVersion::V1_2_0; + filecoin_proofs::PoRepConfig::new_groth16( + seal_proof.sector_size().bytes(), + seal_proof.porep_id(), + api_version, + ) } diff --git a/lib/polka-storage-proofs/src/porep/sealer.rs b/lib/polka-storage-proofs/src/porep/sealer.rs index d7fe7a0a7..473772f12 100644 --- a/lib/polka-storage-proofs/src/porep/sealer.rs +++ b/lib/polka-storage-proofs/src/porep/sealer.rs @@ -5,13 +5,18 @@ use bellperson::groth16; use blstrs::Bls12; use filecoin_hashers::Domain; use filecoin_proofs::{ - add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, SealPreCommitOutput, SealPreCommitPhase1Output, SectorShape2KiB, SectorShape8MiB, UnpaddedBytesAmount + add_piece, as_safe_commitment, parameters::setup_params, DefaultPieceDomain, + DefaultPieceHasher, PaddedBytesAmount, PoRepConfig, SealCommitPhase1Output, + SealPreCommitOutput, SealPreCommitPhase1Output, SectorShape2KiB, SectorShape8MiB, + UnpaddedBytesAmount, }; use primitives::{ commitment::{ piece::{PaddedPieceSize, PieceInfo}, CommD, CommP, CommR, Commitment, - }, proofs::RegisteredSealProof, sector::SectorNumber + }, + proofs::RegisteredSealProof, + sector::SectorNumber, }; use storage_proofs_core::{compound_proof, compound_proof::CompoundProof}; use storage_proofs_porep::stacked::{self, StackedCompound, StackedDrg}; @@ -65,24 +70,21 @@ where } pub struct Sealer { porep_config: PoRepConfig, - _sector_shape: PhantomData + _sector_shape: PhantomData, } - -pub fn select_sealer(seal: RegisteredSealProof) -> Sealer { +pub fn select_sealer( + seal: RegisteredSealProof, +) -> Sealer { match seal { - RegisteredSealProof::StackedDRG2KiBV1P1 => { - Sealer:: { - porep_config: seal_to_config(seal), - _sector_shape: PhantomData, - } + RegisteredSealProof::StackedDRG2KiBV1P1 => Sealer:: { + porep_config: seal_to_config(seal), + _sector_shape: PhantomData, + }, + RegisteredSealProof::StackedDRG8MiBV1 => Sealer:: { + porep_config: seal_to_config(seal), + _sector_shape: PhantomData, }, - RegisteredSealProof::StackedDRG8MiBV1 => { - Sealer:: { - porep_config: seal_to_config(seal), - _sector_shape: PhantomData, - } - } } } diff --git a/lib/polka-storage-proofs/src/post/mod.rs b/lib/polka-storage-proofs/src/post/mod.rs index fc9f1a06b..6883932ad 100644 --- a/lib/polka-storage-proofs/src/post/mod.rs +++ b/lib/polka-storage-proofs/src/post/mod.rs @@ -3,7 +3,8 @@ use std::{collections::BTreeMap, path::PathBuf}; use bellperson::groth16; use blstrs::Bls12; use filecoin_proofs::{ - as_safe_commitment, parameters::window_post_setup_params, PoStType, PrivateReplicaInfo, SectorShape2KiB, SectorShape8MiB, SectorShapeBase + as_safe_commitment, parameters::window_post_setup_params, PoStType, PrivateReplicaInfo, + SectorShape2KiB, SectorShape8MiB, SectorShapeBase, }; use primitives::{proofs::RegisteredPoStProof, sector::SectorNumber}; use rand::rngs::OsRng; @@ -28,9 +29,11 @@ pub fn generate_random_groth16_parameters( let post_config = seal_to_config(seal_proof); let circuit = match seal_proof { - RegisteredPoStProof::StackedDRGWindow2KiBV1P1 | RegisteredPoStProof::StackedDRGWindow8MiBV1 => { - let public_params = - filecoin_proofs::parameters::window_post_public_params::(&post_config)?; + RegisteredPoStProof::StackedDRGWindow2KiBV1P1 + | RegisteredPoStProof::StackedDRGWindow8MiBV1 => { + let public_params = filecoin_proofs::parameters::window_post_public_params::< + SectorShapeBase, + >(&post_config)?; storage_proofs_post::fallback::FallbackPoStCompound::::blank_circuit( &public_params, ) @@ -74,7 +77,8 @@ pub fn generate_window_post( let vanilla_params = window_post_setup_params(&post_config); // ASSUMPTION: there are no duplicates in `partition_replicas`, if there are there is a heavy bug upstream. - let partitions = get_partitions_for_window_post(partition_replicas.len(), post_config.sector_count); + let partitions = + get_partitions_for_window_post(partition_replicas.len(), post_config.sector_count); let sector_count = vanilla_params.sector_count; let setup_params = compound_proof::SetupParams { @@ -86,7 +90,7 @@ pub fn generate_window_post( let (pub_params, replicas) = match proof_type { RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => { let pub_params: compound_proof::PublicParams<'_, FallbackPoSt<'_, SectorShape2KiB>> = - FallbackPoStCompound::setup(&setup_params)?; + FallbackPoStCompound::setup(&setup_params)?; let mut replicas = BTreeMap::new(); for replica in partition_replicas { @@ -100,10 +104,10 @@ pub fn generate_window_post( ); } (pub_params, replicas) - }, + } RegisteredPoStProof::StackedDRGWindow8MiBV1 => { let pub_params: compound_proof::PublicParams<'_, FallbackPoSt<'_, SectorShape8MiB>> = - FallbackPoStCompound::setup(&setup_params)?; + FallbackPoStCompound::setup(&setup_params)?; let mut replicas = BTreeMap::new(); for replica in partition_replicas { @@ -120,7 +124,6 @@ pub fn generate_window_post( } }; - let trees: Vec<_> = replicas .values() .map(|replica| replica.merkle_tree(post_config.sector_size)) @@ -186,7 +189,7 @@ fn seal_to_config(seal_proof: RegisteredPoStProof) -> filecoin_proofs::PoStConfi priority: true, api_version: storage_proofs_core::api_version::ApiVersion::V1_2_0, } - }, + } } } diff --git a/maat/tests/real_world.rs b/maat/tests/real_world.rs index ed82450af..4c6706245 100644 --- a/maat/tests/real_world.rs +++ b/maat/tests/real_world.rs @@ -7,7 +7,9 @@ use maat::*; use polka_storage_proofs::{porep, post}; use polka_storage_provider_common::{deadline::Deadline, sector::UnsealedSector}; use primitives::{ - commitment::{CommP, Commitment}, proofs::RegisteredPoStProof, sector::SectorNumber + commitment::{CommP, Commitment}, + proofs::RegisteredPoStProof, + sector::SectorNumber, }; use storagext::{ clients::ProofsClientExt, @@ -29,19 +31,17 @@ use zombienet_sdk::NetworkConfigExt; /// Network's collator name. Used for logs and so on. const COLLATOR_NAME: &str = "collator"; -async fn register_storage_provider(client: &storagext::Client, charlie: &Keypair, post_proof: RegisteredPoStProof) -where +async fn register_storage_provider( + client: &storagext::Client, + charlie: &Keypair, + post_proof: RegisteredPoStProof, +) where Keypair: subxt::tx::Signer, { let peer_id = PeerId::random(); let result = client - .register_storage_provider( - charlie, - peer_id, - post_proof, - true, - ) + .register_storage_provider(charlie, peer_id, post_proof, true) .await .unwrap() .unwrap(); @@ -54,14 +54,10 @@ where assert_eq!(event.owner, charlie.account_id().clone().into()); assert_eq!(event.info.sector_size, post_proof.sector_size()); - assert_eq!( - event.info.window_post_proof_type, - post_proof, - ); + assert_eq!(event.info.window_post_proof_type, post_proof,); assert_eq!( event.info.window_post_partition_sectors, - post_proof - .window_post_partitions_sector() + post_proof.window_post_partitions_sector() ); } diff --git a/pallets/proofs/src/porep/config.rs b/pallets/proofs/src/porep/config.rs index d77d6a25e..9c31b0c75 100644 --- a/pallets/proofs/src/porep/config.rs +++ b/pallets/proofs/src/porep/config.rs @@ -67,7 +67,7 @@ impl Config { pub fn new(seal_proof: RegisteredSealProof) -> Self { let partitions = partitions(seal_proof); Self { - porep_id: porep_id(seal_proof), + porep_id: seal_proof.porep_id(), // PRE-COND: sector size must be divisible by 32 nodes: (seal_proof.sector_size().bytes() / 32) as usize, challenges: InteractiveChallenges::new(partitions, minimum_challenges(seal_proof)), @@ -90,37 +90,6 @@ impl Config { } } -/// References: -/// * -fn nonce(seal_proof: RegisteredSealProof) -> u64 { - #[allow(clippy::match_single_binding)] - match seal_proof { - // If we ever need to change the nonce for any given RegisteredSealProof, match it here. - _ => 0, - } -} - -/// References: -/// * -pub fn porep_id(seal_proof: RegisteredSealProof) -> PoRepID { - let mut porep_id = [0; 32]; - let registered_proof_id = proof_id(seal_proof); - let n = nonce(seal_proof); - - porep_id[0..8].copy_from_slice(®istered_proof_id.to_le_bytes()); - porep_id[8..16].copy_from_slice(&n.to_le_bytes()); - porep_id -} - -/// Reference: -/// * -fn proof_id(seal_proof: RegisteredSealProof) -> u64 { - match seal_proof { - RegisteredSealProof::StackedDRG2KiBV1P1 => 0, - RegisteredSealProof::StackedDRG8MiBV1 => 1, - } -} - /// Reference: /// * fn partitions(seal_proof: RegisteredSealProof) -> usize { diff --git a/pallets/proofs/src/porep/mod.rs b/pallets/proofs/src/porep/mod.rs index de0c82e31..fb14ce8f3 100644 --- a/pallets/proofs/src/porep/mod.rs +++ b/pallets/proofs/src/porep/mod.rs @@ -254,6 +254,7 @@ fn generate_inclusion_input(challenge: usize) -> Fr { #[cfg(test)] mod tests { + use filecoin_proofs::{MerkleTreeTrait, SectorShape2KiB, SectorShape8MiB}; use primitives::{proofs::RegisteredSealProof, sector::SectorNumber}; use super::{ProofScheme, PublicInputs, Tau}; @@ -270,22 +271,61 @@ mod tests { let comm_d = [15u8; 32]; let comm_r = [151u8; 32]; - let inputs = - ported_generate_public_inputs(&prover_id, sector_id, &ticket, &seed, &comm_d, &comm_r); - let reference_inputs = - reference_generate_public_inputs(prover_id, sector_id, ticket, seed, comm_d, comm_r); + let seal_proof = RegisteredSealProof::StackedDRG2KiBV1P1; + let inputs = ported_generate_public_inputs( + seal_proof, &prover_id, sector_id, &ticket, &seed, &comm_d, &comm_r, + ); + let reference_inputs = reference_generate_public_inputs::( + seal_proof, prover_id, sector_id, ticket, seed, comm_d, comm_r, + ); assert_eq!(reference_inputs.len(), inputs.len()); for index in 0..reference_inputs.len() { // blstrs is based on bls12_381 implementation, so we can compare serialized bytes. assert_eq!( reference_inputs[index].to_bytes_le(), - inputs[index].to_bytes() + inputs[index].to_bytes(), + "failed to compare reference inputs at idx {}", + index + ); + } + } + + #[test] + /// References: + /// * + fn generates_public_inputs_the_same_as_reference_impl_8mib_sector() { + // random numbers, not 0 + let prover_id = [77u8; 32]; + let sector_id = SectorNumber::new(123).unwrap(); + let ticket = [10u8; 32]; + let seed = [10u8; 32]; + let comm_d = [15u8; 32]; + let comm_r = [151u8; 32]; + + let seal_proof = RegisteredSealProof::StackedDRG8MiBV1; + + let inputs = ported_generate_public_inputs( + seal_proof, &prover_id, sector_id, &ticket, &seed, &comm_d, &comm_r, + ); + let reference_inputs = reference_generate_public_inputs::( + seal_proof, prover_id, sector_id, ticket, seed, comm_d, comm_r, + ); + + assert_eq!(reference_inputs.len(), inputs.len()); + for index in 0..reference_inputs.len() { + // blstrs is based on bls12_381 implementation, so we can compare serialized bytes. + assert_eq!( + reference_inputs[index].to_bytes_le(), + inputs[index].to_bytes(), + "failed to compare reference inputs at idx {}", + index ); } } fn ported_generate_public_inputs( + seal_proof: RegisteredSealProof, prover_id: &[u8; 32], sector_id: SectorNumber, ticket: &[u8; 32], @@ -293,7 +333,7 @@ mod tests { comm_d: &[u8; 32], comm_r: &[u8; 32], ) -> Vec { - let proof_scheme = ProofScheme::setup(RegisteredSealProof::StackedDRG2KiBV1P1); + let proof_scheme = ProofScheme::setup(seal_proof); let replica_id = proof_scheme.generate_replica_id(prover_id, sector_id, ticket, comm_d); // `bytes_into_fr_repr_safe` makes sure random values are convertable into Fr let comm_d_fr = @@ -315,7 +355,8 @@ mod tests { .unwrap() } - fn reference_generate_public_inputs( + fn reference_generate_public_inputs( + seal_proof: RegisteredSealProof, prover_id: [u8; 32], sector_id: SectorNumber, ticket: [u8; 32], @@ -323,11 +364,10 @@ mod tests { comm_d: [u8; 32], comm_r: [u8; 32], ) -> Vec { - use filecoin_hashers::{poseidon::PoseidonHasher, sha256::Sha256Hasher}; - use generic_array::typenum::{U0, U8}; + use filecoin_hashers::sha256::Sha256Hasher; use storage_proofs_core::{ api_version::ApiVersion, compound_proof::CompoundProof, drgraph::BASE_DEGREE, - merkle::LCTree, proof::ProofScheme, util::NODE_SIZE, + proof::ProofScheme, util::NODE_SIZE, }; use storage_proofs_porep::stacked::{ generate_replica_id, Challenges, PublicInputs, SetupParams, StackedCompound, @@ -335,14 +375,13 @@ mod tests { }; // https://github.com/filecoin-project/rust-fil-proofs/blob/5a0523ae1ddb73b415ce2fa819367c7989aaf73f/filecoin-proofs/src/constants.rs#L192C28-L192C66 - type SectorShapeBase = LCTree; let setup_params = SetupParams { // https://github.com/filecoin-project/rust-fil-proofs/blob/5a0523ae1ddb73b415ce2fa819367c7989aaf73f/filecoin-proofs/src/constants.rs#L18 - nodes: (1 << 11) / NODE_SIZE, + nodes: (seal_proof.sector_size().bytes() / NODE_SIZE as u64) as usize, degree: BASE_DEGREE, expansion_degree: EXP_DEGREE, // https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/b44e7cecf2a120aa266b6886628e869ba67252af/src/registry.rs#L53 - porep_id: [0u8; 32], + porep_id: seal_proof.porep_id(), // https://github.com/filecoin-project/rust-fil-proofs/blob/5a0523ae1ddb73b415ce2fa819367c7989aaf73f/filecoin-proofs/src/constants.rs#L123 challenges: Challenges::new_interactive(2), // https://github.com/filecoin-project/rust-fil-proofs/blob/5a0523ae1ddb73b415ce2fa819367c7989aaf73f/filecoin-proofs/src/constants.rs#L84 @@ -351,25 +390,20 @@ mod tests { api_features: vec![], }; - let public_params = - StackedDrg::::setup(&setup_params).unwrap(); - let porep_id = [0u8; 32]; + let public_params = StackedDrg::::setup(&setup_params).unwrap(); - let replica_id = generate_replica_id::( + let replica_id = generate_replica_id::<::Hasher, _>( &prover_id, sector_id.into(), &ticket, comm_d, - &porep_id, + &seal_proof.porep_id(), ); let comm_r_safe = fr32::bytes_into_fr_repr_safe(&comm_r).into(); let comm_d_safe = fr32::bytes_into_fr_repr_safe(&comm_d).into(); - let public_inputs = PublicInputs::< - ::Domain, - ::Domain, - > { + let public_inputs = PublicInputs { replica_id, tau: Some(Tau { comm_d: comm_d_safe, @@ -379,7 +413,7 @@ mod tests { k: None, }; - StackedCompound::::generate_public_inputs( + StackedCompound::::generate_public_inputs( &public_inputs, &public_params, None, diff --git a/primitives/src/proofs.rs b/primitives/src/proofs.rs index 4c0853f66..f08f240dc 100644 --- a/primitives/src/proofs.rs +++ b/primitives/src/proofs.rs @@ -88,6 +88,38 @@ impl RegisteredSealProof { } } + /// Byte identifier used to generate the replica. + /// References: + /// * + pub fn porep_id(&self) -> [u8; 32] { + let mut porep_id = [0; 32]; + let registered_proof_id = self.proof_id(); + let n = self.nonce(); + + porep_id[0..8].copy_from_slice(®istered_proof_id.to_le_bytes()); + porep_id[8..16].copy_from_slice(&n.to_le_bytes()); + porep_id + } + + /// References: + /// * + fn nonce(&self) -> u64 { + #[allow(clippy::match_single_binding)] + match self { + // If we ever need to change the nonce for any given RegisteredSealProof, match it here. + _ => 0, + } + } + + /// Reference: + /// * + fn proof_id(&self) -> u64 { + match self { + RegisteredSealProof::StackedDRG2KiBV1P1 => 0, + RegisteredSealProof::StackedDRG8MiBV1 => 1, + } + } + /// Returns [`StackedDRG2KiBV1P1`](RegisteredSealProof::StackedDRG2KiBV1P1). // NOTE(@jmg-duarte,14/01/2025): wanted to avoid setting a default to use in serde // this is the alternative diff --git a/storage-provider/common/src/sector.rs b/storage-provider/common/src/sector.rs index 41629b6ee..9edca9e9f 100644 --- a/storage-provider/common/src/sector.rs +++ b/storage-provider/common/src/sector.rs @@ -1,7 +1,7 @@ use std::{path::PathBuf, sync::Arc}; use polka_storage_proofs::porep::{ - sealer::{prepare_piece, BlstrsProof, PreCommitOutput, select_sealer, SubstrateProof}, + sealer::{prepare_piece, select_sealer, BlstrsProof, PreCommitOutput, SubstrateProof}, PoRepError, PoRepParameters, }; use primitives::{ From 0fe221eceac79d0d33e14ff83e77f7bcc692a326 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 30 Jan 2025 11:11:29 +0100 Subject: [PATCH 08/13] fix: make car reading consistent again --- Cargo.lock | 1 + examples/big_file_184k.car | Bin 0 -> 185459 bytes maat/tests/real_world.rs | 17 +++--- .../client/src/commands/proofs.rs | 18 ++----- storage-provider/common/Cargo.toml | 3 ++ storage-provider/common/src/commp.rs | 50 +++++++++++++++++- storage-provider/server/src/storage.rs | 17 ++---- 7 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 examples/big_file_184k.car diff --git a/Cargo.lock b/Cargo.lock index f3450caad..84cff591a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13897,6 +13897,7 @@ dependencies = [ "chrono", "cid 0.11.1", "filecoin-hashers", + "filecoin-proofs", "fr32", "hex", "jsonrpsee 0.24.7", diff --git a/examples/big_file_184k.car b/examples/big_file_184k.car new file mode 100644 index 0000000000000000000000000000000000000000..d20b96081cba6ef607b3c1a1f0b9c49c1584f774 GIT binary patch literal 185459 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�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

a~>KaBWgsMbM=W)D=JF2ip_zOG-^ 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

1BI{9ODsw3r@y)l{?+Zwo1 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 literal 0 HcmV?d00001 diff --git a/maat/tests/real_world.rs b/maat/tests/real_world.rs index 4c6706245..92e9f8b2e 100644 --- a/maat/tests/real_world.rs +++ b/maat/tests/real_world.rs @@ -1,13 +1,11 @@ use std::{collections::BTreeSet, env, path::Path, sync::Arc, time::Duration}; -use cid::Cid; use codec::Encode; use libp2p::PeerId; use maat::*; use polka_storage_proofs::{porep, post}; -use polka_storage_provider_common::{deadline::Deadline, sector::UnsealedSector}; +use polka_storage_provider_common::{commp::commp, deadline::Deadline, sector::UnsealedSector}; use primitives::{ - commitment::{CommP, Commitment}, proofs::RegisteredPoStProof, sector::SectorNumber, }; @@ -263,7 +261,7 @@ async fn real_world_use_case() { let workspace_root = env::var("CARGO_MANIFEST_DIR").unwrap(); let data_file_path = Path::new(&workspace_root) .join("..") - .join("examples/test-data-big.car"); + .join("examples/big_file_184k.car"); tracing::info!("loading example file from {:?}", data_file_path); let temp_dir = tempdir().unwrap(); @@ -341,17 +339,14 @@ async fn real_world_use_case() { tracing::debug!("adding {} balance to alice", balance); add_balance(&client, &alice_kp, balance).await; - // Valid piece cid of `examples/test-data-big.car`. - // Calculated with executing `polka-storage-provider-client proofs commp examples/test-data-big.car`. - let piece_cid = - Cid::try_from("baga6ea4seaqbfhdvmk5qygevit25ztjwl7voyikb5k2fqcl2lsuefhaqtukuiii").unwrap(); - let commp = Commitment::::from_cid(&piece_cid).unwrap(); + let (commp, piece_size) = commp(&data_file_path).unwrap(); + tracing::debug!("piece_size of {} = {}", data_file_path.display(), *piece_size); let sector_end_block = 165; // Publish a storage deal let deal = DealProposal { - piece_cid, - piece_size: 2048, + piece_cid: commp.cid(), + piece_size: *piece_size, client: alice_kp.account_id().clone(), provider: charlie_kp.account_id().clone(), label: "My lovely big data".to_string(), diff --git a/storage-provider/client/src/commands/proofs.rs b/storage-provider/client/src/commands/proofs.rs index 083e31148..032b37774 100644 --- a/storage-provider/client/src/commands/proofs.rs +++ b/storage-provider/client/src/commands/proofs.rs @@ -12,7 +12,7 @@ use polka_storage_proofs::{ post::{self, ReplicaInfo}, ZeroPaddingReader, }; -use polka_storage_provider_common::commp::{calculate_piece_commitment, CommPError}; +use polka_storage_provider_common::commp::{calculate_piece_commitment, commp, CommPError}; use primitives::{ commitment::{ piece::{PaddedPieceSize, PieceInfo}, @@ -157,20 +157,8 @@ impl ProofsCommand { .map_err(|e| UtilsCommandError::InvalidCARv2(input_path.clone(), e))?; // Calculate the piece commitment. - let source_file = File::open(&input_path)?; - let file_size = source_file.metadata()?.len(); - - let buffered = BufReader::new(source_file); - let padded_piece_size = PaddedPieceSize::from_arbitrary_size(file_size as u64); - let mut zero_padding_reader = ZeroPaddingReader::new(buffered, *padded_piece_size); - - // The calculate_piece_commitment blocks the thread. We could - // use tokio::task::spawn_blocking to avoid this, but in this - // case it doesn't matter because this is the only thing we are - // working on. - let commitment = - calculate_piece_commitment(&mut zero_padding_reader, padded_piece_size) - .map_err(|err| UtilsCommandError::CommPError(err))?; + let commitment = commp(&input_path) + .map_err(|err| UtilsCommandError::CommPError(err))?; let cid = commitment.cid(); // NOTE(@jmg-duarte,09/10/2024): too lazy for proper json diff --git a/storage-provider/common/Cargo.toml b/storage-provider/common/Cargo.toml index 42559d5ef..308319abb 100644 --- a/storage-provider/common/Cargo.toml +++ b/storage-provider/common/Cargo.toml @@ -29,5 +29,8 @@ tokio = { workspace = true, features = ["fs"] } tokio-util = { workspace = true, features = ["rt"] } tracing = { workspace = true } +[dev-dependencies] +filecoin-proofs.workspace = true + [lints] workspace = true diff --git a/storage-provider/common/src/commp.rs b/storage-provider/common/src/commp.rs index b201f773c..049e50ec3 100644 --- a/storage-provider/common/src/commp.rs +++ b/storage-provider/common/src/commp.rs @@ -1,10 +1,11 @@ -use std::io::Read; +use std::{fs::File, io::{BufReader, Read}, path::Path}; use filecoin_hashers::{ sha256::{Sha256Domain, Sha256Hasher}, Domain, }; use fr32::Fr32Reader; +use polka_storage_proofs::ZeroPaddingReader; use primitives::{ commitment::{piece::PaddedPieceSize, CommP, Commitment}, NODE_SIZE, @@ -12,6 +13,24 @@ use primitives::{ use storage_proofs_core::merkle::BinaryMerkleTree; use thiserror::Error; +/// Calculates piece commitment for the file at a path. +/// Assumes the file at path is a CARv2 archive. +pub fn commp>(path: P) -> Result<(Commitment, PaddedPieceSize), CommPError> { + let source_file = File::open(path.as_ref())?; + let file_size = source_file.metadata()?.len(); + + let padded_piece_size = PaddedPieceSize::from_arbitrary_size(file_size as u64); + // how many zeroes we need to add, so after Fr32 padding it'll be a power of two + let padded_with_zeroes = *padded_piece_size.unpadded(); + + let buffered = BufReader::new(source_file); + let mut zero_padding_reader = ZeroPaddingReader::new(buffered, + padded_with_zeroes); + + calculate_piece_commitment(&mut zero_padding_reader, padded_piece_size) + .map(|commp| (commp, padded_piece_size)) +} + /// Calculate the piece commitment for a given data source. /// /// Reference — @@ -58,13 +77,40 @@ pub enum CommPError { #[cfg(test)] mod tests { - use std::io::Cursor; + use std::{env, io::Cursor, path::Path}; use polka_storage_proofs::ZeroPaddingReader; use primitives::{commitment::piece::PaddedPieceSize, sector::SectorSize}; + use filecoin_proofs::generate_piece_commitment; + + use crate::commp::commp; use super::calculate_piece_commitment; + #[test] + fn test_filecoin_commp_matches_ours() { + let workspace_root = env::var("CARGO_MANIFEST_DIR").unwrap(); + let path = Path::new(&workspace_root) + .join("../..") + .join("examples/big_file_184k.car"); + + let (commitment, _) = commp(&path).unwrap(); + + let f = std::fs::File::open(&path).unwrap(); + let len = f.metadata().unwrap().len(); + let size = PaddedPieceSize::from_arbitrary_size(len); + + let piece_info = generate_piece_commitment( + ZeroPaddingReader::new(f, *size.unpadded()), + size.unpadded().into() + ).unwrap(); + + assert_eq!( + piece_info.commitment, + commitment.raw(), + ); + } + #[test] fn test_calculate_piece_commitment() { let data_size: u64 = 200; diff --git a/storage-provider/server/src/storage.rs b/storage-provider/server/src/storage.rs index 359b440f6..dfbb74aa7 100644 --- a/storage-provider/server/src/storage.rs +++ b/storage-provider/server/src/storage.rs @@ -11,7 +11,7 @@ use axum::{ use futures::{TryFutureExt, TryStreamExt}; use mater::Cid; use polka_storage_proofs::ZeroPaddingReader; -use polka_storage_provider_common::commp::{calculate_piece_commitment, CommPError}; +use polka_storage_provider_common::commp::{calculate_piece_commitment, commp, CommPError}; use primitives::{commitment::piece::PaddedPieceSize, proofs::RegisteredPoStProof}; use tokio::{ fs::{self, File}, @@ -269,13 +269,7 @@ async fn upload( // is CPU intensive — i.e. blocking — potentially improvement is to move this completely out of // the tokio runtime into an OS thread let piece_commitment_cid = tokio::task::spawn_blocking(move || -> Result<_, CommPError> { - // Yes, we're reloading the file, this requires the std version - let file = std::fs::File::open(&piece_path)?; - let file_size = file.metadata()?.len(); - let piece_size = PaddedPieceSize::from_arbitrary_size(file_size); - let buffered = std::io::BufReader::new(file); - let reader = ZeroPaddingReader::new(buffered, *piece_size); - let piece_commitment = calculate_piece_commitment(reader, piece_size)?; + let (piece_commitment, _) = commp(&piece_path)?; let piece_commitment_cid = piece_commitment.cid(); tracing::debug!(path = %piece_path.display(), commp = %piece_commitment_cid, "calculated piece commitment"); Ok(piece_commitment_cid) @@ -470,12 +464,7 @@ mod delia_endpoints { // Calculate piece commitment let piece_commitment_cid = tokio::task::spawn_blocking(move || -> Result<_, CommPError> { - let file = std::fs::File::open(&file_path)?; - let file_size = file.metadata()?.len(); - let piece_size = PaddedPieceSize::from_arbitrary_size(file_size); - let buffered = std::io::BufReader::new(file); - let reader = ZeroPaddingReader::new(buffered, *piece_size); - let piece_commitment = calculate_piece_commitment(reader, piece_size)?; + let (piece_commitment, _) = commp(&piece_path)?; let piece_commitment_cid = piece_commitment.cid(); tracing::debug!(path = %file_path.display(), commp = %piece_commitment_cid, "calculated piece commitment"); Ok(piece_commitment_cid) From 5b1918be273881cc13c23a8c854f83df7e8071c0 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 30 Jan 2025 12:00:43 +0100 Subject: [PATCH 09/13] chore: format --- maat/tests/real_world.rs | 11 +++++----- .../client/src/commands/proofs.rs | 4 ++-- storage-provider/common/src/commp.rs | 21 ++++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/maat/tests/real_world.rs b/maat/tests/real_world.rs index 92e9f8b2e..a53a40263 100644 --- a/maat/tests/real_world.rs +++ b/maat/tests/real_world.rs @@ -5,10 +5,7 @@ use libp2p::PeerId; use maat::*; use polka_storage_proofs::{porep, post}; use polka_storage_provider_common::{commp::commp, deadline::Deadline, sector::UnsealedSector}; -use primitives::{ - proofs::RegisteredPoStProof, - sector::SectorNumber, -}; +use primitives::{proofs::RegisteredPoStProof, sector::SectorNumber}; use storagext::{ clients::ProofsClientExt, multipair::MultiPairSigner, @@ -340,7 +337,11 @@ async fn real_world_use_case() { add_balance(&client, &alice_kp, balance).await; let (commp, piece_size) = commp(&data_file_path).unwrap(); - tracing::debug!("piece_size of {} = {}", data_file_path.display(), *piece_size); + tracing::debug!( + "piece_size of {} = {}", + data_file_path.display(), + *piece_size + ); let sector_end_block = 165; // Publish a storage deal diff --git a/storage-provider/client/src/commands/proofs.rs b/storage-provider/client/src/commands/proofs.rs index 032b37774..61ac163b0 100644 --- a/storage-provider/client/src/commands/proofs.rs +++ b/storage-provider/client/src/commands/proofs.rs @@ -157,8 +157,8 @@ impl ProofsCommand { .map_err(|e| UtilsCommandError::InvalidCARv2(input_path.clone(), e))?; // Calculate the piece commitment. - let commitment = commp(&input_path) - .map_err(|err| UtilsCommandError::CommPError(err))?; + let commitment = + commp(&input_path).map_err(|err| UtilsCommandError::CommPError(err))?; let cid = commitment.cid(); // NOTE(@jmg-duarte,09/10/2024): too lazy for proper json diff --git a/storage-provider/common/src/commp.rs b/storage-provider/common/src/commp.rs index 049e50ec3..421012d76 100644 --- a/storage-provider/common/src/commp.rs +++ b/storage-provider/common/src/commp.rs @@ -1,4 +1,8 @@ -use std::{fs::File, io::{BufReader, Read}, path::Path}; +use std::{ + fs::File, + io::{BufReader, Read}, + path::Path, +}; use filecoin_hashers::{ sha256::{Sha256Domain, Sha256Hasher}, @@ -24,8 +28,7 @@ pub fn commp>(path: P) -> Result<(Commitment, PaddedPieceS let padded_with_zeroes = *padded_piece_size.unpadded(); let buffered = BufReader::new(source_file); - let mut zero_padding_reader = ZeroPaddingReader::new(buffered, - padded_with_zeroes); + let mut zero_padding_reader = ZeroPaddingReader::new(buffered, padded_with_zeroes); calculate_piece_commitment(&mut zero_padding_reader, padded_piece_size) .map(|commp| (commp, padded_piece_size)) @@ -79,9 +82,9 @@ pub enum CommPError { mod tests { use std::{env, io::Cursor, path::Path}; + use filecoin_proofs::generate_piece_commitment; use polka_storage_proofs::ZeroPaddingReader; use primitives::{commitment::piece::PaddedPieceSize, sector::SectorSize}; - use filecoin_proofs::generate_piece_commitment; use crate::commp::commp; @@ -102,13 +105,11 @@ mod tests { let piece_info = generate_piece_commitment( ZeroPaddingReader::new(f, *size.unpadded()), - size.unpadded().into() - ).unwrap(); + size.unpadded().into(), + ) + .unwrap(); - assert_eq!( - piece_info.commitment, - commitment.raw(), - ); + assert_eq!(piece_info.commitment, commitment.raw(),); } #[test] From 1bbfa1c050346870ab6b81e086a3fc5e261da934 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 30 Jan 2025 13:06:54 +0100 Subject: [PATCH 10/13] fix: formatting --- storage-provider/common/src/commp.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage-provider/common/src/commp.rs b/storage-provider/common/src/commp.rs index 421012d76..737cb0adb 100644 --- a/storage-provider/common/src/commp.rs +++ b/storage-provider/common/src/commp.rs @@ -86,9 +86,8 @@ mod tests { use polka_storage_proofs::ZeroPaddingReader; use primitives::{commitment::piece::PaddedPieceSize, sector::SectorSize}; - use crate::commp::commp; - use super::calculate_piece_commitment; + use crate::commp::commp; #[test] fn test_filecoin_commp_matches_ours() { From 095783c4d194054c506ae4e86115c2ccf2bda808 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 30 Jan 2025 13:34:39 +0100 Subject: [PATCH 11/13] fix: clippy --- storage-provider/client/src/commands/proofs.rs | 7 +++---- storage-provider/server/src/storage.rs | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/storage-provider/client/src/commands/proofs.rs b/storage-provider/client/src/commands/proofs.rs index 61ac163b0..7e24c6c09 100644 --- a/storage-provider/client/src/commands/proofs.rs +++ b/storage-provider/client/src/commands/proofs.rs @@ -1,6 +1,5 @@ use std::{ - fs::File, - io::{BufReader, Write}, + io::Write, path::PathBuf, str::FromStr, }; @@ -12,7 +11,7 @@ use polka_storage_proofs::{ post::{self, ReplicaInfo}, ZeroPaddingReader, }; -use polka_storage_provider_common::commp::{calculate_piece_commitment, commp, CommPError}; +use polka_storage_provider_common::commp::{commp, CommPError}; use primitives::{ commitment::{ piece::{PaddedPieceSize, PieceInfo}, @@ -157,7 +156,7 @@ impl ProofsCommand { .map_err(|e| UtilsCommandError::InvalidCARv2(input_path.clone(), e))?; // Calculate the piece commitment. - let commitment = + let (commitment, padded_piece_size) = commp(&input_path).map_err(|err| UtilsCommandError::CommPError(err))?; let cid = commitment.cid(); diff --git a/storage-provider/server/src/storage.rs b/storage-provider/server/src/storage.rs index dfbb74aa7..40663edfb 100644 --- a/storage-provider/server/src/storage.rs +++ b/storage-provider/server/src/storage.rs @@ -10,8 +10,7 @@ use axum::{ }; use futures::{TryFutureExt, TryStreamExt}; use mater::Cid; -use polka_storage_proofs::ZeroPaddingReader; -use polka_storage_provider_common::commp::{calculate_piece_commitment, commp, CommPError}; +use polka_storage_provider_common::commp::{commp, CommPError}; use primitives::{commitment::piece::PaddedPieceSize, proofs::RegisteredPoStProof}; use tokio::{ fs::{self, File}, From 4fc6d4ebfe600d9fac5d0637d1889bb0cd525438 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 30 Jan 2025 13:39:08 +0100 Subject: [PATCH 12/13] chore: fmt --- storage-provider/client/src/commands/proofs.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/storage-provider/client/src/commands/proofs.rs b/storage-provider/client/src/commands/proofs.rs index 7e24c6c09..30bb3c94b 100644 --- a/storage-provider/client/src/commands/proofs.rs +++ b/storage-provider/client/src/commands/proofs.rs @@ -1,8 +1,4 @@ -use std::{ - io::Write, - path::PathBuf, - str::FromStr, -}; +use std::{io::Write, path::PathBuf, str::FromStr}; use codec::Encode; use mater::CarV2Reader; From 51358606bde9e06c5fd0443a03d4ef9266de73c1 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Fri, 31 Jan 2025 09:33:24 +0100 Subject: [PATCH 13/13] fix: misspells of 8MiB in primitives serialization --- primitives/src/proofs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/primitives/src/proofs.rs b/primitives/src/proofs.rs index f08f240dc..f9cf9c68c 100644 --- a/primitives/src/proofs.rs +++ b/primitives/src/proofs.rs @@ -54,7 +54,7 @@ pub enum RegisteredSealProof { #[cfg_attr(feature = "serde", serde(alias = "2KiB"))] StackedDRG2KiBV1P1, #[cfg_attr(feature = "clap", clap(name = "8MiB"))] - #[cfg_attr(feature = "serde", serde(alias = "2MiB"))] + #[cfg_attr(feature = "serde", serde(alias = "8MiB"))] StackedDRG8MiBV1, } @@ -142,8 +142,8 @@ pub enum RegisteredPoStProof { #[cfg_attr(feature = "clap", clap(name = "2KiB"))] #[cfg_attr(feature = "serde", serde(alias = "2KiB"))] StackedDRGWindow2KiBV1P1, - #[cfg_attr(feature = "clap", clap(name = "8KiB"))] - #[cfg_attr(feature = "serde", serde(alias = "8KiB"))] + #[cfg_attr(feature = "clap", clap(name = "8MiB"))] + #[cfg_attr(feature = "serde", serde(alias = "8MiB"))] StackedDRGWindow8MiBV1, }