Skip to content

Commit

Permalink
Merge pull request #2198 from AleoHQ/feat/max-transmissions-limit
Browse files Browse the repository at this point in the history
Fixes the maximum transmissions per batch, increases the transactions per block
  • Loading branch information
howardwu authored Nov 30, 2023
2 parents 6c1d418 + 3300460 commit 6fb21fb
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 60 deletions.
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
4 changes: 4 additions & 0 deletions ledger/committee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ package = "snarkvm-console"
path = "../../console"
version = "=0.16.12"

[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
8 changes: 3 additions & 5 deletions ledger/committee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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 @@ -48,7 +49,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 @@ -451,9 +452,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

0 comments on commit 6fb21fb

Please sign in to comment.