From 0d17d7466f40e1228a4bab25f8b4861cb0d2da4d Mon Sep 17 00:00:00 2001 From: Friedel Ziegelmayer Date: Mon, 2 Nov 2020 12:06:36 +0100 Subject: [PATCH] fix(storage-proofs-porep): fix graph generation - expander: divide before casting to u32 - drg: move predecessor to the first position --- fil-proofs-tooling/Cargo.toml | 2 +- .../src/bin/gen_graph_cache/main.rs | 35 +++ filecoin-proofs/Cargo.toml | 4 +- filecoin-proofs/src/constants.rs | 3 + filecoin-proofs/tests/api.rs | 159 ++++++++++--- storage-proofs/Cargo.toml | 1 - storage-proofs/core/Cargo.toml | 4 +- storage-proofs/core/src/drgraph.rs | 55 ++++- storage-proofs/core/src/lib.rs | 16 ++ storage-proofs/porep/Cargo.toml | 4 +- storage-proofs/porep/parent_cache.json | 20 ++ storage-proofs/porep/src/lib.rs | 2 + .../porep/src/stacked/vanilla/cache.rs | 103 +++++---- .../src/stacked/vanilla/create_label/multi.rs | 53 ++++- .../porep/src/stacked/vanilla/graph.rs | 216 +++++++++++++++++- .../porep/src/stacked/vanilla/proof.rs | 45 +++- storage-proofs/post/Cargo.toml | 5 +- 17 files changed, 613 insertions(+), 114 deletions(-) diff --git a/fil-proofs-tooling/Cargo.toml b/fil-proofs-tooling/Cargo.toml index da78a4bd4..9214583a5 100644 --- a/fil-proofs-tooling/Cargo.toml +++ b/fil-proofs-tooling/Cargo.toml @@ -22,7 +22,7 @@ regex = "1.3.7" commandspec = "0.12.2" chrono = { version = "0.4.7", features = ["serde"] } memmap = "0.7.0" -bellperson = { version = "0.11", default-features = false } +bellperson = { version = "0.12", default-features = false } rand = "0.7" tempfile = "3.0.8" cpu-time = "1.0.0" diff --git a/fil-proofs-tooling/src/bin/gen_graph_cache/main.rs b/fil-proofs-tooling/src/bin/gen_graph_cache/main.rs index 830216297..29bde86d0 100644 --- a/fil-proofs-tooling/src/bin/gen_graph_cache/main.rs +++ b/fil-proofs-tooling/src/bin/gen_graph_cache/main.rs @@ -131,6 +131,41 @@ fn main() -> Result<()> { 0, 0, 0, 0, ], ), + ( + SECTOR_SIZE_2_KIB, // v1.1 + [ + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ), + ( + SECTOR_SIZE_8_MIB, // v1.1 + [ + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ), + ( + SECTOR_SIZE_512_MIB, // v1.1 + [ + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ), + ( + SECTOR_SIZE_32_GIB, // v1.1 + [ + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ), + ( + SECTOR_SIZE_64_GIB, // v1.1 + [ + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ), ]; let supported_sector_sizes = sector_sizes_and_porep_ids diff --git a/filecoin-proofs/Cargo.toml b/filecoin-proofs/Cargo.toml index 888c23039..a2497d20c 100644 --- a/filecoin-proofs/Cargo.toml +++ b/filecoin-proofs/Cargo.toml @@ -23,7 +23,7 @@ serde_json = "1.0" regex = "1.3.7" ff = { version = "0.2.3", package = "fff" } blake2b_simd = "0.5" -bellperson = { version = "0.11", default-features = false } +bellperson = { version = "0.12", default-features = false } clap = "2" log = "0.4.7" fil_logger = "0.1" @@ -41,7 +41,7 @@ sha2 = "0.9.1" typenum = "1.11.2" bitintr = "0.3.0" gperftools = { version = "0.2", optional = true } -phase2 = { version = "0.10", package = "phase21", default-features = false } +phase2 = { version = "0.11", package = "phase21", default-features = false } simplelog = "0.8.0" rand_chacha = "0.2.1" dialoguer = "0.7.1" diff --git a/filecoin-proofs/src/constants.rs b/filecoin-proofs/src/constants.rs index da6a72ff7..f76360f38 100644 --- a/filecoin-proofs/src/constants.rs +++ b/filecoin-proofs/src/constants.rs @@ -4,6 +4,7 @@ use std::sync::RwLock; use lazy_static::lazy_static; use storage_proofs::hasher::Hasher; use storage_proofs::util::NODE_SIZE; +use storage_proofs::MAX_LEGACY_POREP_REGISTERED_PROOF_ID; use typenum::{U0, U2, U8}; use crate::types::UnpaddedBytesAmount; @@ -27,6 +28,8 @@ pub const WINDOW_POST_CHALLENGE_COUNT: usize = 10; pub const DRG_DEGREE: usize = storage_proofs::drgraph::BASE_DEGREE; pub const EXP_DEGREE: usize = storage_proofs::porep::stacked::EXP_DEGREE; +pub const MAX_LEGACY_REGISTERED_SEAL_PROOF_ID: u64 = MAX_LEGACY_POREP_REGISTERED_PROOF_ID; + /// Sector sizes for which parameters have been published. pub const PUBLISHED_SECTOR_SIZES: [u64; 10] = [ SECTOR_SIZE_2_KIB, diff --git a/filecoin-proofs/tests/api.rs b/filecoin-proofs/tests/api.rs index 2d0aa9f04..b5a406c7c 100644 --- a/filecoin-proofs/tests/api.rs +++ b/filecoin-proofs/tests/api.rs @@ -15,7 +15,7 @@ use tempfile::NamedTempFile; use filecoin_proofs::*; -// Use a fixed PoRep ID, so that the parents cache can be re-used between different tests +// Use a fixed PoRep ID, so that the parents cache can be re-used between some tests. const ARBITRARY_POREP_ID: [u8; 32] = [28; 32]; static INIT_LOGGER: Once = Once::new(); @@ -31,55 +31,114 @@ const TEST_SEED: [u8; 16] = [ #[test] #[ignore] -fn test_seal_lifecycle_2kib_base_8() -> Result<()> { - seal_lifecycle::(SECTOR_SIZE_2_KIB) +fn test_seal_lifecycle_2kib_porep_id_v1_base_8() -> Result<()> { + let porep_id_v1: u64 = 0; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); + seal_lifecycle::(SECTOR_SIZE_2_KIB, &porep_id) +} + +#[test] +#[ignore] +fn test_seal_lifecycle_2kib_porep_id_v1_1_base_8() -> Result<()> { + let porep_id_v1_1: u64 = 5; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); + seal_lifecycle::(SECTOR_SIZE_2_KIB, &porep_id) } #[test] #[ignore] fn test_seal_lifecycle_4kib_sub_8_2() -> Result<()> { - seal_lifecycle::(SECTOR_SIZE_4_KIB) + seal_lifecycle::(SECTOR_SIZE_4_KIB, &ARBITRARY_POREP_ID) } #[test] #[ignore] fn test_seal_lifecycle_16kib_sub_8_2() -> Result<()> { - seal_lifecycle::(SECTOR_SIZE_16_KIB) + seal_lifecycle::(SECTOR_SIZE_16_KIB, &ARBITRARY_POREP_ID) } #[test] #[ignore] fn test_seal_lifecycle_32kib_top_8_8_2() -> Result<()> { - seal_lifecycle::(SECTOR_SIZE_32_KIB) + seal_lifecycle::(SECTOR_SIZE_32_KIB, &ARBITRARY_POREP_ID) } // These tests are good to run, but take a long time. //#[test] //#[ignore] -//fn test_seal_lifecycle_512mib_top_8_0_0() -> Result<()> { -// seal_lifecycle::(SECTOR_SIZE_512_MIB) +//fn test_seal_lifecycle_512mib_porep_id_v1_top_8_0_0() -> Result<()> { +// let porep_id_v1: u64 = 2; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_512_MIB, &porep_id) +//} + +//#[test] +//#[ignore] +//fn test_seal_lifecycle_512mib_porep_id_v1_1_top_8_0_0() -> Result<()> { +// let porep_id_v1_1: u64 = 7; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_512_MIB, &porep_id) +//} + +//#[test] +//#[ignore] +//fn test_seal_lifecycle_32gib_porep_id_v1_top_8_8_0() -> Result<()> { +// let porep_id_v1: u64 = 3; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_32_GIB, &porep_id) +//} + +//#[test] +//#[ignore] +//fn test_seal_lifecycle_32gib_porep_id_v1_1_top_8_8_0() -> Result<()> { +// let porep_id_v1_1: u64 = 8; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_32_GIB, &porep_id) //} //#[test] //#[ignore] -//fn test_seal_lifecycle_32gib_top_8_8_0() -> Result<()> { -// seal_lifecycle::(SECTOR_SIZE_32_GIB) +//fn test_seal_lifecycle_64gib_porep_id_v1_top_8_8_2() -> Result<()> { +// let porep_id_v1: u64 = 4; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_64_GIB, &porep_id) //} //#[test] //#[ignore] -//fn test_seal_lifecycle_64gib_top_8_8_2() -> Result<()> { -// seal_lifecycle::(SECTOR_SIZE_64_GIB) +//fn test_seal_lifecycle_64gib_porep_id_v1_1_top_8_8_2() -> Result<()> { +// let porep_id_v1_1: u64 = 9; // This is a RegisteredSealProof value +// +// let mut porep_id = [0u8; 32]; +// porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); +// seal_lifecycle::(SECTOR_SIZE_64_GIB, &porep_id) //} -fn seal_lifecycle(sector_size: u64) -> Result<()> { +fn seal_lifecycle( + sector_size: u64, + porep_id: &[u8; 32], +) -> Result<()> { let rng = &mut XorShiftRng::from_seed(TEST_SEED); let prover_fr: DefaultTreeDomain = Fr::random(rng).into(); let mut prover_id = [0u8; 32]; prover_id.copy_from_slice(AsRef::<[u8]>::as_ref(&prover_fr)); - create_seal::<_, Tree>(rng, sector_size, prover_id, false)?; + create_seal::<_, Tree>(rng, sector_size, prover_id, false, porep_id)?; Ok(()) } @@ -116,23 +175,56 @@ fn clear_cache_dir_keep_data_layer(cache_dir: &tempfile::TempDir) { } #[test] -fn test_resumable_seal_skip_proofs() { - run_resumable_seal::(true, 0); - run_resumable_seal::(true, 1); +fn test_resumable_seal_skip_proofs_v1() { + let porep_id_v1: u64 = 0; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); + run_resumable_seal::(true, 0, &porep_id); + run_resumable_seal::(true, 1, &porep_id); +} + +#[test] +fn test_resumable_seal_skip_proofs_v1_1() { + let porep_id_v1_1: u64 = 5; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); + run_resumable_seal::(true, 0, &porep_id); + run_resumable_seal::(true, 1, &porep_id); } #[test] #[ignore] -fn test_resumable_seal() { - run_resumable_seal::(false, 0); - run_resumable_seal::(false, 1); +fn test_resumable_seal_v1() { + let porep_id_v1: u64 = 0; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1.to_le_bytes()); + run_resumable_seal::(false, 0, &porep_id); + run_resumable_seal::(false, 1, &porep_id); +} + +#[test] +#[ignore] +fn test_resumable_seal_v1_1() { + let porep_id_v1_1: u64 = 5; // This is a RegisteredSealProof value + + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&porep_id_v1_1.to_le_bytes()); + run_resumable_seal::(false, 0, &porep_id); + run_resumable_seal::(false, 1, &porep_id); } /// Create a seal, delete a layer and resume /// /// The current code works on two layers only. The `layer_to_delete` specifies (zero-based) which /// layer should be deleted. -fn run_resumable_seal(skip_proofs: bool, layer_to_delete: usize) { +fn run_resumable_seal( + skip_proofs: bool, + layer_to_delete: usize, + porep_id: &[u8; 32], +) { init_logger(); let sector_size = SECTOR_SIZE_2_KIB; @@ -146,7 +238,7 @@ fn run_resumable_seal(skip_proofs: bool, layer_ let sealed_sector_file = NamedTempFile::new().expect("failed to created sealed sector file"); let cache_dir = tempfile::tempdir().expect("failed to create temp dir"); - let config = porep_config(sector_size, ARBITRARY_POREP_ID); + let config = porep_config(sector_size, *porep_id); let ticket = rng.gen(); let sector_id = rng.gen::().into(); @@ -271,7 +363,8 @@ fn test_winning_post_empty_sector_challenge() -> Result<()> { let sector_count = 0; let sector_size = SECTOR_SIZE_2_KIB; - let (_, _, _, _) = create_seal::<_, SectorShape2KiB>(rng, sector_size, prover_id, true)?; + let (_, _, _, _) = + create_seal::<_, SectorShape2KiB>(rng, sector_size, prover_id, true, &ARBITRARY_POREP_ID)?; let random_fr: DefaultTreeDomain = Fr::random(rng).into(); let mut randomness = [0u8; 32]; @@ -304,9 +397,9 @@ fn winning_post(sector_size: u64, fake: bool) - prover_id.copy_from_slice(AsRef::<[u8]>::as_ref(&prover_fr)); let (sector_id, replica, comm_r, cache_dir) = if fake { - create_fake_seal::<_, Tree>(rng, sector_size)? + create_fake_seal::<_, Tree>(rng, sector_size, &ARBITRARY_POREP_ID)? } else { - create_seal::<_, Tree>(rng, sector_size, prover_id, true)? + create_seal::<_, Tree>(rng, sector_size, prover_id, true, &ARBITRARY_POREP_ID)? }; let sector_count = WINNING_POST_SECTOR_COUNT; @@ -496,9 +589,9 @@ fn window_post( for _ in 0..total_sector_count { let (sector_id, replica, comm_r, cache_dir) = if fake { - create_fake_seal::<_, Tree>(rng, sector_size)? + create_fake_seal::<_, Tree>(rng, sector_size, &ARBITRARY_POREP_ID)? } else { - create_seal::<_, Tree>(rng, sector_size, prover_id, true)? + create_seal::<_, Tree>(rng, sector_size, prover_id, true, &ARBITRARY_POREP_ID)? }; priv_replicas.insert( sector_id, @@ -719,6 +812,7 @@ fn create_seal( sector_size: u64, prover_id: ProverId, skip_proof: bool, + porep_id: &[u8; 32], ) -> Result<(SectorId, NamedTempFile, Commitment, tempfile::TempDir)> { init_logger(); @@ -726,7 +820,7 @@ fn create_seal( let sealed_sector_file = NamedTempFile::new()?; let cache_dir = tempfile::tempdir().expect("failed to create temp dir"); - let config = porep_config(sector_size, ARBITRARY_POREP_ID); + let config = porep_config(sector_size, *porep_id); let ticket = rng.gen(); let seed = rng.gen(); let sector_id = rng.gen::().into(); @@ -776,12 +870,19 @@ fn create_seal( fn create_fake_seal( mut rng: &mut R, sector_size: u64, + porep_id: &[u8; 32], ) -> Result<(SectorId, NamedTempFile, Commitment, tempfile::TempDir)> { init_logger(); let sealed_sector_file = NamedTempFile::new()?; - let config = porep_config(sector_size, ARBITRARY_POREP_ID); + let config = PoRepConfig { + sector_size: SectorSize(sector_size), + partitions: PoRepProofPartitions( + *POREP_PARTITIONS.read().unwrap().get(§or_size).unwrap(), + ), + porep_id: *porep_id, + }; let cache_dir = tempfile::tempdir().unwrap(); diff --git a/storage-proofs/Cargo.toml b/storage-proofs/Cargo.toml index 68f8f29fe..ff004027c 100644 --- a/storage-proofs/Cargo.toml +++ b/storage-proofs/Cargo.toml @@ -22,4 +22,3 @@ measurements = ["storage-proofs-core/measurements"] profile = ["measurements"] pairing = ["storage-proofs-core/pairing", "storage-proofs-post/pairing", "storage-proofs-porep/pairing"] blst = ["storage-proofs-core/blst", "storage-proofs-post/blst", "storage-proofs-porep/blst"] - diff --git a/storage-proofs/core/Cargo.toml b/storage-proofs/core/Cargo.toml index 057430f03..39887bb45 100644 --- a/storage-proofs/core/Cargo.toml +++ b/storage-proofs/core/Cargo.toml @@ -30,7 +30,7 @@ blake2b_simd = "0.5" blake2s_simd = "0.5" toml = "0.5" ff = { version = "0.2.3", package = "fff" } -bellperson = { version = "0.11", default-features = false } +bellperson = { version = "0.12", default-features = false } serde_json = "1.0" log = "0.4.7" rand_chacha = "0.2.1" @@ -38,7 +38,7 @@ hex = "0.4.0" generic-array = "0.14.4" anyhow = "1.0.23" thiserror = "1.0.6" -neptune = { version = "2.1.0", default-features = false, features = ["gpu"] } +neptune = { version = "2.2.0", default-features = false, features = ["gpu"] } cpu-time = { version = "1.0", optional = true } gperftools = { version = "0.2", optional = true } num_cpus = "1.10.1" diff --git a/storage-proofs/core/src/drgraph.rs b/storage-proofs/core/src/drgraph.rs index 43f145e7c..218a8906d 100644 --- a/storage-proofs/core/src/drgraph.rs +++ b/storage-proofs/core/src/drgraph.rs @@ -13,6 +13,7 @@ use crate::fr32::bytes_into_fr_repr_safe; use crate::hasher::{Hasher, PoseidonArity}; use crate::parameter_cache::ParameterSetMetadata; use crate::util::{data_at_node_offset, NODE_SIZE}; +use crate::{is_legacy_porep_id, PoRepID}; pub const PARALLEL_MERKLE: bool = true; @@ -55,7 +56,7 @@ pub trait Graph: ::std::fmt::Debug + Clone + PartialEq + Eq { nodes: usize, base_degree: usize, expansion_degree: usize, - porep_id: [u8; 32], + porep_id: PoRepID, ) -> Result; fn seed(&self) -> [u8; 28]; @@ -81,6 +82,7 @@ pub struct BucketGraph { nodes: usize, base_degree: usize, seed: [u8; 28], + is_legacy: bool, _h: PhantomData, } @@ -155,7 +157,13 @@ impl Graph for BucketGraph { let metagraph_node = node as u64 * m_prime as u64; let n_buckets = (metagraph_node as f64).log2().ceil() as u64; - for parent in parents.iter_mut().take(m_prime) { + let (predecessor_index, other_drg_parents) = if self.is_legacy { + (m_prime, &mut parents[..]) + } else { + (0, &mut parents[1..]) + }; + + for parent in other_drg_parents.iter_mut().take(m_prime) { let bucket_index = (rng.gen::() % n_buckets) + 1; let largest_distance_in_bucket = min(metagraph_node, 1 << bucket_index); let smallest_distance_in_bucket = max(2, largest_distance_in_bucket >> 1); @@ -179,7 +187,8 @@ impl Graph for BucketGraph { }; } - parents[m_prime] = node - 1; + // Immediate predecessor must be the first parent, so hashing cannot begin early. + parents[predecessor_index] = node - 1; Ok(()) } } @@ -204,7 +213,7 @@ impl Graph for BucketGraph { nodes: usize, base_degree: usize, expansion_degree: usize, - porep_id: [u8; 32], + porep_id: PoRepID, ) -> Result { ensure!(expansion_degree == 0, "Expension degree must be zero."); @@ -223,12 +232,13 @@ impl Graph for BucketGraph { nodes, base_degree, seed: drg_seed, + is_legacy: is_legacy_porep_id(porep_id), _h: PhantomData, }) } } -pub fn derive_drg_seed(porep_id: [u8; 32]) -> [u8; 28] { +pub fn derive_drg_seed(porep_id: PoRepID) -> [u8; 28] { let mut drg_seed = [0; 28]; let raw_seed = derive_porep_domain_seed(DRSAMPLE_DST, porep_id); drg_seed.copy_from_slice(&raw_seed[..28]); @@ -259,8 +269,25 @@ mod tests { } fn graph_bucket() { + // These PoRepIDs do not correspond to the small-sized graphs used in + // the tests. However, they are sufficient to distinguish legacy vs new + // behavior of parent ordering. + let porep_id = |id: u8| { + let mut porep_id = [0u8; 32]; + porep_id[0] = id; + + porep_id + }; + + let legacy_porep_id = porep_id(0); + let new_porep_id = porep_id(5); + + graph_bucket_aux::(legacy_porep_id); + graph_bucket_aux::(new_porep_id); + } + + fn graph_bucket_aux(porep_id: PoRepID) { let degree = BASE_DEGREE; - let porep_id = [123; 32]; for &size in &[4, 16, 256, 2048] { let g = BucketGraph::::new(size, degree, 0, porep_id).unwrap(); @@ -274,7 +301,7 @@ mod tests { g.parents(1, &mut parents).unwrap(); assert_eq!(parents, vec![0; degree as usize]); - for i in 2..size { + for i in 1..size { let mut pa1 = vec![0; degree]; g.parents(i, &mut pa1).unwrap(); let mut pa2 = vec![0; degree]; @@ -292,6 +319,20 @@ mod tests { // TODO: fix me assert_ne!(i, parent as usize, "self reference found"); } + + if is_legacy_porep_id(porep_id) { + assert_eq!( + i - 1, + pa1[degree - 1] as usize, + "immediate predecessor was not last DRG parent" + ); + } else { + assert_eq!( + i - 1, + pa1[0] as usize, + "immediate predecessor was not first parent" + ); + } } } } diff --git a/storage-proofs/core/src/lib.rs b/storage-proofs/core/src/lib.rs index 4da75b407..9140541f9 100644 --- a/storage-proofs/core/src/lib.rs +++ b/storage-proofs/core/src/lib.rs @@ -35,3 +35,19 @@ pub use self::data::Data; pub(crate) const TEST_SEED: [u8; 16] = [ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, ]; + +pub const MAX_LEGACY_POREP_REGISTERED_PROOF_ID: u64 = 4; + +pub type PoRepID = [u8; 32]; +pub fn is_legacy_porep_id(porep_id: PoRepID) -> bool { + use std::convert::TryInto; + + // NOTE: Because we take only the first 8 bytes, we are actually examining the registered proof type id, + // not the porep_id. The latter requires the full 32 bytes and includes the nonce. + // We are, to some extent depending explictly on the strucuture of the `porep_id`. + // Of course, it happens to be the case that only the 'legacy' ids in question can ever satisfy + // this predicate, so the distinction is somewhat moot. However, for the sake of clarity in any future + // use of `porep_id`, we should pay close attention to this. + let id = u64::from_le_bytes(porep_id[..8].try_into().unwrap()); + id <= MAX_LEGACY_POREP_REGISTERED_PROOF_ID +} diff --git a/storage-proofs/porep/Cargo.toml b/storage-proofs/porep/Cargo.toml index bf5eb5192..17b5c5aa7 100644 --- a/storage-proofs/porep/Cargo.toml +++ b/storage-proofs/porep/Cargo.toml @@ -23,12 +23,12 @@ rayon = "1.0.0" serde = { version = "1.0", features = ["derive"]} serde_json = "1.0" ff = { version = "0.2.3", package = "fff" } -bellperson = { version = "0.11", default-features = false } +bellperson = { version = "0.12", default-features = false } log = "0.4.7" pretty_assertions = "0.6.1" generic-array = "0.14.4" anyhow = "1.0.23" -neptune = { version = "2.1.0", default-features = false, features = ["gpu"] } +neptune = { version = "2.2.0", default-features = false, features = ["gpu"] } num_cpus = "1.10.1" hex = "0.4.2" bincode = "1.1.2" diff --git a/storage-proofs/porep/parent_cache.json b/storage-proofs/porep/parent_cache.json index 761d6ca11..ab20c7a2f 100644 --- a/storage-proofs/porep/parent_cache.json +++ b/storage-proofs/porep/parent_cache.json @@ -1,4 +1,8 @@ { + "v28-sdr-parent-21981246c370f9d76c7a77ab273d94bde0ceb4e938292334960bce05585dc117": { + "sector_size": 34359738368, + "digest": "93deeac5e3052b6927467d4b2641bb782f05491de18d510147c93eeedd8672da" + }, "v28-sdr-parent-2aa9c77c3e58259481351cc4be2079cc71e1c9af39700866545c043bfa30fb42": { "sector_size": 536870912, "digest": "3adcc092423aa76d6a7184016893406da44dd974b219a89cd3ece25e4e3018f5" @@ -7,6 +11,22 @@ "sector_size": 2048, "digest": "3da49221e2ed55371b86d0bf3d6526fcf128af61bed904f966428db1b531750d" }, + "v28-sdr-parent-4905486b7af19558ac3649bc6261411858b6add534438878c4ee3b29d8b9de0b": { + "sector_size": 68719476736, + "digest": "2698b74eb2606b55b98d8b095e18b6320b47f46e00075956d48640ccd1641b03" + }, + "v28-sdr-parent-494d91dc80f2df5272c4b9e129bc7ade9405225993af9fe34e6542a39a47554b": { + "sector_size": 2048, + "digest": "840057702eea7652cf97e04306c30fe57174714d90de156a25eddd6075c25b97" + }, + "v28-sdr-parent-5eed212119fd91aa6220a27f31a8966444a9381842bceb3a1ea61525bd47a5b5": { + "sector_size": 8388608, + "digest": "03cd13565ded97c240a5f52e54295ad127bd0461b57904cb3a4d79b097bbecab" + }, + "v28-sdr-parent-7ba215a1d2345774ab90b8cb1158d296e409d6068819d7b8c7baf0b25d63dc34": { + "sector_size": 536870912, + "digest": "b5877d1963793efebc261fd8fde4dd6bc59e6b5c7abf52617a4ee023b8dc173a" + }, "v28-sdr-parent-8a99e8d6b6be7ab87a56b632e6739ff201c23ea14e99737c74690f0e265574d6": { "sector_size": 68719476736, "digest": "2778a732ad46a7dc18e0564dfdf59fd321dcde74ab476fd6d3c4e6735d7cd89c" diff --git a/storage-proofs/porep/src/lib.rs b/storage-proofs/porep/src/lib.rs index e95bad2de..70e5b62c1 100644 --- a/storage-proofs/porep/src/lib.rs +++ b/storage-proofs/porep/src/lib.rs @@ -44,6 +44,8 @@ pub trait PoRep<'a, H: Hasher, G: Hasher>: ProofScheme<'a> { ) -> Result>; } +pub const MAX_LEGACY_POREP_REGISTERED_PROOF_ID: u64 = 4; + #[cfg(test)] pub(crate) const TEST_SEED: [u8; 16] = [ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, diff --git a/storage-proofs/porep/src/stacked/vanilla/cache.rs b/storage-proofs/porep/src/stacked/vanilla/cache.rs index 12af5b609..601d21de2 100644 --- a/storage-proofs/porep/src/stacked/vanilla/cache.rs +++ b/storage-proofs/porep/src/stacked/vanilla/cache.rs @@ -177,19 +177,30 @@ impl ParentCache { H: Hasher, G: Graph + ParameterSetMetadata + Send + Sync, { - // Check if current entry is part of the official manifest. - // If not, we're dealing with some kind of test sector. - let (parent_cache_data, verify_cache, mut digest_hex) = match get_parent_cache_data(&path) { - None => { - info!("[open] Parent cache data is not supported in production"); - (None, false, "".to_string()) - } - Some(pcd) => ( - Some(pcd), - settings::SETTINGS.verify_cache, - pcd.digest.clone(), - ), - }; + // Check if current entry is part of the official parent cache manifest. If not, we're + // dealing with some kind of test sector. If verify has been requested but it's not a + // production entry in the manifest, we'll calculate the digest so that it can be returned, + // although we don't attempt to match it up to anything. This is useful for the case of + // generating new additions to the parent cache manifest since a valid digest is required. + let (parent_cache_data, verify_cache, is_production, mut digest_hex) = + match get_parent_cache_data(&path) { + None => { + info!("[open] Parent cache data is not supported in production"); + + ( + None, + settings::SETTINGS.verify_cache, + false, // not production since not in manifest + "".to_string(), + ) + } + Some(pcd) => ( + Some(pcd), + settings::SETTINGS.verify_cache, + true, // is_production since it exists in the manifest + pcd.digest.clone(), + ), + }; info!( "parent cache: opening {}, verify enabled: {}", @@ -198,8 +209,6 @@ impl ParentCache { ); if verify_cache { - let parent_cache_data = parent_cache_data.expect("parent_cache_data failure"); - // Always check all of the data for integrity checks, even // if we're only opening a portion of it. let mut hasher = Sha256::new(); @@ -214,30 +223,38 @@ impl ParentCache { drop(data); let hash = hasher.finalize(); - info!("[open] parent cache: calculated consistency digest"); - digest_hex = hash.iter().map(|x| format!("{:01$x}", x, 2)).collect(); - trace!( - "[{}] Comparing {:?} to {:?}", - graph.size() * NODE_SIZE, - digest_hex, - parent_cache_data.digest + info!( + "[open] parent cache: calculated consistency digest: {:?}", + digest_hex ); - if digest_hex == parent_cache_data.digest { - info!("[open] parent cache: cache is verified!"); - } else { - info!( - "[!!!] Parent cache digest mismatch detected. Regenerating {}", - path.display() - ); - ensure!( - Self::generate(len, graph.size() as u32, graph, path.clone()).is_ok(), - "Failed to generate parent cache" + + if is_production { + let parent_cache_data = parent_cache_data.expect("parent_cache_data failure"); + + trace!( + "[{}] Comparing {:?} to {:?}", + graph.size() * NODE_SIZE, + digest_hex, + parent_cache_data.digest ); - // Note that if we wanted the user to manually terminate after repeated - // generation attemps, we could recursively return Self::open(...) here. + if digest_hex == parent_cache_data.digest { + info!("[open] parent cache: cache is verified!"); + } else { + info!( + "[!!!] Parent cache digest mismatch detected. Regenerating {}", + path.display() + ); + ensure!( + Self::generate(len, graph.size() as u32, graph, path.clone()).is_ok(), + "Failed to generate parent cache" + ); + + // Note that if we wanted the user to manually terminate after repeated + // generation attemps, we could recursively return Self::open(...) here. + } } } @@ -293,6 +310,16 @@ impl ParentCache { info!("parent cache: generated"); data.flush().context("failed to flush parent cache")?; + info!("[generate] parent cache: generating consistency digest"); + let mut hasher = Sha256::new(); + hasher.update(&data); + let hash = hasher.finalize(); + digest_hex = hash.iter().map(|x| format!("{:01$x}", x, 2)).collect(); + info!( + "[generate] parent cache: generated consistency digest: {:?}", + digest_hex + ); + // Check if current entry is part of the official manifest and verify // that what we just generated matches what we expect for this entry // (if found). If not, we're dealing with some kind of test sector. @@ -301,14 +328,6 @@ impl ParentCache { info!("[generate] Parent cache data is not supported in production"); } Some(pcd) => { - info!("[generate] parent cache: generating consistency digest"); - let mut hasher = Sha256::new(); - hasher.update(&data); - let hash = hasher.finalize(); - info!("[generate] parent cache: generated consistency digest"); - - digest_hex = hash.iter().map(|x| format!("{:01$x}", x, 2)).collect(); - ensure!( digest_hex == pcd.digest, "Newly generated parent cache is invalid" diff --git a/storage-proofs/porep/src/stacked/vanilla/create_label/multi.rs b/storage-proofs/porep/src/stacked/vanilla/create_label/multi.rs index 36c1d8feb..24f0c546a 100644 --- a/storage-proofs/porep/src/stacked/vanilla/create_label/multi.rs +++ b/storage-proofs/porep/src/stacked/vanilla/create_label/multi.rs @@ -630,17 +630,48 @@ mod tests { let nodes_2k = 1 << 11; let nodes_4k = 1 << 12; let replica_id = [9u8; 32]; - let porep_id = [123; 32]; + + // These PoRepIDs are only useful to distinguish legacy/new sectors. + // They do not correspond to registered proofs of the sizes used here. + let legacy_porep_id = [0; 32]; + let new_porep_id = [123; 32]; test_create_labels_aux( nodes_2k, layers, replica_id, - porep_id, + legacy_porep_id, + Fr::from_repr(FrRepr([ + 0xd3faa96b9a0fba04, + 0xea81a283d106485e, + 0xe3d51b9afa5ac2b3, + 0x0462f4f4f1a68d37, + ])) + .unwrap(), + ); + test_create_labels_aux( + nodes_4k, + layers, + replica_id, + legacy_porep_id, Fr::from_repr(FrRepr([ - 0x1a4017052cbe1c4a, - 0x446354db91e96d8e, - 0xbc864a95454eba0c, - 0x094cf219d72cad06, + 0x7e191e52c4a8da86, + 0x5ae8a1c9e6fac148, + 0xce239f3b88a894b8, + 0x234c00d1dc1d53be, + ])) + .unwrap(), + ); + + test_create_labels_aux( + nodes_2k, + layers, + replica_id, + new_porep_id, + Fr::from_repr(FrRepr([ + 0xabb3f38bb70defcf, + 0x777a2e4d7769119f, + 0x3448959d495490bc, + 0x06021188c7a71cb5, ])) .unwrap(), ); @@ -649,12 +680,12 @@ mod tests { nodes_4k, layers, replica_id, - porep_id, + new_porep_id, Fr::from_repr(FrRepr([ - 0x0a6917a59c51198b, - 0xd2edc96e3717044a, - 0xf438a1131f907206, - 0x084f42888ca2342c, + 0x22ab81cf68c4676d, + 0x7a77a82fc7c9c189, + 0xc6c03d32c1e42d23, + 0x0f777c18cc2c55bd, ])) .unwrap(), ); diff --git a/storage-proofs/porep/src/stacked/vanilla/graph.rs b/storage-proofs/porep/src/stacked/vanilla/graph.rs index 1ef5d31ab..2c4ba9a4f 100644 --- a/storage-proofs/porep/src/stacked/vanilla/graph.rs +++ b/storage-proofs/porep/src/stacked/vanilla/graph.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use std::marker::PhantomData; use anyhow::ensure; @@ -14,9 +14,11 @@ use storage_proofs_core::{ drgraph::{BucketGraph, Graph}, error::Result, hasher::Hasher, + is_legacy_porep_id, parameter_cache::ParameterSetMetadata, settings, util::NODE_SIZE, + PoRepID, }; use super::cache::ParentCache; @@ -36,6 +38,7 @@ where base_graph: G, pub(crate) feistel_keys: [feistel::Index; 4], feistel_precomputed: FeistelPrecomputed, + is_legacy: bool, id: String, _h: PhantomData, } @@ -74,7 +77,7 @@ fn read_node<'a>(i: usize, parents: &[u32], data: &'a [u8]) -> &'a [u8] { &data[start..end] } -pub fn derive_feistel_keys(porep_id: [u8; 32]) -> [u64; 4] { +pub fn derive_feistel_keys(porep_id: PoRepID) -> [u64; 4] { let mut feistel_keys = [0u64; 4]; let raw_seed = derive_porep_domain_seed(FEISTEL_DST, porep_id); feistel_keys[0] = u64::from_le_bytes(raw_seed[0..8].try_into().expect("from_le_bytes failure")); @@ -97,7 +100,7 @@ where nodes: usize, base_degree: usize, expansion_degree: usize, - porep_id: [u8; 32], + porep_id: PoRepID, ) -> Result { assert_eq!(base_degree, BASE_DEGREE); assert_eq!(expansion_degree, EXP_DEGREE); @@ -107,6 +110,7 @@ where Some(graph) => graph, None => G::new(nodes, base_degree, 0, porep_id)?, }; + let bg_id = base_graph.identifier(); let feistel_keys = derive_feistel_keys(porep_id); @@ -120,6 +124,7 @@ where expansion_degree, feistel_keys, feistel_precomputed: feistel::precompute((expansion_degree * nodes) as feistel::Index), + is_legacy: is_legacy_porep_id(porep_id), _h: PhantomData, }; @@ -307,7 +312,7 @@ where nodes: usize, base_degree: usize, expansion_degree: usize, - porep_id: [u8; 32], + porep_id: PoRepID, ) -> Result { Self::new_stacked(nodes, base_degree, expansion_degree, porep_id) } @@ -364,7 +369,14 @@ where &self.feistel_keys, self.feistel_precomputed, ); - transformed as u32 / self.expansion_degree as u32 + + if self.is_legacy { + transformed as u32 / self.expansion_degree as u32 + } else { + u32::try_from(transformed as u64 / self.expansion_degree as u64) + .expect("invalid transformation") + } + // Collapse the output in the matrix search space to the row of the corresponding // node (losing the column information, that will be regenerated later when calling // back this function in the `reversed` direction). @@ -381,7 +393,7 @@ where nodes: usize, base_degree: usize, expansion_degree: usize, - porep_id: [u8; 32], + porep_id: PoRepID, ) -> Result { Self::new(None, nodes, base_degree, expansion_degree, porep_id) } @@ -433,6 +445,22 @@ mod tests { use std::collections::HashSet; + use storage_proofs_core::hasher::PoseidonHasher; + + #[test] + fn test_is_legacy() { + fn p(v: u64) -> PoRepID { + let mut res = [0u8; 32]; + res[..8].copy_from_slice(&v.to_le_bytes()); + res + } + + assert!(is_legacy_porep_id(p(0))); + assert!(is_legacy_porep_id(p(1))); + assert!(is_legacy_porep_id(p(4))); + assert!(!is_legacy_porep_id(p(5))); + } + // Test that 3 (or more) rounds of the Feistel cipher can be used // as a pseudorandom permutation, that is, each input will be mapped // to a unique output (and though not test here, since the cipher @@ -471,4 +499,180 @@ mod tests { // have skipped as duplicates). assert_eq!(shuffled.len(), (n * d) as usize); } + + #[test] + /// The initial implementation had a bug which prevented parents from ever falling in the later half of a sector. + /// In fact, it is even worse than that, in the case of 64GiB sectors. + /// This test demonstrates conclusively that non-legacy graphs do not suffer from this pathology. + /// It also suggests, inconclusively, that legacy graphds do suffer from it (which we already know). + fn test_graph_distribution_pathology() { + let sector32_nodes: u32 = 1 << 30; + let sector64_nodes: u32 = 1 << 31; + + let porep_id = |id: u8| { + let mut porep_id = [0u8; 32]; + porep_id[0] = id; + + porep_id + }; + + test_pathology_aux(porep_id(3), sector32_nodes); + test_pathology_aux(porep_id(4), sector64_nodes); + + test_pathology_aux(porep_id(8), sector32_nodes); + test_pathology_aux(porep_id(9), sector64_nodes); + } + + fn test_pathology_aux(porep_id: PoRepID, nodes: u32) { + // In point of fact, the concrete graphs expected to be non-pathological + // appear to demonstrate this immediately (i.e. in the first node). We + // test more than that just to make the tentative diagnosis of pathology + // more convincing in the cases where we expect it. In the interest of + // keeping the tests brief, we keep this fairly small, though, since we + // already know the previous porep_ids exhibit the problem. The main + // reason to test those cases at all is to convince ourselves the test + // is sound. + let test_n = 1_000; + + let expect_pathological = is_legacy_porep_id(porep_id); + + let graph = StackedBucketGraph::::new_stacked( + nodes as usize, + BASE_DEGREE, + EXP_DEGREE, + porep_id, + ) + .unwrap(); + + // If a parent index is not less than half the total node count, then + // the parent falls in the second half of the previous layer. By the + // definition of 'pathology' used here, that means the graph producing + // this parent is not pathological. + let demonstrably_large_enough = |p: &u32| *p >= (nodes / 2); + + dbg!(&porep_id, &nodes, &expect_pathological); + for i in 0..test_n { + let mut expanded_parents = [0u32; EXP_DEGREE]; + graph.expanded_parents(i, &mut expanded_parents).unwrap(); + + if expect_pathological { + // If we ever see a large-enough parent, then this graph is not + // pathological, so the test fails. + assert!( + !expanded_parents.iter().any(demonstrably_large_enough), + "Expected pathological graph but found large-enough parent." + ); + } else { + if expanded_parents.iter().any(demonstrably_large_enough) { + // If we ever see a large-enough parent, then this graph is + // not pathological, and the test succeeds. This is the only + // way for a test expecting a non-pathological graph to + // succeed, so there is no risk of false negatives (i.e. + // failure to identify pathological graphs when unexpected). + return; + } + } + } + + // If we get here, we did not observe a parent large enough to conclude + // that the graph is not pathological. In that case, the test fails if we + // expected a non-pathological graph and succeeds otherwise. NOTE: this + // could lead us to conclude that an actually non-pathological graph is + // pathological, if `test_n` is set too low. Since the primary purpose + // of this test is to assure us that newer graphs are not pathological, + // it suffices to set `test_n` high enough to detect that. + assert!(expect_pathological, "Did not expect pathological graph, but did not see large-enough parent to prove otherwise."); + } + + // Tests that the set of expander edges has not been truncated. + #[test] + fn test_high_parent_bits() { + // 64GiB sectors have 2^31 nodes. + const N_NODES: usize = 1 << 31; + + // `u32` truncation would reduce the expander edge bit-length from 34 bits to 32 bits, thus + // the first parent truncated would be the node at index `2^32 / EXP_DEGREE = 2^29`. + const FIRST_TRUNCATED_PARENT: u32 = 1 << 29; + + // The number of child nodes to test before failing. This value was chosen arbitrarily and + // can be changed. + const N_CHILDREN_SAMPLED: usize = 3; + + // Non-legacy porep-id. + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&5u64.to_le_bytes()); + + let graph = StackedBucketGraph::::new_stacked( + N_NODES, + BASE_DEGREE, + EXP_DEGREE, + porep_id, + ) + .unwrap(); + + let mut exp_parents = [0u32; EXP_DEGREE]; + for v in 0..N_CHILDREN_SAMPLED { + graph.expanded_parents(v, &mut exp_parents[..]).unwrap(); + if exp_parents.iter().any(|u| *u >= FIRST_TRUNCATED_PARENT) { + return; + } + } + assert!(false); + } + + // Checks that the distribution of parent node indexes within a sector is within a set bound. + #[test] + fn test_exp_parent_histogram() { + // 64GiB sectors have 2^31 nodes. + const N_NODES: usize = 1 << 31; + + // The number of children used to construct the histogram. This value is chosen + // arbitrarily and can be changed. + const N_CHILDREN_SAMPLED: usize = 10000; + + // The number of bins used to partition the set of sector nodes. This value was chosen + // arbitrarily and can be changed to any integer that is a multiple of `EXP_DEGREE` and + // evenly divides `N_NODES`. + const N_BINS: usize = 32; + const N_NODES_PER_BIN: u32 = (N_NODES / N_BINS) as u32; + const PARENT_COUNT_PER_BIN_UNIFORM: usize = N_CHILDREN_SAMPLED * EXP_DEGREE / N_BINS; + + // This test will pass if every bin's parent count is within the bounds: + // `(1 +/- FAILURE_THRESHOLD) * PARENT_COUNT_PER_BIN_UNIFORM`. + const FAILURE_THRESHOLD: f32 = 0.4; + const MAX_PARENT_COUNT_ALLOWED: usize = + ((1.0 + FAILURE_THRESHOLD) * PARENT_COUNT_PER_BIN_UNIFORM as f32) as usize - 1; + const MIN_PARENT_COUNT_ALLOWED: usize = + ((1.0 - FAILURE_THRESHOLD) * PARENT_COUNT_PER_BIN_UNIFORM as f32) as usize + 1; + + // Non-legacy porep-id. + let mut porep_id = [0u8; 32]; + porep_id[..8].copy_from_slice(&5u64.to_le_bytes()); + + let graph = StackedBucketGraph::::new_stacked( + N_NODES, + BASE_DEGREE, + EXP_DEGREE, + porep_id, + ) + .unwrap(); + + // Count the number of parents in each bin. + let mut hist = [0usize; N_BINS]; + let mut exp_parents = [0u32; EXP_DEGREE]; + for sample_index in 0..N_CHILDREN_SAMPLED { + let v = sample_index * N_NODES / N_CHILDREN_SAMPLED; + graph.expanded_parents(v, &mut exp_parents[..]).unwrap(); + for u in exp_parents.iter() { + let bin_index = (u / N_NODES_PER_BIN) as usize; + hist[bin_index] += 1; + } + } + + let success = hist.iter().all(|&n_parents| { + n_parents >= MIN_PARENT_COUNT_ALLOWED && n_parents <= MAX_PARENT_COUNT_ALLOWED + }); + + assert!(success); + } } diff --git a/storage-proofs/porep/src/stacked/vanilla/proof.rs b/storage-proofs/porep/src/stacked/vanilla/proof.rs index 1829380e7..93032d079 100644 --- a/storage-proofs/porep/src/stacked/vanilla/proof.rs +++ b/storage-proofs/porep/src/stacked/vanilla/proof.rs @@ -1857,17 +1857,46 @@ mod tests { let nodes_2k = 1 << 11; let nodes_4k = 1 << 12; let replica_id = [9u8; 32]; + let legacy_porep_id = [0; 32]; let porep_id = [123; 32]; + test_generate_labels_aux( + nodes_2k, + layers, + replica_id, + legacy_porep_id, + Fr::from_repr(FrRepr([ + 0xd3faa96b9a0fba04, + 0xea81a283d106485e, + 0xe3d51b9afa5ac2b3, + 0x0462f4f4f1a68d37, + ])) + .unwrap(), + ); + + test_generate_labels_aux( + nodes_4k, + layers, + replica_id, + legacy_porep_id, + Fr::from_repr(FrRepr([ + 0x7e191e52c4a8da86, + 0x5ae8a1c9e6fac148, + 0xce239f3b88a894b8, + 0x234c00d1dc1d53be, + ])) + .unwrap(), + ); + test_generate_labels_aux( nodes_2k, layers, replica_id, porep_id, Fr::from_repr(FrRepr([ - 0x1a4017052cbe1c4a, - 0x446354db91e96d8e, - 0xbc864a95454eba0c, - 0x094cf219d72cad06, + 0xabb3f38bb70defcf, + 0x777a2e4d7769119f, + 0x3448959d495490bc, + 0x06021188c7a71cb5, ])) .unwrap(), ); @@ -1878,10 +1907,10 @@ mod tests { replica_id, porep_id, Fr::from_repr(FrRepr([ - 0x0a6917a59c51198b, - 0xd2edc96e3717044a, - 0xf438a1131f907206, - 0x084f42888ca2342c, + 0x22ab81cf68c4676d, + 0x7a77a82fc7c9c189, + 0xc6c03d32c1e42d23, + 0x0f777c18cc2c55bd, ])) .unwrap(), ); diff --git a/storage-proofs/post/Cargo.toml b/storage-proofs/post/Cargo.toml index 135324635..695d3dba0 100644 --- a/storage-proofs/post/Cargo.toml +++ b/storage-proofs/post/Cargo.toml @@ -20,12 +20,12 @@ serde = { version = "1.0", features = ["derive"]} blake2b_simd = "0.5" blake2s_simd = "0.5" ff = { version = "0.2.3", package = "fff" } -bellperson = { version = "0.11", default-features = false } +bellperson = { version = "0.12", default-features = false } log = "0.4.7" hex = "0.4.0" generic-array = "0.14.4" anyhow = "1.0.23" -neptune = { version = "2.1.0", default-features = false, features = ["gpu"] } +neptune = { version = "2.2.0", default-features = false, features = ["gpu"] } num_cpus = "1.10.1" [dev-dependencies] @@ -38,4 +38,3 @@ default = ["pairing", "gpu"] gpu = ["storage-proofs-core/gpu"] pairing = ["storage-proofs-core/pairing", "bellperson/pairing", "neptune/pairing"] blst = ["storage-proofs-core/blst", "bellperson/blst", "neptune/blst"] -