From f83d18b4a8e63c1850ab6df065b77a00c5d54985 Mon Sep 17 00:00:00 2001 From: raychu86 <14917648+raychu86@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:11:51 -0700 Subject: [PATCH] Move tx verification logic into check_speculate --- ledger/src/check_next_block.rs | 14 ++------------ synthesizer/src/vm/finalize.rs | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ledger/src/check_next_block.rs b/ledger/src/check_next_block.rs index c23797f8d4..ffb6213299 100644 --- a/ledger/src/check_next_block.rs +++ b/ledger/src/check_next_block.rs @@ -14,8 +14,6 @@ use super::*; -use rand::{rngs::StdRng, SeedableRng}; - impl> Ledger { /// Checks the given block is valid next block. pub fn check_next_block(&self, block: &Block, rng: &mut R) -> Result<()> { @@ -38,14 +36,6 @@ impl> Ledger { } } - // Ensure each transaction is well-formed and unique. - let transactions = block.transactions(); - let rngs = (0..transactions.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); - cfg_iter!(transactions).zip(rngs).try_for_each(|(transaction, mut rng)| { - self.check_transaction_basic(transaction, transaction.to_rejected_id()?, &mut rng) - .map_err(|e| anyhow!("Invalid transaction found in the transactions list: {e}")) - })?; - // TODO (howardwu): Remove this after moving the total supply into credits.aleo. { // // Retrieve the latest total supply. @@ -78,9 +68,9 @@ impl> Ledger { block.previous_hash(), )?; - // Ensure speculation over the unconfirmed transactions is correct. + // Ensure speculation over the unconfirmed transactions is correct and ensure each transaction is well-formed and unique. let ratified_finalize_operations = - self.vm.check_speculate(state, block.ratifications(), block.solutions(), block.transactions())?; + self.vm.check_speculate(state, block.ratifications(), block.solutions(), block.transactions(), rng)?; // Retrieve the committee lookback. let committee_lookback = { diff --git a/synthesizer/src/vm/finalize.rs b/synthesizer/src/vm/finalize.rs index a66a6f8065..216b8d13fb 100644 --- a/synthesizer/src/vm/finalize.rs +++ b/synthesizer/src/vm/finalize.rs @@ -20,6 +20,8 @@ use rand::{rngs::StdRng, SeedableRng}; impl> VM { /// Speculates on the given list of transactions in the VM. + /// This function aborts all transactions that are not are well-formed or unique. + /// /// /// Returns the confirmed transactions, aborted transaction IDs, /// and finalize operations from pre-ratify and post-ratify. @@ -111,18 +113,30 @@ impl> VM { } /// Checks the speculation on the given transactions in the VM. + /// This function also ensure that the given transactions are well-formed and unique. /// /// Returns the finalize operations from pre-ratify and post-ratify. #[inline] - pub fn check_speculate( + pub fn check_speculate( &self, state: FinalizeGlobalState, ratifications: &Ratifications, solutions: &Solutions, transactions: &Transactions, + rng: &mut R, ) -> Result>> { let timer = timer!("VM::check_speculate"); + // Ensure each transaction is well-formed and unique. + // NOTE: We perform the transaction checks here prior to `atomic_speculate` because we must + // ensure that the `Fee` transactions are valid. We can't unify the transaction checks in `atomic_speculate` + // because we run speculation on the unconfirmed variant of the transactions. + let rngs = (0..transactions.len()).map(|_| StdRng::from_seed(rng.gen())).collect::>(); + cfg_iter!(transactions).zip(rngs).try_for_each(|(transaction, mut rng)| { + self.check_transaction(transaction, transaction.to_rejected_id()?, &mut rng) + .map_err(|e| anyhow!("Invalid transaction found in the transactions list: {e}")) + })?; + // Reconstruct the candidate ratifications to verify the speculation. let candidate_ratifications = ratifications.iter().cloned().collect::>(); // Reconstruct the unconfirmed transactions to verify the speculation.