diff --git a/filecoin-proofs/src/api/post_util.rs b/filecoin-proofs/src/api/post_util.rs index aef637696..3f46cd2a9 100644 --- a/filecoin-proofs/src/api/post_util.rs +++ b/filecoin-proofs/src/api/post_util.rs @@ -9,7 +9,9 @@ use log::{debug, info}; use storage_proofs_core::{ cache_key::CacheKey, merkle::MerkleTreeTrait, proof::ProofScheme, sector::SectorId, }; -use storage_proofs_post::fallback::{self, generate_leaf_challenge, FallbackPoSt, SectorProof}; +use storage_proofs_post::fallback::{ + self, generate_leaf_challenge, get_challenge_index, FallbackPoSt, SectorProof, +}; use crate::{ api::as_safe_commitment, @@ -100,9 +102,24 @@ pub fn generate_fallback_sector_challenges( let mut challenges = Vec::new(); for n in 0..post_config.challenge_count { - let challenge_index = ((partition_index * post_config.sector_count + i) - * post_config.challenge_count - + n) as u64; + let challenge_index = match post_config.typ { + PoStType::Window => get_challenge_index( + post_config.api_version, + partition_index, + i, + num_sectors_per_chunk, + post_config.challenge_count, + n, + ), + PoStType::Winning => get_challenge_index( + post_config.api_version, + partition_index, + i, + post_config.sector_count, + post_config.challenge_count, + n, + ), + }; let challenged_leaf = generate_leaf_challenge( &public_params, randomness_safe, diff --git a/filecoin-proofs/tests/api.rs b/filecoin-proofs/tests/api.rs index ca588d9ab..cc5e0e967 100644 --- a/filecoin-proofs/tests/api.rs +++ b/filecoin-proofs/tests/api.rs @@ -52,6 +52,7 @@ use filecoin_proofs::{ // same porep_ids). const ARBITRARY_POREP_ID_V1_0_0: [u8; 32] = [127; 32]; const ARBITRARY_POREP_ID_V1_1_0: [u8; 32] = [128; 32]; +const ARBITRARY_POREP_ID_V1_2_0: [u8; 32] = [129; 32]; const TEST_SEED: [u8; 16] = [ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, @@ -76,6 +77,7 @@ fn test_seal_lifecycle_2kib_porep_id_v1_1_base_8() -> Result<()> { let mut porep_id = [0u8; 32]; porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); assert!(!is_legacy_porep_id(porep_id)); + seal_lifecycle::(SECTOR_SIZE_2_KIB, &porep_id, ApiVersion::V1_1_0) } @@ -290,6 +292,10 @@ fn seal_lifecycle( let mut prover_id = [0u8; 32]; prover_id.copy_from_slice(AsRef::<[u8]>::as_ref(&prover_fr)); + info!( + "Creating seal proof with ApiVersion {} and PoRep ID {:?}", + api_version, porep_id + ); let (_, replica, _, _) = create_seal::<_, Tree>( &mut rng, sector_size, @@ -806,6 +812,7 @@ fn winning_post( let porep_id = match api_version { ApiVersion::V1_0_0 => ARBITRARY_POREP_ID_V1_0_0, ApiVersion::V1_1_0 => ARBITRARY_POREP_ID_V1_1_0, + ApiVersion::V1_2_0 => ARBITRARY_POREP_ID_V1_2_0, }; let (sector_id, replica, comm_r, cache_dir) = if fake { @@ -909,7 +916,7 @@ fn test_window_post_single_partition_smaller_2kib_base_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -934,7 +941,7 @@ fn test_window_post_two_partitions_matching_2kib_base_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -959,7 +966,7 @@ fn test_window_post_two_partitions_matching_4kib_sub_8_2() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -984,7 +991,7 @@ fn test_window_post_two_partitions_matching_16kib_sub_8_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -1015,7 +1022,7 @@ fn test_window_post_two_partitions_matching_32kib_top_8_8_2() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -1046,7 +1053,7 @@ fn test_window_post_two_partitions_smaller_2kib_base_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::( sector_size, @@ -1077,7 +1084,7 @@ fn test_window_post_single_partition_matching_2kib_base_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { window_post::(sector_size, sector_count, sector_count, false, version)?; window_post::(sector_size, sector_count, sector_count, true, version)?; @@ -1095,7 +1102,7 @@ fn test_window_post_partition_matching_2kib_base_8() -> Result<()> { .get(§or_size) .expect("unknown sector size"); - let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0]; + let versions = vec![ApiVersion::V1_0_0, ApiVersion::V1_1_0, ApiVersion::V1_2_0]; for version in versions { partition_window_post::( sector_size, @@ -1133,6 +1140,7 @@ fn partition_window_post( let porep_id = match api_version { ApiVersion::V1_0_0 => ARBITRARY_POREP_ID_V1_0_0, ApiVersion::V1_1_0 => ARBITRARY_POREP_ID_V1_1_0, + ApiVersion::V1_2_0 => ARBITRARY_POREP_ID_V1_2_0, }; for _ in 0..total_sector_count { @@ -1271,6 +1279,7 @@ fn window_post( let porep_id = match api_version { ApiVersion::V1_0_0 => ARBITRARY_POREP_ID_V1_0_0, ApiVersion::V1_1_0 => ARBITRARY_POREP_ID_V1_1_0, + ApiVersion::V1_2_0 => ARBITRARY_POREP_ID_V1_2_0, }; for _ in 0..total_sector_count { diff --git a/storage-proofs-core/src/api_version.rs b/storage-proofs-core/src/api_version.rs index 45cf85748..69d6c992a 100644 --- a/storage-proofs-core/src/api_version.rs +++ b/storage-proofs-core/src/api_version.rs @@ -8,6 +8,7 @@ use semver::Version; pub enum ApiVersion { V1_0_0, V1_1_0, + V1_2_0, } impl ApiVersion { @@ -15,6 +16,7 @@ impl ApiVersion { match self { ApiVersion::V1_0_0 => Version::new(1, 0, 0), ApiVersion::V1_1_0 => Version::new(1, 1, 0), + ApiVersion::V1_2_0 => Version::new(1, 2, 0), } } } @@ -40,6 +42,7 @@ impl FromStr for ApiVersion { match (api_version.major, api_version.minor, api_version.patch) { (1, 0, 0) => Ok(ApiVersion::V1_0_0), (1, 1, 0) => Ok(ApiVersion::V1_1_0), + (1, 2, 0) => Ok(ApiVersion::V1_2_0), (1, 1, _) | (1, 0, _) => Err(format_err!( "Could not parse API Version from string (patch)" )), @@ -57,14 +60,18 @@ impl FromStr for ApiVersion { fn test_fmt() { assert_eq!(format!("{}", ApiVersion::V1_0_0), "1.0.0"); assert_eq!(format!("{}", ApiVersion::V1_1_0), "1.1.0"); + assert_eq!(format!("{}", ApiVersion::V1_2_0), "1.2.0"); } #[test] fn test_as_semver() { assert_eq!(ApiVersion::V1_0_0.as_semver().major, 1); assert_eq!(ApiVersion::V1_1_0.as_semver().major, 1); + assert_eq!(ApiVersion::V1_2_0.as_semver().major, 1); assert_eq!(ApiVersion::V1_0_0.as_semver().minor, 0); assert_eq!(ApiVersion::V1_1_0.as_semver().minor, 1); + assert_eq!(ApiVersion::V1_2_0.as_semver().minor, 2); assert_eq!(ApiVersion::V1_0_0.as_semver().patch, 0); assert_eq!(ApiVersion::V1_1_0.as_semver().patch, 0); + assert_eq!(ApiVersion::V1_2_0.as_semver().patch, 0); } diff --git a/storage-proofs-core/src/drgraph.rs b/storage-proofs-core/src/drgraph.rs index 15da22985..081552633 100644 --- a/storage-proofs-core/src/drgraph.rs +++ b/storage-proofs-core/src/drgraph.rs @@ -165,7 +165,7 @@ impl Graph for BucketGraph { let (predecessor_index, other_drg_parents) = match self.api_version { ApiVersion::V1_0_0 => (m_prime, &mut parents[..]), - ApiVersion::V1_1_0 => (0, &mut parents[1..]), + ApiVersion::V1_1_0 | ApiVersion::V1_2_0 => (0, &mut parents[1..]), }; for parent in other_drg_parents.iter_mut().take(m_prime) { @@ -291,7 +291,7 @@ mod tests { let new_porep_id = porep_id(5); graph_bucket_aux::(legacy_porep_id, ApiVersion::V1_0_0); - graph_bucket_aux::(new_porep_id, ApiVersion::V1_1_0); + graph_bucket_aux::(new_porep_id, ApiVersion::V1_2_0); } fn graph_bucket_aux(porep_id: PoRepID, api_version: ApiVersion) { @@ -337,7 +337,7 @@ mod tests { "immediate predecessor was not last DRG parent" ); } - ApiVersion::V1_1_0 => { + ApiVersion::V1_1_0 | ApiVersion::V1_2_0 => { assert_eq!( i - 1, pa1[0] as usize, @@ -362,7 +362,7 @@ mod tests { fn gen_proof(config: Option) { let leafs = 64; let porep_id = [1; 32]; - let g = BucketGraph::::new(leafs, BASE_DEGREE, 0, porep_id, ApiVersion::V1_1_0) + let g = BucketGraph::::new(leafs, BASE_DEGREE, 0, porep_id, ApiVersion::V1_2_0) .expect("bucket graph new failed"); let data = vec![2u8; NODE_SIZE * leafs]; diff --git a/storage-proofs-porep/src/stacked/vanilla/graph.rs b/storage-proofs-porep/src/stacked/vanilla/graph.rs index ed5b37588..6eedc23d0 100644 --- a/storage-proofs-porep/src/stacked/vanilla/graph.rs +++ b/storage-proofs-porep/src/stacked/vanilla/graph.rs @@ -374,8 +374,10 @@ where match self.api_version { ApiVersion::V1_0_0 => transformed as u32 / self.expansion_degree as u32, - ApiVersion::V1_1_0 => u32::try_from(transformed / self.expansion_degree as u64) - .expect("invalid transformation"), + ApiVersion::V1_1_0 | ApiVersion::V1_2_0 => { + u32::try_from(transformed / self.expansion_degree as u64) + .expect("invalid transformation") + } } // Collapse the output in the matrix search space to the row of the corresponding @@ -511,11 +513,19 @@ mod tests { porep_id }; - test_pathology_aux(porep_id(3), sector32_nodes, ApiVersion::V1_0_0); - test_pathology_aux(porep_id(4), sector64_nodes, ApiVersion::V1_0_0); + let test_inputs = vec![ + (porep_id(3), sector32_nodes, ApiVersion::V1_0_0), + (porep_id(4), sector64_nodes, ApiVersion::V1_0_0), + (porep_id(8), sector32_nodes, ApiVersion::V1_1_0), + (porep_id(9), sector64_nodes, ApiVersion::V1_1_0), + // Confirms that V1_1_0 and V1_2_0 are compatible + (porep_id(8), sector32_nodes, ApiVersion::V1_2_0), + (porep_id(9), sector64_nodes, ApiVersion::V1_2_0), + ]; - test_pathology_aux(porep_id(8), sector32_nodes, ApiVersion::V1_1_0); - test_pathology_aux(porep_id(9), sector64_nodes, ApiVersion::V1_1_0); + for inputs in test_inputs { + test_pathology_aux(inputs.0, inputs.1, inputs.2); + } } fn test_pathology_aux(porep_id: PoRepID, nodes: u32, api_version: ApiVersion) { @@ -531,7 +541,7 @@ mod tests { let expect_pathological = match api_version { ApiVersion::V1_0_0 => true, - ApiVersion::V1_1_0 => false, + ApiVersion::V1_1_0 | ApiVersion::V1_2_0 => false, }; let graph = StackedBucketGraph::::new_stacked( @@ -606,7 +616,7 @@ mod tests { BASE_DEGREE, EXP_DEGREE, porep_id, - ApiVersion::V1_1_0, + ApiVersion::V1_2_0, ) .expect("stacked bucket graph new_stacked"); @@ -656,7 +666,7 @@ mod tests { BASE_DEGREE, EXP_DEGREE, porep_id, - ApiVersion::V1_1_0, + ApiVersion::V1_2_0, ) .expect("stacked bucket graph new_stacked failed"); diff --git a/storage-proofs-post/src/fallback/compound.rs b/storage-proofs-post/src/fallback/compound.rs index 4050ecb7c..5707728ce 100644 --- a/storage-proofs-post/src/fallback/compound.rs +++ b/storage-proofs-post/src/fallback/compound.rs @@ -16,7 +16,9 @@ use storage_proofs_core::{ util::NODE_SIZE, }; -use crate::fallback::{generate_leaf_challenge_inner, FallbackPoSt, FallbackPoStCircuit, Sector}; +use crate::fallback::{ + generate_leaf_challenge_inner, get_challenge_index, FallbackPoSt, FallbackPoStCircuit, Sector, +}; pub struct FallbackPoStCompound where @@ -70,9 +72,14 @@ impl<'a, Tree: 'static + MerkleTreeTrait> // 2. Inputs for verifying inclusion paths for n in 0..pub_params.challenge_count { - let challenge_index = ((partition_index * pub_params.sector_count + i) - * pub_params.challenge_count - + n) as u64; + let challenge_index = get_challenge_index( + pub_params.api_version, + partition_index, + i, + pub_params.sector_count, + pub_params.challenge_count, + n, + ); let challenged_leaf = generate_leaf_challenge_inner::< ::Domain, >( diff --git a/storage-proofs-post/src/fallback/mod.rs b/storage-proofs-post/src/fallback/mod.rs index c63243f96..eabc539a7 100644 --- a/storage-proofs-post/src/fallback/mod.rs +++ b/storage-proofs-post/src/fallback/mod.rs @@ -1,7 +1,9 @@ mod circuit; mod compound; +mod utils; mod vanilla; pub use circuit::*; pub use compound::*; +pub use utils::*; pub use vanilla::*; diff --git a/storage-proofs-post/src/fallback/utils.rs b/storage-proofs-post/src/fallback/utils.rs new file mode 100644 index 000000000..9f510e993 --- /dev/null +++ b/storage-proofs-post/src/fallback/utils.rs @@ -0,0 +1,19 @@ +use storage_proofs_core::api_version::ApiVersion; + +/// Selects the challenge index used to determine the leaf challenge for PoSt +pub fn get_challenge_index( + api_version: ApiVersion, + sector: usize, + sector_chunk_index: usize, + num_sectors_per_chunk: usize, + challenge_count: usize, + challenge_index: usize, +) -> u64 { + (match api_version { + ApiVersion::V1_2_0 => challenge_index, + _ => { + (sector * num_sectors_per_chunk + sector_chunk_index) * challenge_count + + challenge_index + } + } as u64) +} diff --git a/storage-proofs-post/src/fallback/vanilla.rs b/storage-proofs-post/src/fallback/vanilla.rs index f760208d1..2a578067c 100644 --- a/storage-proofs-post/src/fallback/vanilla.rs +++ b/storage-proofs-post/src/fallback/vanilla.rs @@ -22,6 +22,8 @@ use storage_proofs_core::{ util::{default_rows_to_discard, NODE_SIZE}, }; +use super::utils::get_challenge_index; + #[derive(Debug, Clone)] pub struct SetupParams { /// Size of the sector in bytes. @@ -402,9 +404,14 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree> .fold( || (Vec::new(), BTreeSet::new()), |(mut inclusion_proofs, mut faults), n| { - let challenge_index = - ((j * num_sectors_per_chunk + i) * pub_params.challenge_count - + n) as u64; + let challenge_index = get_challenge_index( + pub_params.api_version, + j, + i, + num_sectors_per_chunk, + pub_params.challenge_count, + n, + ); let challenged_leaf = generate_leaf_challenge_inner::< ::Domain, >( @@ -629,8 +636,14 @@ impl<'a, Tree: 'a + MerkleTreeTrait> ProofScheme<'a> for FallbackPoSt<'a, Tree> .par_iter() .enumerate() .map(|(n, inclusion_proof)| -> Result { - let challenge_index = - (j * num_sectors_per_chunk + i) * pub_params.challenge_count + n; + let challenge_index = get_challenge_index( + pub_params.api_version, + j, + i, + num_sectors_per_chunk, + pub_params.challenge_count, + n, + ); let challenged_leaf = generate_leaf_challenge_inner::<::Domain>( challenge_hasher.clone(),