Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ZKS-04] Fixes the maximum transmissions per batch, increases the transactions per block #2198

Merged
merged 12 commits into from
Nov 30, 2023
Merged
6 changes: 3 additions & 3 deletions circuit/program/src/state_path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,16 @@ mod tests {

#[test]
fn test_state_path_new_constant() -> Result<()> {
check_new(Mode::Constant, 446, 1, 0, 0)
check_new(Mode::Constant, 450, 1, 0, 0)
}

#[test]
fn test_state_path_new_public() -> Result<()> {
check_new(Mode::Public, 0, 447, 0, 376)
check_new(Mode::Public, 0, 451, 0, 376)
}

#[test]
fn test_state_path_new_private() -> Result<()> {
check_new(Mode::Private, 0, 1, 446, 376)
check_new(Mode::Private, 0, 1, 450, 376)
}
}
36 changes: 18 additions & 18 deletions circuit/program/src/state_path/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,43 +225,43 @@ mod tests {

#[test]
fn test_state_path_verify_global_constant() -> Result<()> {
check_verify_global(Mode::Constant, true, 106309, 1, 2, 2)?;
check_verify_global(Mode::Constant, false, 106309, 1, 2, 2)
check_verify_global(Mode::Constant, true, 112709, 1, 2, 2)?;
check_verify_global(Mode::Constant, false, 112709, 1, 2, 2)
}

#[test]
fn test_state_path_verify_global_public() -> Result<()> {
check_verify_global(Mode::Public, true, 27814, 449, 123343, 123982)?;
check_verify_global(Mode::Public, false, 27814, 449, 123343, 123982)
check_verify_global(Mode::Public, true, 29450, 453, 130867, 131522)?;
check_verify_global(Mode::Public, false, 29450, 453, 130867, 131522)
}

#[test]
fn test_state_path_verify_global_private() -> Result<()> {
check_verify_global(Mode::Private, true, 27814, 1, 123791, 123982)?;
check_verify_global(Mode::Private, false, 27814, 1, 123791, 123982)
check_verify_global(Mode::Private, true, 29450, 1, 131319, 131522)?;
check_verify_global(Mode::Private, false, 29450, 1, 131319, 131522)
}

#[test]
fn test_state_path_verify_local_constant() -> Result<()> {
check_verify_local(Mode::Constant, false, true, 106309, 1, 2, 2)?;
check_verify_local(Mode::Constant, false, false, 106309, 1, 2, 2)?;
check_verify_local(Mode::Constant, true, true, 106309, 1, 2, 2)?;
check_verify_local(Mode::Constant, true, false, 106309, 1, 2, 2)
check_verify_local(Mode::Constant, false, true, 112709, 1, 2, 2)?;
check_verify_local(Mode::Constant, false, false, 112709, 1, 2, 2)?;
check_verify_local(Mode::Constant, true, true, 112709, 1, 2, 2)?;
check_verify_local(Mode::Constant, true, false, 112709, 1, 2, 2)
}

#[test]
fn test_state_path_verify_local_public() -> Result<()> {
check_verify_local(Mode::Public, false, true, 27814, 449, 123343, 123982)?;
check_verify_local(Mode::Public, false, false, 27814, 449, 123343, 123982)?;
check_verify_local(Mode::Public, true, true, 27814, 449, 123343, 123982)?;
check_verify_local(Mode::Public, true, false, 27814, 449, 123343, 123982)
check_verify_local(Mode::Public, false, true, 29450, 453, 130867, 131522)?;
check_verify_local(Mode::Public, false, false, 29450, 453, 130867, 131522)?;
check_verify_local(Mode::Public, true, true, 29450, 453, 130867, 131522)?;
check_verify_local(Mode::Public, true, false, 29450, 453, 130867, 131522)
}

#[test]
fn test_state_path_verify_local_private() -> Result<()> {
check_verify_local(Mode::Private, false, true, 27814, 1, 123791, 123982)?;
check_verify_local(Mode::Private, false, false, 27814, 1, 123791, 123982)?;
check_verify_local(Mode::Private, true, true, 27814, 1, 123791, 123982)?;
check_verify_local(Mode::Private, true, false, 27814, 1, 123791, 123982)
check_verify_local(Mode::Private, false, true, 29450, 1, 131319, 131522)?;
check_verify_local(Mode::Private, false, false, 29450, 1, 131319, 131522)?;
check_verify_local(Mode::Private, true, true, 29450, 1, 131319, 131522)?;
check_verify_local(Mode::Private, true, false, 29450, 1, 131319, 131522)
}
}
4 changes: 2 additions & 2 deletions console/program/src/state_path/configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ pub const RATIFICATIONS_DEPTH: u8 = 16;
/// The depth the Merkle tree for the subdag certificates in a block.
pub const SUBDAG_CERTIFICATES_DEPTH: u8 = 16;
/// The depth of the Merkle tree for transactions in a block.
/// Note: The technical limit is 2^16 - 1 transactions, to allow compatibility with the
/// Note: The technical limit is 2^20 - 1 transactions, to allow compatibility with the
/// finalize operations tree, which requires 1 leaf for the ratified finalize ID.
pub const TRANSACTIONS_DEPTH: u8 = 16;
pub const TRANSACTIONS_DEPTH: u8 = 20;
/// The depth of the Merkle tree for the transaction.
pub const TRANSACTION_DEPTH: u8 = 5;
/// The depth of the Merkle tree for the transition.
Expand Down
17 changes: 13 additions & 4 deletions ledger/block/src/transactions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,23 @@ pub mod test_helpers {
#[cfg(test)]
mod tests {
use super::*;
use ledger_narwhal_batch_header::BatchHeader;

type CurrentNetwork = console::network::Testnet3;

#[test]
fn test_max_transactions() {
assert_eq!(
Transactions::<CurrentNetwork>::MAX_TRANSACTIONS,
ledger_narwhal_batch_header::BatchHeader::<CurrentNetwork>::MAX_TRANSACTIONS
fn test_max_transmissions() {
// Determine the maximum number of transmissions in a block.
let max_transmissions_per_block = BatchHeader::<CurrentNetwork>::MAX_TRANSMISSIONS_PER_BATCH
* usize::try_from(BatchHeader::<CurrentNetwork>::MAX_GC_ROUNDS).unwrap()
* BatchHeader::<CurrentNetwork>::MAX_CERTIFICATES as usize;

// Note: The maximum number of *transmissions* in a block cannot exceed the maximum number of *transactions* in a block.
// If you intended to change the number of 'MAX_TRANSACTIONS', note that this will break the inclusion proof,
// and you will need to migrate all users to a new circuit for the inclusion proof.
assert!(
max_transmissions_per_block <= Transactions::<CurrentNetwork>::MAX_TRANSACTIONS,
"The maximum number of transmissions in a block is too large"
);
}
}
4 changes: 2 additions & 2 deletions ledger/block/src/transition/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<N: Network> Transition<N> {
// Check if the input ID matches the given ID.
if id == input.id() {
// Return the transition leaf.
return Ok(input.to_transition_leaf(index as u8));
return Ok(input.to_transition_leaf(u8::try_from(index)?));
}
}
// Error if the input ID was not found.
Expand All @@ -48,7 +48,7 @@ impl<N: Network> Transition<N> {
// Check if the output ID matches the given ID.
if id == output.id() {
// Return the transition leaf.
return Ok(output.to_transition_leaf((self.inputs.len() + index) as u8));
return Ok(output.to_transition_leaf(u8::try_from(self.inputs.len() + index)?));
}
}
// Error if the output ID was not found.
Expand Down
8 changes: 4 additions & 4 deletions ledger/committee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ package = "snarkvm-console"
path = "../../console"
version = "=0.16.11"

[dependencies.ledger-narwhal-batch-header]
package = "snarkvm-ledger-narwhal-batch-header"
path = "../narwhal/batch-header"

[dependencies.indexmap]
version = "2.0"
features = [ "serde", "rayon" ]
Expand Down Expand Up @@ -82,7 +86,3 @@ version = "1"
[dev-dependencies.snarkvm-ledger-committee]
path = "."
features = [ "prop-tests" ]

[dev-dependencies.ledger-narwhal-batch-header]
package = "snarkvm-ledger-narwhal-batch-header"
path = "../narwhal/batch-header"
8 changes: 3 additions & 5 deletions ledger/committee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use console::{
};

use indexmap::IndexMap;
use ledger_narwhal_batch_header::BatchHeader;
use std::collections::HashSet;

/// The minimum amount of stake required for a validator to bond.
Expand All @@ -45,7 +46,7 @@ pub struct Committee<N: Network> {

impl<N: Network> Committee<N> {
/// The maximum number of members that may be in a committee.
pub const MAX_COMMITTEE_SIZE: u16 = 200;
pub const MAX_COMMITTEE_SIZE: u16 = BatchHeader::<N>::MAX_CERTIFICATES;

/// Initializes a new `Committee` instance.
pub fn new_genesis(members: IndexMap<Address<N>, (u64, bool)>) -> Result<Self> {
Expand Down Expand Up @@ -447,9 +448,6 @@ mod tests {

#[test]
fn test_maximum_committee_size() {
assert_eq!(
Committee::<CurrentNetwork>::MAX_COMMITTEE_SIZE as usize,
ledger_narwhal_batch_header::BatchHeader::<CurrentNetwork>::MAX_CERTIFICATES
);
assert_eq!(Committee::<CurrentNetwork>::MAX_COMMITTEE_SIZE, BatchHeader::<CurrentNetwork>::MAX_CERTIFICATES);
}
}
10 changes: 5 additions & 5 deletions ledger/narwhal/batch-header/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ impl<N: Network> FromBytes for BatchHeader<N> {
// Read the number of transmission IDs.
let num_transmission_ids = u32::read_le(&mut reader)?;
// Ensure the number of transmission IDs is within bounds.
if num_transmission_ids as usize > Self::MAX_TRANSMISSIONS {
if num_transmission_ids as usize > Self::MAX_TRANSMISSIONS_PER_BATCH {
return Err(error(format!(
"Number of transmission IDs ({num_transmission_ids}) exceeds the maximum ({})",
Self::MAX_TRANSMISSIONS,
Self::MAX_TRANSMISSIONS_PER_BATCH,
)));
}
// Read the transmission IDs.
Expand All @@ -50,9 +50,9 @@ impl<N: Network> FromBytes for BatchHeader<N> {
}

// Read the number of previous certificate IDs.
let num_previous_certificate_ids = u32::read_le(&mut reader)?;
let num_previous_certificate_ids = u16::read_le(&mut reader)?;
// Ensure the number of previous certificate IDs is within bounds.
if num_previous_certificate_ids as usize > Self::MAX_CERTIFICATES {
if num_previous_certificate_ids > Self::MAX_CERTIFICATES {
return Err(error(format!(
"Number of previous certificate IDs ({num_previous_certificate_ids}) exceeds the maximum ({})",
Self::MAX_CERTIFICATES
Expand Down Expand Up @@ -101,7 +101,7 @@ impl<N: Network> ToBytes for BatchHeader<N> {
transmission_id.write_le(&mut writer)?;
}
// Write the number of previous certificate IDs.
u32::try_from(self.previous_certificate_ids.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
u16::try_from(self.previous_certificate_ids.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
// Write the previous certificate IDs.
for certificate_id in &self.previous_certificate_ids {
// Write the certificate ID.
Expand Down
13 changes: 7 additions & 6 deletions ledger/narwhal/batch-header/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ pub struct BatchHeader<N: Network> {

impl<N: Network> BatchHeader<N> {
/// The maximum number of certificates in a batch.
pub const MAX_CERTIFICATES: usize = 200;
/// The maximum number of solutions in a batch.
pub const MAX_SOLUTIONS: usize = N::MAX_SOLUTIONS;
/// The maximum number of transactions in a batch.
pub const MAX_TRANSACTIONS: usize = usize::pow(2, console::program::TRANSACTIONS_DEPTH as u32).saturating_sub(1);
pub const MAX_CERTIFICATES: u16 = 200;
/// The maximum number of rounds to store before garbage collecting.
pub const MAX_GC_ROUNDS: u64 = 100;
/// The maximum number of transmissions in a batch.
pub const MAX_TRANSMISSIONS: usize = Self::MAX_SOLUTIONS + Self::MAX_TRANSACTIONS;
/// Note: This limit is set to 50 as part of safety measures to prevent DoS attacks.
/// This limit can be increased in the future as performance improves. Alternatively,
/// the rate of block production can be sped up to compensate for the limit set here.
pub const MAX_TRANSMISSIONS_PER_BATCH: usize = 50;
}

impl<N: Network> BatchHeader<N> {
Expand Down
8 changes: 4 additions & 4 deletions ledger/narwhal/subdag/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl<N: Network> FromBytes for Subdag<N> {
// Read the number of rounds.
let num_rounds = u32::read_le(&mut reader)?;
// Ensure the number of rounds is within bounds.
if num_rounds as usize > Self::MAX_ROUNDS {
if num_rounds as u64 > Self::MAX_ROUNDS {
return Err(error(format!("Number of rounds ({num_rounds}) exceeds the maximum ({})", Self::MAX_ROUNDS)));
}
// Read the round certificates.
Expand All @@ -36,9 +36,9 @@ impl<N: Network> FromBytes for Subdag<N> {
// Read the round.
let round = u64::read_le(&mut reader)?;
// Read the number of certificates.
let num_certificates = u32::read_le(&mut reader)?;
let num_certificates = u16::read_le(&mut reader)?;
// Ensure the number of certificates is within bounds.
if num_certificates as usize > BatchHeader::<N>::MAX_CERTIFICATES {
if num_certificates > BatchHeader::<N>::MAX_CERTIFICATES {
return Err(error(format!(
"Number of certificates ({num_certificates}) exceeds the maximum ({})",
BatchHeader::<N>::MAX_CERTIFICATES
Expand Down Expand Up @@ -70,7 +70,7 @@ impl<N: Network> ToBytes for Subdag<N> {
// Write the round.
round.write_le(&mut writer)?;
// Write the number of certificates.
u32::try_from(certificates.len()).map_err(error)?.write_le(&mut writer)?;
u16::try_from(certificates.len()).map_err(error)?.write_le(&mut writer)?;
// Write the certificates.
for certificate in certificates {
// Write the certificate.
Expand Down
31 changes: 25 additions & 6 deletions ledger/narwhal/subdag/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<N: Network> Subdag<N> {

impl<N: Network> Subdag<N> {
/// The maximum number of rounds in a subdag (bounded up to GC depth).
pub const MAX_ROUNDS: usize = 50;
pub const MAX_ROUNDS: u64 = BatchHeader::<N>::MAX_GC_ROUNDS;
}

impl<N: Network> Subdag<N> {
Expand Down Expand Up @@ -159,7 +159,7 @@ impl<N: Network> Subdag<N> {
}
}

/// Returns the subdag root of the transactions.
/// Returns the subdag root of the certificates.
pub fn to_subdag_root(&self) -> Result<Field<N>> {
// Prepare the leaves.
let leaves = cfg_iter!(self.subdag)
Expand All @@ -168,10 +168,8 @@ impl<N: Network> Subdag<N> {
})
.collect::<Vec<_>>();

// Compute the subdag tree.
let tree = N::merkle_tree_bhp::<SUBDAG_CERTIFICATES_DEPTH>(&leaves)?;
// Return the subdag root.
Ok(*tree.root())
// Compute the subdag root.
Ok(*N::merkle_tree_bhp::<SUBDAG_CERTIFICATES_DEPTH>(&leaves)?.root())
}
}

Expand Down Expand Up @@ -255,3 +253,24 @@ pub mod test_helpers {
sample
}
}

#[cfg(test)]
mod tests {
use super::*;
use narwhal_batch_header::BatchHeader;

type CurrentNetwork = console::network::Testnet3;

#[test]
fn test_max_certificates() {
// Determine the maximum number of certificates in a block.
let max_certificates_per_block = usize::try_from(BatchHeader::<CurrentNetwork>::MAX_GC_ROUNDS).unwrap()
* BatchHeader::<CurrentNetwork>::MAX_CERTIFICATES as usize;

// Note: The maximum number of certificates in a block must be able to be Merklized.
assert!(
max_certificates_per_block <= 2u32.checked_pow(SUBDAG_CERTIFICATES_DEPTH as u32).unwrap() as usize,
"The maximum number of certificates in a block is too large"
);
}
}
Binary file modified parameters/src/testnet3/resources/block.genesis
Binary file not shown.
6 changes: 3 additions & 3 deletions parameters/src/testnet3/resources/inclusion.metadata
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"prover_checksum": "cd85cc53639becf39b9fc927643abda23f9d385ff2cb890f5df809e7a338bff8",
"prover_size": 232051458,
"verifier_checksum": "e6f3add8fb9f911e02e1aa08b761f24cc8ae5fb70df4da47a36a5bbb83b189ec",
"prover_checksum": "2ccd040f31b1ee3a1e8ed64b046b5f6a81403d434439e40d35a62c734365c7e7",
"prover_size": 233812212,
"verifier_checksum": "cc0dbd07fea975bb869db792e62647d3a17cd3e75228a34e860665f8394424fd",
"verifier_size": 665
}
Binary file modified parameters/src/testnet3/resources/inclusion.verifier
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ outputs:
test_rand.aleo/rand_chacha_check:
outputs:
- '{"type":"future","id":"3721325135151760660773959530505944451747681933722462808964783147996869797702field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 0field,\n false\n ]\n}"}'
speculate: the execution was accepted
speculate: the execution was rejected
add_next_block: succeeded.
- verified: true
execute:
test_rand.aleo/rand_chacha_check:
outputs:
- '{"type":"future","id":"887371549615679800380522845098080464570119184210350810479392117984911457950field","value":"{\n program_id: test_rand.aleo,\n function_name: rand_chacha_check,\n arguments: [\n 1field,\n true\n ]\n}"}'
speculate: the execution was accepted
speculate: the execution was rejected
add_next_block: succeeded.
additional:
- child_outputs:
Expand Down