Skip to content

Commit

Permalink
Merge pull request #1889 from AleoHQ/feat/unconfirmed_tx_id
Browse files Browse the repository at this point in the history
Add `unconfirmed_id` helper method for `ConfirmedTransaction`s
  • Loading branch information
howardwu authored Aug 16, 2023
2 parents 4dc8be9 + 89397b4 commit 89fcb4c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
36 changes: 36 additions & 0 deletions ledger/block/src/transactions/confirmed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ impl<N: Network> ConfirmedTransaction<N> {
Self::RejectedDeploy(..) | Self::RejectedExecute(..) => None,
}
}

/// Returns the unconfirmed transaction ID, which is defined as the transaction ID prior to confirmation.
/// When a transaction is rejected, its fee transition is used to construct the confirmed transaction ID,
/// changing the original transaction ID.
pub fn unconfirmed_id(&self) -> Result<N::TransactionID> {
match self {
Self::AcceptedDeploy(_, transaction, _) => Ok(transaction.id()),
Self::AcceptedExecute(_, transaction, _) => Ok(transaction.id()),
Self::RejectedDeploy(_, fee_transaction, rejected)
| Self::RejectedExecute(_, fee_transaction, rejected) => {
Ok(rejected.to_unconfirmed_id(&fee_transaction.fee_transition())?.into())
}
}
}
}

impl<N: Network> Deref for ConfirmedTransaction<N> {
Expand Down Expand Up @@ -270,6 +284,7 @@ pub mod test_helpers {
mod test {

use super::*;
use crate::transactions::confirmed::test_helpers;

#[test]
fn test_accepted_execute() {
Expand Down Expand Up @@ -305,4 +320,25 @@ mod test {
let confirmed = ConfirmedTransaction::accepted_execute(index, tx, finalize_operations);
assert!(confirmed.is_err());
}

#[test]
fn test_unconfirmed_transaction_ids() {
let rng = &mut TestRng::default();

// Ensure that the unconfirmed transaction ID of an accepted deployment is equivalent to its confirmed transaction ID.
let accepted_deploy = test_helpers::sample_accepted_deploy(Uniform::rand(rng), rng);
assert_eq!(accepted_deploy.unconfirmed_id().unwrap(), accepted_deploy.id());

// Ensure that the unconfirmed transaction ID of an accepted execute is equivalent to its confirmed transaction ID.
let accepted_execution = test_helpers::sample_accepted_execute(Uniform::rand(rng), rng);
assert_eq!(accepted_execution.unconfirmed_id().unwrap(), accepted_execution.id());

// Ensure that the unconfirmed transaction ID of a rejected deployment is not equivalent to its confirmed transaction ID.
let rejected_deploy = test_helpers::sample_rejected_deploy(Uniform::rand(rng), rng);
assert_ne!(rejected_deploy.unconfirmed_id().unwrap(), rejected_deploy.id());

// Ensure that the unconfirmed transaction ID of a rejected execute is not equivalent to its confirmed transaction ID.
let rejected_execution = test_helpers::sample_rejected_execute(Uniform::rand(rng), rng);
assert_ne!(rejected_execution.unconfirmed_id().unwrap(), rejected_execution.id());
}
}
12 changes: 11 additions & 1 deletion ledger/block/src/transactions/rejected/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod string;

use super::*;

use crate::{Deployment, Execution};
use crate::{Deployment, Execution, Fee};

/// A wrapper around the rejected deployment or execution.
#[derive(Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -79,6 +79,16 @@ impl<N: Network> Rejected<N> {
Self::Execution(execution) => execution.to_execution_id(),
}
}

/// Returns the unconfirmed transaction ID, which is defined as the transaction ID prior to confirmation.
/// When a transaction is rejected, its fee transition is used to construct the confirmed transaction ID,
/// changing the original transaction ID.
pub fn to_unconfirmed_id(&self, fee: &Option<Fee<N>>) -> Result<Field<N>> {
match self {
Self::Deployment(_, deployment) => Ok(*Transaction::deployment_tree(deployment, fee.as_ref())?.root()),
Self::Execution(execution) => Ok(*Transaction::execution_tree(execution, fee)?.root()),
}
}
}

#[cfg(test)]
Expand Down
4 changes: 4 additions & 0 deletions ledger/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ finalize failed_assert:
rng,
)
.unwrap();
let failed_assert_transaction_id = failed_assert_transaction.id();

// Construct the next block containing the new transaction.
let next_block = ledger
Expand All @@ -273,6 +274,9 @@ finalize failed_assert:
assert_eq!(confirmed_transaction, &expected_confirmed_transaction);
}

// Check that the unconfirmed transaction ID of the rejected execution is correct.
assert_eq!(confirmed_transaction.unconfirmed_id().unwrap(), failed_assert_transaction_id);

// Check that the next block is valid.
ledger.check_next_block(&next_block).unwrap();

Expand Down
4 changes: 4 additions & 0 deletions synthesizer/src/vm/finalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ finalize transfer_public:

// Fetch a deployment transaction.
let deployment_transaction = crate::vm::test_helpers::sample_deployment_transaction(rng);
let deployment_transaction_id = deployment_transaction.id();

// Construct the program name.
let program_id = ProgramID::from_str("testing.aleo").unwrap();
Expand Down Expand Up @@ -820,6 +821,9 @@ finalize transfer_public:
vm.atomic_speculate(sample_finalize_state(1), &[], None, [deployment_transaction].iter()).unwrap();
assert_eq!(candidate_transactions.len(), 1);
assert!(matches!(candidate_transactions[0], ConfirmedTransaction::RejectedDeploy(..)));

// Check that the unconfirmed transaction id of the rejected deployment is correct.
assert_eq!(candidate_transactions[0].unconfirmed_id().unwrap(), deployment_transaction_id);
}

#[test]
Expand Down

0 comments on commit 89fcb4c

Please sign in to comment.