Skip to content

Commit

Permalink
added proper testing for sorted outputs for BlockVersion version 3 an… (
Browse files Browse the repository at this point in the history
mobilecoinfoundation#2062)

* added proper testing for sorted outputs for BlockVersion version 3 and higher

* linting fix

* linting fix #2

* linting fix #3

* linting fix #4

* linting fix #5

* removed mod crate

Co-authored-by: Eugene Rata <[email protected]>
  • Loading branch information
integral-llc and Eugene Rata authored Jun 1, 2022
1 parent eec47c8 commit fc7936f
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 13 deletions.
59 changes: 55 additions & 4 deletions transaction/core/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,44 @@ pub fn create_transaction_with_amount_and_comparer<
fee: u64,
tombstone_block: BlockIndex,
rng: &mut R,
) -> Tx {
create_transaction_with_amount_and_comparer_and_recipients::<L, R, O>(
block_version,
ledger,
tx_out,
sender,
&[recipient],
value,
fee,
tombstone_block,
rng,
)
}

/// Creates a transaction that sends an arbitrary amount to a single recipient.
///
/// # Arguments:
/// * `ledger` - A ledger containing `tx_out`.
/// * `tx_out` - The TxOut that will be spent.
/// * `sender` - The owner of `tx_out`.
/// * `recipient` - The recipient of the new transaction.
/// * `amount` - Amount to send.
/// * `tombstone_block` - The tombstone block for the new transaction.
/// * `rng` - The randomness used by this function
pub fn create_transaction_with_amount_and_comparer_and_recipients<
L: Ledger,
R: RngCore + CryptoRng,
O: TxOutputsOrdering,
>(
block_version: BlockVersion,
ledger: &mut L,
tx_out: &TxOut,
sender: &AccountKey,
recipients: &[&PublicAddress],
value: u64,
fee: u64,
tombstone_block: BlockIndex,
rng: &mut R,
) -> Tx {
let (sender_amount, _) = tx_out.view_key_match(sender.view_private_key()).unwrap();

Expand Down Expand Up @@ -195,14 +233,27 @@ pub fn create_transaction_with_amount_and_comparer<
transaction_builder.add_input(input_credentials);

let amount = Amount {
value,
value: value / recipients.len() as u64,
token_id: sender_amount.token_id,
};

let rest = value % recipients.len() as u64;

// Output
transaction_builder
.add_output(amount, recipient, rng)
.unwrap();
for (idx, recipient) in recipients.iter().enumerate() {
if idx == 0 && rest != 0 {
let mut dup_amount = amount;
dup_amount.value += rest;
transaction_builder
.add_output(dup_amount, recipient, rng)
.unwrap();
continue;
}

transaction_builder
.add_output(amount, recipient, rng)
.unwrap();
}

// Tombstone block
transaction_builder.set_tombstone_block(tombstone_block);
Expand Down
35 changes: 34 additions & 1 deletion transaction/core/tests/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright (c) 2018-2022 The MobileCoin Foundation

use mc_account_keys::PublicAddress;
use mc_ledger_db::{Ledger, LedgerDB};
use mc_transaction_core::{tx::Tx, BlockVersion};
use mc_transaction_core_test_utils::{
create_ledger, create_transaction, create_transaction_with_amount_and_comparer,
initialize_ledger, AccountKey,
create_transaction_with_amount_and_comparer_and_recipients, initialize_ledger, AccountKey,
};
use mc_transaction_std::{DefaultTxOutputsOrdering, TxOutputsOrdering};
use mc_util_test_helper::{RngType, SeedableRng};
Expand Down Expand Up @@ -74,3 +75,35 @@ pub fn create_test_tx_with_amount_and_comparer<O: TxOutputsOrdering>(

(tx, ledger)
}

#[allow(unused)]
pub fn create_test_tx_with_amount_and_comparer_and_recipients<O: TxOutputsOrdering>(
block_version: BlockVersion,
amount: u64,
fee: u64,
recipients: &[&PublicAddress],
) -> (Tx, LedgerDB) {
let mut rng: RngType = SeedableRng::from_seed([1u8; 32]);
let sender = AccountKey::random(&mut rng);
let mut ledger = create_ledger();
let n_blocks = 1;
initialize_ledger(block_version, &mut ledger, n_blocks, &sender, &mut rng);

// Spend an output from the last block.
let block_contents = ledger.get_block_contents(n_blocks - 1).unwrap();
let tx_out = block_contents.outputs[0].clone();

let tx = create_transaction_with_amount_and_comparer_and_recipients::<_, _, O>(
block_version,
&mut ledger,
&tx_out,
&sender,
recipients,
amount,
fee,
n_blocks + 1,
&mut rng,
);

(tx, ledger)
}
30 changes: 22 additions & 8 deletions transaction/core/tests/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ extern crate alloc;

mod util;

use crate::util::{
create_test_tx, create_test_tx_with_amount,
create_test_tx_with_amount_and_comparer_and_recipients,
};
use alloc::vec::Vec;
use mc_account_keys::AccountKey;
use mc_crypto_keys::{CompressedRistrettoPublic, ReprBytes};
use mc_ledger_db::Ledger;
use mc_transaction_core::{
Expand All @@ -20,7 +25,6 @@ use mc_transaction_core::{
};
use mc_transaction_core_test_utils::{InverseTxOutputsOrdering, INITIALIZE_LEDGER_AMOUNT};
use mc_util_test_helper::get_seeded_rng;
use util::*;

#[test]
// Should return MissingMemo when memos are missing in an output
Expand Down Expand Up @@ -747,21 +751,31 @@ fn test_validate_tombstone_tombstone_block_too_far() {
}
}

// FIXME: This test needs to involve a Tx with more than one output to make
// sense
#[test]
#[ignore]
fn test_global_validate_for_blocks_with_sorted_outputs() {
let mut rng = get_seeded_rng();
let fee = Mob::MINIMUM_FEE + 1;

let recipients = vec![
AccountKey::random(&mut rng).default_subaddress(),
AccountKey::random(&mut rng).default_subaddress(),
AccountKey::random(&mut rng).default_subaddress(),
AccountKey::random(&mut rng).default_subaddress(),
AccountKey::random(&mut rng).default_subaddress(),
];
let recipients_refs = recipients.iter().collect::<Vec<_>>();

for block_version in BlockVersion::iterator() {
// for block version < 3 it doesn't matter
// for >= 3 it shall return an error about unsorted outputs
let (tx, ledger) = create_test_tx_with_amount_and_comparer::<InverseTxOutputsOrdering>(
block_version,
INITIALIZE_LEDGER_AMOUNT - fee,
fee,
);
let (tx, ledger) =
create_test_tx_with_amount_and_comparer_and_recipients::<InverseTxOutputsOrdering>(
block_version,
INITIALIZE_LEDGER_AMOUNT - fee,
fee,
&recipients_refs,
);

let highest_indices = tx.get_membership_proof_highest_indices();
let root_proofs: Vec<TxOutMembershipProof> = ledger
Expand Down

0 comments on commit fc7936f

Please sign in to comment.