From 73d5ad6e156060b185789e7c80dba86948bb84bf Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 31 Oct 2023 13:01:23 +0100 Subject: [PATCH 01/40] perf: use a blocking task for check_batch_header Signed-off-by: ljedrz --- node/bft/src/primary.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 8e79cf7590..a91c4dc020 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -559,7 +559,9 @@ impl Primary { self.ensure_is_signing_round(batch_round)?; // Ensure the batch header from the peer is valid. - let missing_transmissions = self.storage.check_batch_header(&batch_header, transmissions)?; + let storage = self.storage.clone(); + let header = batch_header.clone(); + let missing_transmissions = spawn_blocking!(storage.check_batch_header(&header, transmissions))?; // Inserts the missing transmissions into the workers. self.insert_missing_transmissions_into_workers(peer_ip, missing_transmissions.into_iter())?; From cca737d1f0a1aa60342de0357a75b9138bb2ef9c Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 31 Oct 2023 13:02:46 +0100 Subject: [PATCH 02/40] perf: use a blocking task for insert_certificate Signed-off-by: ljedrz --- node/bft/src/primary.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index a91c4dc020..86f6f25400 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -1186,7 +1186,9 @@ impl Primary { // Note: Do not change the `Proposal` to use a HashMap. The ordering there is necessary for safety. let transmissions = transmissions.into_iter().collect::>(); // Store the certified batch. - self.storage.insert_certificate(certificate.clone(), transmissions)?; + let storage = self.storage.clone(); + let certificate_clone = certificate.clone(); + spawn_blocking!(storage.insert_certificate(certificate_clone, transmissions))?; 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() { @@ -1265,7 +1267,9 @@ impl Primary { // Check if the certificate needs to be stored. if !self.storage.contains_certificate(certificate.id()) { // Store the batch certificate. - self.storage.insert_certificate(certificate.clone(), missing_transmissions)?; + let storage = self.storage.clone(); + let certificate_clone = certificate.clone(); + spawn_blocking!(storage.insert_certificate(certificate_clone, missing_transmissions))?; 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() { From adfc4bcd99f0457f6f0b35e89b9f0fb54188e85b Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 31 Oct 2023 13:22:17 +0100 Subject: [PATCH 03/40] perf: use a blocking task for sync_certificate_with_block Signed-off-by: ljedrz --- node/bft/src/sync/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/node/bft/src/sync/mod.rs b/node/bft/src/sync/mod.rs index 517dbca5eb..5a756cbe07 100644 --- a/node/bft/src/sync/mod.rs +++ b/node/bft/src/sync/mod.rs @@ -14,6 +14,7 @@ use crate::{ helpers::{BFTSender, Pending, Storage, SyncReceiver}, + spawn_blocking, Gateway, Transport, MAX_BATCH_DELAY_IN_MS, @@ -205,9 +206,11 @@ impl Sync { // If the block authority is a subdag, then sync the batch certificates with the block. if let Authority::Quorum(subdag) = block.authority() { // Iterate over the certificates. - for certificate in subdag.values().flatten() { + for certificate in subdag.values().flatten().cloned() { // Sync the batch certificate with the block. - self.storage.sync_certificate_with_block(block, certificate); + let storage = self.storage.clone(); + let block = block.clone(); + let _ = spawn_blocking!(Ok(storage.sync_certificate_with_block(&block, &certificate))); } } } @@ -282,7 +285,10 @@ impl Sync { // Iterate over the certificates. for certificate in subdag.values().flatten() { // Sync the batch certificate with the block. - self.storage.sync_certificate_with_block(&block, certificate); + let storage = self.storage.clone(); + let block_clone = block.clone(); + let certificate_clone = certificate.clone(); + let _ = spawn_blocking!(Ok(storage.sync_certificate_with_block(&block_clone, &certificate_clone))); // If a BFT sender was provided, send the certificate to the BFT. if let Some(bft_sender) = self.bft_sender.get() { // Await the callback to continue. From e8c95e63096ff5b97516121ae7737e52ea24a29b Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 11 Feb 2024 11:35:43 -0800 Subject: [PATCH 04/40] Resolve cherry-pick of d419d9d --- Cargo.lock | 117 +++++++++++++++++++------------------- cli/src/commands/start.rs | 19 ++----- 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b2b6bdb1d..4e962c9049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "anstyle", "anyhow", @@ -3557,7 +3557,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -3587,7 +3587,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3601,7 +3601,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3612,7 +3612,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3622,7 +3622,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3632,7 +3632,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "itertools 0.11.0", @@ -3650,12 +3650,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3666,7 +3666,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3681,7 +3681,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3709,7 +3709,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3718,7 +3718,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3728,7 +3728,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3740,7 +3740,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3752,7 +3752,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3763,7 +3763,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3775,7 +3775,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3788,7 +3788,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "bs58", "snarkvm-console-network", @@ -3799,7 +3799,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "blake2s_simd", "smallvec", @@ -3812,7 +3812,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "rayon", @@ -3823,7 +3823,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "anyhow", "indexmap 2.2.2", @@ -3846,7 +3846,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "anyhow", "bech32", @@ -3864,7 +3864,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "enum_index", "enum_index_derive", @@ -3885,7 +3885,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3900,7 +3900,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3911,7 +3911,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", ] @@ -3919,7 +3919,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3929,7 +3929,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3940,7 +3940,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3951,7 +3951,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3962,7 +3962,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3973,7 +3973,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "rand", "rayon", @@ -3987,7 +3987,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -4004,7 +4004,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -4029,7 +4029,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "anyhow", "rand", @@ -4041,7 +4041,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4060,7 +4060,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-coinbase" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -4080,7 +4080,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "anyhow", "indexmap 2.2.2", @@ -4097,7 +4097,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -4110,7 +4110,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4123,7 +4123,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "serde_json", @@ -4135,7 +4135,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "bytes", "serde_json", @@ -4146,7 +4146,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4160,7 +4160,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "bytes", "serde_json", @@ -4173,7 +4173,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "snarkvm-console", "snarkvm-ledger-coinbase", @@ -4182,7 +4182,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "async-trait", "reqwest", @@ -4195,7 +4195,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std-storage", "anyhow", @@ -4220,7 +4220,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4235,7 +4235,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4244,7 +4244,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -4269,11 +4269,12 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", "indexmap 2.2.2", + "lru", "parking_lot", "rand", "rayon", @@ -4294,7 +4295,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "colored", @@ -4317,7 +4318,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "indexmap 2.2.2", "paste", @@ -4331,7 +4332,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "bincode", "once_cell", @@ -4344,7 +4345,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "aleo-std", "anyhow", @@ -4365,7 +4366,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=81d7c11#81d7c11f3d51d31ceb0628ae81cc8c2ad00a3287" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index fdaec4ed58..4668c4c199 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -465,23 +465,12 @@ impl Start { fn runtime() -> Runtime { // Retrieve the number of cores. let num_cores = num_cpus::get(); - // Determine the number of main cores. - let main_cores = match num_cores { - // Insufficient - 0..=3 => { - eprintln!("The number of cores is insufficient, at least 4 are needed."); - std::process::exit(1); - } - // Efficiency mode - 4..=8 => 2, - // Standard mode - 9..=16 => 8, - // Performance mode - _ => 16, - }; + // Initialize the number of tokio worker threads, max tokio blocking threads, and rayon cores. + // Note: We intentionally set the number of tokio worker threads and number of rayon cores to be + // more than the number of physical cores, because the node is expected to be I/O-bound. let (num_tokio_worker_threads, max_tokio_blocking_threads, num_rayon_cores_global) = - { (num_cores.min(main_cores), 512, num_cores.saturating_sub(main_cores).max(1)) }; + (2 * num_cores, 512, num_cores); // Initialize the parallelization parameters. rayon::ThreadPoolBuilder::new() From 77c549f5cc9ff79702536e6ba8089e96e9b5bfa1 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 11 Feb 2024 11:51:08 -0800 Subject: [PATCH 05/40] Update redundancy factor --- node/sync/src/block_sync.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index aadb6873a8..7fe509f4f0 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -36,8 +36,8 @@ use std::{ time::Instant, }; -pub const REDUNDANCY_FACTOR: usize = 3; -const EXTRA_REDUNDANCY_FACTOR: usize = REDUNDANCY_FACTOR * 2; +pub const REDUNDANCY_FACTOR: usize = 1; +const EXTRA_REDUNDANCY_FACTOR: usize = REDUNDANCY_FACTOR * 3; const NUM_SYNC_CANDIDATE_PEERS: usize = REDUNDANCY_FACTOR * 5; const BLOCK_REQUEST_TIMEOUT_IN_SECS: u64 = 60; // 60 seconds From bda76727564717aca89f94fec212ca35160e69b9 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:04:55 -0800 Subject: [PATCH 06/40] Resolve cherry-pick of f779241 --- cli/src/commands/start.rs | 4 ++-- cli/src/helpers/mod.rs | 8 ++++---- node/bft/src/bft.rs | 2 +- node/bft/src/lib.rs | 1 + node/bft/src/primary.rs | 11 ++++++++--- node/bft/src/sync/mod.rs | 7 ++++--- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index 4668c4c199..281c26e794 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -248,7 +248,7 @@ impl Start { let _ = PrivateKey::::new(&mut rng)?; } let private_key = PrivateKey::::new(&mut rng)?; - println!("🔑 Your development private key for node {dev} is {}\n", private_key.to_string().bold()); + println!("🔑 Your development private key for node {dev} is {}.\n", private_key.to_string().bold()); private_key }) } @@ -411,7 +411,7 @@ impl Start { // If the display is not enabled, render the welcome message. if self.nodisplay { // Print the Aleo address. - println!("🪪 Your Aleo address is {}.\n", account.address().to_string().bold()); + println!("👛 Your Aleo address is {}.\n", account.address().to_string().bold()); // Print the node type and network. println!( "🧭 Starting {} on {} {} at {}.\n", diff --git a/cli/src/helpers/mod.rs b/cli/src/helpers/mod.rs index 6cabe254b2..de3838b1ad 100644 --- a/cli/src/helpers/mod.rs +++ b/cli/src/helpers/mod.rs @@ -41,8 +41,8 @@ pub fn check_open_files_limit(minimum: u64) { // Warn about too low limit. let warning = [ format!("⚠️ The open files limit ({soft_limit}) for this process is lower than recommended."), - format!("⚠️ To ensure correct behavior of the node, please raise it to at least {minimum}."), - "⚠️ See the `ulimit` command and `/etc/security/limits.conf` for more details.".to_owned(), + format!(" • To ensure correct behavior of the node, please raise it to at least {minimum}."), + " • See the `ulimit` command and `/etc/security/limits.conf` for more details.".to_owned(), ] .join("\n") .yellow() @@ -54,8 +54,8 @@ pub fn check_open_files_limit(minimum: u64) { // Warn about unknown limit. let warning = [ format!("⚠️ Unable to check the open files limit for this process due to {err}."), - format!("⚠️ To ensure correct behavior of the node, please ensure it is at least {minimum}."), - "⚠️ See the `ulimit` command and `/etc/security/limits.conf` for more details.".to_owned(), + format!(" • To ensure correct behavior of the node, please ensure it is at least {minimum}."), + " • See the `ulimit` command and `/etc/security/limits.conf` for more details.".to_owned(), ] .join("\n") .yellow() diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 163e2c5bc7..095110f262 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -483,7 +483,7 @@ impl BFT { } /* Proceeding to commit the leader. */ - info!("Proceeding to commit round {commit_round} with leader {leader}..."); + info!("Proceeding to commit round {commit_round} with leader '{}'", fmt_id(leader)); // Prepare the election certificate IDs. let election_certificate_ids = certificates.values().map(|c| c.id()).collect::>(); diff --git a/node/bft/src/lib.rs b/node/bft/src/lib.rs index aa93a882af..3b569e87ae 100644 --- a/node/bft/src/lib.rs +++ b/node/bft/src/lib.rs @@ -14,6 +14,7 @@ #![forbid(unsafe_code)] #![allow(clippy::type_complexity)] +#![allow(clippy::unit_arg)] #[macro_use] extern crate async_trait; diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 86f6f25400..b9def80b35 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -556,7 +556,11 @@ impl Primary { // Ensure the batch is for the current round. // This method must be called after fetching previous certificates (above), // and prior to checking the batch header (below). - self.ensure_is_signing_round(batch_round)?; + if let Err(e) = self.ensure_is_signing_round(batch_round) { + // If the primary is not signing for the peer's round, then return early. + trace!("Skipped signing a batch for round {batch_round} from '{peer_ip}' - {e}"); + return Ok(()); + } // Ensure the batch header from the peer is valid. let storage = self.storage.clone(); @@ -1365,9 +1369,10 @@ impl Primary { return Ok(Default::default()); } - // Ensure this batch ID is new. + // Ensure this batch ID is new, otherwise return early. if self.storage.contains_batch(batch_header.batch_id()) { - bail!("Batch for round {} from peer has already been processed", batch_header.round()) + trace!("Batch for round {} from peer has already been processed", batch_header.round()); + return Ok(Default::default()); } // Retrieve the workers. diff --git a/node/bft/src/sync/mod.rs b/node/bft/src/sync/mod.rs index 5a756cbe07..402f07268c 100644 --- a/node/bft/src/sync/mod.rs +++ b/node/bft/src/sync/mod.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::{ - helpers::{BFTSender, Pending, Storage, SyncReceiver}, + helpers::{fmt_id, BFTSender, Pending, Storage, SyncReceiver}, spawn_blocking, Gateway, Transport, @@ -178,6 +178,7 @@ impl Sync { // Methods to manage storage. impl Sync { /// Syncs the storage with the ledger at bootup. + #[allow(clippy::unnecessary_to_owned)] pub async fn sync_storage_with_ledger_at_bootup(&self) -> Result<()> { // Retrieve the latest block in the ledger. let latest_block = self.ledger.latest_block(); @@ -343,7 +344,7 @@ impl Sync { if self.pending.insert(certificate_id, peer_ip, Some(callback_sender)) { // Send the certificate request to the peer. if self.gateway.send(peer_ip, Event::CertificateRequest(certificate_id.into())).await.is_none() { - bail!("Unable to fetch batch certificate {certificate_id} - failed to send request") + bail!("Unable to fetch certificate {} - failed to send request", fmt_id(certificate_id)) } } // Wait for the certificate to be fetched. @@ -351,7 +352,7 @@ impl Sync { // If the certificate was fetched, return it. Ok(result) => Ok(result?), // If the certificate was not fetched, return an error. - Err(e) => bail!("Unable to fetch batch certificate {certificate_id} - (timeout) {e}"), + Err(e) => bail!("Unable to fetch certificate {} - (timeout) {e}", fmt_id(certificate_id)), } } From 73ca8928d5b2030865da1bc31868c3ae0cfa2844 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:04:55 -0800 Subject: [PATCH 07/40] Improve logging From bf01fc48fd33d695837116cb57c224d23f6c1a2f Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:15:11 -0800 Subject: [PATCH 08/40] Update node/bft/src/primary.rs Signed-off-by: Howard Wu <9260812+howardwu@users.noreply.github.com> --- node/bft/src/primary.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index b9def80b35..2957a4b8d7 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -558,7 +558,7 @@ impl Primary { // and prior to checking the batch header (below). if let Err(e) = self.ensure_is_signing_round(batch_round) { // If the primary is not signing for the peer's round, then return early. - trace!("Skipped signing a batch for round {batch_round} from '{peer_ip}' - {e}"); + debug!("{e} from '{peer_ip}'"); return Ok(()); } From f42ba9bc512efc2fa6c8609ebda845695c927ef4 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 14 Feb 2024 20:39:43 +0100 Subject: [PATCH 09/40] fix: don't try to propose a batch when we're not yet synced --- node/bft/src/bft.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 095110f262..9e2ca61de5 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -254,6 +254,7 @@ impl BFT { // Update to the next round in storage. if let Err(e) = self.storage().increment_to_next_round(current_round) { warn!("BFT failed to increment to the next round from round {current_round} - {e}"); + return false; } // Update the timer for the leader certificate. self.leader_certificate_timer.store(now(), Ordering::SeqCst); From 7cb4d708659bc55f051cc1d09760f8c38c3faa91 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 19 Feb 2024 14:09:58 +0100 Subject: [PATCH 10/40] feat: handle more POSIX signals on UNIX systems Signed-off-by: ljedrz --- node/src/traits.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/node/src/traits.rs b/node/src/traits.rs index 12947ca3f2..6fd41686c6 100644 --- a/node/src/traits.rs +++ b/node/src/traits.rs @@ -17,6 +17,8 @@ use snarkvm::prelude::{Address, Network, PrivateKey, ViewKey}; use once_cell::sync::OnceCell; use std::{ + future::Future, + io, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -53,15 +55,40 @@ pub trait NodeInterface: Routing { /// Handles OS signals for the node to intercept and perform a clean shutdown. /// The optional `shutdown_flag` flag can be used to cleanly terminate the syncing process. - /// Note: Only Ctrl-C is supported; it should work on both Unix-family systems and Windows. fn handle_signals(shutdown_flag: Arc) -> Arc> { // In order for the signal handler to be started as early as possible, a reference to the node needs // to be passed to it at a later time. let node: Arc> = Default::default(); + #[cfg(target_family = "unix")] + fn signal_listener() -> impl Future> { + use tokio::signal::unix::{signal, SignalKind}; + + // Handle SIGINT, SIGTERM, SIGQUIT, and SIGHUP. + let mut s_int = signal(SignalKind::interrupt()).unwrap(); + let mut s_term = signal(SignalKind::terminate()).unwrap(); + let mut s_quit = signal(SignalKind::quit()).unwrap(); + let mut s_hup = signal(SignalKind::hangup()).unwrap(); + + // Return when any of the signals above is received. + async move { + tokio::select!( + _ = s_int.recv() => (), + _ = s_term.recv() => (), + _ = s_quit.recv() => (), + _ = s_hup.recv() => (), + ); + Ok(()) + } + } + #[cfg(not(target_family = "unix"))] + fn signal_listener() -> impl Future> { + tokio::signal::ctrl_c() + } + let node_clone = node.clone(); tokio::task::spawn(async move { - match tokio::signal::ctrl_c().await { + match signal_listener().await { Ok(()) => { match node_clone.get() { // If the node is already initialized, then shut it down. From 9df16b4bb501f53e5d7dc1ab5f82fde15967949e Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:40:02 -0800 Subject: [PATCH 11/40] Update is_proposing check --- node/bft/src/primary.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 2957a4b8d7..267b05f5c6 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -722,6 +722,8 @@ impl Primary { // Retrieve the batch certificate author. let author = certificate.author(); + // Retrieve the batch certificate round. + let certificate_round = certificate.round(); // Ensure the batch certificate is from an authorized validator. if !self.gateway.is_authorized_validator_ip(peer_ip) { @@ -751,14 +753,19 @@ impl Primary { // Check if the certificates have reached the quorum threshold. let is_quorum = committee_lookback.is_quorum_threshold_reached(&authors); - // Determine if we are currently proposing a round. + // Determine if we are currently proposing a round that is relevant. // Note: This is important, because while our peers have advanced, // they may not be proposing yet, and thus still able to sign our proposed batch. - let is_proposing = self.proposed_batch.read().is_some(); + let should_advance = match &*self.proposed_batch.read() { + // We advance if the proposal round is less than the current round that was just certified. + Some(proposal) => proposal.round() < certificate_round, + // If there's no proposal, we consider advancing. + None => true, + }; // Determine whether to advance to the next round. - if is_quorum && !is_proposing { - // If we have reached the quorum threshold, then proceed to the next round. + if is_quorum && should_advance { + // If we have reached the quorum threshold and the round should advance, then proceed to the next round. self.try_increment_to_the_next_round(current_round + 1).await?; } Ok(()) From 441867f40872c14a105cd5f5636b4ebd8e4e2e5f Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 21 Feb 2024 14:42:38 +0100 Subject: [PATCH 12/40] perf: skip the timed batch proposal if round progression already triggered one Signed-off-by: ljedrz --- node/bft/src/primary.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 267b05f5c6..d612c37754 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -978,6 +978,11 @@ impl Primary { debug!("Skipping batch proposal {}", "(node is syncing)".dimmed()); continue; } + // A best-effort attempt to skip the scheduled batch proposal if + // round progression already triggered one. + if self_.propose_lock.try_lock().is_err() { + continue; + }; // If there is no proposed batch, attempt to propose a batch. // Note: Do NOT spawn a task around this function call. Proposing a batch is a critical path, // and only one batch needs be proposed at a time. From 42089dbe593fa27aa84a181a73f81ebf1cb5f3ef Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:08:52 -0700 Subject: [PATCH 13/40] Update node/bft/src/primary.rs Signed-off-by: Howard Wu <9260812+howardwu@users.noreply.github.com> --- node/bft/src/primary.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index d612c37754..ac602114ad 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -981,6 +981,7 @@ impl Primary { // A best-effort attempt to skip the scheduled batch proposal if // round progression already triggered one. if self_.propose_lock.try_lock().is_err() { + trace!("Skipping batch proposal {}", "(node is already proposing)".dimmed()); continue; }; // If there is no proposed batch, attempt to propose a batch. From 72eed647e63cd43726a5981cc61b52b0be01a272 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 20 Feb 2024 12:58:09 +0100 Subject: [PATCH 14/40] perf: cache the recently queried committees Signed-off-by: ljedrz --- node/bft/ledger-service/Cargo.toml | 6 ++++-- node/bft/ledger-service/src/ledger.rs | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/node/bft/ledger-service/Cargo.toml b/node/bft/ledger-service/Cargo.toml index 8a37cdb97e..69d912a82d 100644 --- a/node/bft/ledger-service/Cargo.toml +++ b/node/bft/ledger-service/Cargo.toml @@ -20,7 +20,7 @@ edition = "2021" default = [ ] ledger = [ "rand", "tokio", "tracing" ] ledger-write = [ ] -mock = [ "parking_lot", "tracing" ] +mock = [ "tracing" ] prover = [ ] test = [ "mock", "translucent" ] translucent = [ "ledger" ] @@ -32,9 +32,11 @@ version = "0.1" version = "2.1" features = [ "serde", "rayon" ] +[dependencies.lru] +version = "0.12" + [dependencies.parking_lot] version = "0.12" -optional = true [dependencies.rand] version = "0.8" diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 1f42f909b0..3af160028e 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -26,6 +26,8 @@ use snarkvm::{ }; use indexmap::IndexMap; +use lru::LruCache; +use parking_lot::Mutex; use std::{ fmt, ops::Range, @@ -35,18 +37,23 @@ use std::{ }, }; +/// The capacity of the LRU holiding the recently queried committees. +const COMMITTEE_CACHE_SIZE: usize = 16; + /// A core ledger service. pub struct CoreLedgerService> { ledger: Ledger, coinbase_verifying_key: Arc>, shutdown: Arc, + committee_cache: Arc>>>, } impl> CoreLedgerService { /// Initializes a new core ledger service. pub fn new(ledger: Ledger, shutdown: Arc) -> Self { let coinbase_verifying_key = Arc::new(ledger.coinbase_puzzle().coinbase_verifying_key().clone()); - Self { ledger, coinbase_verifying_key, shutdown } + let committee_cache = Arc::new(Mutex::new(LruCache::new(COMMITTEE_CACHE_SIZE.try_into().unwrap()))); + Self { ledger, coinbase_verifying_key, shutdown, committee_cache } } } @@ -127,20 +134,30 @@ impl> LedgerService for CoreLedgerService< /// Returns the committee for the given round. /// If the given round is in the future, then the current committee is returned. fn get_committee_for_round(&self, round: u64) -> Result> { - match self.ledger.get_committee_for_round(round)? { + // Check if the committee is already in the cache. + if let Some(committee) = self.committee_cache.lock().get(&round) { + return Ok(committee.clone()); + } + + let committee = match self.ledger.get_committee_for_round(round)? { // Return the committee if it exists. - Some(committee) => Ok(committee), + Some(committee) => committee, // Return the current committee if the round is in the future. None => { // Retrieve the current committee. let current_committee = self.current_committee()?; // Return the current committee if the round is in the future. match current_committee.starting_round() <= round { - true => Ok(current_committee), + true => current_committee, false => bail!("No committee found for round {round} in the ledger"), } } - } + }; + + // Insert the committee into the cache. + self.committee_cache.lock().push(round, committee.clone()); + + Ok(committee) } /// Returns the committee lookback for the given round. From a84284d06791d24f3d15cab02704a03d36e34c47 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 21 Feb 2024 10:33:22 +0100 Subject: [PATCH 15/40] fix: only cache committies with matching rounds Signed-off-by: ljedrz --- node/bft/ledger-service/src/ledger.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 3af160028e..1eafd41582 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -139,25 +139,24 @@ impl> LedgerService for CoreLedgerService< return Ok(committee.clone()); } - let committee = match self.ledger.get_committee_for_round(round)? { + match self.ledger.get_committee_for_round(round)? { // Return the committee if it exists. - Some(committee) => committee, + Some(committee) => { + // Insert the committee into the cache. + self.committee_cache.lock().push(round, committee.clone()); + Ok(committee) + } // Return the current committee if the round is in the future. None => { // Retrieve the current committee. let current_committee = self.current_committee()?; // Return the current committee if the round is in the future. match current_committee.starting_round() <= round { - true => current_committee, + true => Ok(current_committee), false => bail!("No committee found for round {round} in the ledger"), } } - }; - - // Insert the committee into the cache. - self.committee_cache.lock().push(round, committee.clone()); - - Ok(committee) + } } /// Returns the committee lookback for the given round. From 6195f3b7584961be7b498c5ef1601eef6bde4f3c Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:06:17 -0800 Subject: [PATCH 16/40] nit: reorder items --- node/bft/ledger-service/src/ledger.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 1eafd41582..520822971a 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -44,8 +44,8 @@ const COMMITTEE_CACHE_SIZE: usize = 16; pub struct CoreLedgerService> { ledger: Ledger, coinbase_verifying_key: Arc>, - shutdown: Arc, committee_cache: Arc>>>, + shutdown: Arc, } impl> CoreLedgerService { @@ -53,7 +53,7 @@ impl> CoreLedgerService { pub fn new(ledger: Ledger, shutdown: Arc) -> Self { let coinbase_verifying_key = Arc::new(ledger.coinbase_puzzle().coinbase_verifying_key().clone()); let committee_cache = Arc::new(Mutex::new(LruCache::new(COMMITTEE_CACHE_SIZE.try_into().unwrap()))); - Self { ledger, coinbase_verifying_key, shutdown, committee_cache } + Self { ledger, coinbase_verifying_key, committee_cache, shutdown } } } @@ -144,6 +144,7 @@ impl> LedgerService for CoreLedgerService< Some(committee) => { // Insert the committee into the cache. self.committee_cache.lock().push(round, committee.clone()); + // Return the committee. Ok(committee) } // Return the current committee if the round is in the future. From e9ea9d5cc24ddb9fee1ccc2a732badf28404cb68 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:13:46 -0800 Subject: [PATCH 17/40] nit: feature optional --- node/bft/ledger-service/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/bft/ledger-service/Cargo.toml b/node/bft/ledger-service/Cargo.toml index 69d912a82d..40d0ca87b8 100644 --- a/node/bft/ledger-service/Cargo.toml +++ b/node/bft/ledger-service/Cargo.toml @@ -18,9 +18,9 @@ edition = "2021" [features] default = [ ] -ledger = [ "rand", "tokio", "tracing" ] +ledger = [ "parking_lot", "rand", "tokio", "tracing" ] ledger-write = [ ] -mock = [ "tracing" ] +mock = [ "parking_lot", "tracing" ] prover = [ ] test = [ "mock", "translucent" ] translucent = [ "ledger" ] @@ -37,6 +37,7 @@ version = "0.12" [dependencies.parking_lot] version = "0.12" +optional = true [dependencies.rand] version = "0.8" From 03564e8bdd31b523e53a66974d967e671a534ba6 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:49:18 -0800 Subject: [PATCH 18/40] Add round check in signed proposals cache --- node/bft/src/primary.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index ac602114ad..624d21ad06 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -527,6 +527,13 @@ impl Primary { if let Some((signed_round, 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. + 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()); + } + // 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. From 6a2aa4adf8fe969d91759d135f7e90f89aa42715 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Sun, 3 Mar 2024 14:34:08 -0800 Subject: [PATCH 19/40] Use the certificate_round for lookback selection --- node/bft/src/primary.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 624d21ad06..57d8813289 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -746,15 +746,13 @@ impl Primary { // Store the certificate, after ensuring it is valid. self.sync_with_certificate_from_peer(peer_ip, certificate).await?; - // If there are enough certificates to reach quorum threshold for the current round, + // If there are enough certificates to reach quorum threshold for the certificate round, // then proceed to advance to the next round. - // Retrieve the current round. - let current_round = self.current_round(); // Retrieve the committee lookback. - let committee_lookback = self.ledger.get_committee_lookback_for_round(current_round)?; + let committee_lookback = self.ledger.get_committee_lookback_for_round(certificate_round)?; // Retrieve the certificates. - let certificates = self.storage.get_certificates_for_round(current_round); + let certificates = self.storage.get_certificates_for_round(certificate_round); // Construct a set over the authors. let authors = certificates.iter().map(BatchCertificate::author).collect(); // Check if the certificates have reached the quorum threshold. @@ -770,8 +768,11 @@ impl Primary { None => true, }; + // Retrieve the current round. + let current_round = self.current_round(); + // Determine whether to advance to the next round. - if is_quorum && should_advance { + if is_quorum && should_advance && certificate_round >= current_round { // If we have reached the quorum threshold and the round should advance, then proceed to the next round. self.try_increment_to_the_next_round(current_round + 1).await?; } From fc3def36c1fe23a02b1902fd5a43c98571b8ce85 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:51:07 -0800 Subject: [PATCH 20/40] Add fee transmission check in ensure_transmission_id_matches --- node/bft/ledger-service/src/ledger.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index 520822971a..e5c98a2af1 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -202,6 +202,7 @@ impl> LedgerService for CoreLedgerService< (TransmissionID::Transaction(expected_transaction_id), Transmission::Transaction(transaction_data)) => { match transaction_data.clone().deserialize_blocking() { Ok(transaction) => { + // Ensure the transaction ID matches the expected transaction ID. if transaction.id() != expected_transaction_id { bail!( "Received mismatching transaction ID - expected {}, found {}", @@ -210,6 +211,11 @@ impl> LedgerService for CoreLedgerService< ); } + // Ensure the transaction is not a fee transaction. + if transaction.is_fee() { + bail!("Received a fee transaction in a transmission"); + } + // Update the transmission with the deserialized transaction. *transaction_data = Data::Object(transaction); } From 572b2fa94f1c2ff0e8c32ee6f67601ada59dda32 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:51:51 -0800 Subject: [PATCH 21/40] Perform basic check on transmissions in batch proposals --- node/bft/src/primary.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index 57d8813289..d2cdb1d388 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -558,7 +558,16 @@ impl Primary { } // If the peer is ahead, use the batch header to sync up to the peer. - let transmissions = self.sync_with_batch_header_from_peer(peer_ip, &batch_header).await?; + let mut transmissions = self.sync_with_batch_header_from_peer(peer_ip, &batch_header).await?; + + // Check that the transmission ids match and are not fee transactions. + for (transmission_id, transmission) in transmissions.iter_mut() { + // If the transmission is invalid, then return early. + if let Err(err) = self.ledger.ensure_transmission_id_matches(*transmission_id, transmission) { + debug!("Batch propose from '{peer_ip}' contains an invalid transmission - {err}",); + return Ok(()); + } + } // Ensure the batch is for the current round. // This method must be called after fetching previous certificates (above), From ff3628352087f0b87decb0a728313678d91f664b Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:10:46 -0800 Subject: [PATCH 22/40] Resolve cherry-pick for f8c2827 --- Cargo.lock | 1 + node/bft/ledger-service/src/ledger.rs | 4 ++-- node/bft/ledger-service/src/mock.rs | 4 ++-- node/bft/ledger-service/src/prover.rs | 4 ++-- node/bft/ledger-service/src/traits.rs | 4 ++-- node/bft/ledger-service/src/translucent.rs | 2 +- node/bft/src/primary.rs | 4 ++-- node/bft/src/worker.rs | 10 ++++++---- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e962c9049..9e2977f723 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3318,6 +3318,7 @@ version = "2.2.7" dependencies = [ "async-trait", "indexmap 2.2.2", + "lru", "parking_lot", "rand", "snarkvm", diff --git a/node/bft/ledger-service/src/ledger.rs b/node/bft/ledger-service/src/ledger.rs index e5c98a2af1..211ea55332 100644 --- a/node/bft/ledger-service/src/ledger.rs +++ b/node/bft/ledger-service/src/ledger.rs @@ -191,8 +191,8 @@ impl> LedgerService for CoreLedgerService< } } - /// Ensures the given transmission ID matches the given transmission. - fn ensure_transmission_id_matches( + /// Ensures that the given transmission is not a fee and matches the given transmission ID. + fn ensure_transmission_is_well_formed( &self, transmission_id: TransmissionID, transmission: &mut Transmission, diff --git a/node/bft/ledger-service/src/mock.rs b/node/bft/ledger-service/src/mock.rs index c36679a40e..00236723ab 100644 --- a/node/bft/ledger-service/src/mock.rs +++ b/node/bft/ledger-service/src/mock.rs @@ -143,8 +143,8 @@ impl LedgerService for MockLedgerService { Ok(false) } - /// Ensures the given transmission ID matches the given transmission. - fn ensure_transmission_id_matches( + /// Ensures that the given transmission is not a fee and matches the given transmission ID. + fn ensure_transmission_is_well_formed( &self, transmission_id: TransmissionID, _transmission: &mut Transmission, diff --git a/node/bft/ledger-service/src/prover.rs b/node/bft/ledger-service/src/prover.rs index 6edfbafd4c..be3e181aaf 100644 --- a/node/bft/ledger-service/src/prover.rs +++ b/node/bft/ledger-service/src/prover.rs @@ -124,8 +124,8 @@ impl LedgerService for ProverLedgerService { bail!("Transmission '{transmission_id}' does not exist in prover") } - /// Ensures the given transmission ID matches the given transmission. - fn ensure_transmission_id_matches( + /// Ensures that the given transmission is not a fee and matches the given transmission ID. + fn ensure_transmission_is_well_formed( &self, _transmission_id: TransmissionID, _transmission: &mut Transmission, diff --git a/node/bft/ledger-service/src/traits.rs b/node/bft/ledger-service/src/traits.rs index a97fdeb373..ff25ae0ca7 100644 --- a/node/bft/ledger-service/src/traits.rs +++ b/node/bft/ledger-service/src/traits.rs @@ -78,8 +78,8 @@ pub trait LedgerService: Debug + Send + Sync { /// Returns `true` if the ledger contains the given transmission ID. fn contains_transmission(&self, transmission_id: &TransmissionID) -> Result; - /// Ensures the given transmission ID matches the given transmission. - fn ensure_transmission_id_matches( + /// Ensures that the given transmission is not a fee and matches the given transmission ID. + fn ensure_transmission_is_well_formed( &self, transmission_id: TransmissionID, transmission: &mut Transmission, diff --git a/node/bft/ledger-service/src/translucent.rs b/node/bft/ledger-service/src/translucent.rs index 34afa15667..09c0c1792c 100644 --- a/node/bft/ledger-service/src/translucent.rs +++ b/node/bft/ledger-service/src/translucent.rs @@ -135,7 +135,7 @@ impl> LedgerService for TranslucentLedgerS } /// Always succeeds. - fn ensure_transmission_id_matches( + fn ensure_transmission_is_well_formed( &self, _transmission_id: TransmissionID, _transmission: &mut Transmission, diff --git a/node/bft/src/primary.rs b/node/bft/src/primary.rs index d2cdb1d388..cabcdbb618 100644 --- a/node/bft/src/primary.rs +++ b/node/bft/src/primary.rs @@ -562,8 +562,8 @@ impl Primary { // Check that the transmission ids match and are not fee transactions. for (transmission_id, transmission) in transmissions.iter_mut() { - // If the transmission is invalid, then return early. - if let Err(err) = self.ledger.ensure_transmission_id_matches(*transmission_id, transmission) { + // If the transmission is not well-formed, then return early. + if let Err(err) = self.ledger.ensure_transmission_is_well_formed(*transmission_id, transmission) { debug!("Batch propose from '{peer_ip}' contains an invalid transmission - {err}",); return Ok(()); } diff --git a/node/bft/src/worker.rs b/node/bft/src/worker.rs index b07cb8a8f1..49ac94f67f 100644 --- a/node/bft/src/worker.rs +++ b/node/bft/src/worker.rs @@ -399,8 +399,8 @@ impl Worker { let exists = self.pending.get(transmission_id).unwrap_or_default().contains(&peer_ip); // If the peer IP exists, finish the pending request. if exists { - // Ensure the transmission ID matches the transmission. - match self.ledger.ensure_transmission_id_matches(transmission_id, &mut transmission) { + // Ensure the transmission is not a fee and matches the transmission ID. + match self.ledger.ensure_transmission_is_well_formed(transmission_id, &mut transmission) { Ok(()) => { // Remove the transmission ID from the pending queue. self.pending.remove(transmission_id, Some(transmission)); @@ -487,7 +487,7 @@ mod tests { fn get_committee_lookback_for_round(&self, round: u64) -> Result>; fn contains_certificate(&self, certificate_id: &Field) -> Result; fn contains_transmission(&self, transmission_id: &TransmissionID) -> Result; - fn ensure_transmission_id_matches( + fn ensure_transmission_is_well_formed( &self, transmission_id: TransmissionID, transmission: &mut Transmission, @@ -550,6 +550,7 @@ mod tests { let rng = &mut TestRng::default(); // Sample a committee. let committee = snarkvm::ledger::committee::test_helpers::sample_committee(rng); + let committee_clone = committee.clone(); // Setup the mock gateway and ledger. let mut gateway = MockGateway::default(); gateway.expect_send().returning(|_, _| { @@ -558,7 +559,8 @@ mod tests { }); let mut mock_ledger = MockLedger::default(); mock_ledger.expect_current_committee().returning(move || Ok(committee.clone())); - mock_ledger.expect_ensure_transmission_id_matches().returning(|_, _| Ok(())); + mock_ledger.expect_get_committee_lookback_for_round().returning(move |_| Ok(committee_clone.clone())); + mock_ledger.expect_ensure_transmission_is_well_formed().returning(|_, _| Ok(())); let ledger: Arc> = Arc::new(mock_ledger); // Initialize the storage. let storage = Storage::::new(ledger.clone(), Arc::new(BFTMemoryService::new()), 1); From 3affa87b59aec62f025570e7c77f7f171147855c Mon Sep 17 00:00:00 2001 From: Haruka Date: Tue, 5 Mar 2024 02:53:45 +0900 Subject: [PATCH 23/40] Skip seen transactions and solutions instead of bailing --- node/router/src/inbound.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/node/router/src/inbound.rs b/node/router/src/inbound.rs index 1b0cf0da22..e47cf39665 100644 --- a/node/router/src/inbound.rs +++ b/node/router/src/inbound.rs @@ -207,7 +207,8 @@ pub trait Inbound: Reading + Outbound { let seen_before = self.router().cache.insert_inbound_solution(peer_ip, message.solution_id).is_some(); // Determine whether to propagate the solution. if seen_before { - bail!("Skipping 'UnconfirmedSolution' from '{peer_ip}'") + trace!("Skipping 'UnconfirmedSolution' from '{peer_ip}'"); + return Ok(()); } // Perform the deferred non-blocking deserialization of the solution. let solution = match message.solution.deserialize().await { @@ -232,7 +233,8 @@ pub trait Inbound: Reading + Outbound { self.router().cache.insert_inbound_transaction(peer_ip, message.transaction_id).is_some(); // Determine whether to propagate the transaction. if seen_before { - bail!("Skipping 'UnconfirmedTransaction' from '{peer_ip}'") + trace!("Skipping 'UnconfirmedTransaction' from '{peer_ip}'"); + return Ok(()); } // Perform the deferred non-blocking deserialization of the transaction. let transaction = match message.transaction.deserialize().await { From c4ecc09aa8ee4314db0be1a6bd6e12f50024b271 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 5 Mar 2024 09:52:11 +0100 Subject: [PATCH 24/40] feat: jemalloc by default on linux --- Cargo.toml | 6 ++---- snarkos/main.rs | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 764d102652..9c3abb0b9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,6 @@ name = "snarkos" path = "snarkos/main.rs" [features] -jemalloc = [ "tikv-jemallocator" ] metrics = [ "snarkos-node-metrics", "snarkos-node/metrics" ] [dependencies.anyhow] @@ -120,9 +119,8 @@ version = "=2.2.7" path = "./node/tcp" version = "=2.2.7" -[dependencies.tikv-jemallocator] -version = "0.5" -optional = true +[target.'cfg(target_os = "linux")'.dependencies] +tikv-jemallocator = "0.5" [dev-dependencies.rusty-hook] version = "0.11.2" diff --git a/snarkos/main.rs b/snarkos/main.rs index 64cef2f182..6ace71ef93 100644 --- a/snarkos/main.rs +++ b/snarkos/main.rs @@ -17,10 +17,10 @@ use snarkos_cli::{commands::CLI, helpers::Updater}; use clap::Parser; use std::process::exit; -#[cfg(feature = "jemalloc")] +#[cfg(target_os = "linux")] use tikv_jemallocator::Jemalloc; -#[cfg(feature = "jemalloc")] +#[cfg(target_os = "linux")] #[global_allocator] static GLOBAL: Jemalloc = Jemalloc; From 94259394d1d00bc790b33d279b0014fd325b358a Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Thu, 7 Mar 2024 21:43:18 +0100 Subject: [PATCH 25/40] fix: x86_64 only --- Cargo.toml | 2 +- snarkos/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9c3abb0b9b..4965fb0009 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,7 +119,7 @@ version = "=2.2.7" path = "./node/tcp" version = "=2.2.7" -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(all(target_os = "linux", target_arch = "x86_64"))'.dependencies] tikv-jemallocator = "0.5" [dev-dependencies.rusty-hook] diff --git a/snarkos/main.rs b/snarkos/main.rs index 6ace71ef93..61a86949b8 100644 --- a/snarkos/main.rs +++ b/snarkos/main.rs @@ -17,10 +17,10 @@ use snarkos_cli::{commands::CLI, helpers::Updater}; use clap::Parser; use std::process::exit; -#[cfg(target_os = "linux")] +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] use tikv_jemallocator::Jemalloc; -#[cfg(target_os = "linux")] +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] #[global_allocator] static GLOBAL: Jemalloc = Jemalloc; From 31ae363045fedcb07bf01440e8424434970ed8ac Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:25:43 -0800 Subject: [PATCH 26/40] Resolve cherry-pick for f033e7f --- node/bft/src/bft.rs | 62 +++++++++------------------------------------ 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 9e2ca61de5..823b9e51f7 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -803,62 +803,24 @@ impl BFT { }); } - /// Syncs the BFT DAG with the given leader certificates and batch certificates. + /// Syncs the BFT DAG with the given batch certificates. These batch certificates **must** + /// already exist in the ledger. /// - /// This method starts by inserting all certificates (except the latest leader certificate) - /// into the DAG. Then, it commits all leader certificates (except the latest leader certificate). - /// Finally, it updates the DAG with the latest leader certificate. + /// This method commits all the certificates into the dag. + /// Note that there is no need to insert the certificates into the DAG, because these certificates + /// already exist in the ledger and therefor do not need to be re-ordered into future + /// committed subdags. async fn sync_bft_dag_at_bootup( &self, - leader_certificates: Vec<(BatchCertificate, IndexSet>)>, + _leader_certificates: Vec<(BatchCertificate, IndexSet>)>, certificates: Vec>, ) { - // Split the leader certificates into past leader certificates, the latest leader certificate, and the election certificate IDs. - let (past_leader_certificates, leader_certificate, election_certificate_ids) = { - // Compute the penultimate index. - let index = leader_certificates.len().saturating_sub(1); - // Split the leader certificates. - let (past, latest) = leader_certificates.split_at(index); - debug_assert!(latest.len() == 1, "There should only be one latest leader certificate"); - // Retrieve the latest leader certificate. - match latest.first() { - Some((leader_certificate, election_certificate_ids)) => { - (past, leader_certificate.clone(), election_certificate_ids.clone()) - } - // If there is no latest leader certificate, return early. - None => return, - } - }; - { - // Acquire the BFT write lock. - let mut dag = self.dag.write(); - // Iterate over the certificates. - for certificate in certificates { - // If the certificate is not the latest leader certificate, insert it. - if leader_certificate.id() != certificate.id() { - // Insert the certificate into the DAG. - dag.insert(certificate); - } - } + // Acquire the BFT write lock. + let mut dag = self.dag.write(); - // Acquire the last election certificate IDs. - let mut last_election_certificate_ids = self.last_election_certificate_ids.write(); - // Iterate over the leader certificates. - for (leader_certificate, election_certificate_ids) in past_leader_certificates { - // Commit the leader certificate. - dag.commit(leader_certificate, self.storage().max_gc_rounds()); - // Update the last election certificate IDs. - // - // Note: Because we will be committing the latest leader certificate after this, - // technically we do not need to be updating the last election certificate IDs - // for intermediate leader certificates. However, this is a safety mechanic to ensure completeness. - *last_election_certificate_ids = election_certificate_ids.clone(); - } - } - // Commit the latest leader certificate. - if let Err(e) = self.commit_leader_certificate::(leader_certificate, election_certificate_ids).await - { - error!("BFT failed to update the DAG with the latest leader certificate - {e}"); + // Commit all the certificates excluding the latest leader certificate. + for certificate in certificates { + dag.commit(&certificate, self.storage().max_gc_rounds()); } } From 91e746031008971b76cec7c9e233cc3fab4dbc86 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:28:07 -0800 Subject: [PATCH 27/40] Skip ordering certs if it exists in the ledger --- node/bft/src/bft.rs | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 823b9e51f7..0888ed8985 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -669,6 +669,11 @@ impl BFT { if self.dag.read().is_recently_committed(previous_round, *previous_certificate_id) { continue; } + // If the previous certificate already exists in the ledger, continue. + if ALLOW_LEDGER_ACCESS && self.ledger().contains_certificate(previous_certificate_id).unwrap_or(false) { + continue; + } + // Retrieve the previous certificate. let previous_certificate = { // Start by retrieving the previous certificate from the DAG. @@ -679,28 +684,11 @@ impl BFT { None => match self.storage().get_certificate(*previous_certificate_id) { // If the previous certificate is found, return it. Some(previous_certificate) => previous_certificate, - // Otherwise, retrieve the previous certificate from the ledger. - None => { - if ALLOW_LEDGER_ACCESS { - match self.ledger().get_batch_certificate(previous_certificate_id) { - // If the previous certificate is found, return it. - Ok(previous_certificate) => previous_certificate, - // Otherwise, the previous certificate is missing, and throw an error. - Err(e) => { - bail!( - "Missing previous certificate {} for round {previous_round} - {e}", - fmt_id(previous_certificate_id) - ) - } - } - } else { - // Otherwise, the previous certificate is missing, and throw an error. - bail!( - "Missing previous certificate {} for round {previous_round}", - fmt_id(previous_certificate_id) - ) - } - } + // Otherwise, the previous certificate is missing, and throw an error. + None => bail!( + "Missing previous certificate {} for round {previous_round}", + fmt_id(previous_certificate_id) + ), }, } }; From 3120192dfe12313929ed13e4380a1ba1c5209369 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:31:07 -0800 Subject: [PATCH 28/40] Resolve cherry-pick for 690323e --- node/bft/src/bft.rs | 10 +++------- node/bft/src/helpers/channels.rs | 6 ++---- node/bft/src/sync/mod.rs | 22 ++-------------------- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 0888ed8985..1d71e15bbf 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -773,8 +773,8 @@ impl BFT { // Process the request to sync the BFT DAG at bootup. let self_ = self.clone(); self.spawn(async move { - while let Some((leader_certificates, certificates)) = rx_sync_bft_dag_at_bootup.recv().await { - self_.sync_bft_dag_at_bootup(leader_certificates, certificates).await; + while let Some(certificates) = rx_sync_bft_dag_at_bootup.recv().await { + self_.sync_bft_dag_at_bootup(certificates).await; } }); @@ -798,11 +798,7 @@ impl BFT { /// Note that there is no need to insert the certificates into the DAG, because these certificates /// already exist in the ledger and therefor do not need to be re-ordered into future /// committed subdags. - async fn sync_bft_dag_at_bootup( - &self, - _leader_certificates: Vec<(BatchCertificate, IndexSet>)>, - certificates: Vec>, - ) { + async fn sync_bft_dag_at_bootup(&self, certificates: Vec>) { // Acquire the BFT write lock. let mut dag = self.dag.write(); diff --git a/node/bft/src/helpers/channels.rs b/node/bft/src/helpers/channels.rs index 8881b1f0ca..182aa0a801 100644 --- a/node/bft/src/helpers/channels.rs +++ b/node/bft/src/helpers/channels.rs @@ -64,8 +64,7 @@ pub struct BFTSender { pub tx_last_election_certificate_ids: mpsc::Sender>>>, pub tx_primary_round: mpsc::Sender<(u64, oneshot::Sender)>, pub tx_primary_certificate: mpsc::Sender<(BatchCertificate, oneshot::Sender>)>, - pub tx_sync_bft_dag_at_bootup: - mpsc::Sender<(Vec<(BatchCertificate, IndexSet>)>, Vec>)>, + pub tx_sync_bft_dag_at_bootup: mpsc::Sender>>, pub tx_sync_bft: mpsc::Sender<(BatchCertificate, oneshot::Sender>)>, } @@ -116,8 +115,7 @@ pub struct BFTReceiver { pub rx_last_election_certificate_ids: mpsc::Receiver>>>, pub rx_primary_round: mpsc::Receiver<(u64, oneshot::Sender)>, pub rx_primary_certificate: mpsc::Receiver<(BatchCertificate, oneshot::Sender>)>, - pub rx_sync_bft_dag_at_bootup: - mpsc::Receiver<(Vec<(BatchCertificate, IndexSet>)>, Vec>)>, + pub rx_sync_bft_dag_at_bootup: mpsc::Receiver>>, pub rx_sync_bft: mpsc::Receiver<(BatchCertificate, oneshot::Sender>)>, } diff --git a/node/bft/src/sync/mod.rs b/node/bft/src/sync/mod.rs index 402f07268c..b41b92b5e5 100644 --- a/node/bft/src/sync/mod.rs +++ b/node/bft/src/sync/mod.rs @@ -218,24 +218,6 @@ impl Sync { /* Sync the BFT DAG */ - // Retrieve the leader certificates. - let leader_certificates = blocks - .iter() - .flat_map(|block| { - match block.authority() { - // If the block authority is a beacon, then skip the block. - Authority::Beacon(_) => None, - // If the block authority is a subdag, then retrieve the certificates. - Authority::Quorum(subdag) => { - Some((subdag.leader_certificate().clone(), subdag.election_certificate_ids().clone())) - } - } - }) - .collect::>(); - if leader_certificates.is_empty() { - return Ok(()); - } - // Construct a list of the certificates. let certificates = blocks .iter() @@ -250,10 +232,10 @@ impl Sync { .flatten() .collect::>(); - // If a BFT sender was provided, send the certificate to the BFT. + // If a BFT sender was provided, send the certificates to the BFT. if let Some(bft_sender) = self.bft_sender.get() { // Await the callback to continue. - if let Err(e) = bft_sender.tx_sync_bft_dag_at_bootup.send((leader_certificates, certificates)).await { + if let Err(e) = bft_sender.tx_sync_bft_dag_at_bootup.send(certificates).await { bail!("Failed to update the BFT DAG from sync: {e}"); } } From 084a0701c2cbdb96ec16dbf44f1ddffb6ceb0c7f Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:35:16 -0800 Subject: [PATCH 29/40] Resolve cherry-pick of 04b0407 --- node/bft/src/bft.rs | 161 +++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 48 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 1d71e15bbf..75f91009d0 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -489,11 +489,11 @@ impl BFT { // Prepare the election certificate IDs. let election_certificate_ids = certificates.values().map(|c| c.id()).collect::>(); // Commit the leader certificate, and all previous leader certificates since the last committed round. - self.commit_leader_certificate::(leader_certificate, election_certificate_ids).await + self.commit_leader_certificate::(leader_certificate, election_certificate_ids).await } /// Commits the leader certificate, and all previous leader certificates since the last committed round. - async fn commit_leader_certificate( + async fn commit_leader_certificate( &self, leader_certificate: BatchCertificate, election_certificate_ids: IndexSet>, @@ -550,10 +550,6 @@ impl BFT { let mut transmissions = IndexMap::new(); // Start from the oldest leader certificate. for certificate in commit_subdag.values().flatten() { - // Update the DAG. - if IS_SYNCING { - self.dag.write().commit(certificate, self.storage().max_gc_rounds()); - } // Retrieve the transmissions. for transmission_id in certificate.transmission_ids() { // If the transmission already exists in the map, skip it. @@ -577,51 +573,49 @@ impl BFT { transmissions.insert(*transmission_id, transmission); } } - // If the node is not syncing, trigger consensus, as this will build a new block for the ledger. - if !IS_SYNCING { - // Construct the subdag. - let subdag = Subdag::from(commit_subdag.clone(), election_certificate_ids.clone())?; - // Retrieve the anchor round. - let anchor_round = subdag.anchor_round(); - // Retrieve the number of transmissions. - let num_transmissions = transmissions.len(); - // Retrieve metadata about the subdag. - let subdag_metadata = subdag.iter().map(|(round, c)| (*round, c.len())).collect::>(); - - // Ensure the subdag anchor round matches the leader round. - ensure!( - anchor_round == leader_round, - "BFT failed to commit - the subdag anchor round {anchor_round} does not match the leader round {leader_round}", - ); - - // Trigger consensus. - if let Some(consensus_sender) = self.consensus_sender.get() { - // Initialize a callback sender and receiver. - let (callback_sender, callback_receiver) = oneshot::channel(); - // Send the subdag and transmissions to consensus. - consensus_sender.tx_consensus_subdag.send((subdag, transmissions, callback_sender)).await?; - // Await the callback to continue. - match callback_receiver.await { - Ok(Ok(())) => (), // continue - Ok(Err(e)) => { - error!("BFT failed to advance the subdag for round {anchor_round} - {e}"); - return Ok(()); - } - Err(e) => { - error!("BFT failed to receive the callback for round {anchor_round} - {e}"); - return Ok(()); - } + // Trigger consensus, as this will build a new block for the ledger. + // Construct the subdag. + let subdag = Subdag::from(commit_subdag.clone(), election_certificate_ids.clone())?; + // Retrieve the anchor round. + let anchor_round = subdag.anchor_round(); + // Retrieve the number of transmissions. + let num_transmissions = transmissions.len(); + // Retrieve metadata about the subdag. + let subdag_metadata = subdag.iter().map(|(round, c)| (*round, c.len())).collect::>(); + + // Ensure the subdag anchor round matches the leader round. + ensure!( + anchor_round == leader_round, + "BFT failed to commit - the subdag anchor round {anchor_round} does not match the leader round {leader_round}", + ); + + // Trigger consensus. + if let Some(consensus_sender) = self.consensus_sender.get() { + // Initialize a callback sender and receiver. + let (callback_sender, callback_receiver) = oneshot::channel(); + // Send the subdag and transmissions to consensus. + consensus_sender.tx_consensus_subdag.send((subdag, transmissions, callback_sender)).await?; + // Await the callback to continue. + match callback_receiver.await { + Ok(Ok(())) => (), // continue + Ok(Err(e)) => { + error!("BFT failed to advance the subdag for round {anchor_round} - {e}"); + return Ok(()); + } + Err(e) => { + error!("BFT failed to receive the callback for round {anchor_round} - {e}"); + return Ok(()); } } + } - info!( - "\n\nCommitting a subdag from round {anchor_round} with {num_transmissions} transmissions: {subdag_metadata:?}\n" - ); - // Update the DAG, as the subdag was successfully included into a block. - let mut dag_write = self.dag.write(); - for certificate in commit_subdag.values().flatten() { - dag_write.commit(certificate, self.storage().max_gc_rounds()); - } + info!( + "\n\nCommitting a subdag from round {anchor_round} with {num_transmissions} transmissions: {subdag_metadata:?}\n" + ); + // Update the DAG, as the subdag was successfully included into a block. + let mut dag_write = self.dag.write(); + for certificate in commit_subdag.values().flatten() { + dag_write.commit(certificate, self.storage().max_gc_rounds()); } // Update the last election certificate IDs. // TODO (howardwu): This is currently writing the *latest* election certificate IDs, @@ -633,6 +627,10 @@ impl BFT { *last_election_certificate_ids = election_certificate_ids.clone(); } } + + // Perform garbage collection based on the latest committed leader round. + // self.storage().garbage_collect_certificates(latest_leader_round); + Ok(()) } @@ -1197,4 +1195,71 @@ mod tests { assert_eq!(result.unwrap_err().to_string(), error_msg); Ok(()) } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_bft_gc_on_commit() -> Result<()> { + let rng = &mut TestRng::default(); + + // Initialize the round parameters. + let max_gc_rounds = 1; + let committee_round = 0; + let commit_round = 2; + let current_round = commit_round + 1; + + // Sample the certificates. + let (_, certificates) = snarkvm::ledger::narwhal::batch_certificate::test_helpers::sample_batch_certificate_with_previous_certificates( + current_round, + rng, + ); + + // Initialize the committee. + let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( + committee_round, + vec![ + certificates[0].author(), + certificates[1].author(), + certificates[2].author(), + certificates[3].author(), + ], + rng, + ); + + // Initialize the ledger. + let ledger = Arc::new(MockLedgerService::new(committee.clone())); + + // Initialize the storage. + let transmissions = Arc::new(BFTMemoryService::new()); + let storage = Storage::new(ledger.clone(), transmissions, max_gc_rounds); + // Insert the certificates into the storage. + for certificate in certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + + // Get the leader certificate. + let leader = committee.get_leader(commit_round).unwrap(); + let leader_certificate = storage.get_certificate_for_round_with_author(commit_round, leader).unwrap(); + + // Initialize the BFT. + let account = Account::new(rng)?; + let bft = BFT::new(account, storage.clone(), ledger, None, &[], None)?; + // Insert a mock DAG in the BFT. + *bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(commit_round); + + // Ensure that the `gc_round` has not been updated yet. + assert_eq!(bft.storage().gc_round(), committee_round.saturating_sub(max_gc_rounds)); + + // Insert the certificates into the BFT. + for certificate in certificates { + assert!(bft.update_dag::(certificate).await.is_ok()); + } + + // Commit the leader certificate. + bft.commit_leader_certificate::(leader_certificate, Default::default()).await.unwrap(); + + // Ensure that the `gc_round` has been updated. + assert_eq!(bft.storage().gc_round(), commit_round - max_gc_rounds); + + Ok(()) + } } From f161cf6189b349a8badf94a70cbbaf99cbfedbf4 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:59:44 -0800 Subject: [PATCH 30/40] Add test for sync_bft_dag_at_bootup --- node/bft/src/bft.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 75f91009d0..01638b0cca 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1262,4 +1262,93 @@ mod tests { Ok(()) } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_sync_bft_dag_at_bootup() -> Result<()> { + let rng = &mut TestRng::default(); + + // Initialize the round parameters. + let max_gc_rounds = 1; + let committee_round = 0; + let commit_round = 2; + let current_round = commit_round + 1; + + // Sample the current certificate and previous certificates. + let (_, certificates) = snarkvm::ledger::narwhal::batch_certificate::test_helpers::sample_batch_certificate_with_previous_certificates( + current_round, + rng, + ); + + // Initialize the committee. + let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( + committee_round, + vec![ + certificates[0].author(), + certificates[1].author(), + certificates[2].author(), + certificates[3].author(), + ], + rng, + ); + + // Initialize the ledger. + let ledger = Arc::new(MockLedgerService::new(committee.clone())); + + // Initialize the storage. + let storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); + // Insert the certificates into the storage. + for certificate in certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + + // Get the leader certificate. + let leader = committee.get_leader(commit_round).unwrap(); + let leader_certificate = storage.get_certificate_for_round_with_author(commit_round, leader).unwrap(); + + // Initialize the BFT. + let account = Account::new(rng)?; + let bft = BFT::new(account.clone(), storage, ledger.clone(), None, &[], None)?; + + // Insert a mock DAG in the BFT. + *bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(commit_round); + + // Insert the previous certificates into the BFT. + for certificate in certificates.clone() { + assert!(bft.update_dag::(certificate).await.is_ok()); + } + + // Commit the leader certificate. + bft.commit_leader_certificate::(leader_certificate.clone()).await.unwrap(); + + // Simulate a bootup of the BFT. + + // Initialize a new instance of storage. + let storage_2 = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); + // Initialize a new instance of BFT. + let bootup_bft = BFT::new(account, storage_2, ledger, None, &[], None)?; + + // Sync the BFT DAG at bootup. + bootup_bft.sync_bft_dag_at_bootup(certificates.clone()).await; + + // Check that the BFT starts from the same last committed round. + assert_eq!(bft.dag.read().last_committed_round(), bootup_bft.dag.read().last_committed_round()); + + // Ensure that both BFTs have committed the leader certificate. + assert!(bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); + assert!(bootup_bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); + + // Check the state of the bootup BFT. + for certificate in certificates { + let certificate_round = certificate.round(); + let certificate_id = certificate.id(); + // Check that the bootup BFT has committed the certificates. + assert!(bootup_bft.dag.read().is_recently_committed(certificate_round, certificate_id)); + // Check that the bootup BFT does not contain the certificates in its graph, because + // it should not need to order them again in subsequent subdags. + assert!(!bootup_bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); + } + + Ok(()) + } } From d30e763a0ac32a5502d1a7ec3e820dff728a886d Mon Sep 17 00:00:00 2001 From: mdelle1 <108158289+mdelle1@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:54:11 -0500 Subject: [PATCH 31/40] Adds unit test for pre and post shutdown bft sync --- node/bft/src/bft.rs | 204 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 01638b0cca..06266c5a77 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1351,4 +1351,208 @@ mod tests { Ok(()) } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_sync_bft_dag_at_bootup_shutdown() -> Result<()> { + + /* + BFT bootup unit test - + 1. Run one uninterrupted BFT on a set of certificates for 2 leader commits. + 2. Run a separate bootup BFT that syncs with a set of pre shutdown certificates, and then commits a second leader normally over a set of post shutdown certificates. + 3. Observe that the uninterrupted BFT and the bootup BFT end in the same state. + */ + + use snarkvm::console::{ + account::PrivateKey, + account::Address, + }; + use indexmap::{IndexMap, IndexSet}; + + let rng = &mut TestRng::default(); + + // Initialize the round parameters. + let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let committee_round = 0; + let commit_round = 2; + let current_round = commit_round + 1; + let next_round = current_round + 1; + + // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. + let (round_to_certificates_map, committee) = { + let private_keys = vec![ + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap() + ]; + let addresses = vec![ + Address::try_from(private_keys[0])?, + Address::try_from(private_keys[1])?, + Address::try_from(private_keys[2])?, + Address::try_from(private_keys[3])?, + ]; + let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( + committee_round, + addresses, + rng, + ); + // Initialize a mapping from the round number to the set of batch certificates in the round. + let mut round_to_certificates_map: IndexMap>> = IndexMap::new(); + let mut previous_certificates = IndexSet::with_capacity(4); + // Initialize the genesis batch certificates. + for _ in 0..4 { + previous_certificates.insert(sample_batch_certificate(rng)); + } + for round in 0..commit_round+3 { + let mut current_certificates = IndexSet::new(); + let previous_certificate_ids: IndexSet<_> = if round == 0 || round == 1 { + IndexSet::new() + } else { + previous_certificates.iter().map(|c| c.id()).collect() + }; + let transmission_ids = snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng).into_iter().collect::>(); + let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); + let committee_id = committee.id(); + for i in 0..4 { + let batch_header = snarkvm::ledger::narwhal::BatchHeader::new(&private_keys[i], round, timestamp, committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), rng).unwrap(); + let mut signatures = IndexSet::with_capacity(4); + for j in 0..4 { + if i != j { + signatures.insert(private_keys[j].sign(&[batch_header.batch_id()], rng).unwrap()); + } + } + let certificate = snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); + current_certificates.insert(certificate); + } + // Update the mapping. + round_to_certificates_map.insert(round, current_certificates.clone()); + previous_certificates = current_certificates.clone(); + } + (round_to_certificates_map, committee) + }; + + // Initialize the ledger. + let ledger = Arc::new(MockLedgerService::new(committee.clone())); + // Initialize the storage. + let storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); + // Get the leaders for the next 2 commit rounds. + let leader = committee.get_leader(commit_round).unwrap(); + let next_leader = committee.get_leader(next_round).unwrap(); + // Insert the pre shutdown certificates into the storage. + let mut pre_shutdown_certificates: Vec> = Vec::new(); + for i in 1..=commit_round { + let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); + if i == commit_round { // Only insert the leader certificate for the commit round. + let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader).clone(); + if let Some(c) = leader_certificate{ + pre_shutdown_certificates.push(c.clone()); + } + continue; + } + pre_shutdown_certificates.extend(certificates); + } + for certificate in pre_shutdown_certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + // Insert the post shutdown certificates into the storage. + let mut post_shutdown_certificates: Vec> = Vec::new(); + for j in commit_round..=commit_round+2 { + let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); + post_shutdown_certificates.extend(certificate); + } + for certificate in post_shutdown_certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + // Get the leader certificates. + let leader_certificate = storage.get_certificate_for_round_with_author(commit_round, leader).unwrap(); + let next_leader_certificate = storage.get_certificate_for_round_with_author(next_round, next_leader).unwrap(); + + // Initialize the BFT without bootup. + let account = Account::new(rng)?; + let bft = BFT::new(account.clone(), storage, ledger.clone(), None, &[], None)?; + + // Insert a mock DAG in the BFT without bootup. + *bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(0); + + // Insert the certificates into the BFT without bootup. + for certificate in pre_shutdown_certificates.clone() { + assert!(bft.update_dag::(certificate).await.is_ok()); + } + + // Insert the post shutdown certificates into the BFT without bootup. + for certificate in post_shutdown_certificates.clone() { + assert!(bft.update_dag::(certificate).await.is_ok()); + } + // Commit the second leader certificate. + let commit_subdag = bft.order_dag_with_dfs::(next_leader_certificate.clone()).unwrap(); + let commit_subdag_metadata = commit_subdag.iter().map(|(round, c)| (*round, c.len())).collect::>(); + bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); + + // Simulate a bootup of the BFT. + + // Initialize a new instance of storage. + let bootup_storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); + + // Initialize a new instance of BFT with bootup. + let bootup_bft = BFT::new(account, bootup_storage.clone(), ledger.clone(), None, &[], None)?; + + // Sync the BFT DAG at bootup. + bootup_bft.sync_bft_dag_at_bootup(pre_shutdown_certificates.clone()).await; + + // Insert the post shutdown certificates to the storage and BFT with bootup. + for certificate in post_shutdown_certificates.iter() { + bootup_bft.storage().testing_only_insert_certificate_testing_only(certificate.clone()); + } + for certificate in post_shutdown_certificates.clone() { + assert!(bootup_bft.update_dag::(certificate).await.is_ok()); + } + // Commit the second leader certificate. + let commit_subdag_bootup = bootup_bft.order_dag_with_dfs::(next_leader_certificate.clone()).unwrap(); + let commit_subdag_metadata_bootup = commit_subdag_bootup.iter().map(|(round, c)| (*round, c.len())).collect::>(); + let committed_certificates_bootup = commit_subdag_bootup.values().flatten(); + bootup_bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); + + // Check that the final state of both BFTs is the same. + + // Check that both BFTs start from the same last committed round. + assert_eq!(bft.dag.read().last_committed_round(), bootup_bft.dag.read().last_committed_round()); + + // Ensure that both BFTs have committed the leader certificates. + assert!(bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); + assert!(bft.dag.read().is_recently_committed(next_leader_certificate.round(), next_leader_certificate.id())); + assert!(bootup_bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); + assert!(bootup_bft.dag.read().is_recently_committed(next_leader_certificate.round(), next_leader_certificate.id())); + + // Check that the bootup BFT has committed the pre shutdown certificates. + for certificate in pre_shutdown_certificates.clone() { + let certificate_round = certificate.round(); + let certificate_id = certificate.id(); + // Check that both BFTs have committed the certificates. + assert!(bft.dag.read().is_recently_committed(certificate_round, certificate_id)); + assert!(bootup_bft.dag.read().is_recently_committed(certificate_round, certificate_id)); + // Check that the bootup BFT does not contain the certificates in its graph, because + // it should not need to order them again in subsequent subdags. + assert!(!bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); + assert!(!bootup_bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); + } + + // Check that that the bootup BFT has committed the subdag stemming from the second leader certificate in consensus. + for certificate in committed_certificates_bootup.clone() { + let certificate_round = certificate.round(); + let certificate_id = certificate.id(); + // Check that the both BFTs have committed the certificates. + assert!(bft.dag.read().is_recently_committed(certificate_round, certificate_id)); + assert!(bootup_bft.dag.read().is_recently_committed(certificate_round, certificate_id)); + // Check that the bootup BFT does not contain the certificates in its graph, because + // it should not need to order them again in subsequent subdags. + assert!(!bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); + assert!(!bootup_bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); + } + + // Check that the commit subdag metadata for the second leader is the same for both BFTs. + assert_eq!(commit_subdag_metadata_bootup, commit_subdag_metadata); + + Ok(()) + } } From fbfe152c3f31afbd44f02df8548ca227987e1efd Mon Sep 17 00:00:00 2001 From: mdelle1 <108158289+mdelle1@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:00:07 -0500 Subject: [PATCH 32/40] Adds unit test for duplicate vertices in commit subdags after bft sync --- node/bft/src/bft.rs | 141 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 06266c5a77..5f3ede4d19 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1555,4 +1555,145 @@ mod tests { Ok(()) } + + #[tokio::test] + #[tracing_test::traced_test] + async fn test_sync_bft_dag_at_bootup_dfs() -> Result<()> { + + /* + BFT bootup unit test - + 1. Run a bootup BFT that syncs with a set of pre shutdown certificates. + 2. Add post shutdown certificates to the bootup BFT. + 2. Observe that in the commit subdag of the second leader certificate, there are no repeated vertices from the pre shutdown certificates. + */ + + use snarkvm::console::{ + account::PrivateKey, + account::Address, + }; + use indexmap::{IndexMap, IndexSet}; + + let rng = &mut TestRng::default(); + + // Initialize the round parameters. + let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let committee_round = 0; + let commit_round = 2; + let current_round = commit_round + 1; + let next_round = current_round + 1; + + // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. + let (round_to_certificates_map, committee) = { + let private_keys = vec![ + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap() + ]; + let addresses = vec![ + Address::try_from(private_keys[0])?, + Address::try_from(private_keys[1])?, + Address::try_from(private_keys[2])?, + Address::try_from(private_keys[3])?, + ]; + let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( + committee_round, + addresses, + rng, + ); + // Initialize a mapping from the round number to the set of batch certificates in the round. + let mut round_to_certificates_map: IndexMap>> = IndexMap::new(); + let mut previous_certificates = IndexSet::with_capacity(4); + // Initialize the genesis batch certificates. + for _ in 0..4 { + previous_certificates.insert(sample_batch_certificate(rng)); + } + for round in 0..=commit_round+2 { + let mut current_certificates = IndexSet::new(); + let previous_certificate_ids: IndexSet<_> = if round == 0 || round == 1 { + IndexSet::new() + } else { + previous_certificates.iter().map(|c| c.id()).collect() + }; + let transmission_ids = snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng).into_iter().collect::>(); + let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); + let committee_id = committee.id(); + for i in 0..4 { + let batch_header = snarkvm::ledger::narwhal::BatchHeader::new(&private_keys[i], round, timestamp, committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), rng).unwrap(); + let mut signatures = IndexSet::with_capacity(4); + for j in 0..4 { + if i != j { + signatures.insert(private_keys[j].sign(&[batch_header.batch_id()], rng).unwrap()); + } + } + let certificate = snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); + current_certificates.insert(certificate); + } + // Update the mapping. + round_to_certificates_map.insert(round, current_certificates.clone()); + previous_certificates = current_certificates.clone(); + } + (round_to_certificates_map, committee) + }; + + // Initialize the ledger. + let ledger = Arc::new(MockLedgerService::new(committee.clone())); + // Initialize the storage. + let storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); + // Get the leaders for the next 2 commit rounds. + let leader = committee.get_leader(commit_round).unwrap(); + let next_leader = committee.get_leader(next_round).unwrap(); + // Insert the pre shutdown certificates into the storage. + let mut pre_shutdown_certificates: Vec> = Vec::new(); + for i in 1..=commit_round { + let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); + if i == commit_round { // Only insert the leader certificate for the commit round. + let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader).clone(); + if let Some(c) = leader_certificate{ + pre_shutdown_certificates.push(c.clone()); + } + continue; + } + pre_shutdown_certificates.extend(certificates); + } + for certificate in pre_shutdown_certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + // Initialize the bootup BFT. + let account = Account::new(rng)?; + let bootup_bft = BFT::new(account.clone(), storage.clone(), ledger.clone(), None, &[], None)?; + // Insert a mock DAG in the BFT without bootup. + *bootup_bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(0); + // Sync the BFT DAG at bootup. + bootup_bft.sync_bft_dag_at_bootup(pre_shutdown_certificates.clone()).await; + + // Insert the post shutdown certificates into the storage. + let mut post_shutdown_certificates: Vec> = Vec::new(); + for j in commit_round..=commit_round+2 { + let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); + post_shutdown_certificates.extend(certificate); + } + for certificate in post_shutdown_certificates.iter() { + storage.testing_only_insert_certificate_testing_only(certificate.clone()); + } + + // Insert the post shutdown certificates into the DAG. + for certificate in post_shutdown_certificates.clone() { + assert!(bootup_bft.update_dag::(certificate).await.is_ok()); + } + + // Get the next leader certificate to commit. + let next_leader_certificate = storage.get_certificate_for_round_with_author(next_round, next_leader).unwrap(); + let commit_subdag = bootup_bft.order_dag_with_dfs::(next_leader_certificate).unwrap(); + let committed_certificates = commit_subdag.values().flatten(); + + // Check that none of the certificates synced from the bootup appear in the subdag for the next commit round. + for pre_shutdown_certificate in pre_shutdown_certificates.clone() { + for committed_certificate in committed_certificates.clone(){ + assert_ne!(pre_shutdown_certificate.id(), committed_certificate.id()); + } + } + Ok(()) + + } } From 8e21015619b4fcddd900a991a07ca0964c3d1091 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:11:06 -0800 Subject: [PATCH 33/40] clippy --- node/bft/src/bft.rs | 296 ++++++++++++++++++++++++-------------------- 1 file changed, 163 insertions(+), 133 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 5f3ede4d19..9e78ca21a0 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1355,79 +1355,91 @@ mod tests { #[tokio::test] #[tracing_test::traced_test] async fn test_sync_bft_dag_at_bootup_shutdown() -> Result<()> { - - /* - BFT bootup unit test - + /* + BFT bootup unit test - 1. Run one uninterrupted BFT on a set of certificates for 2 leader commits. - 2. Run a separate bootup BFT that syncs with a set of pre shutdown certificates, and then commits a second leader normally over a set of post shutdown certificates. - 3. Observe that the uninterrupted BFT and the bootup BFT end in the same state. + 2. Run a separate bootup BFT that syncs with a set of pre shutdown certificates, and then commits a second leader normally over a set of post shutdown certificates. + 3. Observe that the uninterrupted BFT and the bootup BFT end in the same state. */ - use snarkvm::console::{ - account::PrivateKey, - account::Address, - }; use indexmap::{IndexMap, IndexSet}; + use snarkvm::console::account::{Address, PrivateKey}; let rng = &mut TestRng::default(); // Initialize the round parameters. - let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; let committee_round = 0; let commit_round = 2; let current_round = commit_round + 1; - let next_round = current_round + 1; + let next_round = current_round + 1; - // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. + // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. let (round_to_certificates_map, committee) = { let private_keys = vec![ - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap() - ]; + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + ]; let addresses = vec![ - Address::try_from(private_keys[0])?, + Address::try_from(private_keys[0])?, Address::try_from(private_keys[1])?, Address::try_from(private_keys[2])?, Address::try_from(private_keys[3])?, - ]; + ]; let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( committee_round, - addresses, + addresses, rng, ); - // Initialize a mapping from the round number to the set of batch certificates in the round. - let mut round_to_certificates_map: IndexMap>> = IndexMap::new(); + // Initialize a mapping from the round number to the set of batch certificates in the round. + let mut round_to_certificates_map: IndexMap< + u64, + IndexSet>, + > = IndexMap::new(); let mut previous_certificates = IndexSet::with_capacity(4); - // Initialize the genesis batch certificates. + // Initialize the genesis batch certificates. for _ in 0..4 { previous_certificates.insert(sample_batch_certificate(rng)); } - for round in 0..commit_round+3 { - let mut current_certificates = IndexSet::new(); + for round in 0..commit_round + 3 { + let mut current_certificates = IndexSet::new(); let previous_certificate_ids: IndexSet<_> = if round == 0 || round == 1 { - IndexSet::new() + IndexSet::new() } else { previous_certificates.iter().map(|c| c.id()).collect() }; - let transmission_ids = snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng).into_iter().collect::>(); + let transmission_ids = + snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng) + .into_iter() + .collect::>(); let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); - let committee_id = committee.id(); - for i in 0..4 { - let batch_header = snarkvm::ledger::narwhal::BatchHeader::new(&private_keys[i], round, timestamp, committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), rng).unwrap(); + let committee_id = committee.id(); + for (i, private_key_1) in private_keys.iter().enumerate() { + let batch_header = snarkvm::ledger::narwhal::BatchHeader::new( + private_key_1, + round, + timestamp, + committee_id, + transmission_ids.clone(), + previous_certificate_ids.clone(), + rng, + ) + .unwrap(); let mut signatures = IndexSet::with_capacity(4); - for j in 0..4 { + for (j, private_key_2) in private_keys.iter().enumerate() { if i != j { - signatures.insert(private_keys[j].sign(&[batch_header.batch_id()], rng).unwrap()); + signatures.insert(private_key_2.sign(&[batch_header.batch_id()], rng).unwrap()); } } - let certificate = snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); - current_certificates.insert(certificate); + let certificate = + snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); + current_certificates.insert(certificate); } - // Update the mapping. - round_to_certificates_map.insert(round, current_certificates.clone()); - previous_certificates = current_certificates.clone(); + // Update the mapping. + round_to_certificates_map.insert(round, current_certificates.clone()); + previous_certificates = current_certificates.clone(); } (round_to_certificates_map, committee) }; @@ -1436,42 +1448,44 @@ mod tests { let ledger = Arc::new(MockLedgerService::new(committee.clone())); // Initialize the storage. let storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); - // Get the leaders for the next 2 commit rounds. + // Get the leaders for the next 2 commit rounds. let leader = committee.get_leader(commit_round).unwrap(); - let next_leader = committee.get_leader(next_round).unwrap(); - // Insert the pre shutdown certificates into the storage. + let next_leader = committee.get_leader(next_round).unwrap(); + // Insert the pre shutdown certificates into the storage. let mut pre_shutdown_certificates: Vec> = Vec::new(); - for i in 1..=commit_round { - let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); - if i == commit_round { // Only insert the leader certificate for the commit round. - let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader).clone(); - if let Some(c) = leader_certificate{ - pre_shutdown_certificates.push(c.clone()); + for i in 1..=commit_round { + let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); + if i == commit_round { + // Only insert the leader certificate for the commit round. + let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader); + if let Some(c) = leader_certificate { + pre_shutdown_certificates.push(c.clone()); } - continue; + continue; } - pre_shutdown_certificates.extend(certificates); + pre_shutdown_certificates.extend(certificates); } for certificate in pre_shutdown_certificates.iter() { storage.testing_only_insert_certificate_testing_only(certificate.clone()); } - // Insert the post shutdown certificates into the storage. - let mut post_shutdown_certificates: Vec> = Vec::new(); - for j in commit_round..=commit_round+2 { - let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); - post_shutdown_certificates.extend(certificate); + // Insert the post shutdown certificates into the storage. + let mut post_shutdown_certificates: Vec> = + Vec::new(); + for j in commit_round..=commit_round + 2 { + let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); + post_shutdown_certificates.extend(certificate); } for certificate in post_shutdown_certificates.iter() { storage.testing_only_insert_certificate_testing_only(certificate.clone()); } - // Get the leader certificates. + // Get the leader certificates. let leader_certificate = storage.get_certificate_for_round_with_author(commit_round, leader).unwrap(); let next_leader_certificate = storage.get_certificate_for_round_with_author(next_round, next_leader).unwrap(); - - // Initialize the BFT without bootup. + + // Initialize the BFT without bootup. let account = Account::new(rng)?; let bft = BFT::new(account.clone(), storage, ledger.clone(), None, &[], None)?; - + // Insert a mock DAG in the BFT without bootup. *bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(0); @@ -1484,7 +1498,7 @@ mod tests { for certificate in post_shutdown_certificates.clone() { assert!(bft.update_dag::(certificate).await.is_ok()); } - // Commit the second leader certificate. + // Commit the second leader certificate. let commit_subdag = bft.order_dag_with_dfs::(next_leader_certificate.clone()).unwrap(); let commit_subdag_metadata = commit_subdag.iter().map(|(round, c)| (*round, c.len())).collect::>(); bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); @@ -1493,38 +1507,41 @@ mod tests { // Initialize a new instance of storage. let bootup_storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); - - // Initialize a new instance of BFT with bootup. + + // Initialize a new instance of BFT with bootup. let bootup_bft = BFT::new(account, bootup_storage.clone(), ledger.clone(), None, &[], None)?; - // Sync the BFT DAG at bootup. + // Sync the BFT DAG at bootup. bootup_bft.sync_bft_dag_at_bootup(pre_shutdown_certificates.clone()).await; - // Insert the post shutdown certificates to the storage and BFT with bootup. + // Insert the post shutdown certificates to the storage and BFT with bootup. for certificate in post_shutdown_certificates.iter() { bootup_bft.storage().testing_only_insert_certificate_testing_only(certificate.clone()); } for certificate in post_shutdown_certificates.clone() { assert!(bootup_bft.update_dag::(certificate).await.is_ok()); } - // Commit the second leader certificate. + // Commit the second leader certificate. let commit_subdag_bootup = bootup_bft.order_dag_with_dfs::(next_leader_certificate.clone()).unwrap(); - let commit_subdag_metadata_bootup = commit_subdag_bootup.iter().map(|(round, c)| (*round, c.len())).collect::>(); + let commit_subdag_metadata_bootup = + commit_subdag_bootup.iter().map(|(round, c)| (*round, c.len())).collect::>(); let committed_certificates_bootup = commit_subdag_bootup.values().flatten(); bootup_bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); - // Check that the final state of both BFTs is the same. + // Check that the final state of both BFTs is the same. // Check that both BFTs start from the same last committed round. assert_eq!(bft.dag.read().last_committed_round(), bootup_bft.dag.read().last_committed_round()); - // Ensure that both BFTs have committed the leader certificates. + // Ensure that both BFTs have committed the leader certificates. assert!(bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); assert!(bft.dag.read().is_recently_committed(next_leader_certificate.round(), next_leader_certificate.id())); assert!(bootup_bft.dag.read().is_recently_committed(leader_certificate.round(), leader_certificate.id())); - assert!(bootup_bft.dag.read().is_recently_committed(next_leader_certificate.round(), next_leader_certificate.id())); + assert!( + bootup_bft.dag.read().is_recently_committed(next_leader_certificate.round(), next_leader_certificate.id()) + ); - // Check that the bootup BFT has committed the pre shutdown certificates. + // Check that the bootup BFT has committed the pre shutdown certificates. for certificate in pre_shutdown_certificates.clone() { let certificate_round = certificate.round(); let certificate_id = certificate.id(); @@ -1537,7 +1554,7 @@ mod tests { assert!(!bootup_bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); } - // Check that that the bootup BFT has committed the subdag stemming from the second leader certificate in consensus. + // Check that that the bootup BFT has committed the subdag stemming from the second leader certificate in consensus. for certificate in committed_certificates_bootup.clone() { let certificate_round = certificate.round(); let certificate_id = certificate.id(); @@ -1550,7 +1567,7 @@ mod tests { assert!(!bootup_bft.dag.read().contains_certificate_in_round(certificate_round, certificate_id)); } - // Check that the commit subdag metadata for the second leader is the same for both BFTs. + // Check that the commit subdag metadata for the second leader is the same for both BFTs. assert_eq!(commit_subdag_metadata_bootup, commit_subdag_metadata); Ok(()) @@ -1559,79 +1576,91 @@ mod tests { #[tokio::test] #[tracing_test::traced_test] async fn test_sync_bft_dag_at_bootup_dfs() -> Result<()> { - - /* - BFT bootup unit test - - 1. Run a bootup BFT that syncs with a set of pre shutdown certificates. - 2. Add post shutdown certificates to the bootup BFT. - 2. Observe that in the commit subdag of the second leader certificate, there are no repeated vertices from the pre shutdown certificates. + /* + BFT bootup unit test - + 1. Run a bootup BFT that syncs with a set of pre shutdown certificates. + 2. Add post shutdown certificates to the bootup BFT. + 2. Observe that in the commit subdag of the second leader certificate, there are no repeated vertices from the pre shutdown certificates. */ - use snarkvm::console::{ - account::PrivateKey, - account::Address, - }; use indexmap::{IndexMap, IndexSet}; + use snarkvm::console::account::{Address, PrivateKey}; let rng = &mut TestRng::default(); // Initialize the round parameters. - let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; let committee_round = 0; let commit_round = 2; let current_round = commit_round + 1; - let next_round = current_round + 1; + let next_round = current_round + 1; - // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. + // Sample 5 rounds of batch certificates starting at the genesis round from a static set of 4 authors. let (round_to_certificates_map, committee) = { let private_keys = vec![ - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap(), - PrivateKey::new(rng).unwrap() - ]; + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + PrivateKey::new(rng).unwrap(), + ]; let addresses = vec![ - Address::try_from(private_keys[0])?, + Address::try_from(private_keys[0])?, Address::try_from(private_keys[1])?, Address::try_from(private_keys[2])?, Address::try_from(private_keys[3])?, - ]; + ]; let committee = snarkvm::ledger::committee::test_helpers::sample_committee_for_round_and_members( committee_round, - addresses, + addresses, rng, ); - // Initialize a mapping from the round number to the set of batch certificates in the round. - let mut round_to_certificates_map: IndexMap>> = IndexMap::new(); + // Initialize a mapping from the round number to the set of batch certificates in the round. + let mut round_to_certificates_map: IndexMap< + u64, + IndexSet>, + > = IndexMap::new(); let mut previous_certificates = IndexSet::with_capacity(4); - // Initialize the genesis batch certificates. + // Initialize the genesis batch certificates. for _ in 0..4 { previous_certificates.insert(sample_batch_certificate(rng)); } - for round in 0..=commit_round+2 { - let mut current_certificates = IndexSet::new(); + for round in 0..=commit_round + 2 { + let mut current_certificates = IndexSet::new(); let previous_certificate_ids: IndexSet<_> = if round == 0 || round == 1 { - IndexSet::new() + IndexSet::new() } else { previous_certificates.iter().map(|c| c.id()).collect() }; - let transmission_ids = snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng).into_iter().collect::>(); + let transmission_ids = + snarkvm::ledger::narwhal::transmission_id::test_helpers::sample_transmission_ids(rng) + .into_iter() + .collect::>(); let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); - let committee_id = committee.id(); - for i in 0..4 { - let batch_header = snarkvm::ledger::narwhal::BatchHeader::new(&private_keys[i], round, timestamp, committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), rng).unwrap(); + let committee_id = committee.id(); + for (i, private_key_1) in private_keys.iter().enumerate() { + let batch_header = snarkvm::ledger::narwhal::BatchHeader::new( + private_key_1, + round, + timestamp, + committee_id, + transmission_ids.clone(), + previous_certificate_ids.clone(), + rng, + ) + .unwrap(); let mut signatures = IndexSet::with_capacity(4); - for j in 0..4 { + for (j, private_key_2) in private_keys.iter().enumerate() { if i != j { - signatures.insert(private_keys[j].sign(&[batch_header.batch_id()], rng).unwrap()); + signatures.insert(private_key_2.sign(&[batch_header.batch_id()], rng).unwrap()); } } - let certificate = snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); - current_certificates.insert(certificate); + let certificate = + snarkvm::ledger::narwhal::BatchCertificate::from(batch_header, signatures).unwrap(); + current_certificates.insert(certificate); } - // Update the mapping. - round_to_certificates_map.insert(round, current_certificates.clone()); - previous_certificates = current_certificates.clone(); + // Update the mapping. + round_to_certificates_map.insert(round, current_certificates.clone()); + previous_certificates = current_certificates.clone(); } (round_to_certificates_map, committee) }; @@ -1640,60 +1669,61 @@ mod tests { let ledger = Arc::new(MockLedgerService::new(committee.clone())); // Initialize the storage. let storage = Storage::new(ledger.clone(), Arc::new(BFTMemoryService::new()), max_gc_rounds); - // Get the leaders for the next 2 commit rounds. - let leader = committee.get_leader(commit_round).unwrap(); - let next_leader = committee.get_leader(next_round).unwrap(); - // Insert the pre shutdown certificates into the storage. + // Get the leaders for the next 2 commit rounds. + let leader = committee.get_leader(commit_round).unwrap(); + let next_leader = committee.get_leader(next_round).unwrap(); + // Insert the pre shutdown certificates into the storage. let mut pre_shutdown_certificates: Vec> = Vec::new(); - for i in 1..=commit_round { - let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); - if i == commit_round { // Only insert the leader certificate for the commit round. - let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader).clone(); - if let Some(c) = leader_certificate{ - pre_shutdown_certificates.push(c.clone()); + for i in 1..=commit_round { + let certificates = (*round_to_certificates_map.get(&i).unwrap()).clone(); + if i == commit_round { + // Only insert the leader certificate for the commit round. + let leader_certificate = certificates.iter().find(|certificate| certificate.author() == leader); + if let Some(c) = leader_certificate { + pre_shutdown_certificates.push(c.clone()); } - continue; + continue; } - pre_shutdown_certificates.extend(certificates); + pre_shutdown_certificates.extend(certificates); } for certificate in pre_shutdown_certificates.iter() { storage.testing_only_insert_certificate_testing_only(certificate.clone()); } - // Initialize the bootup BFT. + // Initialize the bootup BFT. let account = Account::new(rng)?; let bootup_bft = BFT::new(account.clone(), storage.clone(), ledger.clone(), None, &[], None)?; // Insert a mock DAG in the BFT without bootup. *bootup_bft.dag.write() = crate::helpers::dag::test_helpers::mock_dag_with_modified_last_committed_round(0); - // Sync the BFT DAG at bootup. + // Sync the BFT DAG at bootup. bootup_bft.sync_bft_dag_at_bootup(pre_shutdown_certificates.clone()).await; - // Insert the post shutdown certificates into the storage. - let mut post_shutdown_certificates: Vec> = Vec::new(); - for j in commit_round..=commit_round+2 { - let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); - post_shutdown_certificates.extend(certificate); + // Insert the post shutdown certificates into the storage. + let mut post_shutdown_certificates: Vec> = + Vec::new(); + for j in commit_round..=commit_round + 2 { + let certificate = (*round_to_certificates_map.get(&j).unwrap()).clone(); + post_shutdown_certificates.extend(certificate); } for certificate in post_shutdown_certificates.iter() { storage.testing_only_insert_certificate_testing_only(certificate.clone()); } - // Insert the post shutdown certificates into the DAG. + // Insert the post shutdown certificates into the DAG. for certificate in post_shutdown_certificates.clone() { assert!(bootup_bft.update_dag::(certificate).await.is_ok()); } - - // Get the next leader certificate to commit. + + // Get the next leader certificate to commit. let next_leader_certificate = storage.get_certificate_for_round_with_author(next_round, next_leader).unwrap(); let commit_subdag = bootup_bft.order_dag_with_dfs::(next_leader_certificate).unwrap(); let committed_certificates = commit_subdag.values().flatten(); // Check that none of the certificates synced from the bootup appear in the subdag for the next commit round. - for pre_shutdown_certificate in pre_shutdown_certificates.clone() { - for committed_certificate in committed_certificates.clone(){ + for pre_shutdown_certificate in pre_shutdown_certificates.clone() { + for committed_certificate in committed_certificates.clone() { assert_ne!(pre_shutdown_certificate.id(), committed_certificate.id()); } } Ok(()) - } } From 183b25d3e64a30dea9eb7b4a44e0ae1eab3d7be3 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:37:10 -0800 Subject: [PATCH 34/40] nit --- node/bft/src/bft.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 9e78ca21a0..04713d9492 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -833,6 +833,7 @@ mod tests { use snarkos_node_bft_ledger_service::MockLedgerService; use snarkos_node_bft_storage_service::BFTMemoryService; use snarkvm::{ + console::account::{Address, PrivateKey}, ledger::{ committee::Committee, narwhal::batch_certificate::test_helpers::{sample_batch_certificate, sample_batch_certificate_for_round}, @@ -841,7 +842,7 @@ mod tests { }; use anyhow::Result; - use indexmap::IndexSet; + use indexmap::{IndexMap, IndexSet}; use std::sync::{atomic::Ordering, Arc}; type CurrentNetwork = snarkvm::console::network::Testnet3; @@ -1361,9 +1362,7 @@ mod tests { 2. Run a separate bootup BFT that syncs with a set of pre shutdown certificates, and then commits a second leader normally over a set of post shutdown certificates. 3. Observe that the uninterrupted BFT and the bootup BFT end in the same state. */ - use indexmap::{IndexMap, IndexSet}; - use snarkvm::console::account::{Address, PrivateKey}; let rng = &mut TestRng::default(); @@ -1583,9 +1582,6 @@ mod tests { 2. Observe that in the commit subdag of the second leader certificate, there are no repeated vertices from the pre shutdown certificates. */ - use indexmap::{IndexMap, IndexSet}; - use snarkvm::console::account::{Address, PrivateKey}; - let rng = &mut TestRng::default(); // Initialize the round parameters. From 345681c578a804fb5e04d7c20927d1fb7067050d Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:34:08 -0800 Subject: [PATCH 35/40] nit --- node/bft/src/bft.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 04713d9492..b95a325109 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1357,12 +1357,10 @@ mod tests { #[tracing_test::traced_test] async fn test_sync_bft_dag_at_bootup_shutdown() -> Result<()> { /* - BFT bootup unit test - 1. Run one uninterrupted BFT on a set of certificates for 2 leader commits. 2. Run a separate bootup BFT that syncs with a set of pre shutdown certificates, and then commits a second leader normally over a set of post shutdown certificates. 3. Observe that the uninterrupted BFT and the bootup BFT end in the same state. */ - use indexmap::{IndexMap, IndexSet}; let rng = &mut TestRng::default(); @@ -1576,7 +1574,6 @@ mod tests { #[tracing_test::traced_test] async fn test_sync_bft_dag_at_bootup_dfs() -> Result<()> { /* - BFT bootup unit test - 1. Run a bootup BFT that syncs with a set of pre shutdown certificates. 2. Add post shutdown certificates to the bootup BFT. 2. Observe that in the commit subdag of the second leader certificate, there are no repeated vertices from the pre shutdown certificates. From 843da3ea963df067f3794af4538043f94ad3081b Mon Sep 17 00:00:00 2001 From: Raymond Chu <14917648+raychu86@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:33:07 -0800 Subject: [PATCH 36/40] Update node/bft/src/bft.rs Co-authored-by: Howard Wu <9260812+howardwu@users.noreply.github.com> Signed-off-by: Raymond Chu <14917648+raychu86@users.noreply.github.com> --- node/bft/src/bft.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index b95a325109..eb31b51e24 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -792,10 +792,9 @@ impl BFT { /// Syncs the BFT DAG with the given batch certificates. These batch certificates **must** /// already exist in the ledger. /// - /// This method commits all the certificates into the dag. + /// This method commits all the certificates into the DAG. /// Note that there is no need to insert the certificates into the DAG, because these certificates - /// already exist in the ledger and therefor do not need to be re-ordered into future - /// committed subdags. + /// already exist in the ledger and therefore do not need to be re-ordered into future committed subdags. async fn sync_bft_dag_at_bootup(&self, certificates: Vec>) { // Acquire the BFT write lock. let mut dag = self.dag.write(); From c9a499bafc1b2859ddeb26179b4886db4170398c Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sat, 23 Mar 2024 14:37:35 -0700 Subject: [PATCH 37/40] nit: fix interface --- Cargo.lock | 116 ++++++++++++++++++++++---------------------- node/bft/src/bft.rs | 19 ++++---- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e2977f723..5c1631a709 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3527,7 +3527,7 @@ dependencies = [ [[package]] name = "snarkvm" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "anstyle", "anyhow", @@ -3558,7 +3558,7 @@ dependencies = [ [[package]] name = "snarkvm-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -3588,7 +3588,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-account", "snarkvm-circuit-algorithms", @@ -3602,7 +3602,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-network", @@ -3613,7 +3613,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-types", "snarkvm-console-algorithms", @@ -3623,7 +3623,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-types", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "itertools 0.11.0", @@ -3651,12 +3651,12 @@ dependencies = [ [[package]] name = "snarkvm-circuit-environment-witness" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" [[package]] name = "snarkvm-circuit-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-algorithms", "snarkvm-circuit-collections", @@ -3667,7 +3667,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "paste", "snarkvm-circuit-account", @@ -3682,7 +3682,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-address", @@ -3697,7 +3697,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3710,7 +3710,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-console-types-boolean", @@ -3719,7 +3719,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3729,7 +3729,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3741,7 +3741,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3753,7 +3753,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3764,7 +3764,7 @@ dependencies = [ [[package]] name = "snarkvm-circuit-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-circuit-environment", "snarkvm-circuit-types-boolean", @@ -3776,7 +3776,7 @@ dependencies = [ [[package]] name = "snarkvm-console" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-account", "snarkvm-console-algorithms", @@ -3789,7 +3789,7 @@ dependencies = [ [[package]] name = "snarkvm-console-account" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "bs58", "snarkvm-console-network", @@ -3800,7 +3800,7 @@ dependencies = [ [[package]] name = "snarkvm-console-algorithms" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "blake2s_simd", "smallvec", @@ -3813,7 +3813,7 @@ dependencies = [ [[package]] name = "snarkvm-console-collections" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "rayon", @@ -3824,7 +3824,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "anyhow", "indexmap 2.2.2", @@ -3847,7 +3847,7 @@ dependencies = [ [[package]] name = "snarkvm-console-network-environment" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "anyhow", "bech32", @@ -3865,7 +3865,7 @@ dependencies = [ [[package]] name = "snarkvm-console-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "enum_index", "enum_index_derive", @@ -3886,7 +3886,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-address", @@ -3901,7 +3901,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-address" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3912,7 +3912,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-boolean" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", ] @@ -3920,7 +3920,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-field" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3930,7 +3930,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-group" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3941,7 +3941,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-integers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3952,7 +3952,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-scalar" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3963,7 +3963,7 @@ dependencies = [ [[package]] name = "snarkvm-console-types-string" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console-network-environment", "snarkvm-console-types-boolean", @@ -3974,7 +3974,7 @@ dependencies = [ [[package]] name = "snarkvm-curves" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "rand", "rayon", @@ -3988,7 +3988,7 @@ dependencies = [ [[package]] name = "snarkvm-fields" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4005,7 +4005,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4030,7 +4030,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-authority" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "anyhow", "rand", @@ -4042,7 +4042,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-block" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4061,7 +4061,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-coinbase" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4081,7 +4081,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-committee" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "anyhow", "indexmap 2.2.2", @@ -4098,7 +4098,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-ledger-narwhal-batch-certificate", "snarkvm-ledger-narwhal-batch-header", @@ -4111,7 +4111,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-certificate" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4124,7 +4124,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-batch-header" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "serde_json", @@ -4136,7 +4136,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-data" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "bytes", "serde_json", @@ -4147,7 +4147,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-subdag" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "rayon", @@ -4161,7 +4161,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "bytes", "serde_json", @@ -4174,7 +4174,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-narwhal-transmission-id" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "snarkvm-console", "snarkvm-ledger-coinbase", @@ -4183,7 +4183,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-query" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "async-trait", "reqwest", @@ -4196,7 +4196,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-store" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std-storage", "anyhow", @@ -4221,7 +4221,7 @@ dependencies = [ [[package]] name = "snarkvm-ledger-test-helpers" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "once_cell", "snarkvm-circuit", @@ -4236,7 +4236,7 @@ dependencies = [ [[package]] name = "snarkvm-metrics" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "metrics", "metrics-exporter-prometheus", @@ -4245,7 +4245,7 @@ dependencies = [ [[package]] name = "snarkvm-parameters" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4270,7 +4270,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4296,7 +4296,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-process" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "colored", @@ -4319,7 +4319,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-program" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "indexmap 2.2.2", "paste", @@ -4333,7 +4333,7 @@ dependencies = [ [[package]] name = "snarkvm-synthesizer-snark" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "bincode", "once_cell", @@ -4346,7 +4346,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "aleo-std", "anyhow", @@ -4367,7 +4367,7 @@ dependencies = [ [[package]] name = "snarkvm-utilities-derives" version = "0.16.19" -source = "git+https://github.com/AleoHQ/snarkVM.git?rev=f3779c9#f3779c958b3516bca453c23c92caebe33d925b1d" +source = "git+https://github.com/AleoHQ/snarkVM.git?rev=94d1135#94d113519b90441172d4caab022b622535b3bb3a" dependencies = [ "proc-macro2", "quote 1.0.35", diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index eb31b51e24..0710d8c93b 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1319,7 +1319,7 @@ mod tests { } // Commit the leader certificate. - bft.commit_leader_certificate::(leader_certificate.clone()).await.unwrap(); + bft.commit_leader_certificate::(leader_certificate.clone(), Default::default()).await.unwrap(); // Simulate a bootup of the BFT. @@ -1364,7 +1364,7 @@ mod tests { let rng = &mut TestRng::default(); // Initialize the round parameters. - let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let max_gc_rounds = crate::MAX_GC_ROUNDS; let committee_round = 0; let commit_round = 2; let current_round = commit_round + 1; @@ -1411,15 +1411,14 @@ mod tests { .into_iter() .collect::>(); let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); - let committee_id = committee.id(); for (i, private_key_1) in private_keys.iter().enumerate() { let batch_header = snarkvm::ledger::narwhal::BatchHeader::new( private_key_1, round, timestamp, - committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), + Default::default(), rng, ) .unwrap(); @@ -1497,7 +1496,7 @@ mod tests { // Commit the second leader certificate. let commit_subdag = bft.order_dag_with_dfs::(next_leader_certificate.clone()).unwrap(); let commit_subdag_metadata = commit_subdag.iter().map(|(round, c)| (*round, c.len())).collect::>(); - bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); + bft.commit_leader_certificate::(next_leader_certificate.clone(), Default::default()).await.unwrap(); // Simulate a bootup of the BFT. @@ -1522,7 +1521,10 @@ mod tests { let commit_subdag_metadata_bootup = commit_subdag_bootup.iter().map(|(round, c)| (*round, c.len())).collect::>(); let committed_certificates_bootup = commit_subdag_bootup.values().flatten(); - bootup_bft.commit_leader_certificate::(next_leader_certificate.clone()).await.unwrap(); + bootup_bft + .commit_leader_certificate::(next_leader_certificate.clone(), Default::default()) + .await + .unwrap(); // Check that the final state of both BFTs is the same. @@ -1581,7 +1583,7 @@ mod tests { let rng = &mut TestRng::default(); // Initialize the round parameters. - let max_gc_rounds = snarkvm::ledger::narwhal::BatchHeader::::MAX_GC_ROUNDS as u64; + let max_gc_rounds = crate::MAX_GC_ROUNDS; let committee_round = 0; let commit_round = 2; let current_round = commit_round + 1; @@ -1628,15 +1630,14 @@ mod tests { .into_iter() .collect::>(); let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); - let committee_id = committee.id(); for (i, private_key_1) in private_keys.iter().enumerate() { let batch_header = snarkvm::ledger::narwhal::BatchHeader::new( private_key_1, round, timestamp, - committee_id, transmission_ids.clone(), previous_certificate_ids.clone(), + Default::default(), rng, ) .unwrap(); From 0f599ef8380a6080a11e10bb3da3a2db7e1e16ee Mon Sep 17 00:00:00 2001 From: mdelle1 <108158289+mdelle1@users.noreply.github.com> Date: Sun, 24 Mar 2024 14:08:18 -0400 Subject: [PATCH 38/40] Updates bft unit test for garbage collection --- node/bft/src/bft.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index 0710d8c93b..c605f38eba 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1205,11 +1205,11 @@ mod tests { let max_gc_rounds = 1; let committee_round = 0; let commit_round = 2; - let current_round = commit_round + 1; + let next_round = commit_round + 1; // Sample the certificates. let (_, certificates) = snarkvm::ledger::narwhal::batch_certificate::test_helpers::sample_batch_certificate_with_previous_certificates( - current_round, + next_round, rng, ); @@ -1257,8 +1257,11 @@ mod tests { // Commit the leader certificate. bft.commit_leader_certificate::(leader_certificate, Default::default()).await.unwrap(); + // Increment the BFT to the next round. + let _next_round = bft.storage().increment_to_next_round(commit_round); + // Ensure that the `gc_round` has been updated. - assert_eq!(bft.storage().gc_round(), commit_round - max_gc_rounds); + assert_eq!(bft.storage().gc_round(), next_round - max_gc_rounds); Ok(()) } From 1031c79e452d0c89de1b386259c22fc0522bbfa4 Mon Sep 17 00:00:00 2001 From: mdelle1 <108158289+mdelle1@users.noreply.github.com> Date: Sun, 24 Mar 2024 14:11:27 -0400 Subject: [PATCH 39/40] Updates block sync redundancy factor for unit tests --- node/sync/src/block_sync.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/sync/src/block_sync.rs b/node/sync/src/block_sync.rs index 7fe509f4f0..497d66adb8 100644 --- a/node/sync/src/block_sync.rs +++ b/node/sync/src/block_sync.rs @@ -36,7 +36,10 @@ use std::{ time::Instant, }; +#[cfg(not(test))] pub const REDUNDANCY_FACTOR: usize = 1; +#[cfg(test)] +pub const REDUNDANCY_FACTOR: usize = 3; const EXTRA_REDUNDANCY_FACTOR: usize = REDUNDANCY_FACTOR * 3; const NUM_SYNC_CANDIDATE_PEERS: usize = REDUNDANCY_FACTOR * 5; From ae6d79c8e4f99a9b08150a8178cc15cdf3ec0863 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Sun, 24 Mar 2024 13:18:00 -0700 Subject: [PATCH 40/40] Rustfmt --- node/bft/src/bft.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/bft/src/bft.rs b/node/bft/src/bft.rs index c605f38eba..65cce88743 100644 --- a/node/bft/src/bft.rs +++ b/node/bft/src/bft.rs @@ -1258,7 +1258,7 @@ mod tests { bft.commit_leader_certificate::(leader_certificate, Default::default()).await.unwrap(); // Increment the BFT to the next round. - let _next_round = bft.storage().increment_to_next_round(commit_round); + let _next_round = bft.storage().increment_to_next_round(commit_round); // Ensure that the `gc_round` has been updated. assert_eq!(bft.storage().gc_round(), next_round - max_gc_rounds);