From 4e00085b5ca31e975aa4f334e783b6e23fa6a584 Mon Sep 17 00:00:00 2001 From: miazn Date: Wed, 13 Mar 2024 17:01:34 -0700 Subject: [PATCH 01/72] add metrics for transmission latency and stale transmissions --- node/consensus/src/lib.rs | 53 +++++++++++++++++++++++++++++++++++++-- node/metrics/src/names.rs | 10 ++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index af0b568c01..5ff5b063f2 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -52,6 +52,8 @@ use tokio::{ sync::{oneshot, OnceCell}, task::JoinHandle, }; +#[cfg(feature = "metrics")] +use std::collections::HashMap; /// Percentage of mempool transactions capacity reserved for deployments. const CAPACITY_FOR_DEPLOYMENTS: usize = 20; @@ -97,6 +99,8 @@ pub struct Consensus { seen_transactions: Arc>>, /// The spawned handles. handles: Arc>>>, + #[cfg(feature = "metrics")] + transmissions_queue_timestamps: Arc, i64>>>, } impl Consensus { @@ -131,6 +135,8 @@ impl Consensus { seen_solutions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), handles: Default::default(), + #[cfg(feature = "metrics")] + transmissions_queue_timestamps: Arc::new(Mutex::new(HashMap::new())) }) } @@ -216,6 +222,7 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); + self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); } // Process the unconfirmed solution. { @@ -274,6 +281,7 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); + self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); } // Process the unconfirmed transaction. { @@ -404,7 +412,7 @@ impl Consensus { let current_block_timestamp = self.ledger.latest_block().header().metadata().timestamp(); // Create the candidate next block. - let next_block = self.ledger.prepare_advance_to_next_quorum_block(subdag, transmissions)?; + let next_block = self.ledger.prepare_advance_to_next_quorum_block(subdag, transmissions)?; // Check that the block is well-formed. self.ledger.check_next_block(&next_block)?; // Advance to the next block. @@ -419,6 +427,8 @@ impl Consensus { let num_tx = next_block.transactions().len(); let num_transmissions = num_tx + num_sol; + self.add_transmission_latency_metric(&next_block); + metrics::gauge(metrics::blocks::HEIGHT, next_block.height() as f64); metrics::increment_gauge(metrics::blocks::SOLUTIONS, num_sol as f64); metrics::increment_gauge(metrics::blocks::TRANSACTIONS, num_tx as f64); @@ -427,10 +437,49 @@ impl Consensus { metrics::gauge(metrics::consensus::COMMITTED_CERTIFICATES, num_committed_certificates as f64); metrics::histogram(metrics::consensus::CERTIFICATE_COMMIT_LATENCY, elapsed.as_secs_f64()); metrics::histogram(metrics::consensus::BLOCK_LATENCY, block_latency as f64); - } + } Ok(()) } + #[cfg(feature = "metrics")] + fn add_transmission_latency_metric(&self, next_block: &Block) { + let age_threshold_seconds = 30 * 60; // 30 minutes set as stale transmission threshold + + let mut keys_to_remove = Vec::new(); + let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); + + let solution_ids: std::collections::HashSet<_> = next_block.solutions().solution_ids().collect(); + let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().collect(); + + for (key, timestamp) in transmission_queue_timestamps.iter() { + let elapsed_time = std::time::Duration::from_secs((snarkos_node_bft::helpers::now() - *timestamp) as u64); + + if elapsed_time.as_secs() > age_threshold_seconds as u64 { + // This entry is stale-- remove it from transmission queue and record it as a stale transmission + metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); + keys_to_remove.push(key.clone()); + } else { + let transmission_type = match key { + TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), + TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => Some("transaction"), + _ => None, + }; + + if let Some(transmission_type_string) = transmission_type { + metrics::histogram_label(metrics::consensus::TRANSMISSION_LATENCY, "transmission_type", transmission_type_string.to_string(), elapsed_time.as_secs_f64()); + keys_to_remove.push(key.clone()); + } else { + continue + } + } + } + + // Remove keys of stale or seen transmissions + for key in keys_to_remove { + transmission_queue_timestamps.remove(&key); + } + } + /// Reinserts the given transmissions into the memory pool. async fn reinsert_transmissions(&self, transmissions: IndexMap, Transmission>) { // Iterate over the transmissions. diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 7afcc59845..0c01c8738c 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(super) const COUNTER_NAMES: [&str; 1] = [bft::LEADERS_ELECTED]; +pub(super) const COUNTER_NAMES: [&str; 2] = [ + bft::LEADERS_ELECTED, + consensus::STALE_UNCONFIRMED_TRANSMISSIONS, +]; pub(super) const GAUGE_NAMES: [&str; 18] = [ bft::CONNECTED, @@ -35,10 +38,11 @@ pub(super) const GAUGE_NAMES: [&str; 18] = [ tcp::TCP_TASKS, ]; -pub(super) const HISTOGRAM_NAMES: [&str; 7] = [ +pub(super) const HISTOGRAM_NAMES: [&str; 8] = [ bft::COMMIT_ROUNDS_LATENCY, consensus::CERTIFICATE_COMMIT_LATENCY, consensus::BLOCK_LATENCY, + consensus::TRANSMISSION_LATENCY, tcp::NOISE_CODEC_ENCRYPTION_TIME, tcp::NOISE_CODEC_DECRYPTION_TIME, tcp::NOISE_CODEC_ENCRYPTION_SIZE, @@ -70,6 +74,8 @@ pub mod consensus { pub const UNCONFIRMED_TRANSACTIONS: &str = "snarkos_consensus_unconfirmed_transactions_total"; pub const UNCONFIRMED_TRANSMISSIONS: &str = "snarkos_consensus_unconfirmed_transmissions_total"; pub const UNCONFIRMED_SOLUTIONS: &str = "snarkos_consensus_unconfirmed_solutions_total"; + pub const TRANSMISSION_LATENCY: &str = "snarkos_consensus_transmission_latency"; + pub const STALE_UNCONFIRMED_TRANSMISSIONS: &str = "snarkos_consensus_stale_unconfirmed_transmissions"; } pub mod router { From 700d0ef3e1177e5802fa20d0a1f3c3c1659d9aab Mon Sep 17 00:00:00 2001 From: miazn Date: Wed, 13 Mar 2024 17:41:36 -0700 Subject: [PATCH 02/72] add loglines to check metric updates --- node/consensus/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 5ff5b063f2..fc3641a4a4 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -223,6 +223,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); + info!("added unconfirmed solution to queue"); } // Process the unconfirmed solution. { @@ -282,6 +283,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); + info!("added unconfirmed transaction to queue"); } // Process the unconfirmed transaction. { @@ -443,6 +445,7 @@ impl Consensus { #[cfg(feature = "metrics")] fn add_transmission_latency_metric(&self, next_block: &Block) { + info!("adding latency to next block"); let age_threshold_seconds = 30 * 60; // 30 minutes set as stale transmission threshold let mut keys_to_remove = Vec::new(); @@ -459,6 +462,7 @@ impl Consensus { metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); keys_to_remove.push(key.clone()); } else { + info!("looking for transmission key {}", key); let transmission_type = match key { TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => Some("transaction"), From 2e8b64dba2128921acb43914c9802d564b1fe84d Mon Sep 17 00:00:00 2001 From: miazn Date: Wed, 13 Mar 2024 20:54:07 -0700 Subject: [PATCH 03/72] testing by verifying loglines --- node/consensus/src/lib.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 21e9ce900a..7122231de8 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -55,18 +55,10 @@ use tokio::{ #[cfg(feature = "metrics")] use std::collections::HashMap; -/// The capacity of the queue reserved for deployments. -/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. -const CAPACITY_FOR_DEPLOYMENTS: usize = 1 << 10; -/// The capacity of the queue reserved for executions. -/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. -const CAPACITY_FOR_EXECUTIONS: usize = 1 << 10; -/// The capacity of the queue reserved for solutions. -/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. -const CAPACITY_FOR_SOLUTIONS: usize = 1 << 10; -/// The **suggested** maximum number of deployments in each interval. -/// Note: This is an inbound queue limit, not a Narwhal-enforced limit. -const MAX_DEPLOYMENTS_PER_INTERVAL: usize = 1; +/// Percentage of mempool transactions capacity reserved for deployments. +const CAPACITY_FOR_DEPLOYMENTS: usize = 20; +/// Percentage of mempool transactions capacity reserved for executions. +const CAPACITY_FOR_EXECUTIONS: usize = 80; /// Helper struct to track incoming transactions. struct TransactionsQueue { @@ -77,8 +69,14 @@ struct TransactionsQueue { impl Default for TransactionsQueue { fn default() -> Self { Self { - deployments: LruCache::new(NonZeroUsize::new(CAPACITY_FOR_DEPLOYMENTS).unwrap()), - executions: LruCache::new(NonZeroUsize::new(CAPACITY_FOR_EXECUTIONS).unwrap()), + deployments: LruCache::new( + NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH * CAPACITY_FOR_DEPLOYMENTS / 100) + .unwrap(), + ), + executions: LruCache::new( + NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH * CAPACITY_FOR_EXECUTIONS / 100) + .unwrap(), + ), } } } @@ -130,7 +128,9 @@ impl Consensus { ledger, bft, primary_sender: Default::default(), - solutions_queue: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(CAPACITY_FOR_SOLUTIONS).unwrap()))), + solutions_queue: Arc::new(Mutex::new(LruCache::new( + NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH).unwrap(), + ))), transactions_queue: Default::default(), seen_solutions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), @@ -223,7 +223,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); - info!("added unconfirmed solution to queue"); + info!("added unconfirmed solution {} to queue", solution.commitment()); } // Process the unconfirmed solution. { @@ -283,7 +283,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); - info!("added unconfirmed transaction to queue"); + info!("added unconfirmed transaction {} to queue", transaction.id()); } // Process the unconfirmed transaction. { @@ -325,7 +325,7 @@ impl Consensus { // Acquire the lock on the transactions queue. let mut tx_queue = self.transactions_queue.lock(); // Determine the number of deployments to send. - let num_deployments = tx_queue.deployments.len().min(capacity).min(MAX_DEPLOYMENTS_PER_INTERVAL); + let num_deployments = tx_queue.deployments.len().min(capacity * CAPACITY_FOR_DEPLOYMENTS / 100); // Determine the number of executions to send. let num_executions = tx_queue.executions.len().min(capacity.saturating_sub(num_deployments)); // Create an iterator which will select interleaved deployments and executions within the capacity. From 6f586cd8c490bb6c33487f4b29aaa329dee22743 Mon Sep 17 00:00:00 2001 From: miazn Date: Thu, 14 Mar 2024 12:56:58 -0400 Subject: [PATCH 04/72] remove logging and pull new changes --- node/consensus/src/lib.rs | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 7122231de8..3b77fa68a2 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -55,10 +55,18 @@ use tokio::{ #[cfg(feature = "metrics")] use std::collections::HashMap; -/// Percentage of mempool transactions capacity reserved for deployments. -const CAPACITY_FOR_DEPLOYMENTS: usize = 20; -/// Percentage of mempool transactions capacity reserved for executions. -const CAPACITY_FOR_EXECUTIONS: usize = 80; +/// The capacity of the queue reserved for deployments. +/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. +const CAPACITY_FOR_DEPLOYMENTS: usize = 1 << 10; +/// The capacity of the queue reserved for executions. +/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. +const CAPACITY_FOR_EXECUTIONS: usize = 1 << 10; +/// The capacity of the queue reserved for solutions. +/// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. +const CAPACITY_FOR_SOLUTIONS: usize = 1 << 10; +/// The **suggested** maximum number of deployments in each interval. +/// Note: This is an inbound queue limit, not a Narwhal-enforced limit. +const MAX_DEPLOYMENTS_PER_INTERVAL: usize = 1; /// Helper struct to track incoming transactions. struct TransactionsQueue { @@ -69,14 +77,8 @@ struct TransactionsQueue { impl Default for TransactionsQueue { fn default() -> Self { Self { - deployments: LruCache::new( - NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH * CAPACITY_FOR_DEPLOYMENTS / 100) - .unwrap(), - ), - executions: LruCache::new( - NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH * CAPACITY_FOR_EXECUTIONS / 100) - .unwrap(), - ), + deployments: LruCache::new(NonZeroUsize::new(CAPACITY_FOR_DEPLOYMENTS).unwrap()), + executions: LruCache::new(NonZeroUsize::new(CAPACITY_FOR_EXECUTIONS).unwrap()), } } } @@ -223,7 +225,6 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); - info!("added unconfirmed solution {} to queue", solution.commitment()); } // Process the unconfirmed solution. { @@ -283,7 +284,6 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); - info!("added unconfirmed transaction {} to queue", transaction.id()); } // Process the unconfirmed transaction. { @@ -325,7 +325,7 @@ impl Consensus { // Acquire the lock on the transactions queue. let mut tx_queue = self.transactions_queue.lock(); // Determine the number of deployments to send. - let num_deployments = tx_queue.deployments.len().min(capacity * CAPACITY_FOR_DEPLOYMENTS / 100); + let num_deployments = tx_queue.deployments.len().min(capacity).min(MAX_DEPLOYMENTS_PER_INTERVAL); // Determine the number of executions to send. let num_executions = tx_queue.executions.len().min(capacity.saturating_sub(num_deployments)); // Create an iterator which will select interleaved deployments and executions within the capacity. @@ -414,7 +414,7 @@ impl Consensus { let current_block_timestamp = self.ledger.latest_block().header().metadata().timestamp(); // Create the candidate next block. - let next_block = self.ledger.prepare_advance_to_next_quorum_block(subdag, transmissions)?; + let next_block = self.ledger.prepare_advance_to_next_quorum_block(subdag, transmissions)?; // Check that the block is well-formed. self.ledger.check_next_block(&next_block)?; // Advance to the next block. @@ -439,13 +439,12 @@ impl Consensus { metrics::gauge(metrics::consensus::COMMITTED_CERTIFICATES, num_committed_certificates as f64); metrics::histogram(metrics::consensus::CERTIFICATE_COMMIT_LATENCY, elapsed.as_secs_f64()); metrics::histogram(metrics::consensus::BLOCK_LATENCY, block_latency as f64); - } + } Ok(()) } #[cfg(feature = "metrics")] fn add_transmission_latency_metric(&self, next_block: &Block) { - info!("adding latency to next block"); let age_threshold_seconds = 30 * 60; // 30 minutes set as stale transmission threshold let mut keys_to_remove = Vec::new(); @@ -462,7 +461,6 @@ impl Consensus { metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); keys_to_remove.push(key.clone()); } else { - info!("looking for transmission key {}", key); let transmission_type = match key { TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => Some("transaction"), From 27d81a32f72333de607f77b82cab388a000924c0 Mon Sep 17 00:00:00 2001 From: miazn Date: Thu, 14 Mar 2024 12:59:51 -0400 Subject: [PATCH 05/72] pull mainnet-staging --- node/consensus/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 3b77fa68a2..747f1815a0 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -130,9 +130,7 @@ impl Consensus { ledger, bft, primary_sender: Default::default(), - solutions_queue: Arc::new(Mutex::new(LruCache::new( - NonZeroUsize::new(BatchHeader::::MAX_TRANSMISSIONS_PER_BATCH).unwrap(), - ))), + solutions_queue: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(CAPACITY_FOR_SOLUTIONS).unwrap()))), transactions_queue: Default::default(), seen_solutions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), From 0c2e30b1893dd582288065963a862137283caef5 Mon Sep 17 00:00:00 2001 From: miazn Date: Thu, 14 Mar 2024 14:10:31 -0400 Subject: [PATCH 06/72] nits --- node/consensus/src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 747f1815a0..e35006102e 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -442,8 +442,8 @@ impl Consensus { } #[cfg(feature = "metrics")] - fn add_transmission_latency_metric(&self, next_block: &Block) { - let age_threshold_seconds = 30 * 60; // 30 minutes set as stale transmission threshold + fn add_transmission_latency_metric(&self, next_block: &Block) {hold + const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold let mut keys_to_remove = Vec::new(); let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); @@ -454,7 +454,7 @@ impl Consensus { for (key, timestamp) in transmission_queue_timestamps.iter() { let elapsed_time = std::time::Duration::from_secs((snarkos_node_bft::helpers::now() - *timestamp) as u64); - if elapsed_time.as_secs() > age_threshold_seconds as u64 { + if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { // This entry is stale-- remove it from transmission queue and record it as a stale transmission metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); keys_to_remove.push(key.clone()); @@ -468,8 +468,6 @@ impl Consensus { if let Some(transmission_type_string) = transmission_type { metrics::histogram_label(metrics::consensus::TRANSMISSION_LATENCY, "transmission_type", transmission_type_string.to_string(), elapsed_time.as_secs_f64()); keys_to_remove.push(key.clone()); - } else { - continue } } } From 4dd9375d08b53a699dea222a0728e0a81a6c485d Mon Sep 17 00:00:00 2001 From: miazn Date: Thu, 14 Mar 2024 14:29:33 -0400 Subject: [PATCH 07/72] fix typo --- node/consensus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index e35006102e..06a02bb0c8 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -442,7 +442,7 @@ impl Consensus { } #[cfg(feature = "metrics")] - fn add_transmission_latency_metric(&self, next_block: &Block) {hold + fn add_transmission_latency_metric(&self, next_block: &Block) { const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold let mut keys_to_remove = Vec::new(); From 2d6b0aa3021529688ebe53118df580923814cf47 Mon Sep 17 00:00:00 2001 From: miazn Date: Mon, 18 Mar 2024 11:36:34 -0400 Subject: [PATCH 08/72] formatting --- node/consensus/src/lib.rs | 39 +++++++++++++++++++++++++-------------- node/metrics/src/names.rs | 5 +---- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 06a02bb0c8..b3a11e174c 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -47,13 +47,13 @@ use colored::Colorize; use indexmap::IndexMap; use lru::LruCache; use parking_lot::Mutex; +#[cfg(feature = "metrics")] +use std::collections::HashMap; use std::{future::Future, net::SocketAddr, num::NonZeroUsize, sync::Arc}; use tokio::{ sync::{oneshot, OnceCell}, task::JoinHandle, }; -#[cfg(feature = "metrics")] -use std::collections::HashMap; /// The capacity of the queue reserved for deployments. /// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. @@ -102,7 +102,7 @@ pub struct Consensus { /// The spawned handles. handles: Arc>>>, #[cfg(feature = "metrics")] - transmissions_queue_timestamps: Arc, i64>>>, + transmissions_queue_timestamps: Arc, i64>>>, } impl Consensus { @@ -136,7 +136,7 @@ impl Consensus { seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), handles: Default::default(), #[cfg(feature = "metrics")] - transmissions_queue_timestamps: Arc::new(Mutex::new(HashMap::new())) + transmissions_queue_timestamps: Arc::new(Mutex::new(HashMap::new())), }) } @@ -222,7 +222,9 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); - self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); + self.transmissions_queue_timestamps + .lock() + .insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); } // Process the unconfirmed solution. { @@ -281,7 +283,9 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); - self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); + self.transmissions_queue_timestamps + .lock() + .insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); } // Process the unconfirmed transaction. { @@ -444,16 +448,16 @@ impl Consensus { #[cfg(feature = "metrics")] fn add_transmission_latency_metric(&self, next_block: &Block) { const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold - + let mut keys_to_remove = Vec::new(); let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); - + let solution_ids: std::collections::HashSet<_> = next_block.solutions().solution_ids().collect(); let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().collect(); - + for (key, timestamp) in transmission_queue_timestamps.iter() { let elapsed_time = std::time::Duration::from_secs((snarkos_node_bft::helpers::now() - *timestamp) as u64); - + if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { // This entry is stale-- remove it from transmission queue and record it as a stale transmission metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); @@ -461,23 +465,30 @@ impl Consensus { } else { let transmission_type = match key { TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), - TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => Some("transaction"), + TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => { + Some("transaction") + } _ => None, }; if let Some(transmission_type_string) = transmission_type { - metrics::histogram_label(metrics::consensus::TRANSMISSION_LATENCY, "transmission_type", transmission_type_string.to_string(), elapsed_time.as_secs_f64()); + metrics::histogram_label( + metrics::consensus::TRANSMISSION_LATENCY, + "transmission_type", + transmission_type_string.to_string(), + elapsed_time.as_secs_f64(), + ); keys_to_remove.push(key.clone()); } } } - + // Remove keys of stale or seen transmissions for key in keys_to_remove { transmission_queue_timestamps.remove(&key); } } - + /// Reinserts the given transmissions into the memory pool. async fn reinsert_transmissions(&self, transmissions: IndexMap, Transmission>) { // Iterate over the transmissions. diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 0c01c8738c..b94af54033 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -12,10 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(super) const COUNTER_NAMES: [&str; 2] = [ - bft::LEADERS_ELECTED, - consensus::STALE_UNCONFIRMED_TRANSMISSIONS, -]; +pub(super) const COUNTER_NAMES: [&str; 2] = [bft::LEADERS_ELECTED, consensus::STALE_UNCONFIRMED_TRANSMISSIONS]; pub(super) const GAUGE_NAMES: [&str; 18] = [ bft::CONNECTED, From 572900f0b2040839884956a6b696551f1d66e584 Mon Sep 17 00:00:00 2001 From: shnacke <93600681+miazn@users.noreply.github.com> Date: Wed, 20 Mar 2024 08:41:22 -0400 Subject: [PATCH 09/72] Update node/consensus/src/lib.rs Co-authored-by: ljedrz Signed-off-by: shnacke <93600681+miazn@users.noreply.github.com> --- node/consensus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index b3a11e174c..595054d7f6 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -475,7 +475,7 @@ impl Consensus { metrics::histogram_label( metrics::consensus::TRANSMISSION_LATENCY, "transmission_type", - transmission_type_string.to_string(), + transmission_type_string.to_owned(), elapsed_time.as_secs_f64(), ); keys_to_remove.push(key.clone()); From 06aeeb38ad022e0ebaa0b70d7fe9cf622188d27e Mon Sep 17 00:00:00 2001 From: shnacke <93600681+miazn@users.noreply.github.com> Date: Wed, 20 Mar 2024 08:56:28 -0400 Subject: [PATCH 10/72] Update node/consensus/src/lib.rs Co-authored-by: ljedrz Signed-off-by: shnacke <93600681+miazn@users.noreply.github.com> --- node/consensus/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 595054d7f6..3bb9b0d2fe 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -136,7 +136,7 @@ impl Consensus { seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), handles: Default::default(), #[cfg(feature = "metrics")] - transmissions_queue_timestamps: Arc::new(Mutex::new(HashMap::new())), + transmissions_queue_timestamps: Default::default(), }) } From 39c9eb2b1ec072c31662112e7cc60d7255821b34 Mon Sep 17 00:00:00 2001 From: miazn Date: Wed, 20 Mar 2024 09:03:02 -0400 Subject: [PATCH 11/72] changes --- node/consensus/src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 595054d7f6..fd948cbc6e 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -222,9 +222,10 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); + let timestamp = snarkos_node_bft::helpers::now(); self.transmissions_queue_timestamps .lock() - .insert(TransmissionID::Solution(solution.commitment()), snarkos_node_bft::helpers::now()); + .insert(TransmissionID::Solution(solution.commitment()), timestamp); } // Process the unconfirmed solution. { @@ -283,9 +284,10 @@ impl Consensus { { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); + let timestamp = snarkos_node_bft::helpers::now(); self.transmissions_queue_timestamps .lock() - .insert(TransmissionID::Transaction(transaction.id()), snarkos_node_bft::helpers::now()); + .insert(TransmissionID::Transaction(transaction.id()), timestamp); } // Process the unconfirmed transaction. { @@ -450,16 +452,17 @@ impl Consensus { const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold let mut keys_to_remove = Vec::new(); - let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); let solution_ids: std::collections::HashSet<_> = next_block.solutions().solution_ids().collect(); let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().collect(); + let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); + let ts_now = snarkos_node_bft::helpers::now(); for (key, timestamp) in transmission_queue_timestamps.iter() { - let elapsed_time = std::time::Duration::from_secs((snarkos_node_bft::helpers::now() - *timestamp) as u64); + let elapsed_time = std::time::Duration::from_secs((ts_now - *timestamp) as u64); if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { - // This entry is stale-- remove it from transmission queue and record it as a stale transmission + // This entry is stale-- remove it from transmission queue and record it as a stale transmission. metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); keys_to_remove.push(key.clone()); } else { From ac18bdd7a39e886a1252ca0f980f9659cf432fc8 Mon Sep 17 00:00:00 2001 From: miazn Date: Wed, 20 Mar 2024 09:04:06 -0400 Subject: [PATCH 12/72] changes --- node/consensus/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index fd948cbc6e..e0bf173ddd 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -285,9 +285,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); let timestamp = snarkos_node_bft::helpers::now(); - self.transmissions_queue_timestamps - .lock() - .insert(TransmissionID::Transaction(transaction.id()), timestamp); + self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), timestamp); } // Process the unconfirmed transaction. { @@ -457,7 +455,7 @@ impl Consensus { let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().collect(); let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); - let ts_now = snarkos_node_bft::helpers::now(); + let ts_now = snarkos_node_bft::helpers::now(); for (key, timestamp) in transmission_queue_timestamps.iter() { let elapsed_time = std::time::Duration::from_secs((ts_now - *timestamp) as u64); From d403902a4c4054a2763dcd3bb4cd5b6b4fbde94e Mon Sep 17 00:00:00 2001 From: miazn Date: Thu, 21 Mar 2024 11:34:09 -0400 Subject: [PATCH 13/72] change from clone to dereference --- node/consensus/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 95c27c2c6c..037015869c 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -462,7 +462,7 @@ impl Consensus { if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { // This entry is stale-- remove it from transmission queue and record it as a stale transmission. metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); - keys_to_remove.push(key.clone()); + keys_to_remove.push(*key); } else { let transmission_type = match key { TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), @@ -479,7 +479,7 @@ impl Consensus { transmission_type_string.to_owned(), elapsed_time.as_secs_f64(), ); - keys_to_remove.push(key.clone()); + keys_to_remove.push(*key); } } } From b1bd3bf7457a162641b835d97adb8b6405bef6ed Mon Sep 17 00:00:00 2001 From: Victor Sint Nicolaas Date: Mon, 25 Mar 2024 21:28:59 +0100 Subject: [PATCH 14/72] Make --node optional to ensure it still has an influence even when using --dev --- cli/src/commands/start.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index dbe2bd14bf..a3d2767f80 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -90,8 +90,8 @@ pub struct Start { pub private_key_file: Option, /// Specify the IP address and port for the node server - #[clap(default_value = "0.0.0.0:4130", long = "node")] - pub node: SocketAddr, + #[clap(long = "node")] + pub node: Option, /// Specify the IP address and port for the BFT #[clap(long = "bft")] pub bft: Option, @@ -308,11 +308,15 @@ impl Start { } } // Set the node IP to `4130 + dev`. - self.node = SocketAddr::from_str(&format!("0.0.0.0:{}", 4130 + dev))?; + // + // Note: the `node` flag is an option to detect remote devnet testing. + if self.node.is_none() { + self.node = Some(SocketAddr::from_str(&format!("0.0.0.0:{}", 4130 + dev))?); + } // If the `norest` flag is not set, and the `bft` flag was not overridden, // then set the REST IP to `3030 + dev`. // - // Note: the reason the `bft` flag is an option is to detect for remote devnet testing. + // Note: the `bft` flag is an option to detect remote devnet testing. if !self.norest && self.bft.is_none() { self.rest = SocketAddr::from_str(&format!("0.0.0.0:{}", 3030 + dev))?; } @@ -490,6 +494,10 @@ impl Start { true => None, false => Some(self.rest), }; + // Parse the bft ip. + let bft_ip = if self.dev.is_some() { self.bft } else { None }; + // Parse the node ip. + let node_ip = if let Some(node_ip) = self.node { node_ip } else { SocketAddr::from_str("0.0.0.0:4130").unwrap() }; // If the display is not enabled, render the welcome message. if self.nodisplay { @@ -500,7 +508,7 @@ impl Start { "🧭 Starting {} on {} at {}.\n", node_type.description().bold(), N::NAME.bold(), - self.node.to_string().bold() + node_ip.to_string().bold() ); // If the node is running a REST server, print the REST IP and JWT. @@ -547,11 +555,10 @@ impl Start { }; // Initialize the node. - let bft_ip = if self.dev.is_some() { self.bft } else { None }; match node_type { - NodeType::Validator => Node::new_validator(self.node, bft_ip, rest_ip, self.rest_rps, account, &trusted_peers, &trusted_validators, genesis, cdn, storage_mode, self.allow_external_peers, dev_txs).await, - NodeType::Prover => Node::new_prover(self.node, account, &trusted_peers, genesis, storage_mode).await, - NodeType::Client => Node::new_client(self.node, rest_ip, self.rest_rps, account, &trusted_peers, genesis, cdn, storage_mode).await, + NodeType::Validator => Node::new_validator(node_ip, bft_ip, rest_ip, self.rest_rps, account, &trusted_peers, &trusted_validators, genesis, cdn, storage_mode, self.allow_external_peers, dev_txs).await, + NodeType::Prover => Node::new_prover(node_ip, account, &trusted_peers, genesis, storage_mode).await, + NodeType::Client => Node::new_client(node_ip, rest_ip, self.rest_rps, account, &trusted_peers, genesis, cdn, storage_mode).await, } } @@ -834,7 +841,7 @@ mod tests { let mut config = Start::try_parse_from(["snarkos", "--dev", "0"].iter()).unwrap(); config.parse_development(&mut trusted_peers, &mut trusted_validators).unwrap(); let expected_genesis = config.parse_genesis::().unwrap(); - assert_eq!(config.node, SocketAddr::from_str("0.0.0.0:4130").unwrap()); + assert_eq!(config.node, Some(SocketAddr::from_str("0.0.0.0:4130").unwrap())); assert_eq!(config.rest, SocketAddr::from_str("0.0.0.0:3030").unwrap()); assert_eq!(trusted_peers.len(), 0); assert_eq!(trusted_validators.len(), 1); @@ -849,7 +856,7 @@ mod tests { Start::try_parse_from(["snarkos", "--dev", "1", "--validator", "--private-key", ""].iter()).unwrap(); config.parse_development(&mut trusted_peers, &mut trusted_validators).unwrap(); let genesis = config.parse_genesis::().unwrap(); - assert_eq!(config.node, SocketAddr::from_str("0.0.0.0:4131").unwrap()); + assert_eq!(config.node, Some(SocketAddr::from_str("0.0.0.0:4131").unwrap())); assert_eq!(config.rest, SocketAddr::from_str("0.0.0.0:3031").unwrap()); assert_eq!(trusted_peers.len(), 1); assert_eq!(trusted_validators.len(), 1); @@ -864,7 +871,7 @@ mod tests { Start::try_parse_from(["snarkos", "--dev", "2", "--prover", "--private-key", ""].iter()).unwrap(); config.parse_development(&mut trusted_peers, &mut trusted_validators).unwrap(); let genesis = config.parse_genesis::().unwrap(); - assert_eq!(config.node, SocketAddr::from_str("0.0.0.0:4132").unwrap()); + assert_eq!(config.node, Some(SocketAddr::from_str("0.0.0.0:4132").unwrap())); assert_eq!(config.rest, SocketAddr::from_str("0.0.0.0:3032").unwrap()); assert_eq!(trusted_peers.len(), 2); assert_eq!(trusted_validators.len(), 2); @@ -879,7 +886,7 @@ mod tests { Start::try_parse_from(["snarkos", "--dev", "3", "--client", "--private-key", ""].iter()).unwrap(); config.parse_development(&mut trusted_peers, &mut trusted_validators).unwrap(); let genesis = config.parse_genesis::().unwrap(); - assert_eq!(config.node, SocketAddr::from_str("0.0.0.0:4133").unwrap()); + assert_eq!(config.node, Some(SocketAddr::from_str("0.0.0.0:4133").unwrap())); assert_eq!(config.rest, SocketAddr::from_str("0.0.0.0:3033").unwrap()); assert_eq!(trusted_peers.len(), 3); assert_eq!(trusted_validators.len(), 2); From a2f89dd1f6d24abf94dd4f53228c8c70f86125f2 Mon Sep 17 00:00:00 2001 From: miazn Date: Tue, 26 Mar 2024 14:21:23 -0400 Subject: [PATCH 15/72] fmt --- node/consensus/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index cd85df2143..3e470428d2 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -224,9 +224,7 @@ impl Consensus { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); let timestamp = snarkos_node_bft::helpers::now(); - self.transmissions_queue_timestamps - .lock() - .insert(TransmissionID::Solution(solution.commitment()), timestamp); + self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.id()), timestamp); } // Process the unconfirmed solution. { From 5d43a73d4852b40ffa8e3e0b38baaf65bcef79ec Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 26 Mar 2024 18:25:53 -0400 Subject: [PATCH 16/72] Prevent proposing batches too quickly --- node/bft/src/lib.rs | 2 ++ node/bft/src/primary.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/node/bft/src/lib.rs b/node/bft/src/lib.rs index d6fcbae66f..550fb20232 100644 --- a/node/bft/src/lib.rs +++ b/node/bft/src/lib.rs @@ -49,6 +49,8 @@ pub const MEMORY_POOL_PORT: u16 = 5000; // port /// The maximum number of milliseconds to wait before proposing a batch. pub const MAX_BATCH_DELAY_IN_MS: u64 = 2500; // ms +/// The maximum number of seconds to wait before proposing a batch (rounded down to the nearest second). +pub const MAX_BATCH_DELAY_IN_SECS: u64 = MAX_BATCH_DELAY_IN_MS / 1000; // seconds /// The maximum number of milliseconds to wait before timing out on a fetch. pub const MAX_FETCH_TIMEOUT_IN_MS: u64 = 3 * MAX_BATCH_DELAY_IN_MS; // ms /// The maximum number of seconds allowed for the leader to send their certificate. diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index a2a070183e..5b566a9def 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -33,6 +33,7 @@ use crate::{ Transport, Worker, MAX_BATCH_DELAY_IN_MS, + MAX_BATCH_DELAY_IN_SECS, MAX_WORKERS, PRIMARY_PING_IN_MS, WORKER_PING_IN_MS, @@ -321,6 +322,21 @@ impl Primary { #[cfg(feature = "metrics")] metrics::gauge(metrics::bft::PROPOSAL_ROUND, round as f64); + // Ensure that the primary does not create a new proposal too quickly. + if let Some(previous_certificate) = self + .storage + .get_certificate_for_round_with_author(round.saturating_sub(1), self.gateway.account().address()) + { + // If the primary proposed a previous certificate too recently, return early. + if now().saturating_sub(previous_certificate.timestamp()) < MAX_BATCH_DELAY_IN_SECS as i64 { + debug!( + "Primary is safely skipping a batch proposal {}", + format!("(round {round} was proposed too quickly)").dimmed() + ); + return Ok(()); + } + } + // Ensure the primary has not proposed a batch for this round before. if self.storage.contains_certificate_in_round_from(round, self.gateway.account().address()) { // If a BFT sender was provided, attempt to advance the current round. From 3758d2603db86d745b655495049a17f7e57ebd5e Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:21:13 -0400 Subject: [PATCH 17/72] Prevent signing proposals that were created too quickly --- node/bft/src/primary.rs | 47 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 5b566a9def..e38436eff2 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -318,23 +318,16 @@ impl Primary { // Retrieve the current round. let round = self.current_round(); + // Compute the previous round. + let previous_round = round.saturating_sub(1); #[cfg(feature = "metrics")] metrics::gauge(metrics::bft::PROPOSAL_ROUND, round as f64); // Ensure that the primary does not create a new proposal too quickly. - if let Some(previous_certificate) = self - .storage - .get_certificate_for_round_with_author(round.saturating_sub(1), self.gateway.account().address()) - { - // If the primary proposed a previous certificate too recently, return early. - if now().saturating_sub(previous_certificate.timestamp()) < MAX_BATCH_DELAY_IN_SECS as i64 { - debug!( - "Primary is safely skipping a batch proposal {}", - format!("(round {round} was proposed too quickly)").dimmed() - ); - return Ok(()); - } + if let Err(e) = self.ensure_proposal_frequency(previous_round, self.gateway.account().address(), now()) { + debug!("Primary is safely skipping a batch proposal - {}", format!("{e}").dimmed()); + return Ok(()); } // Ensure the primary has not proposed a batch for this round before. @@ -375,8 +368,6 @@ impl Primary { } } - // Compute the previous round. - let previous_round = round.saturating_sub(1); // Retrieve the previous certificates. let previous_certificates = self.storage.get_certificates_for_round(previous_round); @@ -611,6 +602,15 @@ impl Primary { } } + // Compute the previous round. + let previous_round = batch_round.saturating_sub(1); + // Ensure that the peer did not propose a batch too quickly. + if let Err(e) = self.ensure_proposal_frequency(previous_round, batch_author, batch_header.timestamp()) { + // Proceed to disconnect the validator. + self.gateway.disconnect(peer_ip); + bail!("Malicious peer - {e} from '{peer_ip}'"); + } + // If the peer is ahead, use the batch header to sync up to the peer. let mut transmissions = self.sync_with_batch_header_from_peer(peer_ip, &batch_header).await?; @@ -1205,6 +1205,25 @@ impl Primary { Ok(()) } + /// Ensure the primary is not creating batch proposals too frequently. + /// This checks that the certificate timestamp for the previous round is within the expected range. + fn ensure_proposal_frequency(&self, previous_round: u64, author: Address, timestamp: i64) -> Result<()> { + // Ensure that the primary does not create a new proposal too quickly. + match self.storage.get_certificate_for_round_with_author(previous_round, author) { + // Ensure that the previous certificate was created at least `MAX_BATCH_DELAY_IN_SECS` seconds ago. + Some(certificate) => { + match timestamp.saturating_sub(certificate.timestamp()) < MAX_BATCH_DELAY_IN_SECS as i64 { + true => { + bail!("Proposed batch was created too quickly after the certificate at round {previous_round}") + } + false => Ok(()), + } + } + // If we do not see a previous certificate for the author, then proceed optimistically. + None => Ok(()), + } + } + /// Stores the certified batch and broadcasts it to all validators, returning the certificate. async fn store_and_broadcast_certificate(&self, proposal: &Proposal, committee: &Committee) -> Result<()> { // Create the batch certificate and transmissions. From 95fe67aad4f79674961427a14e11d41fb25d9053 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:35:06 -0400 Subject: [PATCH 18/72] Fix tests and update naming --- node/bft/src/primary.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index e38436eff2..d5687917b2 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -325,7 +325,7 @@ impl Primary { metrics::gauge(metrics::bft::PROPOSAL_ROUND, round as f64); // Ensure that the primary does not create a new proposal too quickly. - if let Err(e) = self.ensure_proposal_frequency(previous_round, self.gateway.account().address(), now()) { + if let Err(e) = self.check_proposal_timestamp(previous_round, self.gateway.account().address(), now()) { debug!("Primary is safely skipping a batch proposal - {}", format!("{e}").dimmed()); return Ok(()); } @@ -605,7 +605,7 @@ impl Primary { // Compute the previous round. let previous_round = batch_round.saturating_sub(1); // Ensure that the peer did not propose a batch too quickly. - if let Err(e) = self.ensure_proposal_frequency(previous_round, batch_author, batch_header.timestamp()) { + if let Err(e) = self.check_proposal_timestamp(previous_round, batch_author, batch_header.timestamp()) { // Proceed to disconnect the validator. self.gateway.disconnect(peer_ip); bail!("Malicious peer - {e} from '{peer_ip}'"); @@ -1207,12 +1207,17 @@ impl Primary { /// Ensure the primary is not creating batch proposals too frequently. /// This checks that the certificate timestamp for the previous round is within the expected range. - fn ensure_proposal_frequency(&self, previous_round: u64, author: Address, timestamp: i64) -> Result<()> { + fn check_proposal_timestamp(&self, previous_round: u64, author: Address, timestamp: i64) -> Result<()> { // Ensure that the primary does not create a new proposal too quickly. match self.storage.get_certificate_for_round_with_author(previous_round, author) { // Ensure that the previous certificate was created at least `MAX_BATCH_DELAY_IN_SECS` seconds ago. Some(certificate) => { - match timestamp.saturating_sub(certificate.timestamp()) < MAX_BATCH_DELAY_IN_SECS as i64 { + // Determine the elapsed time since the previous certificate. + let elapsed = timestamp.checked_sub(certificate.timestamp()).ok_or_else(|| { + anyhow!("Proposed batch has a timestamp earlier than the certificate at round {previous_round}") + })?; + // Ensure the elapsed time is within the expected range. + match elapsed < MAX_BATCH_DELAY_IN_SECS as i64 { true => { bail!("Proposed batch was created too quickly after the certificate at round {previous_round}") } @@ -1894,7 +1899,7 @@ mod tests { let round = 1; let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -1930,7 +1935,7 @@ mod tests { // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -1961,7 +1966,7 @@ mod tests { let round = 1; let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -2003,7 +2008,7 @@ mod tests { // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -2041,7 +2046,7 @@ mod tests { // Create a valid proposal. let round = 1; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), @@ -2114,7 +2119,7 @@ mod tests { // Create a valid proposal. let round = 1; - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), @@ -2151,7 +2156,7 @@ mod tests { let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); // Create a valid proposal. - let timestamp = now(); + let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), From 58097554296d80417098710f2bb85e609f38794e Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:42:48 -0400 Subject: [PATCH 19/72] Add tests for invalid proposal timestamps --- node/bft/src/primary.rs | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index d5687917b2..a23291572d 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -2038,6 +2038,78 @@ mod tests { ); } + #[tokio::test] + async fn test_batch_propose_from_peer_with_invalid_timestamp() { + let round = 2; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + + // Generate certificates. + let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Create a valid proposal with an author that isn't the primary. + let peer_account = &accounts[1]; + let peer_ip = peer_account.0; + let invalid_timestamp = now(); // Use a timestamp that is too early. + let proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates, + invalid_timestamp, + &mut rng, + ); + + // Make sure the primary is aware of the transmissions in the proposal. + for (transmission_id, transmission) in proposal.transmissions() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()) + } + + // The author must be known to resolver to pass propose checks. + primary.gateway.resolver().insert_peer(peer_ip, peer_ip, peer_account.1.address()); + + // Try to process the batch proposal from the peer, should error. + assert!( + primary.process_batch_propose_from_peer(peer_ip, (*proposal.batch_header()).clone().into()).await.is_err() + ); + } + + #[tokio::test] + async fn test_batch_propose_from_peer_with_past_timestamp() { + let round = 2; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + + // Generate certificates. + let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Create a valid proposal with an author that isn't the primary. + let peer_account = &accounts[1]; + let peer_ip = peer_account.0; + let past_timestamp = now() - 5; // Use a timestamp that is in the past. + let proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates, + past_timestamp, + &mut rng, + ); + + // Make sure the primary is aware of the transmissions in the proposal. + for (transmission_id, transmission) in proposal.transmissions() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()) + } + + // The author must be known to resolver to pass propose checks. + primary.gateway.resolver().insert_peer(peer_ip, peer_ip, peer_account.1.address()); + + // Try to process the batch proposal from the peer, should error. + assert!( + primary.process_batch_propose_from_peer(peer_ip, (*proposal.batch_header()).clone().into()).await.is_err() + ); + } + #[tokio::test(flavor = "multi_thread")] async fn test_batch_signature_from_peer() { let mut rng = TestRng::default(); From 742c67faa5a085aca27463d0fd35811c38ddba56 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:04:56 -0400 Subject: [PATCH 20/72] Add waits in tests --- node/bft/src/primary.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index a23291572d..2d2ad04585 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1806,6 +1806,9 @@ mod tests { // Fill primary storage. store_certificate_chain(&primary, &accounts, round, &mut rng); + // Sleep for a while to ensure the primary is ready to propose the next round. + tokio::time::sleep(Duration::from_secs(MAX_BATCH_DELAY_IN_SECS + 1)).await; + // Try to propose a batch. There are no transmissions in the workers so the method should // just return without proposing a batch. assert!(primary.propose_batch().await.is_ok()); @@ -1874,6 +1877,9 @@ mod tests { primary.storage.insert_certificate(certificate, transmissions).unwrap(); } + // Sleep for a while to ensure the primary is ready to propose the next round. + tokio::time::sleep(Duration::from_secs(MAX_BATCH_DELAY_IN_SECS + 1)).await; + // Advance to the next round. assert!(primary.storage.increment_to_next_round(round).is_ok()); From 37bb04b28d8133f96675bb7f720e856d29180e07 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:26:53 -0400 Subject: [PATCH 21/72] Update log messages --- node/bft/src/primary.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 2d2ad04585..b267f4fc36 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1214,13 +1214,11 @@ impl Primary { Some(certificate) => { // Determine the elapsed time since the previous certificate. let elapsed = timestamp.checked_sub(certificate.timestamp()).ok_or_else(|| { - anyhow!("Proposed batch has a timestamp earlier than the certificate at round {previous_round}") + anyhow!("Timestamp cannot be before the previous certificate at round {previous_round}") })?; // Ensure the elapsed time is within the expected range. match elapsed < MAX_BATCH_DELAY_IN_SECS as i64 { - true => { - bail!("Proposed batch was created too quickly after the certificate at round {previous_round}") - } + true => bail!("Timestamp is too soon after the previous certificate at round {previous_round}"), false => Ok(()), } } From bc6086340a3967ce217c8b09009600ad7c0368cc Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:27:12 -0400 Subject: [PATCH 22/72] Use MIN_BATCH_DELAY_IN_SECS --- node/bft/src/lib.rs | 4 ++-- node/bft/src/primary.rs | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/node/bft/src/lib.rs b/node/bft/src/lib.rs index 550fb20232..ff2fe665a5 100644 --- a/node/bft/src/lib.rs +++ b/node/bft/src/lib.rs @@ -49,8 +49,8 @@ pub const MEMORY_POOL_PORT: u16 = 5000; // port /// The maximum number of milliseconds to wait before proposing a batch. pub const MAX_BATCH_DELAY_IN_MS: u64 = 2500; // ms -/// The maximum number of seconds to wait before proposing a batch (rounded down to the nearest second). -pub const MAX_BATCH_DELAY_IN_SECS: u64 = MAX_BATCH_DELAY_IN_MS / 1000; // seconds +/// The minimum number of seconds to wait before proposing a batch. +pub const MIN_BATCH_DELAY_IN_SECS: u64 = 1; // seconds /// The maximum number of milliseconds to wait before timing out on a fetch. pub const MAX_FETCH_TIMEOUT_IN_MS: u64 = 3 * MAX_BATCH_DELAY_IN_MS; // ms /// The maximum number of seconds allowed for the leader to send their certificate. diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index b267f4fc36..8b033fe4a9 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -33,8 +33,8 @@ use crate::{ Transport, Worker, MAX_BATCH_DELAY_IN_MS, - MAX_BATCH_DELAY_IN_SECS, MAX_WORKERS, + MIN_BATCH_DELAY_IN_SECS, PRIMARY_PING_IN_MS, WORKER_PING_IN_MS, }; @@ -1210,14 +1210,14 @@ impl Primary { fn check_proposal_timestamp(&self, previous_round: u64, author: Address, timestamp: i64) -> Result<()> { // Ensure that the primary does not create a new proposal too quickly. match self.storage.get_certificate_for_round_with_author(previous_round, author) { - // Ensure that the previous certificate was created at least `MAX_BATCH_DELAY_IN_SECS` seconds ago. + // Ensure that the previous certificate was created at least `MIN_BATCH_DELAY_IN_MS` seconds ago. Some(certificate) => { // Determine the elapsed time since the previous certificate. let elapsed = timestamp.checked_sub(certificate.timestamp()).ok_or_else(|| { anyhow!("Timestamp cannot be before the previous certificate at round {previous_round}") })?; // Ensure the elapsed time is within the expected range. - match elapsed < MAX_BATCH_DELAY_IN_SECS as i64 { + match elapsed < MIN_BATCH_DELAY_IN_SECS as i64 { true => bail!("Timestamp is too soon after the previous certificate at round {previous_round}"), false => Ok(()), } @@ -1805,7 +1805,7 @@ mod tests { store_certificate_chain(&primary, &accounts, round, &mut rng); // Sleep for a while to ensure the primary is ready to propose the next round. - tokio::time::sleep(Duration::from_secs(MAX_BATCH_DELAY_IN_SECS + 1)).await; + tokio::time::sleep(Duration::from_secs(MIN_BATCH_DELAY_IN_SECS)).await; // Try to propose a batch. There are no transmissions in the workers so the method should // just return without proposing a batch. @@ -1876,7 +1876,7 @@ mod tests { } // Sleep for a while to ensure the primary is ready to propose the next round. - tokio::time::sleep(Duration::from_secs(MAX_BATCH_DELAY_IN_SECS + 1)).await; + tokio::time::sleep(Duration::from_secs(MIN_BATCH_DELAY_IN_SECS)).await; // Advance to the next round. assert!(primary.storage.increment_to_next_round(round).is_ok()); @@ -1903,7 +1903,7 @@ mod tests { let round = 1; let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -1939,7 +1939,7 @@ mod tests { // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -1970,7 +1970,7 @@ mod tests { let round = 1; let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -2012,7 +2012,7 @@ mod tests { // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_ip = peer_account.0; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( &peer_account.1, primary.ledger.current_committee().unwrap(), @@ -2122,7 +2122,7 @@ mod tests { // Create a valid proposal. let round = 1; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), @@ -2195,7 +2195,7 @@ mod tests { // Create a valid proposal. let round = 1; - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), @@ -2232,7 +2232,7 @@ mod tests { let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); // Create a valid proposal. - let timestamp = now() + MAX_BATCH_DELAY_IN_SECS as i64; + let timestamp = now() + MIN_BATCH_DELAY_IN_SECS as i64; let proposal = create_test_proposal( primary.gateway.account(), primary.ledger.current_committee().unwrap(), From 9eb781eba7c26b8f72a8ea9dba1736e8dded3abd Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:30:30 -0400 Subject: [PATCH 23/72] Add to check_proposal_timestamp condition --- node/bft/src/primary.rs | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 8b033fe4a9..dbfa65d0dc 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1208,22 +1208,32 @@ impl Primary { /// Ensure the primary is not creating batch proposals too frequently. /// This checks that the certificate timestamp for the previous round is within the expected range. fn check_proposal_timestamp(&self, previous_round: u64, author: Address, timestamp: i64) -> Result<()> { - // Ensure that the primary does not create a new proposal too quickly. - match self.storage.get_certificate_for_round_with_author(previous_round, author) { + // Retrieve the timestamp of the previous timestamp to check against. + let previous_timestamp = match self.storage.get_certificate_for_round_with_author(previous_round, author) { // Ensure that the previous certificate was created at least `MIN_BATCH_DELAY_IN_MS` seconds ago. - Some(certificate) => { - // Determine the elapsed time since the previous certificate. - let elapsed = timestamp.checked_sub(certificate.timestamp()).ok_or_else(|| { - anyhow!("Timestamp cannot be before the previous certificate at round {previous_round}") - })?; - // Ensure the elapsed time is within the expected range. - match elapsed < MIN_BATCH_DELAY_IN_SECS as i64 { - true => bail!("Timestamp is too soon after the previous certificate at round {previous_round}"), - false => Ok(()), - } - } - // If we do not see a previous certificate for the author, then proceed optimistically. - None => Ok(()), + Some(certificate) => certificate.timestamp(), + // If we do not see a previous certificate for the author, then proceed check against the earliest timestamp in the previous round. + None => match self + .storage + .get_certificates_for_round(previous_round) + .iter() + .map(BatchCertificate::timestamp) + .min() + { + Some(latest_timestamp) => latest_timestamp, + // If there are no certificates in the previous round, then return early. + None => return Ok(()), + }, + }; + + // Determine the elapsed time since the previous timestamp. + let elapsed = timestamp + .checked_sub(previous_timestamp) + .ok_or_else(|| anyhow!("Timestamp cannot be before the previous certificate at round {previous_round}"))?; + // Ensure that the previous certificate was created at least `MIN_BATCH_DELAY_IN_MS` seconds ago. + match elapsed < MIN_BATCH_DELAY_IN_SECS as i64 { + true => bail!("Timestamp is too soon after the previous certificate at round {previous_round}"), + false => Ok(()), } } From 03cc214d349edd6e016147817e6a1a91fe07fbc4 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Fri, 29 Mar 2024 13:09:24 -0400 Subject: [PATCH 24/72] Track the latest batch proposal timestamp --- node/bft/src/primary.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index dbfa65d0dc..5ecccd2132 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -91,6 +91,8 @@ pub struct Primary { bft_sender: Arc>>, /// The batch proposal, if the primary is currently proposing a batch. proposed_batch: Arc>, + /// The timestamp of the most recent proposed batch. + latest_proposed_batch_timestamp: Arc>, /// The recently-signed batch proposals (a map from the address to the round, batch ID, and signature). signed_proposals: Arc, (u64, Field, Signature)>>>, /// The spawned handles. @@ -125,6 +127,7 @@ impl Primary { workers: Arc::from(vec![]), bft_sender: Default::default(), proposed_batch: Default::default(), + latest_proposed_batch_timestamp: Default::default(), signed_proposals: Default::default(), handles: Default::default(), propose_lock: Default::default(), @@ -505,6 +508,8 @@ impl Primary { let proposal = Proposal::new(committee_lookback, batch_header.clone(), transmissions)?; // Broadcast the batch to all validators for signing. self.gateway.broadcast(Event::BatchPropose(batch_header.into())); + // Set the timestamp of the latest proposed batch. + *self.latest_proposed_batch_timestamp.write() = proposal.timestamp(); // Set the proposed batch. *self.proposed_batch.write() = Some(proposal); Ok(()) @@ -1212,17 +1217,11 @@ impl Primary { let previous_timestamp = match self.storage.get_certificate_for_round_with_author(previous_round, author) { // Ensure that the previous certificate was created at least `MIN_BATCH_DELAY_IN_MS` seconds ago. Some(certificate) => certificate.timestamp(), - // If we do not see a previous certificate for the author, then proceed check against the earliest timestamp in the previous round. - None => match self - .storage - .get_certificates_for_round(previous_round) - .iter() - .map(BatchCertificate::timestamp) - .min() - { - Some(latest_timestamp) => latest_timestamp, - // If there are no certificates in the previous round, then return early. - None => return Ok(()), + None => match self.gateway.account().address() == author { + // If we are the author, then ensure the previous proposal was created at least `MIN_BATCH_DELAY_IN_MS` seconds ago. + true => *self.latest_proposed_batch_timestamp.read(), + // If we do not see a previous certificate for the author, then proceed optimistically. + false => return Ok(()), }, }; From f654dae1efa4a0862944fa4935655901a8c77259 Mon Sep 17 00:00:00 2001 From: Victor Sint Nicolaas Date: Mon, 1 Apr 2024 19:45:24 +0200 Subject: [PATCH 25/72] Ensure validator accepts connections from validators --- node/router/src/handshake.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/node/router/src/handshake.rs b/node/router/src/handshake.rs index 57198692d4..92b8f8462e 100644 --- a/node/router/src/handshake.rs +++ b/node/router/src/handshake.rs @@ -17,6 +17,7 @@ use crate::{ Peer, Router, }; +use snarkos_node_router_messages::NodeType; use snarkos_node_tcp::{ConnectionSide, Tcp, P2P}; use snarkvm::{ ledger::narwhal::Data, @@ -202,7 +203,7 @@ impl Router { let peer_ip = peer_ip.unwrap(); // Knowing the peer's listening address, ensure it is allowed to connect. - if let Err(forbidden_message) = self.ensure_peer_is_allowed(peer_ip) { + if let Err(forbidden_message) = self.ensure_peer_is_allowed(peer_ip, peer_request.node_type) { return Err(error(format!("{forbidden_message}"))); } // Verify the challenge request. If a disconnect reason was returned, send the disconnect message and abort. @@ -251,7 +252,7 @@ impl Router { } /// Ensure the peer is allowed to connect. - fn ensure_peer_is_allowed(&self, peer_ip: SocketAddr) -> Result<()> { + fn ensure_peer_is_allowed(&self, peer_ip: SocketAddr, node_type: NodeType) -> Result<()> { // Ensure the peer IP is not this node. if self.is_local_ip(&peer_ip) { bail!("Dropping connection request from '{peer_ip}' (attempted to self-connect)") @@ -265,7 +266,7 @@ impl Router { bail!("Dropping connection request from '{peer_ip}' (already connected)") } // Only allow trusted peers to connect if allow_external_peers is set - if !self.allow_external_peers() && !self.is_trusted(&peer_ip) { + if !node_type.is_validator() && !self.allow_external_peers() && !self.is_trusted(&peer_ip) { bail!("Dropping connection request from '{peer_ip}' (untrusted)") } // Ensure the peer is not restricted. From 9c03d9f367bcdff2a6475dcfbce7090f20b07202 Mon Sep 17 00:00:00 2001 From: Victor Sint Nicolaas Date: Mon, 1 Apr 2024 20:05:06 +0200 Subject: [PATCH 26/72] Add unit test asserting validator connection --- node/router/tests/cleanups.rs | 2 +- node/router/tests/common/mod.rs | 4 +-- node/router/tests/connect.rs | 43 ++++++++++++++++++++++++++++++--- node/router/tests/disconnect.rs | 4 +-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/node/router/tests/cleanups.rs b/node/router/tests/cleanups.rs index 587b0db2ff..ab8507dec8 100644 --- a/node/router/tests/cleanups.rs +++ b/node/router/tests/cleanups.rs @@ -43,7 +43,7 @@ async fn test_connection_cleanups() { let node = match rng.gen_range(0..3) % 3 { 0 => client(0, 1).await, 1 => prover(0, 1).await, - 2 => validator(0, 1).await, + 2 => validator(0, 1, true).await, _ => unreachable!(), }; diff --git a/node/router/tests/common/mod.rs b/node/router/tests/common/mod.rs index 8938e5b067..73d3f5e774 100644 --- a/node/router/tests/common/mod.rs +++ b/node/router/tests/common/mod.rs @@ -104,14 +104,14 @@ pub async fn prover(listening_port: u16, max_peers: u16) -> TestRouter TestRouter { +pub async fn validator(listening_port: u16, max_peers: u16, allow_external_peers: bool) -> TestRouter { Router::new( SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), listening_port), NodeType::Validator, sample_account(), &[], max_peers, - true, // Router tests require validators to connect to peers. + allow_external_peers, true, ) .await diff --git a/node/router/tests/connect.rs b/node/router/tests/connect.rs index 8264ab93d2..e1fa935d54 100644 --- a/node/router/tests/connect.rs +++ b/node/router/tests/connect.rs @@ -22,7 +22,7 @@ use core::time::Duration; #[tokio::test] async fn test_connect_without_handshake() { // Create 2 routers. - let node0 = validator(0, 2).await; + let node0 = validator(0, 2, true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -78,7 +78,7 @@ async fn test_connect_without_handshake() { #[tokio::test] async fn test_connect_with_handshake() { // Create 2 routers. - let node0 = validator(0, 2).await; + let node0 = validator(0, 2, true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -150,11 +150,48 @@ async fn test_connect_with_handshake() { } } +#[tokio::test] +async fn test_validator_connection() { + // Create 2 routers. + let node0 = validator(0, 2, false).await; + let node1 = validator(0, 2, false).await; + assert_eq!(node0.number_of_connected_peers(), 0); + assert_eq!(node1.number_of_connected_peers(), 0); + + // Enable handshake protocol. + node0.enable_handshake().await; + node1.enable_handshake().await; + + // Start listening. + node0.tcp().enable_listener().await.unwrap(); + node1.tcp().enable_listener().await.unwrap(); + + { + // Connect node0 to node1. + node0.connect(node1.local_ip()); + // Sleep briefly. + tokio::time::sleep(Duration::from_millis(200)).await; + + print_tcp!(node0); + print_tcp!(node1); + + // Check the TCP level. + assert_eq!(node0.tcp().num_connected(), 1); + assert_eq!(node0.tcp().num_connecting(), 0); + assert_eq!(node1.tcp().num_connected(), 1); + assert_eq!(node1.tcp().num_connecting(), 0); + + // Check the router level. + assert_eq!(node0.number_of_connected_peers(), 1); + assert_eq!(node1.number_of_connected_peers(), 1); + } +} + #[ignore] #[tokio::test] async fn test_connect_simultaneously_with_handshake() { // Create 2 routers. - let node0 = validator(0, 2).await; + let node0 = validator(0, 2, true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); diff --git a/node/router/tests/disconnect.rs b/node/router/tests/disconnect.rs index bbcb6c8e33..3d27583e02 100644 --- a/node/router/tests/disconnect.rs +++ b/node/router/tests/disconnect.rs @@ -22,7 +22,7 @@ use core::time::Duration; #[tokio::test] async fn test_disconnect_without_handshake() { // Create 2 routers. - let node0 = validator(0, 1).await; + let node0 = validator(0, 1, true).await; let node1 = client(0, 1).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -64,7 +64,7 @@ async fn test_disconnect_without_handshake() { #[tokio::test] async fn test_disconnect_with_handshake() { // Create 2 routers. - let node0 = validator(0, 1).await; + let node0 = validator(0, 1, true).await; let node1 = client(0, 1).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); From 297461215a24fca050881424fd02cd913aff8326 Mon Sep 17 00:00:00 2001 From: Victor Sint Nicolaas Date: Tue, 2 Apr 2024 17:14:09 +0200 Subject: [PATCH 27/72] Only allow validator routers to connect as trusted peers --- node/router/src/handshake.rs | 7 +++-- node/router/tests/cleanups.rs | 2 +- node/router/tests/common/mod.rs | 9 +++++-- node/router/tests/connect.rs | 48 ++++++++++++++++++++++----------- node/router/tests/disconnect.rs | 4 +-- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/node/router/src/handshake.rs b/node/router/src/handshake.rs index 92b8f8462e..57198692d4 100644 --- a/node/router/src/handshake.rs +++ b/node/router/src/handshake.rs @@ -17,7 +17,6 @@ use crate::{ Peer, Router, }; -use snarkos_node_router_messages::NodeType; use snarkos_node_tcp::{ConnectionSide, Tcp, P2P}; use snarkvm::{ ledger::narwhal::Data, @@ -203,7 +202,7 @@ impl Router { let peer_ip = peer_ip.unwrap(); // Knowing the peer's listening address, ensure it is allowed to connect. - if let Err(forbidden_message) = self.ensure_peer_is_allowed(peer_ip, peer_request.node_type) { + if let Err(forbidden_message) = self.ensure_peer_is_allowed(peer_ip) { return Err(error(format!("{forbidden_message}"))); } // Verify the challenge request. If a disconnect reason was returned, send the disconnect message and abort. @@ -252,7 +251,7 @@ impl Router { } /// Ensure the peer is allowed to connect. - fn ensure_peer_is_allowed(&self, peer_ip: SocketAddr, node_type: NodeType) -> Result<()> { + fn ensure_peer_is_allowed(&self, peer_ip: SocketAddr) -> Result<()> { // Ensure the peer IP is not this node. if self.is_local_ip(&peer_ip) { bail!("Dropping connection request from '{peer_ip}' (attempted to self-connect)") @@ -266,7 +265,7 @@ impl Router { bail!("Dropping connection request from '{peer_ip}' (already connected)") } // Only allow trusted peers to connect if allow_external_peers is set - if !node_type.is_validator() && !self.allow_external_peers() && !self.is_trusted(&peer_ip) { + if !self.allow_external_peers() && !self.is_trusted(&peer_ip) { bail!("Dropping connection request from '{peer_ip}' (untrusted)") } // Ensure the peer is not restricted. diff --git a/node/router/tests/cleanups.rs b/node/router/tests/cleanups.rs index ab8507dec8..3a8b8ed83f 100644 --- a/node/router/tests/cleanups.rs +++ b/node/router/tests/cleanups.rs @@ -43,7 +43,7 @@ async fn test_connection_cleanups() { let node = match rng.gen_range(0..3) % 3 { 0 => client(0, 1).await, 1 => prover(0, 1).await, - 2 => validator(0, 1, true).await, + 2 => validator(0, 1, &[], true).await, _ => unreachable!(), }; diff --git a/node/router/tests/common/mod.rs b/node/router/tests/common/mod.rs index 73d3f5e774..b42b0a2063 100644 --- a/node/router/tests/common/mod.rs +++ b/node/router/tests/common/mod.rs @@ -104,12 +104,17 @@ pub async fn prover(listening_port: u16, max_peers: u16) -> TestRouter TestRouter { +pub async fn validator( + listening_port: u16, + max_peers: u16, + trusted_peers: &[SocketAddr], + allow_external_peers: bool, +) -> TestRouter { Router::new( SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), listening_port), NodeType::Validator, sample_account(), - &[], + trusted_peers, max_peers, allow_external_peers, true, diff --git a/node/router/tests/connect.rs b/node/router/tests/connect.rs index e1fa935d54..60c9b15449 100644 --- a/node/router/tests/connect.rs +++ b/node/router/tests/connect.rs @@ -22,7 +22,7 @@ use core::time::Duration; #[tokio::test] async fn test_connect_without_handshake() { // Create 2 routers. - let node0 = validator(0, 2, true).await; + let node0 = validator(0, 2, &[], true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -78,7 +78,7 @@ async fn test_connect_without_handshake() { #[tokio::test] async fn test_connect_with_handshake() { // Create 2 routers. - let node0 = validator(0, 2, true).await; + let node0 = validator(0, 2, &[], true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -152,18 +152,19 @@ async fn test_connect_with_handshake() { #[tokio::test] async fn test_validator_connection() { - // Create 2 routers. - let node0 = validator(0, 2, false).await; - let node1 = validator(0, 2, false).await; + // Create first router and start listening. + let node0 = validator(0, 2, &[], false).await; assert_eq!(node0.number_of_connected_peers(), 0); - assert_eq!(node1.number_of_connected_peers(), 0); - - // Enable handshake protocol. node0.enable_handshake().await; - node1.enable_handshake().await; - - // Start listening. node0.tcp().enable_listener().await.unwrap(); + + // Get the local IP address from the first router. + let addr0 = node0.local_ip(); + + // Create second router, trusting the first router, and start listening. + let node1 = validator(0, 2, &[addr0], false).await; + assert_eq!(node1.number_of_connected_peers(), 0); + node1.enable_handshake().await; node1.tcp().enable_listener().await.unwrap(); { @@ -175,15 +176,30 @@ async fn test_validator_connection() { print_tcp!(node0); print_tcp!(node1); - // Check the TCP level. + // Check the TCP level - connection was accepted. assert_eq!(node0.tcp().num_connected(), 1); - assert_eq!(node0.tcp().num_connecting(), 0); assert_eq!(node1.tcp().num_connected(), 1); - assert_eq!(node1.tcp().num_connecting(), 0); - // Check the router level. + // Check the router level - connection was accepted. assert_eq!(node0.number_of_connected_peers(), 1); assert_eq!(node1.number_of_connected_peers(), 1); + + // Disconnect the nodes. + node0.disconnect(node1.local_ip()); + node1.disconnect(node0.local_ip()); + + // Connect node1 to node0. + node1.connect(node0.local_ip()); + // Sleep briefly. + tokio::time::sleep(Duration::from_millis(200)).await; + + // Check the TCP level - connection was not accepted. + assert_eq!(node0.tcp().num_connected(), 0); + assert_eq!(node1.tcp().num_connected(), 0); + + // Check the router level - connection was not accepted. + assert_eq!(node0.number_of_connected_peers(), 0); + assert_eq!(node1.number_of_connected_peers(), 0); } } @@ -191,7 +207,7 @@ async fn test_validator_connection() { #[tokio::test] async fn test_connect_simultaneously_with_handshake() { // Create 2 routers. - let node0 = validator(0, 2, true).await; + let node0 = validator(0, 2, &[], true).await; let node1 = client(0, 2).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); diff --git a/node/router/tests/disconnect.rs b/node/router/tests/disconnect.rs index 3d27583e02..df9eee1016 100644 --- a/node/router/tests/disconnect.rs +++ b/node/router/tests/disconnect.rs @@ -22,7 +22,7 @@ use core::time::Duration; #[tokio::test] async fn test_disconnect_without_handshake() { // Create 2 routers. - let node0 = validator(0, 1, true).await; + let node0 = validator(0, 1, &[], true).await; let node1 = client(0, 1).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); @@ -64,7 +64,7 @@ async fn test_disconnect_without_handshake() { #[tokio::test] async fn test_disconnect_with_handshake() { // Create 2 routers. - let node0 = validator(0, 1, true).await; + let node0 = validator(0, 1, &[], true).await; let node1 = client(0, 1).await; assert_eq!(node0.number_of_connected_peers(), 0); assert_eq!(node1.number_of_connected_peers(), 0); From 6ff3343244899d53d81ffd86717c77bcc015c00f Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:56:56 -0400 Subject: [PATCH 28/72] Track the proposal timestamp in signed_proposals --- node/bft/src/primary.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index a2a070183e..1bf15b04a1 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -90,8 +90,8 @@ pub struct Primary { bft_sender: Arc>>, /// The batch proposal, if the primary is currently proposing a batch. proposed_batch: Arc>, - /// The recently-signed batch proposals (a map from the address to the round, batch ID, and signature). - signed_proposals: Arc, (u64, Field, Signature)>>>, + /// The recently-signed batch proposals (a map from the address to the round, timestamp, batch ID, and signature). + signed_proposals: Arc, (u64, i64, Field, Signature)>>>, /// The spawned handles. handles: Arc>>>, /// The lock for propose_batch. @@ -562,7 +562,7 @@ impl Primary { } // Retrieve the cached round and batch ID for this validator. - if let Some((signed_round, signed_batch_id, signature)) = + if let Some((signed_round, timestamp, signed_batch_id, signature)) = self.signed_proposals.read().get(&batch_author).copied() { // If the signed round is ahead of the peer's batch round, then the validator is malicious. @@ -626,6 +626,8 @@ impl Primary { // Retrieve the batch ID. let batch_id = batch_header.batch_id(); + // Retrieve the proposal timestamp. + let timestamp = batch_header.timestamp(); // Sign the batch ID. let account = self.gateway.account().clone(); let signature = spawn_blocking!(account.sign(&[batch_id], &mut rand::thread_rng()))?; @@ -644,13 +646,13 @@ impl Primary { if entry.get().0 == batch_round { return Ok(()); } - // Otherwise, cache the round, batch ID, and signature for this validator. - entry.insert((batch_round, batch_id, signature)); + // Otherwise, cache the round, timestamp, batch ID, and signature for this validator. + entry.insert((batch_round, timestamp, batch_id, signature)); } // If the validator has not signed a batch before, then continue. std::collections::hash_map::Entry::Vacant(entry) => { - // Cache the round, batch ID, and signature for this validator. - entry.insert((batch_round, batch_id, signature)); + // Cache the round, timestamp, batch ID, and signature for this validator. + entry.insert((batch_round, timestamp, batch_id, signature)); } }; From 11c4618635729f19087c547cee7843f70b556e49 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 2 Apr 2024 16:01:08 -0400 Subject: [PATCH 29/72] Expire proposals after PROPOSAL_EXPIRATION_IN_SECS --- node/bft/src/lib.rs | 3 ++ node/bft/src/primary.rs | 65 ++++++++++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/node/bft/src/lib.rs b/node/bft/src/lib.rs index d6fcbae66f..2a63523f63 100644 --- a/node/bft/src/lib.rs +++ b/node/bft/src/lib.rs @@ -58,6 +58,9 @@ pub const MAX_TIMESTAMP_DELTA_IN_SECS: i64 = 10; // seconds /// The maximum number of workers that can be spawned. pub const MAX_WORKERS: u8 = 1; // worker(s) +/// The number of seconds a proposal is valid for before it expires. +pub const PROPOSAL_EXPIRATION_IN_SECS: i64 = 60; // seconds + /// The frequency at which each primary broadcasts a ping to every other node. /// Note: If this is updated, be sure to update `MAX_BLOCKS_BEHIND` to correspond properly. pub const PRIMARY_PING_IN_MS: u64 = 2 * MAX_BATCH_DELAY_IN_MS; // ms diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 1bf15b04a1..b6516767cf 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -35,6 +35,7 @@ use crate::{ MAX_BATCH_DELAY_IN_MS, MAX_WORKERS, PRIMARY_PING_IN_MS, + PROPOSAL_EXPIRATION_IN_SECS, WORKER_PING_IN_MS, }; use snarkos_account::Account; @@ -572,26 +573,43 @@ impl Primary { bail!("Malicious peer - proposed a batch for a previous round ({})", batch_header.round()); } - // If the round matches and the batch ID differs, then the validator is malicious. - if signed_round == batch_header.round() && signed_batch_id != batch_header.batch_id() { - // Proceed to disconnect the validator. - self.gateway.disconnect(peer_ip); - bail!("Malicious peer - proposed another batch for the same round ({signed_round})"); - } - // If the round and batch ID matches, then skip signing the batch a second time. - // Instead, rebroadcast the cached signature to the peer. - if signed_round == batch_header.round() && signed_batch_id == batch_header.batch_id() { - let gateway = self.gateway.clone(); - tokio::spawn(async move { - debug!("Resending a signature for a batch in round {batch_round} from '{peer_ip}'"); - let event = Event::BatchSignature(BatchSignature::new(batch_header.batch_id(), signature)); - // Resend the batch signature to the peer. - if gateway.send(peer_ip, event).await.is_none() { - warn!("Failed to resend a signature for a batch in round {batch_round} to '{peer_ip}'"); + // If the signed round matches the peer's batch round then check the contents. + if signed_round == batch_header.round() { + // Determine if the proposal has expired. + let is_proposal_expired = now().saturating_sub(timestamp) >= PROPOSAL_EXPIRATION_IN_SECS; + match is_proposal_expired { + // If the proposal has expired, then remove the cached signature. + true => { + self.signed_proposals.write().remove(&batch_author); } - }); - // Return early. - return Ok(()); + // If the proposal has not expired, then check the batch id. + false => match signed_batch_id == batch_header.batch_id() { + // If the batch ID matches, then skip signing the batch a second time. + // Instead, rebroadcast the cached signature to the peer. + true => { + let gateway = self.gateway.clone(); + tokio::spawn(async move { + debug!("Resending a signature for a batch in round {batch_round} from '{peer_ip}'"); + let event = + Event::BatchSignature(BatchSignature::new(batch_header.batch_id(), signature)); + // Resend the batch signature to the peer. + if gateway.send(peer_ip, event).await.is_none() { + warn!( + "Failed to resend a signature for a batch in round {batch_round} to '{peer_ip}'" + ); + } + }); + // Return early. + return Ok(()); + } + // If the batch ID differs, then the validator is malicious. + false => { + // Proceed to disconnect the validator. + self.gateway.disconnect(peer_ip); + bail!("Malicious peer - proposed another batch for the same round ({signed_round})"); + } + }, + } } } @@ -1102,7 +1120,14 @@ impl Primary { async fn check_proposed_batch_for_expiration(&self) -> Result<()> { // Check if the proposed batch is timed out or stale. let is_expired = match self.proposed_batch.read().as_ref() { - Some(proposal) => proposal.round() < self.current_round(), + Some(proposal) => { + // Determine if the proposal is stale. + let is_stale = proposal.round() < self.current_round(); + // Determine if the proposal is timed out. + let is_timed_out = now().saturating_sub(proposal.timestamp()) >= PROPOSAL_EXPIRATION_IN_SECS; + // Determine if the proposal is expired. + is_stale || is_timed_out + } None => false, }; // If the batch is expired, clear the proposed batch. From 2dc94f514a5db82f3667b4c4eb23d3684a5a06f1 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:14:45 -0400 Subject: [PATCH 30/72] Cleanup and add tests --- node/bft/src/helpers/proposal.rs | 1 + node/bft/src/lib.rs | 5 + node/bft/src/primary.rs | 188 +++++++++++++++++++++++++++++-- 3 files changed, 186 insertions(+), 8 deletions(-) diff --git a/node/bft/src/helpers/proposal.rs b/node/bft/src/helpers/proposal.rs index 1137ddaa68..06db003c3d 100644 --- a/node/bft/src/helpers/proposal.rs +++ b/node/bft/src/helpers/proposal.rs @@ -28,6 +28,7 @@ use snarkvm::{ use indexmap::{IndexMap, IndexSet}; use std::collections::HashSet; +#[derive(Clone, Debug, PartialEq, Eq)] pub struct Proposal { /// The proposed batch header. batch_header: BatchHeader, diff --git a/node/bft/src/lib.rs b/node/bft/src/lib.rs index 2a63523f63..95a1ee97e8 100644 --- a/node/bft/src/lib.rs +++ b/node/bft/src/lib.rs @@ -59,7 +59,12 @@ pub const MAX_TIMESTAMP_DELTA_IN_SECS: i64 = 10; // seconds pub const MAX_WORKERS: u8 = 1; // worker(s) /// The number of seconds a proposal is valid for before it expires. +#[cfg(not(any(test, feature = "test")))] pub const PROPOSAL_EXPIRATION_IN_SECS: i64 = 60; // seconds +/// The number of seconds a proposal is valid for before it expires. +/// This is set to a deliberately low value (5) for testing purposes only. +#[cfg(any(test, feature = "test"))] +pub const PROPOSAL_EXPIRATION_IN_SECS: i64 = 5; // seconds /// The frequency at which each primary broadcasts a ping to every other node. /// Note: If this is updated, be sure to update `MAX_BLOCKS_BEHIND` to correspond properly. diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index b6516767cf..6ff515f319 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -96,7 +96,7 @@ pub struct Primary { /// The spawned handles. handles: Arc>>>, /// The lock for propose_batch. - propose_lock: Arc>, + propose_lock: Arc>, } impl Primary { @@ -465,14 +465,18 @@ impl Primary { debug!("Primary is safely skipping a batch proposal {}", "(no unconfirmed transactions)".dimmed()); return Ok(()); } - // Ditto if the batch had already been proposed. + // Ditto if the batch had already been proposed and not expired. ensure!(round > 0, "Round 0 cannot have transaction batches"); - if *lock_guard == round { + // Determine the current timestamp. + let current_timestamp = now(); + // Determine if the current proposal is expired. + let is_expired = current_timestamp.saturating_sub(lock_guard.1) >= PROPOSAL_EXPIRATION_IN_SECS; + if lock_guard.0 == round && !is_expired { warn!("Primary is safely skipping a batch proposal - round {round} already proposed"); return Ok(()); } - *lock_guard = round; + *lock_guard = (round, current_timestamp); /* Proceeding to sign & propose the batch. */ info!("Proposing a batch with {} transmissions for round {round}...", transmissions.len()); @@ -489,7 +493,7 @@ impl Primary { let batch_header = spawn_blocking!(BatchHeader::new( &private_key, round, - now(), + current_timestamp, committee_id, transmission_ids, previous_certificate_ids, @@ -563,9 +567,8 @@ impl Primary { } // Retrieve the cached round and batch ID for this validator. - if let Some((signed_round, timestamp, signed_batch_id, signature)) = - self.signed_proposals.read().get(&batch_author).copied() - { + let signed_proposal = self.signed_proposals.read().get(&batch_author).copied(); + if let Some((signed_round, timestamp, signed_batch_id, signature)) = signed_proposal { // If the signed round is ahead of the peer's batch round, then the validator is malicious. if signed_round > batch_header.round() { // Proceed to disconnect the validator. @@ -1877,6 +1880,46 @@ mod tests { assert!(proposed_transmissions.contains_key(&TransmissionID::Transaction(transaction_id))); } + #[tokio::test] + async fn test_propose_batch_expired() { + let round = 3; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + + // Fill primary storage. + store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Try to propose a batch. There are no transmissions in the workers so the method should + // just return without proposing a batch. + assert!(primary.propose_batch().await.is_ok()); + assert!(primary.proposed_batch.read().is_none()); + + // Generate a solution and a transaction. + let (solution_id, solution) = sample_unconfirmed_solution(&mut rng); + let (transaction_id, transaction) = sample_unconfirmed_transaction(&mut rng); + + // Store it on one of the workers. + primary.workers[0].process_unconfirmed_solution(solution_id, solution).await.unwrap(); + primary.workers[0].process_unconfirmed_transaction(transaction_id, transaction).await.unwrap(); + + // Propose a batch again. This time, it should succeed. + assert!(primary.propose_batch().await.is_ok()); + let original_proposed_batch = primary.proposed_batch.read().clone().unwrap(); + + // Try to propose the batch again. This time, it should return the same proposal. + assert!(primary.propose_batch().await.is_ok()); + let proposal = primary.proposed_batch.read().clone().unwrap(); + assert_eq!(proposal, original_proposed_batch); + + // Sleep until the proposal is expired. + tokio::time::sleep(Duration::from_secs(PROPOSAL_EXPIRATION_IN_SECS as u64)).await; + + // Try to propose a batch again. This time the proposal should be expired and a new proposal should be created. + assert!(primary.propose_batch().await.is_ok()); + let new_proposal = primary.proposed_batch.read().clone().unwrap(); + assert_ne!(new_proposal, proposal); + } + #[tokio::test] async fn test_batch_propose_from_peer() { let mut rng = TestRng::default(); @@ -2025,6 +2068,135 @@ mod tests { ); } + #[tokio::test] + async fn test_batch_propose_from_peer_expired() { + let round = 2; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + + // Generate certificates. + let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Create a valid proposal with an author that isn't the primary. + let peer_account = &accounts[1]; + let peer_address = peer_account.1.address(); + let peer_ip = peer_account.0; + let timestamp = now(); + let proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates.clone(), + timestamp, + &mut rng, + ); + + // Make sure the primary is aware of the transmissions in the proposal. + for (transmission_id, transmission) in proposal.transmissions() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()) + } + + // The author must be known to resolver to pass propose checks. + primary.gateway.resolver().insert_peer(peer_ip, peer_ip, peer_account.1.address()); + + // Try to process the batch proposal from the peer, should succeed. + primary.process_batch_propose_from_peer(peer_ip, (*proposal.batch_header()).clone().into()).await.unwrap(); + + // Fetch the original round and batch ID of the signed proposal. + let original_round = primary.signed_proposals.read().get(&peer_address).unwrap().0; + let original_batch_id = primary.signed_proposals.read().get(&peer_address).unwrap().2; + + // Construct a new proposal. + let new_proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates.clone(), + now(), + &mut rng, + ); + + // Try to process the batch proposal from the peer again, should error. + assert!( + primary + .process_batch_propose_from_peer(peer_ip, (*new_proposal.batch_header()).clone().into()) + .await + .is_err() + ); + + // Ensure that the round and batch ID of the signed proposal did not change. + let round = primary.signed_proposals.read().get(&peer_address).unwrap().0; + let batch_id = primary.signed_proposals.read().get(&peer_address).unwrap().2; + assert_eq!(round, original_round); + assert_eq!(batch_id, original_batch_id); + } + + #[tokio::test] + async fn test_batch_propose_from_peer_after_expiration() { + let round = 2; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + + // Generate certificates. + let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Create a valid proposal with an author that isn't the primary. + let peer_account = &accounts[1]; + let peer_address = peer_account.1.address(); + let peer_ip = peer_account.0; + let timestamp = now(); + let proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates.clone(), + timestamp, + &mut rng, + ); + + // Make sure the primary is aware of the transmissions in the proposal. + for (transmission_id, transmission) in proposal.transmissions() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()) + } + + // The author must be known to resolver to pass propose checks. + primary.gateway.resolver().insert_peer(peer_ip, peer_ip, peer_account.1.address()); + + // Try to process the batch proposal from the peer, should succeed. + primary.process_batch_propose_from_peer(peer_ip, (*proposal.batch_header()).clone().into()).await.unwrap(); + + // Fetch the original round and batch ID of the signed proposal. + let original_round = primary.signed_proposals.read().get(&peer_address).unwrap().0; + let original_batch_id = primary.signed_proposals.read().get(&peer_address).unwrap().2; + + // Sleep until the current proposal is expired. + tokio::time::sleep(Duration::from_secs(PROPOSAL_EXPIRATION_IN_SECS as u64)).await; + + // Create a new proposal after the previous one has expired. + let new_proposal = create_test_proposal( + &peer_account.1, + primary.ledger.current_committee().unwrap(), + round, + previous_certificates, + now(), + &mut rng, + ); + + // Make sure the primary is aware of the transmissions in the proposal. + for (transmission_id, transmission) in new_proposal.transmissions() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()) + } + + // Try to process the batch proposal from the peer, should succeed. + primary.process_batch_propose_from_peer(peer_ip, (*new_proposal.batch_header()).clone().into()).await.unwrap(); + + // Ensure that the batch ID of the signed proposal has changed, but the round has not. + let round = primary.signed_proposals.read().get(&peer_address).unwrap().0; + let batch_id = primary.signed_proposals.read().get(&peer_account.1.address()).unwrap().2; + assert_eq!(round, original_round); + assert_ne!(batch_id, original_batch_id); + } + #[tokio::test(flavor = "multi_thread")] async fn test_batch_signature_from_peer() { let mut rng = TestRng::default(); From ab93cd6710edddf057c5f2b9306fb240e13cde09 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:05:19 -0400 Subject: [PATCH 31/72] cleanup --- node/bft/src/primary.rs | 61 +++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 6ff515f319..71bf7cb277 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -576,43 +576,32 @@ impl Primary { bail!("Malicious peer - proposed a batch for a previous round ({})", batch_header.round()); } - // If the signed round matches the peer's batch round then check the contents. - if signed_round == batch_header.round() { - // Determine if the proposal has expired. - let is_proposal_expired = now().saturating_sub(timestamp) >= PROPOSAL_EXPIRATION_IN_SECS; - match is_proposal_expired { - // If the proposal has expired, then remove the cached signature. - true => { - self.signed_proposals.write().remove(&batch_author); + // Determine if the proposal has expired. + let is_proposal_expired = now().saturating_sub(timestamp) >= PROPOSAL_EXPIRATION_IN_SECS; + // If the round matches and the proposal has expired, then remove the cached signature. + if signed_round == batch_header.round() && is_proposal_expired { + self.signed_proposals.write().remove(&batch_author); + } + // If the round matches and the batch ID differs, then the validator is malicious. + else if signed_round == batch_header.round() && signed_batch_id != batch_header.batch_id() { + // Proceed to disconnect the validator. + self.gateway.disconnect(peer_ip); + bail!("Malicious peer - proposed another batch for the same round ({signed_round})"); + } + // If the round and batch ID matches, then skip signing the batch a second time. + // Instead, rebroadcast the cached signature to the peer. + else if signed_round == batch_header.round() && signed_batch_id == batch_header.batch_id() { + let gateway = self.gateway.clone(); + tokio::spawn(async move { + debug!("Resending a signature for a batch in round {batch_round} from '{peer_ip}'"); + let event = Event::BatchSignature(BatchSignature::new(batch_header.batch_id(), signature)); + // Resend the batch signature to the peer. + if gateway.send(peer_ip, event).await.is_none() { + warn!("Failed to resend a signature for a batch in round {batch_round} to '{peer_ip}'"); } - // If the proposal has not expired, then check the batch id. - false => match signed_batch_id == batch_header.batch_id() { - // If the batch ID matches, then skip signing the batch a second time. - // Instead, rebroadcast the cached signature to the peer. - true => { - let gateway = self.gateway.clone(); - tokio::spawn(async move { - debug!("Resending a signature for a batch in round {batch_round} from '{peer_ip}'"); - let event = - Event::BatchSignature(BatchSignature::new(batch_header.batch_id(), signature)); - // Resend the batch signature to the peer. - if gateway.send(peer_ip, event).await.is_none() { - warn!( - "Failed to resend a signature for a batch in round {batch_round} to '{peer_ip}'" - ); - } - }); - // Return early. - return Ok(()); - } - // If the batch ID differs, then the validator is malicious. - false => { - // Proceed to disconnect the validator. - self.gateway.disconnect(peer_ip); - bail!("Malicious peer - proposed another batch for the same round ({signed_round})"); - } - }, - } + }); + // Return early. + return Ok(()); } } From 0400e76f83afcbefb236e829d49c12e6000e443e Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Tue, 2 Apr 2024 22:46:03 -0700 Subject: [PATCH 32/72] Lower priority of warnings on invalid solutions --- node/consensus/src/lib.rs | 11 ++++++++++- node/src/client/router.rs | 5 ++++- node/src/prover/router.rs | 7 ++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index f9a247704e..348786fb36 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -265,7 +265,16 @@ impl Consensus { if let Err(e) = self.primary_sender().send_unconfirmed_solution(solution_id, Data::Object(solution)).await { // If the BFT is synced, then log the warning. if self.bft.is_synced() { - warn!("Failed to add unconfirmed solution '{}' to the memory pool - {e}", fmt_id(solution_id)); + match self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { + true => warn!( + "Failed to add unconfirmed solution '{}' to the memory pool - {e}", + fmt_id(solution_id) + ), + false => error!( + "Failed to add unconfirmed solution '{}' to the memory pool - {e}", + fmt_id(solution_id) + ), + } } } } diff --git a/node/src/client/router.rs b/node/src/client/router.rs index 898b2bee82..1f325a1ca8 100644 --- a/node/src/client/router.rs +++ b/node/src/client/router.rs @@ -284,7 +284,10 @@ impl> Inbound for Client { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } - Err(error) => warn!("Failed to verify the solution: {error}"), + Err(error) => match self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { + true => warn!("Failed to verify the solution - {error}"), + false => trace!("Failed to verify the solution - {error}"), + }, } } true diff --git a/node/src/prover/router.rs b/node/src/prover/router.rs index a5e1489947..8f1771095a 100644 --- a/node/src/prover/router.rs +++ b/node/src/prover/router.rs @@ -240,7 +240,12 @@ impl> Inbound for Prover { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } - Err(error) => warn!("Failed to verify the solution - {error}"), + Err(error) => match self.latest_block_header.read().as_ref().map(|header| header.height()) { + Some(height) if height % N::NUM_BLOCKS_PER_EPOCH > 10 => { + warn!("Failed to verify the solution - {error}") + } + _ => trace!("Failed to verify the solution - {error}"), + }, } } true From 7ac2c090b9461d576149cbccea6445811736c932 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Tue, 2 Apr 2024 22:56:34 -0700 Subject: [PATCH 33/72] Clean up and document --- node/consensus/src/lib.rs | 9 +++++---- node/src/client/router.rs | 7 ++++--- node/src/prover/router.rs | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 348786fb36..a91d2935c3 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -265,16 +265,17 @@ impl Consensus { if let Err(e) = self.primary_sender().send_unconfirmed_solution(solution_id, Data::Object(solution)).await { // If the BFT is synced, then log the warning. if self.bft.is_synced() { - match self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { - true => warn!( + // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. + match self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + true => trace!( "Failed to add unconfirmed solution '{}' to the memory pool - {e}", fmt_id(solution_id) ), - false => error!( + false => warn!( "Failed to add unconfirmed solution '{}' to the memory pool - {e}", fmt_id(solution_id) ), - } + }; } } } diff --git a/node/src/client/router.rs b/node/src/client/router.rs index 1f325a1ca8..62133ab47d 100644 --- a/node/src/client/router.rs +++ b/node/src/client/router.rs @@ -284,9 +284,10 @@ impl> Inbound for Client { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } - Err(error) => match self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { - true => warn!("Failed to verify the solution - {error}"), - false => trace!("Failed to verify the solution - {error}"), + // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. + Err(error) => match self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + true => trace!("Failed to verify the solution - {error}"), + false => warn!("Failed to verify the solution - {error}"), }, } } diff --git a/node/src/prover/router.rs b/node/src/prover/router.rs index 8f1771095a..518c21f91c 100644 --- a/node/src/prover/router.rs +++ b/node/src/prover/router.rs @@ -240,6 +240,7 @@ impl> Inbound for Prover { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } + // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. Err(error) => match self.latest_block_header.read().as_ref().map(|header| header.height()) { Some(height) if height % N::NUM_BLOCKS_PER_EPOCH > 10 => { warn!("Failed to verify the solution - {error}") From 3f8cf7cfb09c3e4319d1b3ca78085d81035be15b Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:18:32 -0400 Subject: [PATCH 34/72] Reduce aggressive disconnect --- node/bft/src/primary.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 71bf7cb277..1b6c22bb81 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -569,11 +569,9 @@ impl Primary { // Retrieve the cached round and batch ID for this validator. let signed_proposal = self.signed_proposals.read().get(&batch_author).copied(); if let Some((signed_round, timestamp, signed_batch_id, signature)) = signed_proposal { - // If the signed round is ahead of the peer's batch round, then the validator is malicious. + // If the signed round is ahead of the peer's batch round, then then ignore the proposal. if signed_round > batch_header.round() { - // Proceed to disconnect the validator. - self.gateway.disconnect(peer_ip); - bail!("Malicious peer - proposed a batch for a previous round ({})", batch_header.round()); + bail!("Proposed a batch for a previous round ({})", batch_header.round()); } // Determine if the proposal has expired. @@ -1127,6 +1125,7 @@ impl Primary { // Reset the proposed batch. let proposal = self.proposed_batch.write().take(); if let Some(proposal) = proposal { + debug!("Cleared expired proposal for round {}", proposal.round()); self.reinsert_transmissions_into_workers(proposal)?; } } From ed30f9e1e4e9947c63762bdf4fe56c3bc70a3236 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:43:22 -0700 Subject: [PATCH 35/72] nit: reorder cli flags, improve order --- cli/src/commands/start.rs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index a3d2767f80..03fe2c82ae 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -55,7 +55,7 @@ const DEVELOPMENT_MODE_NUM_GENESIS_COMMITTEE_MEMBERS: u16 = 4; /// A mapping of `staker_address` to `(validator_address, withdrawal_address, amount)`. #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -struct BondedBalances(IndexMap); +pub struct BondedBalances(IndexMap); impl FromStr for BondedBalances { type Err = serde_json::Error; @@ -101,6 +101,9 @@ pub struct Start { /// Specify the IP address and port of the validator(s) to connect to #[clap(default_value = "", long = "validators")] pub validators: String, + /// If the flag is set, a node will allow untrusted peers to connect + #[clap(long = "allow-external-peers")] + pub allow_external_peers: bool, /// Specify the IP address and port for the REST server #[clap(default_value = "0.0.0.0:3030", long = "rest")] @@ -125,6 +128,9 @@ pub struct Start { #[clap(default_value = "false", long = "metrics")] pub metrics: bool, + /// Specify the path to a directory containing the ledger + #[clap(long = "storage_path")] + pub storage_path: Option, /// Enables the node to prefetch initial blocks from a CDN #[clap(default_value = "https://s3.us-west-1.amazonaws.com/testnet3.blocks/phase3", long = "cdn")] pub cdn: String, @@ -141,17 +147,9 @@ pub struct Start { /// If developtment mode is enabled, specify whether node 0 should generate traffic to drive the network #[clap(default_value = "false", long = "no-dev-txs")] pub no_dev_txs: bool, - /// Specify the path to a directory containing the ledger - #[clap(long = "storage_path")] - pub storage_path: Option, - - /// If development mode is enabled, specify the custom bonded balances as a json object. (default: None) + /// If development mode is enabled, specify the custom bonded balances as a JSON object (default: None) #[clap(long)] - dev_bonded_balances: Option, - - /// If the flag is set, the validator will allow untrusted peers to connect - #[clap(long = "allow-external-peers")] - allow_external_peers: bool, + pub dev_bonded_balances: Option, } impl Start { @@ -489,15 +487,21 @@ impl Start { // Parse the node type. let node_type = self.parse_node_type(); + // Parse the node IP. + let node_ip = match self.node { + Some(node_ip) => node_ip, + None => SocketAddr::from_str("0.0.0.0:4130").unwrap(), + }; + // Parse the BFT IP. + let bft_ip = match self.dev.is_some() { + true => self.bft, + false => None + }; // Parse the REST IP. let rest_ip = match self.norest { true => None, false => Some(self.rest), }; - // Parse the bft ip. - let bft_ip = if self.dev.is_some() { self.bft } else { None }; - // Parse the node ip. - let node_ip = if let Some(node_ip) = self.node { node_ip } else { SocketAddr::from_str("0.0.0.0:4130").unwrap() }; // If the display is not enabled, render the welcome message. if self.nodisplay { From b17ab57e529f7e35ca4ecc8c299efd5378b6e5f2 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:46:17 -0700 Subject: [PATCH 36/72] Switches storage_path to storage --- cli/src/commands/start.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index 03fe2c82ae..06640bf5be 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -128,9 +128,9 @@ pub struct Start { #[clap(default_value = "false", long = "metrics")] pub metrics: bool, - /// Specify the path to a directory containing the ledger - #[clap(long = "storage_path")] - pub storage_path: Option, + /// Specify the path to a directory containing the storage database for the ledger + #[clap(long = "storage")] + pub storage: Option, /// Enables the node to prefetch initial blocks from a CDN #[clap(default_value = "https://s3.us-west-1.amazonaws.com/testnet3.blocks/phase3", long = "cdn")] pub cdn: String, @@ -541,7 +541,7 @@ impl Start { } // Initialize the storage mode. - let storage_mode = match &self.storage_path { + let storage_mode = match &self.storage { Some(path) => StorageMode::Custom(path.clone()), None => StorageMode::from(self.dev), }; From 1b6386f9688e8b4af0ca176057c30f4d60dfe901 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:59:20 -0400 Subject: [PATCH 37/72] Remove unused derivations --- node/bft/src/helpers/proposal.rs | 1 - node/bft/src/primary.rs | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/node/bft/src/helpers/proposal.rs b/node/bft/src/helpers/proposal.rs index 06db003c3d..1137ddaa68 100644 --- a/node/bft/src/helpers/proposal.rs +++ b/node/bft/src/helpers/proposal.rs @@ -28,7 +28,6 @@ use snarkvm::{ use indexmap::{IndexMap, IndexSet}; use std::collections::HashSet; -#[derive(Clone, Debug, PartialEq, Eq)] pub struct Proposal { /// The proposed batch header. batch_header: BatchHeader, diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 69773aa750..88d96211b0 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1945,20 +1945,20 @@ mod tests { // Propose a batch again. This time, it should succeed. assert!(primary.propose_batch().await.is_ok()); - let original_proposed_batch = primary.proposed_batch.read().clone().unwrap(); + let original_proposed_batch_id = primary.proposed_batch.read().as_ref().unwrap().batch_id(); // Try to propose the batch again. This time, it should return the same proposal. assert!(primary.propose_batch().await.is_ok()); - let proposal = primary.proposed_batch.read().clone().unwrap(); - assert_eq!(proposal, original_proposed_batch); + let proposal_batch_id = primary.proposed_batch.read().as_ref().unwrap().batch_id(); + assert_eq!(proposal_batch_id, original_proposed_batch_id); // Sleep until the proposal is expired. tokio::time::sleep(Duration::from_secs(PROPOSAL_EXPIRATION_IN_SECS as u64)).await; // Try to propose a batch again. This time the proposal should be expired and a new proposal should be created. assert!(primary.propose_batch().await.is_ok()); - let new_proposal = primary.proposed_batch.read().clone().unwrap(); - assert_ne!(new_proposal, proposal); + let new_proposal_batch_id = primary.proposed_batch.read().as_ref().unwrap().batch_id(); + assert_ne!(new_proposal_batch_id, original_proposed_batch_id); } #[tokio::test] From 7fec5803a9212182640552655a40dfafea5064d8 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:22:59 -0400 Subject: [PATCH 38/72] Unify timestamp checks to a helper method --- node/bft/src/helpers/timestamp.rs | 11 ++++++++++- node/bft/src/primary.rs | 9 +++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/node/bft/src/helpers/timestamp.rs b/node/bft/src/helpers/timestamp.rs index 2b361fa3cc..2769101b7d 100644 --- a/node/bft/src/helpers/timestamp.rs +++ b/node/bft/src/helpers/timestamp.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::MAX_TIMESTAMP_DELTA_IN_SECS; +use crate::{MAX_TIMESTAMP_DELTA_IN_SECS, PROPOSAL_EXPIRATION_IN_SECS}; use snarkvm::prelude::{bail, Result}; use time::OffsetDateTime; @@ -31,6 +31,15 @@ pub fn check_timestamp_for_liveness(timestamp: i64) -> Result<()> { Ok(()) } +/// Returns whether the proposal is expired. +pub fn is_proposal_expired(current_timestamp: i64, proposal_timestamp: i64) -> bool { + debug_assert!( + current_timestamp >= proposal_timestamp, + "Current timestamp must be greater or equal to the proposal timestamp" + ); + current_timestamp.saturating_sub(proposal_timestamp) >= PROPOSAL_EXPIRATION_IN_SECS +} + #[cfg(test)] mod prop_tests { use super::*; diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 88d96211b0..e0b7dcd2df 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -20,6 +20,7 @@ use crate::{ fmt_id, init_sync_channels, init_worker_channels, + is_proposal_expired, now, BFTSender, PrimaryReceiver, @@ -36,7 +37,6 @@ use crate::{ MAX_WORKERS, MIN_BATCH_DELAY_IN_SECS, PRIMARY_PING_IN_MS, - PROPOSAL_EXPIRATION_IN_SECS, WORKER_PING_IN_MS, }; use snarkos_account::Account; @@ -480,7 +480,7 @@ impl Primary { // Determine the current timestamp. let current_timestamp = now(); // Determine if the current proposal is expired. - let is_expired = current_timestamp.saturating_sub(lock_guard.1) >= PROPOSAL_EXPIRATION_IN_SECS; + let is_expired = is_proposal_expired(current_timestamp, lock_guard.1); if lock_guard.0 == round && !is_expired { warn!("Primary is safely skipping a batch proposal - round {round} already proposed"); return Ok(()); @@ -587,7 +587,7 @@ impl Primary { } // Determine if the proposal has expired. - let is_proposal_expired = now().saturating_sub(timestamp) >= PROPOSAL_EXPIRATION_IN_SECS; + let is_proposal_expired = is_proposal_expired(now(), timestamp); // If the round matches and the proposal has expired, then remove the cached signature. if signed_round == batch_header.round() && is_proposal_expired { self.signed_proposals.write().remove(&batch_author); @@ -1135,7 +1135,7 @@ impl Primary { // Determine if the proposal is stale. let is_stale = proposal.round() < self.current_round(); // Determine if the proposal is timed out. - let is_timed_out = now().saturating_sub(proposal.timestamp()) >= PROPOSAL_EXPIRATION_IN_SECS; + let is_timed_out = is_proposal_expired(now(), proposal.timestamp()); // Determine if the proposal is expired. is_stale || is_timed_out } @@ -1557,6 +1557,7 @@ impl Primary { #[cfg(test)] mod tests { use super::*; + use crate::PROPOSAL_EXPIRATION_IN_SECS; use snarkos_node_bft_ledger_service::MockLedgerService; use snarkos_node_bft_storage_service::BFTMemoryService; use snarkvm::{ From 830a8b8ae998e73f7a62c8ac51cf4f5d4c8bd734 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:40:47 -0400 Subject: [PATCH 39/72] cleanup --- node/bft/src/primary.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index e0b7dcd2df..2f37854907 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -585,22 +585,22 @@ impl Primary { if signed_round > batch_header.round() { bail!("Proposed a batch for a previous round ({})", batch_header.round()); } - - // Determine if the proposal has expired. - let is_proposal_expired = is_proposal_expired(now(), timestamp); - // If the round matches and the proposal has expired, then remove the cached signature. - if signed_round == batch_header.round() && is_proposal_expired { - self.signed_proposals.write().remove(&batch_author); - } - // If the round matches and the batch ID differs, then the validator is malicious. - else if signed_round == batch_header.round() && signed_batch_id != batch_header.batch_id() { - // Proceed to disconnect the validator. - self.gateway.disconnect(peer_ip); - bail!("Malicious peer - proposed another batch for the same round ({signed_round})"); + // If the round matches and the batch ID differs, then check if the proposal is expired. + if signed_round == batch_header.round() && signed_batch_id != batch_header.batch_id() { + // Check if the proposal has expired. + match is_proposal_expired(now(), timestamp) { + // If the proposal has expired, then remove the cached signature. + true => self.signed_proposals.write().remove(&batch_author), + // If the proposal has not expired, then disconnect the validator. + false => { + self.gateway.disconnect(peer_ip); + bail!("Proposed another batch for the same round ({signed_round}) prior to expiration"); + } + }; } // If the round and batch ID matches, then skip signing the batch a second time. // Instead, rebroadcast the cached signature to the peer. - else if signed_round == batch_header.round() && signed_batch_id == batch_header.batch_id() { + if signed_round == batch_header.round() && signed_batch_id == batch_header.batch_id() { let gateway = self.gateway.clone(); tokio::spawn(async move { debug!("Resending a signature for a batch in round {batch_round} from '{peer_ip}'"); From 2e756352b21d71f12ac4e4cdb47e04280ef7fc39 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:53:32 -0400 Subject: [PATCH 40/72] Fix tests --- node/bft/src/primary.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 2f37854907..5e27aa3d21 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1936,6 +1936,9 @@ mod tests { assert!(primary.propose_batch().await.is_ok()); assert!(primary.proposed_batch.read().is_none()); + // Sleep for a while to ensure the primary is ready to propose the next round. + tokio::time::sleep(Duration::from_secs(MIN_BATCH_DELAY_IN_SECS)).await; + // Generate a solution and a transaction. let (solution_id, solution) = sample_unconfirmed_solution(&mut rng); let (transaction_id, transaction) = sample_unconfirmed_transaction(&mut rng); @@ -2119,6 +2122,9 @@ mod tests { // Generate certificates. let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + // Sleep for a while to ensure the primary is ready to propose the next round. + tokio::time::sleep(Duration::from_secs(MIN_BATCH_DELAY_IN_SECS)).await; + // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_address = peer_account.1.address(); @@ -2182,6 +2188,9 @@ mod tests { // Generate certificates. let previous_certificates = store_certificate_chain(&primary, &accounts, round, &mut rng); + // Sleep for a while to ensure the primary is ready to propose the next round. + tokio::time::sleep(Duration::from_secs(MIN_BATCH_DELAY_IN_SECS)).await; + // Create a valid proposal with an author that isn't the primary. let peer_account = &accounts[1]; let peer_address = peer_account.1.address(); @@ -2332,6 +2341,9 @@ mod tests { // Store the proposal on the primary. *primary.proposed_batch.write() = Some(proposal); + // Sleep for a while to ensure the primary is ready to process the proposal. + tokio::time::sleep(Duration::from_secs(1)).await; + // Each committee member signs the batch. let signatures = peer_signatures_for_proposal(&primary, &accounts, &mut rng); @@ -2370,6 +2382,9 @@ mod tests { // Store the proposal on the primary. *primary.proposed_batch.write() = Some(proposal); + // Sleep for a while to ensure the primary is ready to process the proposal. + tokio::time::sleep(Duration::from_secs(1)).await; + // Each committee member signs the batch. let signatures = peer_signatures_for_proposal(&primary, &accounts, &mut rng); @@ -2405,6 +2420,9 @@ mod tests { // Store the proposal on the primary. *primary.proposed_batch.write() = Some(proposal); + // Sleep for a while to ensure the primary is ready to process the proposal. + tokio::time::sleep(Duration::from_secs(1)).await; + // Each committee member signs the batch. let signatures = peer_signatures_for_proposal(&primary, &accounts, &mut rng); @@ -2442,6 +2460,9 @@ mod tests { // Store the proposal on the primary. *primary.proposed_batch.write() = Some(proposal); + // Sleep for a while to ensure the primary is ready to process the proposal. + tokio::time::sleep(Duration::from_secs(1)).await; + // Each committee member signs the batch. let signatures = peer_signatures_for_proposal(&primary, &accounts, &mut rng); From 982b0171ee214e40fb65affc72d777365442a973 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Wed, 3 Apr 2024 18:58:11 -0400 Subject: [PATCH 41/72] Bump snarkVM rev - 39282a1 --- Cargo.lock | 119 +++++++++++++++++++++++++++-------------------------- Cargo.toml | 2 +- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2d86d1bb5..e63e24e687 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3301,7 +3301,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anstyle", "anyhow", @@ -3332,7 +3332,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -3362,7 +3362,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3387,7 +3387,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3397,7 +3397,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3407,7 +3407,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "itertools 0.11.0", @@ -3425,12 +3425,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3441,7 +3441,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3456,7 +3456,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3471,7 +3471,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3484,7 +3484,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3503,7 +3503,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3527,7 +3527,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3538,7 +3538,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3550,7 +3550,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3563,7 +3563,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "bs58", "snarkvm-console-network", @@ -3574,7 +3574,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "blake2s_simd", "smallvec", @@ -3587,7 +3587,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "rayon", @@ -3598,7 +3598,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3621,7 +3621,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anyhow", "bech32", @@ -3639,7 +3639,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "enum_index", "enum_index_derive", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3675,7 +3675,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3686,7 +3686,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", ] @@ -3694,7 +3694,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3704,7 +3704,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3726,7 +3726,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3737,7 +3737,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "rand", "rayon", @@ -3762,7 +3762,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -3779,7 +3779,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -3804,7 +3804,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anyhow", "rand", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3880,7 +3880,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3893,7 +3893,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "bytes", "serde_json", @@ -3904,7 +3904,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3919,7 +3919,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "bytes", "serde_json", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "snarkvm-console", "snarkvm-ledger-puzzle", @@ -3941,7 +3941,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -3961,7 +3961,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle-epoch" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "anyhow", "colored", @@ -3976,7 +3976,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "async-trait", "reqwest", @@ -3989,7 +3989,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std-storage", "anyhow", @@ -4015,7 +4015,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4030,7 +4030,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -4064,7 +4064,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -4086,13 +4086,14 @@ dependencies = [ "snarkvm-synthesizer-process", "snarkvm-synthesizer-program", "snarkvm-synthesizer-snark", + "snarkvm-utilities", "tracing", ] [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "colored", @@ -4115,7 +4116,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "indexmap 2.2.5", "paste", @@ -4129,7 +4130,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "bincode", "once_cell", @@ -4142,7 +4143,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "aleo-std", "anyhow", @@ -4163,7 +4164,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=0029b6a#0029b6a7ba23998c56c8abf4a1772c1f2763a0d4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/Cargo.toml b/Cargo.toml index 64d09eb9b1..dd552cadf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ default-features = false [workspace.dependencies.snarkvm] git = "https://github.com/AleoHQ/snarkVM.git" -rev = "0029b6a" +rev = "39282a1" #version = "=0.16.18" features = [ "circuit", "console", "rocks" ] From 18486887cea28130493db8c8c72c9909080d9d08 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:02:32 -0700 Subject: [PATCH 42/72] Silence instead of tracing solution errors within 10 blocks of the interval --- node/consensus/src/lib.rs | 13 +++---------- node/src/client/router.rs | 11 ++++++----- node/src/prover/router.rs | 13 +++++++------ 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index a91d2935c3..ea9a935968 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -265,16 +265,9 @@ impl Consensus { if let Err(e) = self.primary_sender().send_unconfirmed_solution(solution_id, Data::Object(solution)).await { // If the BFT is synced, then log the warning. if self.bft.is_synced() { - // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. - match self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { - true => trace!( - "Failed to add unconfirmed solution '{}' to the memory pool - {e}", - fmt_id(solution_id) - ), - false => warn!( - "Failed to add unconfirmed solution '{}' to the memory pool - {e}", - fmt_id(solution_id) - ), + // If error occurs after the first 10 blocks of the epoch, log it as a warning, otherwise ignore. + if self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + warn!("Failed to add unconfirmed solution '{}' to the memory pool - {e}", fmt_id(solution_id)) }; } } diff --git a/node/src/client/router.rs b/node/src/client/router.rs index 62133ab47d..f7cb2510aa 100644 --- a/node/src/client/router.rs +++ b/node/src/client/router.rs @@ -284,11 +284,12 @@ impl> Inbound for Client { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } - // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. - Err(error) => match self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { - true => trace!("Failed to verify the solution - {error}"), - false => warn!("Failed to verify the solution - {error}"), - }, + // If error occurs after the first 10 blocks of the epoch, log it as a warning, otherwise ignore. + Err(error) => { + if self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + warn!("Failed to verify the solution - {error}") + } + } } } true diff --git a/node/src/prover/router.rs b/node/src/prover/router.rs index 518c21f91c..1628ffac32 100644 --- a/node/src/prover/router.rs +++ b/node/src/prover/router.rs @@ -240,13 +240,14 @@ impl> Inbound for Prover { Ok(Err(_)) => { trace!("Invalid solution '{}' for the proof target.", solution.id()) } - // If error occurs in the first 10 blocks of the epoch, then log it as a trace, otherwise log it as a warning. - Err(error) => match self.latest_block_header.read().as_ref().map(|header| header.height()) { - Some(height) if height % N::NUM_BLOCKS_PER_EPOCH > 10 => { - warn!("Failed to verify the solution - {error}") + // If error occurs after the first 10 blocks of the epoch, log it as a warning, otherwise ignore. + Err(error) => { + if let Some(height) = self.latest_block_header.read().as_ref().map(|header| header.height()) { + if height % N::NUM_BLOCKS_PER_EPOCH > 10 { + warn!("Failed to verify the solution - {error}") + } } - _ => trace!("Failed to verify the solution - {error}"), - }, + } } } true From 080ee55a7c7b009e42426bf11d012fe1a38cc55a Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:03:59 -0700 Subject: [PATCH 43/72] Fix --- node/consensus/src/lib.rs | 2 +- node/src/client/router.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index ea9a935968..12005de1cf 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -266,7 +266,7 @@ impl Consensus { // If the BFT is synced, then log the warning. if self.bft.is_synced() { // If error occurs after the first 10 blocks of the epoch, log it as a warning, otherwise ignore. - if self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + if self.ledger().latest_block_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { warn!("Failed to add unconfirmed solution '{}' to the memory pool - {e}", fmt_id(solution_id)) }; } diff --git a/node/src/client/router.rs b/node/src/client/router.rs index f7cb2510aa..d71e21eb7e 100644 --- a/node/src/client/router.rs +++ b/node/src/client/router.rs @@ -286,7 +286,7 @@ impl> Inbound for Client { } // If error occurs after the first 10 blocks of the epoch, log it as a warning, otherwise ignore. Err(error) => { - if self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH <= 10 { + if self.ledger.latest_height() % N::NUM_BLOCKS_PER_EPOCH > 10 { warn!("Failed to verify the solution - {error}") } } From d389dd5d4aa8645452acd270c6d91d171e182528 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:10:25 -0400 Subject: [PATCH 44/72] Update snarkVM rev - 36a1e0f --- Cargo.lock | 118 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e63e24e687..d5ea3a4e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3301,7 +3301,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anstyle", "anyhow", @@ -3332,7 +3332,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -3362,7 +3362,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3387,7 +3387,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3397,7 +3397,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3407,7 +3407,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "itertools 0.11.0", @@ -3425,12 +3425,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3441,7 +3441,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3456,7 +3456,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3471,7 +3471,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3484,7 +3484,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3503,7 +3503,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3527,7 +3527,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3538,7 +3538,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3550,7 +3550,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3563,7 +3563,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "bs58", "snarkvm-console-network", @@ -3574,7 +3574,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "blake2s_simd", "smallvec", @@ -3587,7 +3587,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "rayon", @@ -3598,7 +3598,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3621,7 +3621,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anyhow", "bech32", @@ -3639,7 +3639,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "enum_index", "enum_index_derive", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3675,7 +3675,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3686,7 +3686,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", ] @@ -3694,7 +3694,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3704,7 +3704,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3726,7 +3726,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3737,7 +3737,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "rand", "rayon", @@ -3762,7 +3762,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -3779,7 +3779,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -3804,7 +3804,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anyhow", "rand", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3880,7 +3880,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3893,7 +3893,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "bytes", "serde_json", @@ -3904,7 +3904,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3919,7 +3919,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "bytes", "serde_json", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "snarkvm-console", "snarkvm-ledger-puzzle", @@ -3941,7 +3941,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -3961,7 +3961,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle-epoch" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "anyhow", "colored", @@ -3976,7 +3976,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "async-trait", "reqwest", @@ -3989,7 +3989,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std-storage", "anyhow", @@ -4015,7 +4015,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4030,7 +4030,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -4064,7 +4064,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -4093,7 +4093,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "colored", @@ -4116,7 +4116,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "indexmap 2.2.5", "paste", @@ -4130,7 +4130,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "bincode", "once_cell", @@ -4143,7 +4143,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "aleo-std", "anyhow", @@ -4164,7 +4164,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=39282a1#39282a1b53527b98f746b51014c41fb0377b17a4" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/Cargo.toml b/Cargo.toml index dd552cadf4..ed8b581b81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ default-features = false [workspace.dependencies.snarkvm] git = "https://github.com/AleoHQ/snarkVM.git" -rev = "39282a1" +rev = "36a1e0f" #version = "=0.16.18" features = [ "circuit", "console", "rocks" ] From 2913459787d1912593bc69f29102766889e06f2e Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Thu, 4 Apr 2024 21:52:21 -0700 Subject: [PATCH 45/72] Update snarkVM rev - ed20562 --- Cargo.lock | 118 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5ea3a4e02..6c549775cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3301,7 +3301,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anstyle", "anyhow", @@ -3332,7 +3332,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -3362,7 +3362,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3376,7 +3376,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3387,7 +3387,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3397,7 +3397,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3407,7 +3407,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "itertools 0.11.0", @@ -3425,12 +3425,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3441,7 +3441,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3456,7 +3456,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3471,7 +3471,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3484,7 +3484,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3503,7 +3503,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3527,7 +3527,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3538,7 +3538,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3550,7 +3550,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3563,7 +3563,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "bs58", "snarkvm-console-network", @@ -3574,7 +3574,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "blake2s_simd", "smallvec", @@ -3587,7 +3587,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "rayon", @@ -3598,7 +3598,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3621,7 +3621,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anyhow", "bech32", @@ -3639,7 +3639,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "enum_index", "enum_index_derive", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3675,7 +3675,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3686,7 +3686,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", ] @@ -3694,7 +3694,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3704,7 +3704,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3726,7 +3726,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3737,7 +3737,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "rand", "rayon", @@ -3762,7 +3762,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -3779,7 +3779,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -3804,7 +3804,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anyhow", "rand", @@ -3816,7 +3816,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3854,7 +3854,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -3867,7 +3867,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3880,7 +3880,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3893,7 +3893,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "bytes", "serde_json", @@ -3904,7 +3904,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3919,7 +3919,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "bytes", "serde_json", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "snarkvm-console", "snarkvm-ledger-puzzle", @@ -3941,7 +3941,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -3961,7 +3961,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle-epoch" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "anyhow", "colored", @@ -3976,7 +3976,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "async-trait", "reqwest", @@ -3989,7 +3989,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std-storage", "anyhow", @@ -4015,7 +4015,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4030,7 +4030,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -4064,7 +4064,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -4093,7 +4093,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "colored", @@ -4116,7 +4116,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "indexmap 2.2.5", "paste", @@ -4130,7 +4130,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "bincode", "once_cell", @@ -4143,7 +4143,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "aleo-std", "anyhow", @@ -4164,7 +4164,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=36a1e0f#36a1e0fb285762eae8e15e93270845fc86938336" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/Cargo.toml b/Cargo.toml index ed8b581b81..81b8254f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ default-features = false [workspace.dependencies.snarkvm] git = "https://github.com/AleoHQ/snarkVM.git" -rev = "36a1e0f" +rev = "ed20562" #version = "=0.16.18" features = [ "circuit", "console", "rocks" ] From 8357eaee8986c6023ee1672fcbf23c3a03559769 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:13:27 -0700 Subject: [PATCH 46/72] nit: reorder --- node/consensus/src/lib.rs | 83 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 6538d2c2a8..fa97681b00 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -48,14 +48,15 @@ use colored::Colorize; use indexmap::IndexMap; use lru::LruCache; use parking_lot::Mutex; -#[cfg(feature = "metrics")] -use std::collections::HashMap; use std::{future::Future, net::SocketAddr, num::NonZeroUsize, sync::Arc}; use tokio::{ sync::{oneshot, OnceCell}, task::JoinHandle, }; +#[cfg(feature = "metrics")] +use std::collections::HashMap; + /// The capacity of the queue reserved for deployments. /// Note: This is an inbound queue capacity, not a Narwhal-enforced capacity. const CAPACITY_FOR_DEPLOYMENTS: usize = 1 << 10; @@ -100,10 +101,10 @@ pub struct Consensus { seen_solutions: Arc, ()>>>, /// The recently-seen unconfirmed transactions. seen_transactions: Arc>>, - /// The spawned handles. - handles: Arc>>>, #[cfg(feature = "metrics")] transmissions_queue_timestamps: Arc, i64>>>, + /// The spawned handles. + handles: Arc>>>, } impl Consensus { @@ -135,9 +136,9 @@ impl Consensus { transactions_queue: Default::default(), seen_solutions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), seen_transactions: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1 << 16).unwrap()))), - handles: Default::default(), #[cfg(feature = "metrics")] transmissions_queue_timestamps: Default::default(), + handles: Default::default(), }) } @@ -456,6 +457,42 @@ impl Consensus { Ok(()) } + /// Reinserts the given transmissions into the memory pool. + async fn reinsert_transmissions(&self, transmissions: IndexMap, Transmission>) { + // Iterate over the transmissions. + for (transmission_id, transmission) in transmissions.into_iter() { + // Reinsert the transmission into the memory pool. + if let Err(e) = self.reinsert_transmission(transmission_id, transmission).await { + warn!("Unable to reinsert transmission {} into the memory pool - {e}", fmt_id(transmission_id)); + } + } + } + + /// Reinserts the given transmission into the memory pool. + async fn reinsert_transmission( + &self, + transmission_id: TransmissionID, + transmission: Transmission, + ) -> Result<()> { + // Initialize a callback sender and receiver. + let (callback, callback_receiver) = oneshot::channel(); + // Send the transmission to the primary. + match (transmission_id, transmission) { + (TransmissionID::Ratification, Transmission::Ratification) => return Ok(()), + (TransmissionID::Solution(solution_id), Transmission::Solution(solution)) => { + // Send the solution to the primary. + self.primary_sender().tx_unconfirmed_solution.send((solution_id, solution, callback)).await?; + } + (TransmissionID::Transaction(transaction_id), Transmission::Transaction(transaction)) => { + // Send the transaction to the primary. + self.primary_sender().tx_unconfirmed_transaction.send((transaction_id, transaction, callback)).await?; + } + _ => bail!("Mismatching `(transmission_id, transmission)` pair in consensus"), + } + // Await the callback. + callback_receiver.await? + } + #[cfg(feature = "metrics")] fn add_transmission_latency_metric(&self, next_block: &Block) { const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold @@ -501,42 +538,6 @@ impl Consensus { } } - /// Reinserts the given transmissions into the memory pool. - async fn reinsert_transmissions(&self, transmissions: IndexMap, Transmission>) { - // Iterate over the transmissions. - for (transmission_id, transmission) in transmissions.into_iter() { - // Reinsert the transmission into the memory pool. - if let Err(e) = self.reinsert_transmission(transmission_id, transmission).await { - warn!("Unable to reinsert transmission {} into the memory pool - {e}", fmt_id(transmission_id)); - } - } - } - - /// Reinserts the given transmission into the memory pool. - async fn reinsert_transmission( - &self, - transmission_id: TransmissionID, - transmission: Transmission, - ) -> Result<()> { - // Initialize a callback sender and receiver. - let (callback, callback_receiver) = oneshot::channel(); - // Send the transmission to the primary. - match (transmission_id, transmission) { - (TransmissionID::Ratification, Transmission::Ratification) => return Ok(()), - (TransmissionID::Solution(solution_id), Transmission::Solution(solution)) => { - // Send the solution to the primary. - self.primary_sender().tx_unconfirmed_solution.send((solution_id, solution, callback)).await?; - } - (TransmissionID::Transaction(transaction_id), Transmission::Transaction(transaction)) => { - // Send the transaction to the primary. - self.primary_sender().tx_unconfirmed_transaction.send((transaction_id, transaction, callback)).await?; - } - _ => bail!("Mismatching `(transmission_id, transmission)` pair in consensus"), - } - // Await the callback. - callback_receiver.await? - } - /// Spawns a task with the given future; it should only be used for long-running tasks. fn spawn + Send + 'static>(&self, future: T) { self.handles.lock().push(tokio::spawn(future)); From 348b21e7ce83d255d4bf24d2b889fade2c146488 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:15:04 -0700 Subject: [PATCH 47/72] Include the aborted solution IDs and transaction IDs --- node/consensus/src/lib.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index fa97681b00..13b31a1c03 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -497,10 +497,16 @@ impl Consensus { fn add_transmission_latency_metric(&self, next_block: &Block) { const AGE_THRESHOLD_SECONDS: i32 = 30 * 60; // 30 minutes set as stale transmission threshold - let mut keys_to_remove = Vec::new(); + // Retrieve the solution IDs. + let solution_ids: std::collections::HashSet<_> = + next_block.solutions().solution_ids().chain(next_block.aborted_solution_ids()).collect(); + + // Retrieve the transaction IDs. + let transaction_ids: std::collections::HashSet<_> = + next_block.transaction_ids().chain(next_block.aborted_transaction_ids()).collect(); - let solution_ids: std::collections::HashSet<_> = next_block.solutions().solution_ids().collect(); - let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().collect(); + // Initialize a list of keys to remove. + let mut keys_to_remove = Vec::new(); let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); let ts_now = snarkos_node_bft::helpers::now(); From 53bd65d955a9c570035dc4baaa577d9502653441 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:22:54 -0700 Subject: [PATCH 48/72] Parallelize potentially slow for loop --- Cargo.lock | 1 + node/consensus/Cargo.toml | 3 ++ node/consensus/src/lib.rs | 63 +++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c549775cc..9ba6c74fe9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3144,6 +3144,7 @@ dependencies = [ "once_cell", "parking_lot", "rand", + "rayon", "snarkos-account", "snarkos-node-bft", "snarkos-node-bft-ledger-service", diff --git a/node/consensus/Cargo.toml b/node/consensus/Cargo.toml index 81fdcd867b..ac9ccc1afb 100644 --- a/node/consensus/Cargo.toml +++ b/node/consensus/Cargo.toml @@ -48,6 +48,9 @@ version = "0.12" [dependencies.rand] version = "0.8" +[dependencies.rayon] +version = "1" + [dependencies.snarkos-account] path = "../../account" version = "=2.2.7" diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 13b31a1c03..7177f3e6a5 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -54,6 +54,8 @@ use tokio::{ task::JoinHandle, }; +#[cfg(feature = "metrics")] +use rayon::prelude::*; #[cfg(feature = "metrics")] use std::collections::HashMap; @@ -505,40 +507,43 @@ impl Consensus { let transaction_ids: std::collections::HashSet<_> = next_block.transaction_ids().chain(next_block.aborted_transaction_ids()).collect(); - // Initialize a list of keys to remove. - let mut keys_to_remove = Vec::new(); - let mut transmission_queue_timestamps = self.transmissions_queue_timestamps.lock(); let ts_now = snarkos_node_bft::helpers::now(); - for (key, timestamp) in transmission_queue_timestamps.iter() { - let elapsed_time = std::time::Duration::from_secs((ts_now - *timestamp) as u64); - - if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { - // This entry is stale-- remove it from transmission queue and record it as a stale transmission. - metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); - keys_to_remove.push(*key); - } else { - let transmission_type = match key { - TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), - TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => { - Some("transaction") + + // Determine which keys to remove. + let keys_to_remove = cfg_iter!(transmission_queue_timestamps) + .flat_map(|(key, timestamp)| { + let elapsed_time = std::time::Duration::from_secs((ts_now - *timestamp) as u64); + + if elapsed_time.as_secs() > AGE_THRESHOLD_SECONDS as u64 { + // This entry is stale-- remove it from transmission queue and record it as a stale transmission. + metrics::increment_counter(metrics::consensus::STALE_UNCONFIRMED_TRANSMISSIONS); + Some(*key) + } else { + let transmission_type = match key { + TransmissionID::Solution(solution_id) if solution_ids.contains(solution_id) => Some("solution"), + TransmissionID::Transaction(transaction_id) if transaction_ids.contains(transaction_id) => { + Some("transaction") + } + _ => None, + }; + + if let Some(transmission_type_string) = transmission_type { + metrics::histogram_label( + metrics::consensus::TRANSMISSION_LATENCY, + "transmission_type", + transmission_type_string.to_owned(), + elapsed_time.as_secs_f64(), + ); + Some(*key) + } else { + None } - _ => None, - }; - - if let Some(transmission_type_string) = transmission_type { - metrics::histogram_label( - metrics::consensus::TRANSMISSION_LATENCY, - "transmission_type", - transmission_type_string.to_owned(), - elapsed_time.as_secs_f64(), - ); - keys_to_remove.push(*key); } - } - } + }) + .collect::>(); - // Remove keys of stale or seen transmissions + // Remove keys of stale or seen transmissions. for key in keys_to_remove { transmission_queue_timestamps.remove(&key); } From 1ebf4d599f8ea7b8389f0fb4af2f0f5f19e03557 Mon Sep 17 00:00:00 2001 From: miazn Date: Mon, 8 Apr 2024 17:24:36 -0400 Subject: [PATCH 49/72] remove register histogram --- node/metrics/src/names.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 7f5820e4cf..4d696c3873 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -38,11 +38,10 @@ pub(super) const GAUGE_NAMES: [&str; 21] = [ tcp::TCP_TASKS, ]; -pub(super) const HISTOGRAM_NAMES: [&str; 8] = [ +pub(super) const HISTOGRAM_NAMES: [&str; 7] = [ bft::COMMIT_ROUNDS_LATENCY, consensus::CERTIFICATE_COMMIT_LATENCY, consensus::BLOCK_LATENCY, - consensus::TRANSMISSION_LATENCY, tcp::NOISE_CODEC_ENCRYPTION_TIME, tcp::NOISE_CODEC_DECRYPTION_TIME, tcp::NOISE_CODEC_ENCRYPTION_SIZE, From 8e79de5154be9fd88494a1e6263fbd61e9c2abbb Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 8 Apr 2024 17:59:05 -0400 Subject: [PATCH 50/72] Add aborted_transmissions to find_missing_transmissions --- node/bft/storage-service/src/memory.rs | 22 +++++++++++++------ node/bft/storage-service/src/persistent.rs | 25 ++++++++++++++++------ node/bft/storage-service/src/traits.rs | 6 +++++- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/node/bft/storage-service/src/memory.rs b/node/bft/storage-service/src/memory.rs index f91623bd3f..d4ffc6ca98 100644 --- a/node/bft/storage-service/src/memory.rs +++ b/node/bft/storage-service/src/memory.rs @@ -20,7 +20,7 @@ use snarkvm::{ use indexmap::{indexset, map::Entry, IndexMap, IndexSet}; use parking_lot::RwLock; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use tracing::error; /// A BFT in-memory storage service. @@ -63,6 +63,7 @@ impl StorageService for BFTMemoryService { &self, batch_header: &BatchHeader, mut transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result, Transmission>> { // Initialize a list for the missing transmissions from storage. let mut missing_transmissions = HashMap::new(); @@ -70,14 +71,21 @@ impl StorageService for BFTMemoryService { let known_transmissions = self.transmissions.read(); // Ensure the declared transmission IDs are all present in storage or the given transmissions map. for transmission_id in batch_header.transmission_ids() { - // If the transmission ID does not exist, ensure it was provided by the caller. + // If the transmission ID does not exist, ensure it was provided by the caller or aborted. if !known_transmissions.contains_key(transmission_id) { // Retrieve the transmission. - let Some(transmission) = transmissions.remove(transmission_id) else { - bail!("Failed to provide a transmission"); - }; - // Append the transmission. - missing_transmissions.insert(*transmission_id, transmission); + match transmissions.remove(transmission_id) { + // Append the transmission if it exists. + Some(transmission) => { + missing_transmissions.insert(*transmission_id, transmission); + } + // If the transmission does not exist, check if it was aborted. + None => { + if !aborted_transmissions.contains(transmission_id) { + bail!("Failed to provide a transmission"); + } + } + } } } Ok(missing_transmissions) diff --git a/node/bft/storage-service/src/persistent.rs b/node/bft/storage-service/src/persistent.rs index a44b428e18..a3fc665d17 100644 --- a/node/bft/storage-service/src/persistent.rs +++ b/node/bft/storage-service/src/persistent.rs @@ -33,7 +33,10 @@ use snarkvm::{ use aleo_std::StorageMode; use indexmap::{indexset, IndexSet}; -use std::{borrow::Cow, collections::HashMap}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, +}; use tracing::error; /// A BFT persistent storage service. @@ -91,19 +94,27 @@ impl StorageService for BFTPersistentStorage { &self, batch_header: &BatchHeader, mut transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result, Transmission>> { // Initialize a list for the missing transmissions from storage. let mut missing_transmissions = HashMap::new(); // Ensure the declared transmission IDs are all present in storage or the given transmissions map. for transmission_id in batch_header.transmission_ids() { - // If the transmission ID does not exist, ensure it was provided by the caller. + // If the transmission ID does not exist, ensure it was provided by the caller or aborted. if !self.contains_transmission(*transmission_id) { // Retrieve the transmission. - let Some(transmission) = transmissions.remove(transmission_id) else { - bail!("Failed to provide a transmission"); - }; - // Append the transmission. - missing_transmissions.insert(*transmission_id, transmission); + match transmissions.remove(transmission_id) { + // Append the transmission if it exists. + Some(transmission) => { + missing_transmissions.insert(*transmission_id, transmission); + } + // If the transmission does not exist, check if it was aborted. + None => { + if !aborted_transmissions.contains(transmission_id) { + bail!("Failed to provide a transmission"); + } + } + } } } Ok(missing_transmissions) diff --git a/node/bft/storage-service/src/traits.rs b/node/bft/storage-service/src/traits.rs index 8770c770fb..d2c1478978 100644 --- a/node/bft/storage-service/src/traits.rs +++ b/node/bft/storage-service/src/traits.rs @@ -18,7 +18,10 @@ use snarkvm::{ }; use indexmap::IndexSet; -use std::{collections::HashMap, fmt::Debug}; +use std::{ + collections::{HashMap, HashSet}, + fmt::Debug, +}; pub trait StorageService: Debug + Send + Sync { /// Returns `true` if the storage contains the specified `transmission ID`. @@ -33,6 +36,7 @@ pub trait StorageService: Debug + Send + Sync { &self, batch_header: &BatchHeader, transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result, Transmission>>; /// Inserts the given certificate ID for each of the transmission IDs, using the missing transmissions map, into storage. From bf07a9225e6e6cd998c408c18a41af5001629863 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:04:11 -0400 Subject: [PATCH 51/72] Track aborted transactions in insert_certificate and check_certificate --- node/bft/src/helpers/storage.rs | 33 +++++++++++++++++++++++++++------ node/bft/src/primary.rs | 11 ++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/node/bft/src/helpers/storage.rs b/node/bft/src/helpers/storage.rs index f69b45b56d..1cd51464a0 100644 --- a/node/bft/src/helpers/storage.rs +++ b/node/bft/src/helpers/storage.rs @@ -339,6 +339,7 @@ impl Storage { &self, batch_header: &BatchHeader, transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result, Transmission>> { // Retrieve the round. let round = batch_header.round(); @@ -367,7 +368,7 @@ impl Storage { // Retrieve the missing transmissions in storage from the given transmissions. let missing_transmissions = self .transmissions - .find_missing_transmissions(batch_header, transmissions) + .find_missing_transmissions(batch_header, transmissions, aborted_transmissions) .map_err(|e| anyhow!("{e} for round {round} {gc_log}"))?; // Compute the previous round. @@ -435,6 +436,7 @@ impl Storage { &self, certificate: &BatchCertificate, transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result, Transmission>> { // Retrieve the round. let round = certificate.round(); @@ -454,7 +456,8 @@ impl Storage { } // Ensure the batch header is well-formed. - let missing_transmissions = self.check_batch_header(certificate.batch_header(), transmissions)?; + let missing_transmissions = + self.check_batch_header(certificate.batch_header(), transmissions, aborted_transmissions)?; // Check the timestamp for liveness. check_timestamp_for_liveness(certificate.timestamp())?; @@ -503,11 +506,12 @@ impl Storage { &self, certificate: BatchCertificate, transmissions: HashMap, Transmission>, + aborted_transmissions: HashSet>, ) -> Result<()> { // Ensure the certificate round is above the GC round. ensure!(certificate.round() > self.gc_round(), "Certificate round is at or below the GC round"); // Ensure the certificate and its transmissions are valid. - let missing_transmissions = self.check_certificate(&certificate, transmissions)?; + let missing_transmissions = self.check_certificate(&certificate, transmissions, aborted_transmissions)?; // Insert the certificate into storage. self.insert_certificate_atomic(certificate, missing_transmissions); Ok(()) @@ -631,6 +635,9 @@ impl Storage { // Retrieve the transmissions for the certificate. let mut missing_transmissions = HashMap::new(); + // Retrieve the aborted transmissions for the certificate. + let mut aborted_transmissions = HashSet::new(); + // Iterate over the transmission IDs. for transmission_id in certificate.transmission_ids() { // If the transmission ID already exists in the map, skip it. @@ -653,8 +660,15 @@ impl Storage { None => match self.ledger.get_solution(solution_id) { // Insert the solution. Ok(solution) => missing_transmissions.insert(*transmission_id, solution.into()), + // Check if the solution is in the aborted solutions. Err(_) => { - error!("Missing solution {solution_id} in block {}", block.height()); + // Insert the aborted solution if it exists in the block. + match block.aborted_solution_ids().contains(solution_id) { + true => { + aborted_transmissions.insert(*transmission_id); + } + false => error!("Missing solution {solution_id} in block {}", block.height()), + } continue; } }, @@ -669,8 +683,15 @@ impl Storage { None => match self.ledger.get_unconfirmed_transaction(*transaction_id) { // Insert the transaction. Ok(transaction) => missing_transmissions.insert(*transmission_id, transaction.into()), + // Check if the transaction is in the aborted transactions. Err(_) => { - warn!("Missing transaction {transaction_id} in block {}", block.height()); + // Insert the aborted transaction if it exists in the block. + match block.aborted_transaction_ids().contains(transaction_id) { + true => { + aborted_transmissions.insert(*transmission_id); + } + false => warn!("Missing transaction {transaction_id} in block {}", block.height()), + } continue; } }, @@ -685,7 +706,7 @@ impl Storage { certificate.round(), certificate.transmission_ids().len() ); - if let Err(error) = self.insert_certificate(certificate, missing_transmissions) { + if let Err(error) = self.insert_certificate(certificate, missing_transmissions, aborted_transmissions) { error!("Failed to insert certificate '{certificate_id}' from block {} - {error}", block.height()); } } diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 5e27aa3d21..c7498697ba 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -647,7 +647,8 @@ impl Primary { // Ensure the batch header from the peer is valid. let (storage, header) = (self.storage.clone(), batch_header.clone()); - let missing_transmissions = spawn_blocking!(storage.check_batch_header(&header, transmissions))?; + let missing_transmissions = + spawn_blocking!(storage.check_batch_header(&header, transmissions, Default::default()))?; // Inserts the missing transmissions into the workers. self.insert_missing_transmissions_into_workers(peer_ip, missing_transmissions.into_iter())?; @@ -1263,7 +1264,7 @@ impl Primary { let transmissions = transmissions.into_iter().collect::>(); // Store the certified batch. let (storage, certificate_) = (self.storage.clone(), certificate.clone()); - spawn_blocking!(storage.insert_certificate(certificate_, transmissions))?; + spawn_blocking!(storage.insert_certificate(certificate_, transmissions, Default::default()))?; debug!("Stored a batch certificate for round {}", certificate.round()); // If a BFT sender was provided, send the certificate to the BFT. if let Some(bft_sender) = self.bft_sender.get() { @@ -1343,7 +1344,7 @@ impl Primary { if !self.storage.contains_certificate(certificate.id()) { // Store the batch certificate. let (storage, certificate_) = (self.storage.clone(), certificate.clone()); - spawn_blocking!(storage.insert_certificate(certificate_, missing_transmissions))?; + spawn_blocking!(storage.insert_certificate(certificate_, missing_transmissions, Default::default()))?; debug!("Stored a batch certificate for round {batch_round} from '{peer_ip}'"); // If a BFT sender was provided, send the round and certificate to the BFT. if let Some(bft_sender) = self.bft_sender.get() { @@ -1777,7 +1778,7 @@ mod tests { rng, ); next_certificates.insert(certificate.id()); - assert!(primary.storage.insert_certificate(certificate, transmissions).is_ok()); + assert!(primary.storage.insert_certificate(certificate, transmissions, Default::default()).is_ok()); } assert!(primary.storage.increment_to_next_round(cur_round).is_ok()); @@ -1900,7 +1901,7 @@ mod tests { // Insert the certificate to storage. num_transmissions_in_previous_round += transmissions.len(); - primary.storage.insert_certificate(certificate, transmissions).unwrap(); + primary.storage.insert_certificate(certificate, transmissions, Default::default()).unwrap(); } // Sleep for a while to ensure the primary is ready to propose the next round. From 190cd43fd6549fa9ee166c5ebe275b8ca9568e62 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:31:22 -0400 Subject: [PATCH 52/72] Add test for inserting certificate with aborted transmissions --- node/bft/src/primary.rs | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index c7498697ba..7f86443b93 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -2476,4 +2476,79 @@ mod tests { // Check the round was incremented. assert_eq!(primary.current_round(), round); } + + #[tokio::test] + async fn test_insert_certificate_with_aborted_transmissions() { + let round = 3; + let prev_round = round - 1; + let mut rng = TestRng::default(); + let (primary, accounts) = primary_without_handlers(&mut rng).await; + let peer_account = &accounts[1]; + let peer_ip = peer_account.0; + + // Fill primary storage. + store_certificate_chain(&primary, &accounts, round, &mut rng); + + // Get transmissions from previous certificates. + let previous_certificate_ids: IndexSet<_> = + primary.storage.get_certificates_for_round(prev_round).iter().map(|cert| cert.id()).collect(); + + // Generate a solution and a transaction. + let (solution_commitment, solution) = sample_unconfirmed_solution(&mut rng); + let (transaction_id, transaction) = sample_unconfirmed_transaction(&mut rng); + + // Store it on one of the workers. + primary.workers[0].process_unconfirmed_solution(solution_commitment, solution).await.unwrap(); + primary.workers[0].process_unconfirmed_transaction(transaction_id, transaction).await.unwrap(); + + // Check that the worker has 2 transmissions. + assert_eq!(primary.workers[0].num_transmissions(), 2); + + // Create certificates for the current round. + let account = accounts[0].1.clone(); + let (certificate, transmissions) = + create_batch_certificate(account.address(), &accounts, round, previous_certificate_ids.clone(), &mut rng); + let certificate_id = certificate.id(); + + // Randomly abort some of the transmissions. + let mut aborted_transmissions = HashSet::new(); + let mut transmissions_without_aborted = HashMap::new(); + for (transmission_id, transmission) in transmissions.clone() { + match rng.gen::() { + true => { + // Insert the aborted transmission. + aborted_transmissions.insert(transmission_id); + } + false => { + // Insert the transmission without the aborted transmission. + transmissions_without_aborted.insert(transmission_id, transmission); + } + }; + } + + // Add the non-aborted transmissions to the worker. + for (transmission_id, transmission) in transmissions_without_aborted.iter() { + primary.workers[0].process_transmission_from_peer(peer_ip, *transmission_id, transmission.clone()); + } + + // Check that inserting the transmission with missing transmissions fails. + assert!( + primary + .storage + .check_certificate(&certificate, transmissions_without_aborted.clone(), Default::default()) + .is_err() + ); + assert!( + primary + .storage + .insert_certificate(certificate.clone(), transmissions_without_aborted.clone(), Default::default()) + .is_err() + ); + + // Insert the certificate to storage. + primary.storage.insert_certificate(certificate, transmissions_without_aborted, aborted_transmissions).unwrap(); + + // Ensure the certificate exists in storage. + assert!(primary.storage.contains_certificate(certificate_id)); + } } From e753a81d64baa7679fb14d7b597f25324d4f4161 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:38:35 -0400 Subject: [PATCH 53/72] Add ledger check for aborted transmissions --- node/bft/src/helpers/storage.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/node/bft/src/helpers/storage.rs b/node/bft/src/helpers/storage.rs index 1cd51464a0..d97e552fed 100644 --- a/node/bft/src/helpers/storage.rs +++ b/node/bft/src/helpers/storage.rs @@ -662,8 +662,10 @@ impl Storage { Ok(solution) => missing_transmissions.insert(*transmission_id, solution.into()), // Check if the solution is in the aborted solutions. Err(_) => { - // Insert the aborted solution if it exists in the block. - match block.aborted_solution_ids().contains(solution_id) { + // Insert the aborted solution if it exists in the block or ledger. + match block.aborted_solution_ids().contains(solution_id) + || self.ledger.contains_transmission(transmission_id).unwrap_or(false) + { true => { aborted_transmissions.insert(*transmission_id); } @@ -685,8 +687,10 @@ impl Storage { Ok(transaction) => missing_transmissions.insert(*transmission_id, transaction.into()), // Check if the transaction is in the aborted transactions. Err(_) => { - // Insert the aborted transaction if it exists in the block. - match block.aborted_transaction_ids().contains(transaction_id) { + // Insert the aborted transaction if it exists in the block or ledger. + match block.aborted_transaction_ids().contains(transaction_id) + || self.ledger.contains_transmission(transmission_id).unwrap_or(false) + { true => { aborted_transmissions.insert(*transmission_id); } From f812c260a97e87c3648584ef805be6293badc679 Mon Sep 17 00:00:00 2001 From: miazn Date: Tue, 9 Apr 2024 14:32:04 -0400 Subject: [PATCH 54/72] move some metrics to CoreLedgerService, out of consensus --- node/bft/ledger-service/src/ledger.rs | 11 +++++++++++ node/consensus/src/lib.rs | 8 -------- node/metrics/src/names.rs | 12 +++++------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 5c19e83215..d87052ce7d 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -336,4 +336,15 @@ impl> LedgerService for CoreLedgerService< tracing::info!("\n\nAdvanced to block {} at round {} - {}\n", block.height(), block.round(), block.hash()); Ok(()) } + + #[cfg(feature = "metrics")] + fn update_bft_metrics(&self, block: &Block) { + let num_sol = next_block.solutions().len(); + let num_tx = next_block.transactions().len(); + + metrics::gauge(metrics::bft::HEIGHT, block.height() as f64); + metrics::gauge(metrics::bft::LAST_COMMITTED_ROUND, block.round() as f64); + metrics::increment_gauge(metrics::blocks::SOLUTIONS, num_sol as f64); + metrics::increment_gauge(metrics::blocks::TRANSACTIONS, num_tx as f64); + } } diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 7177f3e6a5..29d50affbe 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -435,20 +435,12 @@ impl Consensus { let elapsed = std::time::Duration::from_secs((snarkos_node_bft::helpers::now() - start) as u64); let next_block_timestamp = next_block.header().metadata().timestamp(); let block_latency = next_block_timestamp - current_block_timestamp; - let num_sol = next_block.solutions().len(); - let num_tx = next_block.transactions().len(); - let num_transmissions = num_tx + num_sol; let proof_target = next_block.header().proof_target(); let coinbase_target = next_block.header().coinbase_target(); let cumulative_proof_target = next_block.header().cumulative_proof_target(); self.add_transmission_latency_metric(&next_block); - metrics::gauge(metrics::blocks::HEIGHT, next_block.height() as f64); - metrics::increment_gauge(metrics::blocks::SOLUTIONS, num_sol as f64); - metrics::increment_gauge(metrics::blocks::TRANSACTIONS, num_tx as f64); - metrics::increment_gauge(metrics::blocks::TRANSMISSIONS, num_transmissions as f64); - metrics::gauge(metrics::consensus::LAST_COMMITTED_ROUND, next_block.round() as f64); metrics::gauge(metrics::consensus::COMMITTED_CERTIFICATES, num_committed_certificates as f64); metrics::histogram(metrics::consensus::CERTIFICATE_COMMIT_LATENCY, elapsed.as_secs_f64()); metrics::histogram(metrics::consensus::BLOCK_LATENCY, block_latency as f64); diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 4d696c3873..217a7c0ca2 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -14,21 +14,20 @@ pub(super) const COUNTER_NAMES: [&str; 2] = [bft::LEADERS_ELECTED, consensus::STALE_UNCONFIRMED_TRANSMISSIONS]; -pub(super) const GAUGE_NAMES: [&str; 21] = [ +pub(super) const GAUGE_NAMES: [&str; 20] = [ bft::CONNECTED, bft::CONNECTING, bft::LAST_STORED_ROUND, bft::PROPOSAL_ROUND, bft::CERTIFIED_BATCHES, - blocks::HEIGHT, + bft::HEIGHT, + bft::LAST_COMMITTED_ROUND, blocks::SOLUTIONS, blocks::TRANSACTIONS, - blocks::TRANSMISSIONS, blocks::PROOF_TARGET, blocks::COINBASE_TARGET, blocks::CUMULATIVE_PROOF_TARGET, consensus::COMMITTED_CERTIFICATES, - consensus::LAST_COMMITTED_ROUND, consensus::UNCONFIRMED_SOLUTIONS, consensus::UNCONFIRMED_TRANSACTIONS, consensus::UNCONFIRMED_TRANSMISSIONS, @@ -56,12 +55,12 @@ pub mod bft { pub const LEADERS_ELECTED: &str = "snarkos_bft_leaders_elected_total"; pub const PROPOSAL_ROUND: &str = "snarkos_bft_primary_proposal_round"; pub const CERTIFIED_BATCHES: &str = "snarkos_bft_primary_certified_batches"; + pub const HEIGHT: &str = "snarkos_bft_height_total"; + pub const LAST_COMMITTED_ROUND: &str = "snarkos_bft_last_committed_round"; } pub mod blocks { - pub const HEIGHT: &str = "snarkos_blocks_height_total"; pub const TRANSACTIONS: &str = "snarkos_blocks_transactions_total"; - pub const TRANSMISSIONS: &str = "snarkos_blocks_transmissions_total"; pub const SOLUTIONS: &str = "snarkos_blocks_solutions_total"; pub const PROOF_TARGET: &str = "snarkos_blocks_proof_target"; pub const COINBASE_TARGET: &str = "snarkos_blocks_coinbase_target"; @@ -71,7 +70,6 @@ pub mod blocks { pub mod consensus { pub const CERTIFICATE_COMMIT_LATENCY: &str = "snarkos_consensus_certificate_commit_latency_secs"; pub const COMMITTED_CERTIFICATES: &str = "snarkos_consensus_committed_certificates_total"; - pub const LAST_COMMITTED_ROUND: &str = "snarkos_consensus_last_committed_round"; pub const BLOCK_LATENCY: &str = "snarkos_consensus_block_latency_secs"; pub const UNCONFIRMED_TRANSACTIONS: &str = "snarkos_consensus_unconfirmed_transactions_total"; pub const UNCONFIRMED_TRANSMISSIONS: &str = "snarkos_consensus_unconfirmed_transmissions_total"; From 2646592b36f1d0806572ad38b084c23937c74ce0 Mon Sep 17 00:00:00 2001 From: miazn Date: Tue, 9 Apr 2024 15:12:37 -0400 Subject: [PATCH 55/72] add func --- node/bft/ledger-service/src/ledger.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index d87052ce7d..d91a377847 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -333,6 +333,10 @@ impl> LedgerService for CoreLedgerService< } // Advance to the next block. self.ledger.advance_to_next_block(block)?; + // Update BFT metrics. + #[cfg(feature = "metrics")] + self.update_bft_metrics(block); + tracing::info!("\n\nAdvanced to block {} at round {} - {}\n", block.height(), block.round(), block.hash()); Ok(()) } From 19ba95e01cad558845c29f2f8ec6c060b60f81b3 Mon Sep 17 00:00:00 2001 From: miazn Date: Tue, 9 Apr 2024 15:47:36 -0400 Subject: [PATCH 56/72] remove unconfirmed transmissions --- node/bft/ledger-service/src/ledger.rs | 4 ++-- node/consensus/src/lib.rs | 2 -- node/metrics/src/names.rs | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index d91a377847..2ceec88fbd 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -343,8 +343,8 @@ impl> LedgerService for CoreLedgerService< #[cfg(feature = "metrics")] fn update_bft_metrics(&self, block: &Block) { - let num_sol = next_block.solutions().len(); - let num_tx = next_block.transactions().len(); + let num_sol = block.solutions().len(); + let num_tx = block.transactions().len(); metrics::gauge(metrics::bft::HEIGHT, block.height() as f64); metrics::gauge(metrics::bft::LAST_COMMITTED_ROUND, block.round() as f64); diff --git a/node/consensus/src/lib.rs b/node/consensus/src/lib.rs index 29d50affbe..3b6471e13d 100644 --- a/node/consensus/src/lib.rs +++ b/node/consensus/src/lib.rs @@ -225,7 +225,6 @@ impl Consensus { #[cfg(feature = "metrics")] { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_SOLUTIONS, 1f64); - metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); let timestamp = snarkos_node_bft::helpers::now(); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Solution(solution.id()), timestamp); } @@ -291,7 +290,6 @@ impl Consensus { #[cfg(feature = "metrics")] { metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSACTIONS, 1f64); - metrics::increment_gauge(metrics::consensus::UNCONFIRMED_TRANSMISSIONS, 1f64); let timestamp = snarkos_node_bft::helpers::now(); self.transmissions_queue_timestamps.lock().insert(TransmissionID::Transaction(transaction.id()), timestamp); } diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 217a7c0ca2..8dec924a7b 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -14,7 +14,7 @@ pub(super) const COUNTER_NAMES: [&str; 2] = [bft::LEADERS_ELECTED, consensus::STALE_UNCONFIRMED_TRANSMISSIONS]; -pub(super) const GAUGE_NAMES: [&str; 20] = [ +pub(super) const GAUGE_NAMES: [&str; 19] = [ bft::CONNECTED, bft::CONNECTING, bft::LAST_STORED_ROUND, @@ -30,7 +30,6 @@ pub(super) const GAUGE_NAMES: [&str; 20] = [ consensus::COMMITTED_CERTIFICATES, consensus::UNCONFIRMED_SOLUTIONS, consensus::UNCONFIRMED_TRANSACTIONS, - consensus::UNCONFIRMED_TRANSMISSIONS, router::CONNECTED, router::CANDIDATE, router::RESTRICTED, @@ -72,7 +71,6 @@ pub mod consensus { pub const COMMITTED_CERTIFICATES: &str = "snarkos_consensus_committed_certificates_total"; pub const BLOCK_LATENCY: &str = "snarkos_consensus_block_latency_secs"; pub const UNCONFIRMED_TRANSACTIONS: &str = "snarkos_consensus_unconfirmed_transactions_total"; - pub const UNCONFIRMED_TRANSMISSIONS: &str = "snarkos_consensus_unconfirmed_transmissions_total"; pub const UNCONFIRMED_SOLUTIONS: &str = "snarkos_consensus_unconfirmed_solutions_total"; pub const TRANSMISSION_LATENCY: &str = "snarkos_consensus_transmission_latency"; pub const STALE_UNCONFIRMED_TRANSMISSIONS: &str = "snarkos_consensus_stale_unconfirmed_transmissions"; From 234f11e86c7142c4cdfcf04bc2145b73d523ab78 Mon Sep 17 00:00:00 2001 From: miazn Date: Tue, 9 Apr 2024 16:19:40 -0400 Subject: [PATCH 57/72] fmt --- Cargo.lock | 1 + node/bft/Cargo.toml | 2 +- node/bft/ledger-service/Cargo.toml | 7 +++++++ node/bft/ledger-service/src/ledger.rs | 21 +++++++++------------ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ba6c74fe9..e93e06f25d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3096,6 +3096,7 @@ dependencies = [ "lru", "parking_lot", "rand", + "snarkos-node-metrics", "snarkvm", "tokio", "tracing", diff --git a/node/bft/Cargo.toml b/node/bft/Cargo.toml index 86f15dd7e3..660cfabc88 100644 --- a/node/bft/Cargo.toml +++ b/node/bft/Cargo.toml @@ -18,7 +18,7 @@ edition = "2021" [features] default = [ ] -metrics = [ "dep:metrics", "snarkos-node-bft-events/metrics" ] +metrics = [ "dep:metrics", "snarkos-node-bft-events/metrics", "snarkos-node-bft-ledger-service/metrics" ] [dependencies.aleo-std] workspace = true diff --git a/node/bft/ledger-service/Cargo.toml b/node/bft/ledger-service/Cargo.toml index e5a75a795d..6f83c661e4 100644 --- a/node/bft/ledger-service/Cargo.toml +++ b/node/bft/ledger-service/Cargo.toml @@ -20,6 +20,7 @@ edition = "2021" default = [ ] ledger = [ "lru", "parking_lot", "rand", "tokio", "tracing" ] ledger-write = [ ] +metrics = ["dep:metrics", "snarkvm/metrics"] mock = [ "parking_lot", "tracing" ] prover = [ ] test = [ "mock", "translucent" ] @@ -36,6 +37,12 @@ features = [ "serde", "rayon" ] version = "0.12" optional = true +[dependencies.metrics] +package = "snarkos-node-metrics" +path = "../../metrics" +version = "=2.2.7" +optional = true + [dependencies.parking_lot] version = "0.12" optional = true diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 2ceec88fbd..73f09d1f07 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -335,20 +335,17 @@ impl> LedgerService for CoreLedgerService< self.ledger.advance_to_next_block(block)?; // Update BFT metrics. #[cfg(feature = "metrics")] - self.update_bft_metrics(block); + { + let num_sol = block.solutions().len(); + let num_tx = block.transactions().len(); + + metrics::gauge(metrics::bft::HEIGHT, block.height() as f64); + metrics::gauge(metrics::bft::LAST_COMMITTED_ROUND, block.round() as f64); + metrics::increment_gauge(metrics::blocks::SOLUTIONS, num_sol as f64); + metrics::increment_gauge(metrics::blocks::TRANSACTIONS, num_tx as f64); + } tracing::info!("\n\nAdvanced to block {} at round {} - {}\n", block.height(), block.round(), block.hash()); Ok(()) } - - #[cfg(feature = "metrics")] - fn update_bft_metrics(&self, block: &Block) { - let num_sol = block.solutions().len(); - let num_tx = block.transactions().len(); - - metrics::gauge(metrics::bft::HEIGHT, block.height() as f64); - metrics::gauge(metrics::bft::LAST_COMMITTED_ROUND, block.round() as f64); - metrics::increment_gauge(metrics::blocks::SOLUTIONS, num_sol as f64); - metrics::increment_gauge(metrics::blocks::TRANSACTIONS, num_tx as f64); - } } From 5a3f5b0d4dfd9d1210d22a045a7fe69ea1e44131 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 9 Apr 2024 18:59:31 -0400 Subject: [PATCH 58/72] Optimize check --- node/bft/src/helpers/storage.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/node/bft/src/helpers/storage.rs b/node/bft/src/helpers/storage.rs index d97e552fed..f555099712 100644 --- a/node/bft/src/helpers/storage.rs +++ b/node/bft/src/helpers/storage.rs @@ -638,6 +638,10 @@ impl Storage { // Retrieve the aborted transmissions for the certificate. let mut aborted_transmissions = HashSet::new(); + // Track the block's aborted solutions and transactions. + let aborted_solutions: IndexSet<_> = block.aborted_solution_ids().iter().collect(); + let aborted_transactions: IndexSet<_> = block.aborted_transaction_ids().iter().collect(); + // Iterate over the transmission IDs. for transmission_id in certificate.transmission_ids() { // If the transmission ID already exists in the map, skip it. @@ -663,7 +667,7 @@ impl Storage { // Check if the solution is in the aborted solutions. Err(_) => { // Insert the aborted solution if it exists in the block or ledger. - match block.aborted_solution_ids().contains(solution_id) + match aborted_solutions.contains(solution_id) || self.ledger.contains_transmission(transmission_id).unwrap_or(false) { true => { @@ -688,7 +692,7 @@ impl Storage { // Check if the transaction is in the aborted transactions. Err(_) => { // Insert the aborted transaction if it exists in the block or ledger. - match block.aborted_transaction_ids().contains(transaction_id) + match aborted_transactions.contains(transaction_id) || self.ledger.contains_transmission(transmission_id).unwrap_or(false) { true => { From 08361b4220a87d2f027f87866d24d43a61158219 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:51:10 -0700 Subject: [PATCH 59/72] Removes request_timeouts from BlockSync --- node/sync/src/block_sync.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index 97e05561bd..e300430a83 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -45,7 +45,6 @@ const NUM_SYNC_CANDIDATE_PEERS: usize = REDUNDANCY_FACTOR * 5; const BLOCK_REQUEST_TIMEOUT_IN_SECS: u64 = 600; // 600 seconds const MAX_BLOCK_REQUESTS: usize = 50; // 50 requests -const MAX_BLOCK_REQUEST_TIMEOUTS: usize = 5; // 5 timeouts /// The maximum number of blocks tolerated before the primary is considered behind its peers. pub const MAX_BLOCKS_BEHIND: u32 = 1; // blocks @@ -104,9 +103,6 @@ pub struct BlockSync { /// The map of block height to the timestamp of the last time the block was requested. /// This map is used to determine which requests to remove if they have been pending for too long. request_timestamps: Arc>>, - /// The map of (timed out) peer IPs to their request timestamps. - /// This map is used to determine which peers to remove if they have timed out too many times. - request_timeouts: Arc>>>, /// The boolean indicator of whether the node is synced up to the latest block (within the given tolerance). is_block_synced: Arc, /// The lock to guarantee advance_with_sync_blocks() is called only once at a time. @@ -124,7 +120,6 @@ impl BlockSync { requests: Default::default(), responses: Default::default(), request_timestamps: Default::default(), - request_timeouts: Default::default(), is_block_synced: Default::default(), advance_with_sync_blocks_lock: Default::default(), } @@ -402,8 +397,6 @@ impl BlockSync { self.locators.write().swap_remove(peer_ip); // Remove all block requests to the peer. self.remove_block_requests_to_peer(peer_ip); - // Remove the timeouts for the peer. - self.request_timeouts.write().swap_remove(peer_ip); } } @@ -659,16 +652,6 @@ impl BlockSync { !is_timeout }); - // If there are timeout IPs, then add them to the request timeouts map. - if !timeout_ips.is_empty() { - // Acquire the write lock on the request timeouts map. - let mut request_timeouts = self.request_timeouts.write(); - // Add each timeout IP to the request timeouts map. - for timeout_ip in timeout_ips { - request_timeouts.entry(timeout_ip).or_default().push(now); - } - } - num_timed_out_block_requests } @@ -677,21 +660,12 @@ impl BlockSync { // Retrieve the latest canon height. let latest_canon_height = self.canon.latest_block_height(); - // Compute the timeout frequency of each peer. - let timeouts = self - .request_timeouts - .read() - .iter() - .map(|(peer_ip, timestamps)| (*peer_ip, timestamps.len())) - .collect::>(); - // Pick a set of peers above the latest canon height, and include their locators. let candidate_locators: IndexMap<_, _> = self .locators .read() .iter() .filter(|(_, locators)| locators.latest_locator_height() > latest_canon_height) - .filter(|(ip, _)| timeouts.get(*ip).map(|count| *count < MAX_BLOCK_REQUEST_TIMEOUTS).unwrap_or(true)) .sorted_by(|(_, a), (_, b)| b.latest_locator_height().cmp(&a.latest_locator_height())) .take(NUM_SYNC_CANDIDATE_PEERS) .map(|(peer_ip, locators)| (*peer_ip, locators.clone())) From cced2c25170f6b54d279f36f9d5ef1c5ad134991 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:58:33 -0700 Subject: [PATCH 60/72] Adds a shuffle on the sync_peers --- node/sync/src/block_sync.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index e300430a83..83c5dd7270 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -726,6 +726,10 @@ impl BlockSync { return None; } + // Shuffle the sync peers prior to returning. This ensures the rest of the stack + // does not rely on the order of the sync peers, and that the sync peers are not biased. + let sync_peers = shuffle_indexmap(sync_peers, &mut rand::thread_rng()); + Some((sync_peers, min_common_ancestor)) } @@ -853,6 +857,18 @@ fn construct_request( (hash, previous_hash, num_sync_ips, is_honest) } +/// Shuffles a given `IndexMap` using the given random number generator. +fn shuffle_indexmap(mut map: IndexMap, rng: &mut R) -> IndexMap +where + K: core::hash::Hash + Eq + Clone, + V: Clone, +{ + use rand::seq::SliceRandom; + let mut pairs: Vec<_> = map.drain(..).collect(); // Drain elements to a vector + pairs.shuffle(rng); // Shuffle the vector of tuples + pairs.into_iter().collect() // Collect back into an IndexMap +} + #[cfg(test)] mod tests { use super::*; From 42094a217e0026320e1372fbb6e08a5b81acfc5a Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:07:05 -0700 Subject: [PATCH 61/72] Remove timeout vec --- node/sync/src/block_sync.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index 83c5dd7270..7fb7ef94fc 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -22,7 +22,7 @@ use snarkos_node_sync_locators::{CHECKPOINT_INTERVAL, NUM_RECENT_BLOCKS}; use snarkvm::prelude::{block::Block, Network}; use anyhow::{bail, ensure, Result}; -use indexmap::{IndexMap, IndexSet}; +use indexmap::IndexMap; use itertools::Itertools; use parking_lot::{Mutex, RwLock}; use rand::{prelude::IteratorRandom, CryptoRng, Rng}; @@ -621,8 +621,6 @@ impl BlockSync { // Retrieve the current time. let now = Instant::now(); - // Track each unique peer IP that has timed out. - let mut timeout_ips = IndexSet::new(); // Track the number of timed out block requests. let mut num_timed_out_block_requests = 0; @@ -639,10 +637,7 @@ impl BlockSync { // If the request has timed out, then remove it. if is_timeout { // Remove the request entry for the given height. - if let Some((_, _, sync_ips)) = requests.remove(height) { - // Add each sync IP to the timeout IPs. - timeout_ips.extend(sync_ips); - } + requests.remove(height); // Remove the response entry for the given height. responses.remove(height); // Increment the number of timed out block requests. @@ -880,7 +875,7 @@ mod tests { use snarkos_node_bft_ledger_service::MockLedgerService; use snarkvm::prelude::{Field, TestRng}; - use indexmap::indexset; + use indexmap::{indexset, IndexSet}; use snarkvm::ledger::committee::Committee; use std::net::{IpAddr, Ipv4Addr}; From 27aea25c3f1d70e812347d6b076edf4137ffe0ce Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 6 Mar 2024 23:05:12 +0100 Subject: [PATCH 62/72] deps(bft): add `pea2pea` to dev deps --- node/bft/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/bft/Cargo.toml b/node/bft/Cargo.toml index 660cfabc88..2f3d3b20c8 100644 --- a/node/bft/Cargo.toml +++ b/node/bft/Cargo.toml @@ -137,6 +137,9 @@ version = "5" [dev-dependencies.paste] version = "1" +[dev-dependencies.pea2pea] + version = "0.46" + [dev-dependencies.proptest] version = "1.4.0" From 2c67849eb6418e3eb1e5434d277dddfbafbef594 Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 6 Mar 2024 23:06:07 +0100 Subject: [PATCH 63/72] tests: implement test peer tooling --- node/bft/tests/common/mod.rs | 1 + node/bft/tests/common/test_peer.rs | 150 +++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 node/bft/tests/common/test_peer.rs diff --git a/node/bft/tests/common/mod.rs b/node/bft/tests/common/mod.rs index 2505f6add7..febf3dc3a5 100644 --- a/node/bft/tests/common/mod.rs +++ b/node/bft/tests/common/mod.rs @@ -13,6 +13,7 @@ // limitations under the License. pub mod primary; +pub mod test_peer; pub mod utils; pub type CurrentNetwork = snarkvm::prelude::MainnetV0; diff --git a/node/bft/tests/common/test_peer.rs b/node/bft/tests/common/test_peer.rs new file mode 100644 index 0000000000..db1bf37afe --- /dev/null +++ b/node/bft/tests/common/test_peer.rs @@ -0,0 +1,150 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the snarkOS library. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::common::CurrentNetwork; +use snarkos_node_bft_events::{Event, EventCodec}; + +use std::{ + io, + net::{IpAddr, Ipv4Addr, SocketAddr}, + time::Duration, +}; + +use pea2pea::{ + protocols::{Disconnect, Handshake, Reading, Writing}, + Config, + Connection, + ConnectionSide, + Node, + Pea2Pea, +}; + +use tokio::{ + sync::mpsc::{self, Receiver, Sender}, + time::timeout, +}; + +pub struct TestPeer { + inner_node: InnerNode, + inbound_rx: Receiver<(SocketAddr, Event)>, +} + +#[derive(Clone)] +struct InnerNode { + // The pea2pea node instance. + node: Node, + // The inbound channel sender, used to consolidate inbound messages into a single queue so they + // can be read in order in tests. + inbound_tx: Sender<(SocketAddr, Event)>, +} + +impl TestPeer { + pub async fn new() -> Self { + let (tx, rx) = mpsc::channel(100); + let inner_node = InnerNode { + node: Node::new(Config { + listener_ip: Some(IpAddr::V4(Ipv4Addr::LOCALHOST)), + max_connections: 200, + ..Default::default() + }), + inbound_tx: tx, + }; + + inner_node.enable_handshake().await; + inner_node.enable_reading().await; + inner_node.enable_writing().await; + inner_node.enable_disconnect().await; + inner_node.node().start_listening().await.unwrap(); + + Self { inner_node, inbound_rx: rx } + } + + pub fn listening_addr(&self) -> SocketAddr { + self.inner_node.node().listening_addr().expect("addr should be present") + } + + pub async fn connect(&self, target: SocketAddr) -> io::Result<()> { + self.inner_node.node().connect(target).await?; + Ok(()) + } + + // Note: the codec doesn't actually support sending bytes post-handshake, perhaps this should + // be relaxed by making a test-only codec in future. + pub fn unicast(&self, target: SocketAddr, message: Event) -> io::Result<()> { + self.inner_node.unicast(target, message)?; + Ok(()) + } + + pub async fn recv(&mut self) -> (SocketAddr, Event) { + match self.inbound_rx.recv().await { + Some(message) => message, + None => panic!("all senders dropped!"), + } + } + + pub async fn recv_timeout(&mut self, duration: Duration) -> (SocketAddr, Event) { + match timeout(duration, self.recv()).await { + Ok(message) => message, + _ => panic!("timed out waiting for message"), + } + } +} + +impl Pea2Pea for InnerNode { + fn node(&self) -> &Node { + &self.node + } +} + +#[async_trait::async_trait] +impl Handshake for InnerNode { + // Set the timeout on the test peer to be longer than the gateway's timeout. + const TIMEOUT_MS: u64 = 10_000; + + async fn perform_handshake(&self, connection: Connection) -> io::Result { + // Don't perform the Aleo handshake so we can test the edge cases fully. + Ok(connection) + } +} + +#[async_trait::async_trait] +impl Writing for InnerNode { + type Codec = EventCodec; + type Message = Event; + + fn codec(&self, _peer_addr: SocketAddr, _side: ConnectionSide) -> Self::Codec { + Default::default() + } +} + +#[async_trait::async_trait] +impl Reading for InnerNode { + type Codec = EventCodec; + type Message = Event; + + fn codec(&self, _peer_addr: SocketAddr, _side: ConnectionSide) -> Self::Codec { + Default::default() + } + + async fn process_message(&self, peer_addr: SocketAddr, message: Self::Message) -> io::Result<()> { + self.inbound_tx.send((peer_addr, message)).await.map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to send message to test peer, all receivers have been dropped") + }) + } +} + +#[async_trait::async_trait] +impl Disconnect for InnerNode { + async fn handle_disconnect(&self, _peer_addr: SocketAddr) {} +} From 816fbf1646926b82c33bfba15566df6abeb822c1 Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 6 Mar 2024 23:06:42 +0100 Subject: [PATCH 64/72] tests: implement gateway handshake cases Includes responder side: - timeouts - invalid challenge request/response - unexpected disconnects --- node/bft/tests/gateway_e2e.rs | 263 ++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 node/bft/tests/gateway_e2e.rs diff --git a/node/bft/tests/gateway_e2e.rs b/node/bft/tests/gateway_e2e.rs new file mode 100644 index 0000000000..4ed944ae37 --- /dev/null +++ b/node/bft/tests/gateway_e2e.rs @@ -0,0 +1,263 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the snarkOS library. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[allow(dead_code)] +mod common; + +use crate::common::{primary::new_test_committee, test_peer::TestPeer, CurrentNetwork}; +use snarkos_account::Account; +use snarkos_node_bft::{helpers::init_primary_channels, Gateway}; +use snarkos_node_bft_events::{ChallengeRequest, ChallengeResponse, Disconnect, DisconnectReason, Event, WorkerPing}; +use snarkos_node_bft_ledger_service::MockLedgerService; +use snarkos_node_tcp::P2P; +use snarkvm::{ + ledger::{committee::Committee, narwhal::Data}, + prelude::TestRng, +}; + +use std::{net::SocketAddr, str::FromStr, sync::Arc, time::Duration}; + +use deadline::deadline; +use rand::Rng; + +async fn new_test_gateway( + accounts: &[Account], + committee: &Committee, +) -> Gateway { + let ledger = Arc::new(MockLedgerService::new(committee.clone())); + let addr = SocketAddr::from_str("127.0.0.1:0").ok(); + let trusted_validators = []; + let gateway = Gateway::new(accounts.first().unwrap().clone(), ledger, addr, &trusted_validators, None).unwrap(); + + // Set up primary channels, we discard the rx as we're testing the gateway sans BFT. + let (primary_tx, _primary_rx) = init_primary_channels(); + + gateway.run(primary_tx, [].into(), None).await; + + gateway +} + +// The test peer connects to the gateway and completes the no-op handshake (so +// the connection is registered). The gateway's handshake should timeout. +#[tokio::test(flavor = "multi_thread")] +async fn handshake_responder_side_timeout() { + const NUM_NODES: u16 = 4; + let (accounts, committee) = new_test_committee(NUM_NODES); + let gateway = new_test_gateway(&accounts, &committee).await; + let test_peer = TestPeer::new().await; + + // Initiate a connection with the gateway, this will only return once the handshake protocol has + // completed on the test peer's side, which is a no-op. + assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); + + /* Don't send any further messages and wait for the gateway to timeout. */ + + // Check the connection has been registered. + assert_eq!(gateway.tcp().num_connecting(), 1); + + // Check the tcp stack's connection counts, wait longer than the gateway's timeout to ensure + // connecting peers are cleared. + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(5), move || gateway_clone.tcp().num_connecting() == 0); + + // Check the test peer hasn't been added to the gateway's connected peers. + assert!(gateway.connected_peers().read().is_empty()); + assert_eq!(gateway.tcp().num_connected(), 0); +} + +// The test peer connects to the gateway and sends an unexpected event. +// The gateway's handshake should be interrupted and the peer should be +// disconnected. +macro_rules! handshake_responder_side_unexpected_event { + ($test_name:ident, $payload:expr) => { + paste::paste! { + #[tokio::test(flavor = "multi_thread")] + async fn []() { + const NUM_NODES: u16 = 4; + let (accounts, committee) = new_test_committee(NUM_NODES); + let gateway = new_test_gateway(&accounts, &committee).await; + let test_peer = TestPeer::new().await; + + // Initiate a connection with the gateway, this will only return once the handshake protocol has + // completed on the test peer's side, which is a no-op. + assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); + + // Check the connection has been registered. + assert_eq!(gateway.tcp().num_connecting(), 1); + + // Send an unexpected event. + let _ = test_peer.unicast( + gateway.local_ip(), + $payload + ); + + // Check the tcp stack's connection counts, make sure the disconnect interrupted handshaking, + // wait a short time to ensure the gateway has time to process the disconnect (note: this is + // shorter than the gateway's timeout, so we can ensure that's not the reason for the + // disconnect). + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 0); + + // Check the test peer hasn't been added to the gateway's connected peers. + assert!(gateway.connected_peers().read().is_empty()); + assert_eq!(gateway.tcp().num_connected(), 0); + } + } + }; +} + +/* Unexpected disconnects. */ + +macro_rules! handshake_responder_side_unexpected_disconnect { + ($($reason:ident),*) => { + $( + paste::paste! { + handshake_responder_side_unexpected_event!( + [], + Event::Disconnect(Disconnect::from(DisconnectReason::$reason)) + ); + } + )* + } + } + +handshake_responder_side_unexpected_disconnect!( + ProtocolViolation, + NoReasonGiven, + InvalidChallengeResponse, + OutdatedClientVersion +); + +/* Other unexpected event types */ + +handshake_responder_side_unexpected_event!(worker_ping, Event::WorkerPing(WorkerPing::new([].into()))); + +// TODO(nkls): other event types, can be done as a follow up. + +/* Invalid challenge request */ + +#[tokio::test(flavor = "multi_thread")] +async fn handshake_responder_side_invalid_challenge_request() { + const NUM_NODES: u16 = 4; + + let mut rng = TestRng::default(); + let (accounts, committee) = new_test_committee(NUM_NODES); + let gateway = new_test_gateway(&accounts, &committee).await; + let test_peer = TestPeer::new().await; + + // Initiate a connection with the gateway, this will only return once the handshake protocol has + // completed on the test peer's side, which is a no-op. + assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); + + // Check the connection has been registered. + assert_eq!(gateway.tcp().num_connecting(), 1); + + // Use the address from the second peer in the list, the test peer will use the first. + let listener_port = test_peer.listening_addr().port(); + let address = accounts.get(1).unwrap().address(); + let nonce = rng.gen(); + // Set the wrong version so the challenge request is invalid. + let challenge_request = ChallengeRequest { version: 0, listener_port, address, nonce }; + + // Send the message + let _ = test_peer.unicast(gateway.local_ip(), Event::ChallengeRequest(challenge_request)); + + // FIXME(nkls): currently we can't assert on the disconnect type, the message isn't always sent + // before the disconnect. + + // Check the test peer has been removed from the gateway's connecting peers. + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 0); + // Check the test peer hasn't been added to the gateway's connected peers. + assert!(gateway.connected_peers().read().is_empty()); + assert_eq!(gateway.tcp().num_connected(), 0); +} + +/* Invalid challenge response */ + +#[tokio::test(flavor = "multi_thread")] +async fn handshake_responder_side_invalid_challenge_response() { + const NUM_NODES: u16 = 4; + + let mut rng = TestRng::default(); + let (accounts, committee) = new_test_committee(NUM_NODES); + let gateway = new_test_gateway(&accounts, &committee).await; + let mut test_peer = TestPeer::new().await; + + // Initiate a connection with the gateway, this will only return once the handshake protocol has + // completed on the test peer's side, which is a no-op for the moment. + assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); + + // Check the connection has been registered. + assert_eq!(gateway.tcp().num_connecting(), 1); + + // Use the address from the second peer in the list, the test peer will use the first. + let listener_port = test_peer.listening_addr().port(); + let address = accounts.get(1).unwrap().address(); + let our_nonce = rng.gen(); + let challenge_request = ChallengeRequest { version: 6, listener_port, address, nonce: our_nonce }; + + // Send the challenge request. + let _ = test_peer.unicast(gateway.local_ip(), Event::ChallengeRequest(challenge_request)); + + // Receive the gateway's challenge response. + let (peer_addr, Event::ChallengeResponse(ChallengeResponse { signature, nonce })) = + test_peer.recv_timeout(Duration::from_secs(1)).await + else { + panic!("Expected challenge response") + }; + + // Check the sender is the gateway. + assert_eq!(peer_addr, gateway.local_ip()); + // Check the nonce we sent is in the signature. + assert!( + signature.deserialize_blocking().unwrap().verify_bytes( + &accounts.first().unwrap().address(), + &[our_nonce.to_le_bytes(), nonce.to_le_bytes()].concat() + ) + ); + + // Receive the gateway's challenge request. + let (peer_addr, Event::ChallengeRequest(challenge_request)) = test_peer.recv_timeout(Duration::from_secs(1)).await + else { + panic!("Expected challenge request") + }; + // Check the version, listener port and address are correct. + assert_eq!(peer_addr, gateway.local_ip()); + assert_eq!(challenge_request.version, 6); + assert_eq!(challenge_request.listener_port, gateway.local_ip().port()); + assert_eq!(challenge_request.address, accounts.first().unwrap().address()); + + // Send the challenge response with an invalid signature. + let response_nonce = rng.gen(); + let _ = test_peer.unicast( + gateway.local_ip(), + Event::ChallengeResponse(ChallengeResponse { + signature: Data::Object( + accounts.get(2).unwrap().sign_bytes(&challenge_request.nonce.to_le_bytes(), &mut rng).unwrap(), + ), + nonce: response_nonce, + }), + ); + + // FIXME(nkls): currently we can't assert on the disconnect type, the message isn't always sent + // before the disconnect. + + // Check the test peer has been removed from the gateway's connecting peers. + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 0); + // Check the test peer hasn't been added to the gateway's connected peers. + assert!(gateway.connected_peers().read().is_empty()); + assert_eq!(gateway.tcp().num_connected(), 0); +} From b9f11e18f3a910ca8f7871d086331e16d47b4ac3 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 7 Mar 2024 13:29:40 +0100 Subject: [PATCH 65/72] tests: `deadline!` assertions to fix CI flakiness --- node/bft/tests/gateway_e2e.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/node/bft/tests/gateway_e2e.rs b/node/bft/tests/gateway_e2e.rs index 4ed944ae37..ab451bed85 100644 --- a/node/bft/tests/gateway_e2e.rs +++ b/node/bft/tests/gateway_e2e.rs @@ -64,7 +64,8 @@ async fn handshake_responder_side_timeout() { /* Don't send any further messages and wait for the gateway to timeout. */ // Check the connection has been registered. - assert_eq!(gateway.tcp().num_connecting(), 1); + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 1); // Check the tcp stack's connection counts, wait longer than the gateway's timeout to ensure // connecting peers are cleared. @@ -94,7 +95,8 @@ macro_rules! handshake_responder_side_unexpected_event { assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); // Check the connection has been registered. - assert_eq!(gateway.tcp().num_connecting(), 1); + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 1); // Send an unexpected event. let _ = test_peer.unicast( @@ -161,7 +163,8 @@ async fn handshake_responder_side_invalid_challenge_request() { assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); // Check the connection has been registered. - assert_eq!(gateway.tcp().num_connecting(), 1); + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 1); // Use the address from the second peer in the list, the test peer will use the first. let listener_port = test_peer.listening_addr().port(); @@ -200,7 +203,8 @@ async fn handshake_responder_side_invalid_challenge_response() { assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); // Check the connection has been registered. - assert_eq!(gateway.tcp().num_connecting(), 1); + let gateway_clone = gateway.clone(); + deadline!(Duration::from_secs(1), move || gateway_clone.tcp().num_connecting() == 1); // Use the address from the second peer in the list, the test peer will use the first. let listener_port = test_peer.listening_addr().port(); From 4cb04786ee7af69c1375b2e7f9dc33b78c843f25 Mon Sep 17 00:00:00 2001 From: Niklas Date: Tue, 19 Mar 2024 16:45:16 +0100 Subject: [PATCH 66/72] tests: fix post-rebase Also moves the test helpers from components into utils. --- node/bft/tests/common/primary.rs | 9 ++-- node/bft/tests/common/utils.rs | 76 ++++++++++++++++++++++++++-- node/bft/tests/components/mod.rs | 65 ------------------------ node/bft/tests/components/pending.rs | 8 +-- node/bft/tests/components/worker.rs | 23 +++++---- node/bft/tests/gateway_e2e.rs | 47 ++++++++--------- 6 files changed, 120 insertions(+), 108 deletions(-) diff --git a/node/bft/tests/common/primary.rs b/node/bft/tests/common/primary.rs index 029c8d54b0..abef3f015e 100644 --- a/node/bft/tests/common/primary.rs +++ b/node/bft/tests/common/primary.rs @@ -127,11 +127,13 @@ impl TestValidator { impl TestNetwork { // Creates a new test network with the given configuration. pub fn new(config: TestNetworkConfig) -> Self { + let mut rng = TestRng::default(); + if let Some(log_level) = config.log_level { initialize_logger(log_level); } - let (accounts, committee) = new_test_committee(config.num_nodes); + let (accounts, committee) = new_test_committee(config.num_nodes, &mut rng); let bonded_balances: IndexMap<_, _> = committee .members() .iter() @@ -148,7 +150,6 @@ impl TestNetwork { let mut validators = HashMap::with_capacity(config.num_nodes as usize); for (id, account) in accounts.into_iter().enumerate() { - let mut rng = TestRng::fixed(id as u64); let gen_ledger = genesis_ledger(gen_key, committee.clone(), balances.clone(), bonded_balances.clone(), &mut rng); let ledger = Arc::new(TranslucentLedgerService::new(gen_ledger, Default::default())); @@ -329,12 +330,12 @@ impl TestNetwork { } // Initializes a new test committee. -pub fn new_test_committee(n: u16) -> (Vec>, Committee) { +pub fn new_test_committee(n: u16, rng: &mut TestRng) -> (Vec>, Committee) { let mut accounts = Vec::with_capacity(n as usize); let mut members = IndexMap::with_capacity(n as usize); for i in 0..n { // Sample the account. - let account = Account::new(&mut TestRng::fixed(i as u64)).unwrap(); + let account = Account::new(rng).unwrap(); info!("Validator {}: {}", i, account.address()); members.insert(account.address(), (MIN_VALIDATOR_STAKE, false)); diff --git a/node/bft/tests/common/utils.rs b/node/bft/tests/common/utils.rs index 1fa074f102..bd558f418a 100644 --- a/node/bft/tests/common/utils.rs +++ b/node/bft/tests/common/utils.rs @@ -12,12 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::common::CurrentNetwork; -use snarkos_node_bft::helpers::PrimarySender; +use crate::common::{primary, CurrentNetwork, TranslucentLedgerService}; +use snarkos_account::Account; +use snarkos_node_bft::{ + helpers::{PrimarySender, Storage}, + Gateway, + Worker, +}; + +use snarkos_node_bft_storage_service::BFTMemoryService; use snarkvm::{ - ledger::narwhal::Data, + console::account::Address, + ledger::{ + committee::Committee, + narwhal::{BatchHeader, Data}, + store::helpers::memory::ConsensusMemory, + }, prelude::{ block::Transaction, + committee::MIN_VALIDATOR_STAKE, puzzle::{Solution, SolutionID}, Field, Network, @@ -26,9 +39,11 @@ use snarkvm::{ }, }; -use std::time::Duration; +use std::{sync::Arc, time::Duration}; use ::bytes::Bytes; +use indexmap::IndexMap; +use parking_lot::RwLock; use rand::Rng; use tokio::{sync::oneshot, task::JoinHandle, time::sleep}; use tracing::*; @@ -164,3 +179,56 @@ pub fn fire_unconfirmed_transactions( } }) } + +/// Samples a new ledger with the given number of nodes. +pub fn sample_ledger( + accounts: &[Account], + committee: &Committee, + rng: &mut TestRng, +) -> Arc>> { + let num_nodes = committee.num_members(); + let bonded_balances: IndexMap<_, _> = + committee.members().iter().map(|(address, (amount, _))| (*address, (*address, *address, *amount))).collect(); + let gen_key = *accounts[0].private_key(); + let public_balance_per_validator = + (CurrentNetwork::STARTING_SUPPLY - (num_nodes as u64) * MIN_VALIDATOR_STAKE) / (num_nodes as u64); + let mut balances = IndexMap::, u64>::new(); + for account in accounts.iter() { + balances.insert(account.address(), public_balance_per_validator); + } + + let gen_ledger = + primary::genesis_ledger(gen_key, committee.clone(), balances.clone(), bonded_balances.clone(), rng); + Arc::new(TranslucentLedgerService::new(gen_ledger, Default::default())) +} + +/// Samples a new storage with the given ledger. +pub fn sample_storage(ledger: Arc>>) -> Storage { + Storage::new(ledger, Arc::new(BFTMemoryService::new()), BatchHeader::::MAX_GC_ROUNDS as u64) +} + +/// Samples a new gateway with the given ledger. +pub fn sample_gateway( + account: Account, + storage: Storage, + ledger: Arc>>, +) -> Gateway { + // Initialize the gateway. + Gateway::new(account, storage, ledger, None, &[], None).unwrap() +} + +/// Samples a new worker with the given ledger. +pub fn sample_worker( + id: u8, + account: Account, + ledger: Arc>>, +) -> Worker { + // Sample a storage. + let storage = sample_storage(ledger.clone()); + // Sample a gateway. + let gateway = sample_gateway(account, storage.clone(), ledger.clone()); + // Sample a dummy proposed batch. + let proposed_batch = Arc::new(RwLock::new(None)); + // Construct the worker instance. + Worker::new(id, Arc::new(gateway.clone()), storage.clone(), ledger, proposed_batch).unwrap() +} diff --git a/node/bft/tests/components/mod.rs b/node/bft/tests/components/mod.rs index 65336665cc..d58afbf610 100644 --- a/node/bft/tests/components/mod.rs +++ b/node/bft/tests/components/mod.rs @@ -15,69 +15,4 @@ pub mod pending; pub mod worker; -use crate::common::{primary, CurrentNetwork, TranslucentLedgerService}; -use snarkos_account::Account; -use snarkos_node_bft::{helpers::Storage, Gateway, Worker}; -use snarkos_node_bft_ledger_service::LedgerService; -use snarkos_node_bft_storage_service::BFTMemoryService; -use snarkvm::{ - console::{account::Address, network::Network}, - ledger::{committee::MIN_VALIDATOR_STAKE, narwhal::BatchHeader, store::helpers::memory::ConsensusMemory}, - prelude::TestRng, -}; - -use indexmap::IndexMap; -use parking_lot::RwLock; -use std::{str::FromStr, sync::Arc}; - const ITERATIONS: u32 = 100; - -/// Samples a new ledger with the given number of nodes. -pub fn sample_ledger( - num_nodes: u16, - rng: &mut TestRng, -) -> Arc>> { - let (accounts, committee) = primary::new_test_committee(num_nodes); - let bonded_balances: IndexMap<_, _> = - committee.members().iter().map(|(address, (amount, _))| (*address, (*address, *address, *amount))).collect(); - let gen_key = *accounts[0].private_key(); - let public_balance_per_validator = - (CurrentNetwork::STARTING_SUPPLY - (num_nodes as u64) * MIN_VALIDATOR_STAKE) / (num_nodes as u64); - let mut balances = IndexMap::, u64>::new(); - for account in accounts.iter() { - balances.insert(account.address(), public_balance_per_validator); - } - - let gen_ledger = - primary::genesis_ledger(gen_key, committee.clone(), balances.clone(), bonded_balances.clone(), rng); - Arc::new(TranslucentLedgerService::new(gen_ledger, Default::default())) -} - -/// Samples a new storage with the given ledger. -pub fn sample_storage(ledger: Arc>>) -> Storage { - Storage::new(ledger, Arc::new(BFTMemoryService::new()), BatchHeader::::MAX_GC_ROUNDS as u64) -} - -/// Samples a new gateway with the given ledger. -pub fn sample_gateway( - storage: Storage, - ledger: Arc>>, -) -> Gateway { - let num_nodes: u16 = ledger.current_committee().unwrap().num_members().try_into().unwrap(); - let (accounts, _committee) = primary::new_test_committee(num_nodes); - let account = Account::from_str(&accounts[0].private_key().to_string()).unwrap(); - // Initialize the gateway. - Gateway::new(account, storage, ledger, None, &[], None).unwrap() -} - -/// Samples a new worker with the given ledger. -pub fn sample_worker(id: u8, ledger: Arc>>) -> Worker { - // Sample a storage. - let storage = sample_storage(ledger.clone()); - // Sample a gateway. - let gateway = sample_gateway(storage.clone(), ledger.clone()); - // Sample a dummy proposed batch. - let proposed_batch = Arc::new(RwLock::new(None)); - // Construct the worker instance. - Worker::new(id, Arc::new(gateway.clone()), storage.clone(), ledger, proposed_batch).unwrap() -} diff --git a/node/bft/tests/components/pending.rs b/node/bft/tests/components/pending.rs index f4766084a5..2825637369 100644 --- a/node/bft/tests/components/pending.rs +++ b/node/bft/tests/components/pending.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{common::CurrentNetwork, components::sample_ledger}; +use crate::common::{primary::new_test_committee, utils::sample_ledger, CurrentNetwork}; use snarkos_node_bft::helpers::max_redundant_requests; use snarkvm::{ledger::committee::Committee, prelude::TestRng}; @@ -21,9 +21,11 @@ fn test_max_redundant_requests() { const NUM_NODES: u16 = Committee::::MAX_COMMITTEE_SIZE; // Initialize the RNG. - let rng = &mut TestRng::default(); + let mut rng = TestRng::default(); + // Initialize the accounts and the committee. + let (accounts, committee) = new_test_committee(NUM_NODES, &mut rng); // Sample a ledger. - let ledger = sample_ledger(NUM_NODES, rng); + let ledger = sample_ledger(&accounts, &committee, &mut rng); // Ensure the maximum number of redundant requests is correct and consistent across iterations. assert_eq!(max_redundant_requests(ledger, 0), 34, "Update me if the formula changes"); } diff --git a/node/bft/tests/components/worker.rs b/node/bft/tests/components/worker.rs index 1877bd859a..2236d73699 100644 --- a/node/bft/tests/components/worker.rs +++ b/node/bft/tests/components/worker.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{ - common::CurrentNetwork, - components::{sample_ledger, sample_worker}, +use crate::common::{ + primary::new_test_committee, + utils::{sample_ledger, sample_worker}, + CurrentNetwork, }; use snarkos_node_bft::helpers::max_redundant_requests; use snarkvm::{ @@ -30,11 +31,13 @@ async fn test_resend_transmission_request() { const NUM_NODES: u16 = Committee::::MAX_COMMITTEE_SIZE; // Initialize the RNG. - let rng = &mut TestRng::default(); + let mut rng = TestRng::default(); + // Initialize the accounts and the committee. + let (accounts, committee) = new_test_committee(NUM_NODES, &mut rng); // Sample a ledger. - let ledger = sample_ledger(NUM_NODES, rng); + let ledger = sample_ledger(&accounts, &committee, &mut rng); // Sample a worker. - let worker = sample_worker(0, ledger.clone()); + let worker = sample_worker(0, accounts[0].clone(), ledger.clone()); // Determine the maximum number of redundant requests. let max_redundancy = max_redundant_requests(ledger.clone(), 0); @@ -89,11 +92,13 @@ async fn test_flood_transmission_requests() { const NUM_NODES: u16 = Committee::::MAX_COMMITTEE_SIZE; // Initialize the RNG. - let rng = &mut TestRng::default(); + let mut rng = TestRng::default(); + // Initialize the accounts and the committee. + let (accounts, committee) = new_test_committee(NUM_NODES, &mut rng); // Sample a ledger. - let ledger = sample_ledger(NUM_NODES, rng); + let ledger = sample_ledger(&accounts, &committee, &mut rng); // Sample a worker. - let worker = sample_worker(0, ledger.clone()); + let worker = sample_worker(0, accounts[0].clone(), ledger.clone()); // Determine the maximum number of redundant requests. let max_redundancy = max_redundant_requests(ledger.clone(), 0); diff --git a/node/bft/tests/gateway_e2e.rs b/node/bft/tests/gateway_e2e.rs index ab451bed85..09fd79794c 100644 --- a/node/bft/tests/gateway_e2e.rs +++ b/node/bft/tests/gateway_e2e.rs @@ -15,37 +15,38 @@ #[allow(dead_code)] mod common; -use crate::common::{primary::new_test_committee, test_peer::TestPeer, CurrentNetwork}; +use crate::common::{ + primary::new_test_committee, + test_peer::TestPeer, + utils::{sample_gateway, sample_ledger, sample_storage}, + CurrentNetwork, +}; use snarkos_account::Account; use snarkos_node_bft::{helpers::init_primary_channels, Gateway}; use snarkos_node_bft_events::{ChallengeRequest, ChallengeResponse, Disconnect, DisconnectReason, Event, WorkerPing}; -use snarkos_node_bft_ledger_service::MockLedgerService; use snarkos_node_tcp::P2P; -use snarkvm::{ - ledger::{committee::Committee, narwhal::Data}, - prelude::TestRng, -}; +use snarkvm::{ledger::narwhal::Data, prelude::TestRng}; -use std::{net::SocketAddr, str::FromStr, sync::Arc, time::Duration}; +use std::time::Duration; use deadline::deadline; use rand::Rng; async fn new_test_gateway( - accounts: &[Account], - committee: &Committee, -) -> Gateway { - let ledger = Arc::new(MockLedgerService::new(committee.clone())); - let addr = SocketAddr::from_str("127.0.0.1:0").ok(); - let trusted_validators = []; - let gateway = Gateway::new(accounts.first().unwrap().clone(), ledger, addr, &trusted_validators, None).unwrap(); + num_nodes: u16, + rng: &mut TestRng, +) -> (Vec>, Gateway) { + let (accounts, committee) = new_test_committee(num_nodes, rng); + let ledger = sample_ledger(&accounts, &committee, rng); + let storage = sample_storage(ledger.clone()); + let gateway = sample_gateway(accounts[0].clone(), storage, ledger); // Set up primary channels, we discard the rx as we're testing the gateway sans BFT. let (primary_tx, _primary_rx) = init_primary_channels(); gateway.run(primary_tx, [].into(), None).await; - gateway + (accounts, gateway) } // The test peer connects to the gateway and completes the no-op handshake (so @@ -53,8 +54,9 @@ async fn new_test_gateway( #[tokio::test(flavor = "multi_thread")] async fn handshake_responder_side_timeout() { const NUM_NODES: u16 = 4; - let (accounts, committee) = new_test_committee(NUM_NODES); - let gateway = new_test_gateway(&accounts, &committee).await; + + let mut rng = TestRng::default(); + let (_accounts, gateway) = new_test_gateway(NUM_NODES, &mut rng).await; let test_peer = TestPeer::new().await; // Initiate a connection with the gateway, this will only return once the handshake protocol has @@ -86,8 +88,9 @@ macro_rules! handshake_responder_side_unexpected_event { #[tokio::test(flavor = "multi_thread")] async fn []() { const NUM_NODES: u16 = 4; - let (accounts, committee) = new_test_committee(NUM_NODES); - let gateway = new_test_gateway(&accounts, &committee).await; + + let mut rng = TestRng::default(); + let (_accounts, gateway) = new_test_gateway(NUM_NODES, &mut rng).await; let test_peer = TestPeer::new().await; // Initiate a connection with the gateway, this will only return once the handshake protocol has @@ -154,8 +157,7 @@ async fn handshake_responder_side_invalid_challenge_request() { const NUM_NODES: u16 = 4; let mut rng = TestRng::default(); - let (accounts, committee) = new_test_committee(NUM_NODES); - let gateway = new_test_gateway(&accounts, &committee).await; + let (accounts, gateway) = new_test_gateway(NUM_NODES, &mut rng).await; let test_peer = TestPeer::new().await; // Initiate a connection with the gateway, this will only return once the handshake protocol has @@ -194,8 +196,7 @@ async fn handshake_responder_side_invalid_challenge_response() { const NUM_NODES: u16 = 4; let mut rng = TestRng::default(); - let (accounts, committee) = new_test_committee(NUM_NODES); - let gateway = new_test_gateway(&accounts, &committee).await; + let (accounts, gateway) = new_test_gateway(NUM_NODES, &mut rng).await; let mut test_peer = TestPeer::new().await; // Initiate a connection with the gateway, this will only return once the handshake protocol has From 88dfdc6f7c67550642db8d53042d5ee28dd6e5c9 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 25 Mar 2024 14:49:47 +0100 Subject: [PATCH 67/72] deps: update `pea2pea` --- node/Cargo.toml | 2 +- node/bft/Cargo.toml | 2 +- node/bft/tests/common/test_peer.rs | 12 ++++-------- node/bft/tests/gateway_e2e.rs | 2 ++ node/tests/common/test_peer.rs | 12 ++++-------- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/node/Cargo.toml b/node/Cargo.toml index 88e23403fd..82cf32b8e6 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -129,7 +129,7 @@ version = "0.2" version = "1" [dev-dependencies.pea2pea] -version = "0.46" +version = "0.49" [dev-dependencies.snarkos-node-router] path = "./router" diff --git a/node/bft/Cargo.toml b/node/bft/Cargo.toml index 2f3d3b20c8..8b2c5ed86c 100644 --- a/node/bft/Cargo.toml +++ b/node/bft/Cargo.toml @@ -138,7 +138,7 @@ version = "5" version = "1" [dev-dependencies.pea2pea] - version = "0.46" + version = "0.49" [dev-dependencies.proptest] version = "1.4.0" diff --git a/node/bft/tests/common/test_peer.rs b/node/bft/tests/common/test_peer.rs index db1bf37afe..508ab75d6f 100644 --- a/node/bft/tests/common/test_peer.rs +++ b/node/bft/tests/common/test_peer.rs @@ -22,7 +22,7 @@ use std::{ }; use pea2pea::{ - protocols::{Disconnect, Handshake, Reading, Writing}, + protocols::{Handshake, OnDisconnect, Reading, Writing}, Config, Connection, ConnectionSide, @@ -54,8 +54,8 @@ impl TestPeer { let (tx, rx) = mpsc::channel(100); let inner_node = InnerNode { node: Node::new(Config { - listener_ip: Some(IpAddr::V4(Ipv4Addr::LOCALHOST)), max_connections: 200, + listener_addr: Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0)), ..Default::default() }), inbound_tx: tx, @@ -107,7 +107,6 @@ impl Pea2Pea for InnerNode { } } -#[async_trait::async_trait] impl Handshake for InnerNode { // Set the timeout on the test peer to be longer than the gateway's timeout. const TIMEOUT_MS: u64 = 10_000; @@ -118,7 +117,6 @@ impl Handshake for InnerNode { } } -#[async_trait::async_trait] impl Writing for InnerNode { type Codec = EventCodec; type Message = Event; @@ -128,7 +126,6 @@ impl Writing for InnerNode { } } -#[async_trait::async_trait] impl Reading for InnerNode { type Codec = EventCodec; type Message = Event; @@ -144,7 +141,6 @@ impl Reading for InnerNode { } } -#[async_trait::async_trait] -impl Disconnect for InnerNode { - async fn handle_disconnect(&self, _peer_addr: SocketAddr) {} +impl OnDisconnect for InnerNode { + async fn on_disconnect(&self, _peer_addr: SocketAddr) {} } diff --git a/node/bft/tests/gateway_e2e.rs b/node/bft/tests/gateway_e2e.rs index 09fd79794c..46a270bf56 100644 --- a/node/bft/tests/gateway_e2e.rs +++ b/node/bft/tests/gateway_e2e.rs @@ -59,6 +59,8 @@ async fn handshake_responder_side_timeout() { let (_accounts, gateway) = new_test_gateway(NUM_NODES, &mut rng).await; let test_peer = TestPeer::new().await; + dbg!(test_peer.listening_addr()); + // Initiate a connection with the gateway, this will only return once the handshake protocol has // completed on the test peer's side, which is a no-op. assert!(test_peer.connect(gateway.local_ip()).await.is_ok()); diff --git a/node/tests/common/test_peer.rs b/node/tests/common/test_peer.rs index 4c7cfc037a..1a2bbcd337 100644 --- a/node/tests/common/test_peer.rs +++ b/node/tests/common/test_peer.rs @@ -30,7 +30,7 @@ use std::{ use futures_util::{sink::SinkExt, TryStreamExt}; use pea2pea::{ - protocols::{Disconnect, Handshake, Reading, Writing}, + protocols::{Handshake, OnDisconnect, Reading, Writing}, Config, Connection, ConnectionSide, @@ -82,8 +82,8 @@ impl TestPeer { pub async fn new(node_type: NodeType, account: Account) -> Self { let peer = Self { node: Node::new(Config { - listener_ip: Some(IpAddr::V4(Ipv4Addr::LOCALHOST)), max_connections: 200, + listener_addr: Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0)), ..Default::default() }), node_type, @@ -113,7 +113,6 @@ impl TestPeer { } } -#[async_trait::async_trait] impl Handshake for TestPeer { async fn perform_handshake(&self, mut conn: Connection) -> io::Result { let rng = &mut TestRng::default(); @@ -174,7 +173,6 @@ impl Handshake for TestPeer { } } -#[async_trait::async_trait] impl Writing for TestPeer { type Codec = MessageCodec; type Message = Message; @@ -184,7 +182,6 @@ impl Writing for TestPeer { } } -#[async_trait::async_trait] impl Reading for TestPeer { type Codec = MessageCodec; type Message = Message; @@ -198,7 +195,6 @@ impl Reading for TestPeer { } } -#[async_trait::async_trait] -impl Disconnect for TestPeer { - async fn handle_disconnect(&self, _peer_addr: SocketAddr) {} +impl OnDisconnect for TestPeer { + async fn on_disconnect(&self, _peer_addr: SocketAddr) {} } From e01a32992765259328efa1942b4f3463ed91ae73 Mon Sep 17 00:00:00 2001 From: Niklas Date: Tue, 19 Mar 2024 16:49:11 +0100 Subject: [PATCH 68/72] chore: update lock file --- Cargo.lock | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e93e06f25d..cd3394f07c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2080,14 +2080,12 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pea2pea" -version = "0.46.0" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1051ff6b30971947b93dc4d76f281a276200a3a0fffd95abe8274e8d92455f2" +checksum = "908db9c51d2d2a4c379bce9395cac8305a464780b0c809969001501743207191" dependencies = [ - "async-trait", "bytes", "futures-util", - "once_cell", "parking_lot", "tokio", "tokio-util", @@ -3042,6 +3040,7 @@ dependencies = [ "open", "parking_lot", "paste", + "pea2pea", "proptest", "rand", "rand_chacha", From 1fb1448b164c01ba584d7ebb226bc1d1a7b29f53 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 12 Apr 2024 17:40:35 +0100 Subject: [PATCH 69/72] chore: clean up a little lingering noise --- node/bft/events/src/helpers/codec.rs | 3 --- node/metrics/src/names.rs | 15 ++------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/node/bft/events/src/helpers/codec.rs b/node/bft/events/src/helpers/codec.rs index 73b764c453..cee8db29cf 100644 --- a/node/bft/events/src/helpers/codec.rs +++ b/node/bft/events/src/helpers/codec.rs @@ -25,9 +25,6 @@ const MAX_HANDSHAKE_SIZE: usize = 1024 * 1024; // 1 MiB /// The maximum size of an event that can be transmitted in the network. const MAX_EVENT_SIZE: usize = 128 * 1024 * 1024; // 128 MiB -/// The type of noise handshake to use for network encryption. -pub const NOISE_HANDSHAKE_TYPE: &str = "Noise_XX_25519_ChaChaPoly_BLAKE2s"; - /// The codec used to decode and encode network `Event`s. pub struct EventCodec { codec: LengthDelimitedCodec, diff --git a/node/metrics/src/names.rs b/node/metrics/src/names.rs index 8dec924a7b..45ef04e8fd 100644 --- a/node/metrics/src/names.rs +++ b/node/metrics/src/names.rs @@ -36,15 +36,8 @@ pub(super) const GAUGE_NAMES: [&str; 19] = [ tcp::TCP_TASKS, ]; -pub(super) const HISTOGRAM_NAMES: [&str; 7] = [ - bft::COMMIT_ROUNDS_LATENCY, - consensus::CERTIFICATE_COMMIT_LATENCY, - consensus::BLOCK_LATENCY, - tcp::NOISE_CODEC_ENCRYPTION_TIME, - tcp::NOISE_CODEC_DECRYPTION_TIME, - tcp::NOISE_CODEC_ENCRYPTION_SIZE, - tcp::NOISE_CODEC_DECRYPTION_SIZE, -]; +pub(super) const HISTOGRAM_NAMES: [&str; 3] = + [bft::COMMIT_ROUNDS_LATENCY, consensus::CERTIFICATE_COMMIT_LATENCY, consensus::BLOCK_LATENCY]; pub mod bft { pub const COMMIT_ROUNDS_LATENCY: &str = "snarkos_bft_commit_rounds_latency_secs"; // <-- This one doesn't even make sense. @@ -83,9 +76,5 @@ pub mod router { } pub mod tcp { - pub const NOISE_CODEC_ENCRYPTION_TIME: &str = "snarkos_tcp_noise_codec_encryption_micros"; - pub const NOISE_CODEC_DECRYPTION_TIME: &str = "snarkos_tcp_noise_codec_decryption_micros"; - pub const NOISE_CODEC_ENCRYPTION_SIZE: &str = "snarkos_tcp_noise_codec_encryption_size"; - pub const NOISE_CODEC_DECRYPTION_SIZE: &str = "snarkos_tcp_noise_codec_decryption_size"; pub const TCP_TASKS: &str = "snarkos_tcp_tasks_total"; } From d6589a2d36c6d15f0229ad249c86a85d7d390a69 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:43:50 -0400 Subject: [PATCH 70/72] Update DataBlocks::MAXIMUM_NUMBER_OF_BLOCKS to 10 --- node/bft/events/src/block_response.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/bft/events/src/block_response.rs b/node/bft/events/src/block_response.rs index 1ca7ab86ef..ea56fa9579 100644 --- a/node/bft/events/src/block_response.rs +++ b/node/bft/events/src/block_response.rs @@ -64,7 +64,7 @@ pub struct DataBlocks(pub Vec>); impl DataBlocks { /// The maximum number of blocks that can be sent in a single message. - pub const MAXIMUM_NUMBER_OF_BLOCKS: u8 = 1; + pub const MAXIMUM_NUMBER_OF_BLOCKS: u8 = 10; /// Ensures that the blocks are well-formed in a block response. pub fn ensure_response_is_well_formed( From ff93a40ce0c0dc5f1fd5b83add69ee3ff01a00ba Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:51:30 -0400 Subject: [PATCH 71/72] Update MAX_EVENT_SIZE to 256mb --- node/bft/events/src/helpers/codec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/bft/events/src/helpers/codec.rs b/node/bft/events/src/helpers/codec.rs index 73b764c453..6bd37959eb 100644 --- a/node/bft/events/src/helpers/codec.rs +++ b/node/bft/events/src/helpers/codec.rs @@ -23,7 +23,7 @@ use tracing::*; /// The maximum size of an event that can be transmitted during the handshake. const MAX_HANDSHAKE_SIZE: usize = 1024 * 1024; // 1 MiB /// The maximum size of an event that can be transmitted in the network. -const MAX_EVENT_SIZE: usize = 128 * 1024 * 1024; // 128 MiB +const MAX_EVENT_SIZE: usize = 256 * 1024 * 1024; // 256 MiB /// The type of noise handshake to use for network encryption. pub const NOISE_HANDSHAKE_TYPE: &str = "Noise_XX_25519_ChaChaPoly_BLAKE2s"; From 29cf16a019b1d4247128029919c01c9b7c6edc70 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Fri, 12 Apr 2024 20:19:13 -0400 Subject: [PATCH 72/72] Bump snarkVM rev - d48f6fb --- Cargo.lock | 118 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd3394f07c..f8e8f17fc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3302,7 +3302,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anstyle", "anyhow", @@ -3333,7 +3333,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -3363,7 +3363,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3377,7 +3377,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3398,7 +3398,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3408,7 +3408,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "itertools 0.11.0", @@ -3426,12 +3426,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3442,7 +3442,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3457,7 +3457,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3485,7 +3485,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3494,7 +3494,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3504,7 +3504,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3516,7 +3516,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3528,7 +3528,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3539,7 +3539,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3564,7 +3564,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "bs58", "snarkvm-console-network", @@ -3575,7 +3575,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "blake2s_simd", "smallvec", @@ -3588,7 +3588,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "rayon", @@ -3599,7 +3599,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3622,7 +3622,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anyhow", "bech32", @@ -3640,7 +3640,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "enum_index", "enum_index_derive", @@ -3661,7 +3661,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3676,7 +3676,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3687,7 +3687,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", ] @@ -3695,7 +3695,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3705,7 +3705,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3716,7 +3716,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3738,7 +3738,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3749,7 +3749,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "rand", "rayon", @@ -3763,7 +3763,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -3780,7 +3780,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -3805,7 +3805,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anyhow", "rand", @@ -3817,7 +3817,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3836,7 +3836,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anyhow", "indexmap 2.2.5", @@ -3855,7 +3855,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -3868,7 +3868,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3881,7 +3881,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3894,7 +3894,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "bytes", "serde_json", @@ -3905,7 +3905,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "rayon", @@ -3920,7 +3920,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "bytes", "serde_json", @@ -3933,7 +3933,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "snarkvm-console", "snarkvm-ledger-puzzle", @@ -3942,7 +3942,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -3962,7 +3962,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-puzzle-epoch" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "anyhow", "colored", @@ -3977,7 +3977,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "async-trait", "reqwest", @@ -3990,7 +3990,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std-storage", "anyhow", @@ -4016,7 +4016,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4031,7 +4031,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4040,7 +4040,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -4065,7 +4065,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -4094,7 +4094,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "colored", @@ -4117,7 +4117,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "indexmap 2.2.5", "paste", @@ -4131,7 +4131,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "bincode", "once_cell", @@ -4144,7 +4144,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "aleo-std", "anyhow", @@ -4165,7 +4165,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=ed20562#ed20562d6f97ef593f051ce3cc848644e785f817" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=d48f6fb#d48f6fb7d7ca36d134407baebcc59952fe58c546" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/Cargo.toml b/Cargo.toml index 81b8254f8b..ae4b77d9c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ default-features = false [workspace.dependencies.snarkvm] git = "https://github.com/AleoHQ/snarkVM.git" -rev = "ed20562" +rev = "d48f6fb" #version = "=0.16.18" features = [ "circuit", "console", "rocks" ]