diff --git a/primitives/src/vid/advz.rs b/primitives/src/vid/advz.rs index 187c5799d..182baf31d 100644 --- a/primitives/src/vid/advz.rs +++ b/primitives/src/vid/advz.rs @@ -128,20 +128,22 @@ where /// Return [`VidError::Argument`] if `num_storage_nodes < /// payload_chunk_size`. pub(crate) fn new_internal( - payload_chunk_size: usize, // k - num_storage_nodes: usize, // n (code rate: r = k/n) - multiplicity: usize, // batch m chunks, keep the rate r = (m*k)/(m*n) + erasure_code_rate: usize, // inverse of r + num_storage_nodes: usize, // n + multiplicity: usize, // m srs: impl Borrow>, ) -> VidResult { - // TODO support any degree, give multiple shares to nodes if needed - // https://github.com/EspressoSystems/jellyfish/issues/393 - if num_storage_nodes < payload_chunk_size { + // return error if rate r > 1 (implied by erasure_code_rate < 1) + if erasure_code_rate < 1 { return Err(VidError::Argument(format!( - "payload_chunk_size {} exceeds num_storage_nodes {}", - payload_chunk_size, num_storage_nodes + "erasure_code_rate {} should be greater than 1", + erasure_code_rate ))); } + // payload_chunk_size: k = r*n + let payload_chunk_size = num_storage_nodes.div_ceil(erasure_code_rate); + if !(1..=16).contains(&multiplicity) || !multiplicity.is_power_of_two() { return Err(VidError::Argument(format!( "multiplicity {} not allowed", @@ -211,20 +213,20 @@ where { /// Construct a new VID instance /// - /// - `payload_chunk_size`: k - /// - `num_storage_nodes`: n (code rate: r = k/n) + /// - `erasure_code_rate`: r + /// - `num_storage_nodes`: n (payload_chunk_size: k = r*n) /// - `multiplicity`: batch m chunks, keep the rate r = (m*k)/(m*n) /// /// # Errors /// Return [`VidError::Argument`] if `num_storage_nodes < /// payload_chunk_size`. pub fn new( - payload_chunk_size: usize, + erasure_code_rate: usize, num_storage_nodes: usize, multiplicity: usize, srs: impl Borrow>, ) -> VidResult { - Self::new_internal(payload_chunk_size, num_storage_nodes, multiplicity, srs) + Self::new_internal(erasure_code_rate, num_storage_nodes, multiplicity, srs) } } @@ -236,21 +238,20 @@ where { /// construct a new VID instance with SRS loaded to GPU /// - /// - `payload_chunk_size`: k - /// - `num_storage_nodes`: n (code rate: r = k/n) + /// - `erasure_code_rate`: r + /// - `num_storage_nodes`: n (payload_chunk_size: k = r*n) /// - `multiplicity`: batch m chunks, keep the rate r = (m*k)/(m*n) /// /// # Errors /// Return [`VidError::Argument`] if `num_storage_nodes < /// payload_chunk_size`. pub fn new( - payload_chunk_size: usize, + erasure_code_rate: usize, num_storage_nodes: usize, multiplicity: usize, srs: impl Borrow>, ) -> VidResult { - let mut advz = - Self::new_internal(payload_chunk_size, num_storage_nodes, multiplicity, srs)?; + let mut advz = Self::new_internal(erasure_code_rate, num_storage_nodes, multiplicity, srs)?; let srs_on_gpu = as GPUCommittable>::load_prover_param_to_gpu( &advz.ck, advz.ck.powers_of_g.len() - 1, @@ -969,15 +970,21 @@ mod tests { #[test] fn disperse_timer() { // run with 'print-trace' feature to see timer output - let (payload_chunk_size, num_storage_nodes) = (256, 512); + let (erasure_code_rate, num_storage_nodes, multiplicity) = (4usize, 512usize, 1usize); + let payload_chunk_size = num_storage_nodes.div_ceil(erasure_code_rate); let mut rng = jf_utils::test_rng(); - let srs = init_srs(payload_chunk_size, &mut rng); + let srs = init_srs(payload_chunk_size * multiplicity, &mut rng); let mut advz = - Advz::::new(payload_chunk_size, num_storage_nodes, 1, srs).unwrap(); - #[cfg(feature = "gpu-vid")] - let mut advz_gpu = - AdvzGPU::<'_, Bn254, Sha256>::new(payload_chunk_size, num_storage_nodes, 1, &srs) + Advz::::new(erasure_code_rate, num_storage_nodes, multiplicity, srs) .unwrap(); + #[cfg(feature = "gpu-vid")] + let mut advz_gpu = AdvzGPU::<'_, Bn254, Sha256>::new( + erasure_code_rate, + num_storage_nodes, + multiplicity, + &srs, + ) + .unwrap(); let payload_random = init_random_payload(1 << 25, &mut rng); @@ -990,14 +997,16 @@ mod tests { #[test] fn commit_only_timer() { // run with 'print-trace' feature to see timer output - let (payload_chunk_size, num_storage_nodes) = (256, 512); + let (erasure_code_rate, num_storage_nodes, multiplicity) = (2usize, 512usize, 1usize); + let payload_chunk_size = num_storage_nodes.div_ceil(erasure_code_rate); let mut rng = jf_utils::test_rng(); - let srs = init_srs(payload_chunk_size, &mut rng); + let srs = init_srs(payload_chunk_size * multiplicity, &mut rng); let mut advz = - Advz::::new(payload_chunk_size, num_storage_nodes, 1, srs).unwrap(); + Advz::::new(erasure_code_rate, num_storage_nodes, multiplicity, srs) + .unwrap(); #[cfg(feature = "gpu-vid")] let mut advz_gpu = - AdvzGPU::<'_, Bn254, Sha256>::new(payload_chunk_size, num_storage_nodes, 1, &srs) + AdvzGPU::<'_, Bn254, Sha256>::new(erasure_code_rate, num_storage_nodes, 1, &srs) .unwrap(); let payload_random = init_random_payload(1 << 25, &mut rng); @@ -1207,10 +1216,12 @@ mod tests { /// 1. An initialized [`Advz`] instance. /// 2. A `Vec` filled with random bytes. pub(super) fn advz_init() -> (Advz, Vec) { - let (payload_chunk_size, num_storage_nodes) = (4, 6); + // run with 'print-trace' feature to see timer output + let (erasure_code_rate, num_storage_nodes) = (3usize, 6usize); + let payload_chunk_size = num_storage_nodes.div_ceil(erasure_code_rate); let mut rng = jf_utils::test_rng(); let srs = init_srs(payload_chunk_size, &mut rng); - let advz = Advz::new(payload_chunk_size, num_storage_nodes, 1, srs).unwrap(); + let advz = Advz::new(erasure_code_rate, num_storage_nodes, 1, srs).unwrap(); let bytes_random = init_random_payload(4000, &mut rng); (advz, bytes_random) } diff --git a/primitives/tests/advz.rs b/primitives/tests/advz.rs index e0305a9f6..f54b3a555 100644 --- a/primitives/tests/advz.rs +++ b/primitives/tests/advz.rs @@ -13,7 +13,7 @@ mod vid; #[test] fn round_trip() { // play with these items - let vid_sizes = [(2, 3), (8, 11)]; + let vid_sizes = [(2, 3), (3, 11)]; let payload_byte_lens = [0, 1, 2, 16, 32, 47, 48, 49, 64, 100, 400]; let mut multiplicities = [1, 2, 4, 8, 16]; @@ -34,14 +34,9 @@ fn round_trip() { ); vid::round_trip( - |payload_chunk_size, num_storage_nodes, multiplicity| { - Advz::::new( - payload_chunk_size, - num_storage_nodes, - multiplicity, - &srs, - ) - .unwrap() + |erasure_code_rate, num_storage_nodes, multiplicity| { + Advz::::new(erasure_code_rate, num_storage_nodes, multiplicity, &srs) + .unwrap() }, &vid_sizes, &multiplicities, diff --git a/primitives/tests/vid/mod.rs b/primitives/tests/vid/mod.rs index 229f0a5e4..95c3afeca 100644 --- a/primitives/tests/vid/mod.rs +++ b/primitives/tests/vid/mod.rs @@ -21,16 +21,17 @@ pub fn round_trip( V: VidScheme, R: RngCore + CryptoRng, { - for (&mult, &(payload_chunk_size, num_storage_nodes)) in + for (&mult, &(erasure_code_rate, num_storage_nodes)) in zip(multiplicities.iter().cycle(), vid_sizes) { - let mut vid = vid_factory(payload_chunk_size, num_storage_nodes, mult); + let mut vid = vid_factory(erasure_code_rate, num_storage_nodes, mult); for &len in payload_byte_lens { println!( - "m: {} n: {} mult: {} byte_len: {}", - payload_chunk_size, num_storage_nodes, mult, len + "r: {} n: {} mult: {} byte_len: {}", + erasure_code_rate, num_storage_nodes, mult, len ); + let payload_chunk_size = num_storage_nodes.div_ceil(erasure_code_rate); let bytes_random = { let mut bytes_random = vec![0u8; len];