Skip to content

Commit

Permalink
Merge pull request #378 from phklive/script-naming
Browse files Browse the repository at this point in the history
Split test code, fix assertions and follow idiomatic test naming
  • Loading branch information
bobbinth authored Dec 21, 2023
2 parents d901d51 + c2dbca7 commit d935e85
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ fn test_faucet_contract_mint_fungible_asset_succeeds() {
.unwrap();

let created_note = transaction_result.created_notes().notes()[0].clone();
assert!(created_note.recipient() == expected_note.recipient());
assert!(created_note.vault() == expected_note.vault());
assert!(created_note.metadata() == expected_note.metadata());
assert_eq!(created_note.recipient(), expected_note.recipient());
assert_eq!(created_note.vault(), expected_note.vault());
assert_eq!(created_note.metadata(), expected_note.metadata());
}

#[test]
Expand Down Expand Up @@ -162,13 +162,13 @@ fn test_faucet_contract_burn_fungible_asset_succeeds() {
let fungible_asset = FungibleAsset::new(faucet_account.id(), 100).unwrap();

// check that max_supply (slot 1) is 200 and amount already issued (slot 255) is 100
assert!(
faucet_account.storage().get_item(1)
== [Felt::new(200), Felt::new(0), Felt::new(0), Felt::new(0)].into()
assert_eq!(
faucet_account.storage().get_item(1),
[Felt::new(200), Felt::new(0), Felt::new(0), Felt::new(0)].into()
);
assert!(
faucet_account.storage().get_item(FAUCET_STORAGE_DATA_SLOT)
== [Felt::new(0), Felt::new(0), Felt::new(0), Felt::new(100)].into()
assert_eq!(
faucet_account.storage().get_item(FAUCET_STORAGE_DATA_SLOT),
[Felt::new(0), Felt::new(0), Felt::new(0), Felt::new(100)].into()
);

// need to create a note with the fungible asset to be burned
Expand Down Expand Up @@ -245,12 +245,12 @@ fn test_faucet_contract_creation() {
.unwrap();

// check that max_supply (slot 1) is 123
assert!(
faucet_account.storage().get_item(1)
== [Felt::new(123), Felt::new(2), TokenSymbol::from(token_symbol).into(), ZERO].into()
assert_eq!(
faucet_account.storage().get_item(1),
[Felt::new(123), Felt::new(2), TokenSymbol::from(token_symbol).into(), ZERO].into()
);

assert!(faucet_account.is_faucet() == true);
assert_eq!(faucet_account.is_faucet(), true);

let exp_faucet_account_code_src =
include_str!("../../miden-lib/asm/miden/faucets/basic_fungible.masm");
Expand All @@ -260,7 +260,7 @@ fn test_faucet_contract_creation() {
let exp_faucet_account_code =
AccountCode::new(exp_faucet_account_code_ast.clone(), &mut account_assembler).unwrap();

assert!(faucet_account.code() == &exp_faucet_account_code);
assert_eq!(faucet_account.code(), &exp_faucet_account_code);
}

fn get_faucet_account_with_max_supply_and_total_issuance(
Expand Down
267 changes: 267 additions & 0 deletions miden-tx/tests/p2id_script_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
use miden_lib::notes::{create_note, Script};
use miden_objects::{
accounts::{Account, AccountId, AccountVault},
assembly::ProgramAst,
assets::{Asset, FungibleAsset},
utils::collections::Vec,
Felt,
};
use miden_tx::TransactionExecutor;
use mock::constants::{
ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2,
ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER,
};

mod common;
use common::{
get_account_with_default_account_code, get_new_key_pair_with_advice_map, MockDataStore,
};

// P2ID TESTS
// ===============================================================================================
// We test the Pay to ID script. So we create a note that can only be consumed by the target
// account.
#[test]
fn test_p2id_script() {
// Create assets
let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap();
let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into();

// Create sender and target account
let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap();

let target_account_id =
AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap();
let (target_pub_key, target_sk_pk_felt) = get_new_key_pair_with_advice_map();
let target_account =
get_account_with_default_account_code(target_account_id, target_pub_key.clone(), None);

// Create the note
let p2id_script = Script::P2ID {
target: target_account_id,
};
let note = create_note(
p2id_script,
vec![fungible_asset],
sender_account_id,
None,
[Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)],
)
.unwrap();

// CONSTRUCT AND EXECUTE TX (Success)
// --------------------------------------------------------------------------------------------
let data_store =
MockDataStore::with_existing(Some(target_account.clone()), Some(vec![note.clone()]), None);

let mut executor = TransactionExecutor::new(data_store.clone());
executor.load_account(target_account_id).unwrap();

let block_ref = data_store.block_header.block_num();
let note_origins =
data_store.notes.iter().map(|note| note.origin().clone()).collect::<Vec<_>>();

let tx_script_code = ProgramAst::parse(
format!(
"
use.miden::auth::basic->auth_tx
begin
call.auth_tx::auth_tx_rpo_falcon512
end
"
)
.as_str(),
)
.unwrap();
let tx_script_target = executor
.compile_tx_script(
tx_script_code.clone(),
vec![(target_pub_key, target_sk_pk_felt)],
vec![],
)
.unwrap();

// Execute the transaction and get the witness
let transaction_result = executor
.execute_transaction(target_account_id, block_ref, &note_origins, Some(tx_script_target))
.unwrap();

// vault delta
let target_account_after: Account = Account::new(
target_account.id(),
AccountVault::new(&vec![fungible_asset]).unwrap(),
target_account.storage().clone(),
target_account.code().clone(),
Felt::new(2),
);
assert_eq!(transaction_result.final_account_hash(), target_account_after.hash());

// CONSTRUCT AND EXECUTE TX (Failure)
// --------------------------------------------------------------------------------------------
// A "malicious" account tries to consume the note, we expect an error

let malicious_account_id =
AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN + 1).unwrap();
let (malicious_pub_key, malicious_keypair_felt) = get_new_key_pair_with_advice_map();
let malicious_account = get_account_with_default_account_code(
malicious_account_id,
malicious_pub_key.clone(),
None,
);

let data_store_malicious_account =
MockDataStore::with_existing(Some(malicious_account), Some(vec![note]), None);
let mut executor_2 = TransactionExecutor::new(data_store_malicious_account.clone());
executor_2.load_account(malicious_account_id).unwrap();
let tx_script_malicious = executor
.compile_tx_script(
tx_script_code,
vec![(malicious_pub_key, malicious_keypair_felt)],
vec![],
)
.unwrap();

let block_ref = data_store_malicious_account.block_header.block_num();
let note_origins = data_store_malicious_account
.notes
.iter()
.map(|note| note.origin().clone())
.collect::<Vec<_>>();

// Execute the transaction and get the witness
let transaction_result_2 = executor_2.execute_transaction(
malicious_account_id,
block_ref,
&note_origins,
Some(tx_script_malicious),
);

// Check that we got the expected result - TransactionExecutorError
assert!(transaction_result_2.is_err());
}

/// We test the Pay to script with 2 assets to test the loop inside the script.
/// So we create a note containing two assets that can only be consumed by the target account.
#[test]
fn test_p2id_script_multiple_assets() {
// Create assets
let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap();
let fungible_asset_1: Asset = FungibleAsset::new(faucet_id, 123).unwrap().into();

let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2).unwrap();
let fungible_asset_2: Asset = FungibleAsset::new(faucet_id_2, 456).unwrap().into();

// Create sender and target account
let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap();

let target_account_id =
AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap();
let (target_pub_key, target_keypair_felt) = get_new_key_pair_with_advice_map();
let target_account =
get_account_with_default_account_code(target_account_id, target_pub_key.clone(), None);

// Create the note
let p2id_script = Script::P2ID {
target: target_account_id,
};
let note = create_note(
p2id_script,
vec![fungible_asset_1, fungible_asset_2],
sender_account_id,
None,
[Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)],
)
.unwrap();

// CONSTRUCT AND EXECUTE TX (Success)
// --------------------------------------------------------------------------------------------
let data_store =
MockDataStore::with_existing(Some(target_account.clone()), Some(vec![note.clone()]), None);

let mut executor = TransactionExecutor::new(data_store.clone());
executor.load_account(target_account_id).unwrap();

let block_ref = data_store.block_header.block_num();
let note_origins =
data_store.notes.iter().map(|note| note.origin().clone()).collect::<Vec<_>>();

let tx_script_code = ProgramAst::parse(
format!(
"
use.miden::auth::basic->auth_tx
begin
call.auth_tx::auth_tx_rpo_falcon512
end
"
)
.as_str(),
)
.unwrap();
let tx_script_target = executor
.compile_tx_script(
tx_script_code.clone(),
vec![(target_pub_key, target_keypair_felt)],
vec![],
)
.unwrap();

// Execute the transaction and get the witness
let transaction_result = executor
.execute_transaction(target_account_id, block_ref, &note_origins, Some(tx_script_target))
.unwrap();

// vault delta
let target_account_after: Account = Account::new(
target_account.id(),
AccountVault::new(&vec![fungible_asset_1, fungible_asset_2]).unwrap(),
target_account.storage().clone(),
target_account.code().clone(),
Felt::new(2),
);
assert_eq!(transaction_result.final_account_hash(), target_account_after.hash());

// CONSTRUCT AND EXECUTE TX (Failure)
// --------------------------------------------------------------------------------------------
// A "malicious" account tries to consume the note, we expect an error

let malicious_account_id =
AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN + 1).unwrap();
let (malicious_pub_key, malicious_keypair_felt) = get_new_key_pair_with_advice_map();
let malicious_account = get_account_with_default_account_code(
malicious_account_id,
malicious_pub_key.clone(),
None,
);

let data_store_malicious_account =
MockDataStore::with_existing(Some(malicious_account), Some(vec![note]), None);
let mut executor_2 = TransactionExecutor::new(data_store_malicious_account.clone());
executor_2.load_account(malicious_account_id).unwrap();
let tx_script_malicious = executor
.compile_tx_script(
tx_script_code.clone(),
vec![(malicious_pub_key, malicious_keypair_felt)],
vec![],
)
.unwrap();

let block_ref = data_store_malicious_account.block_header.block_num();
let note_origins = data_store_malicious_account
.notes
.iter()
.map(|note| note.origin().clone())
.collect::<Vec<_>>();

// Execute the transaction and get the witness
let transaction_result_2 = executor_2.execute_transaction(
malicious_account_id,
block_ref,
&note_origins,
Some(tx_script_malicious),
);

// Check that we got the expected result - TransactionExecutorError
assert!(transaction_result_2.is_err());
}
Loading

0 comments on commit d935e85

Please sign in to comment.