From 6353b49771a58829e86656f4690fc98942b1b1cc Mon Sep 17 00:00:00 2001 From: k0k0ne Date: Wed, 18 Sep 2024 12:07:47 +0800 Subject: [PATCH] add check_fungible_history and send_to_oneself tests --- tests/transfers.rs | 99 ++++++++++++++++++++++++++++++++++++++++++ tests/utils/helpers.rs | 85 ++++++++++++++++++++++++++++++++++++ tests/utils/mod.rs | 4 +- 3 files changed, 186 insertions(+), 2 deletions(-) diff --git a/tests/transfers.rs b/tests/transfers.rs index 9daf6ba..38c2c72 100644 --- a/tests/transfers.rs +++ b/tests/transfers.rs @@ -1089,3 +1089,102 @@ fn receive_from_unbroadcasted_transfer_to_blinded() { Failure::SealNoPubWitness(_, _, _) )); } + +#[test] +fn check_fungible_history() { + initialize(); + + let mut wlt_1 = get_wallet(&DescriptorType::Wpkh); + let mut wlt_2 = get_wallet(&DescriptorType::Wpkh); + + let issue_supply = 600; + + let (contract_id, iface_type_name) = wlt_1.issue_nia(issue_supply, wlt_1.close_method(), None); + + wlt_1.debug_contracts(); + wlt_1.debug_history(contract_id, &iface_type_name, false); + + wlt_1.check_history_operation( + &contract_id, + &iface_type_name, + None, + OpDirection::Issued, + issue_supply, + ); + + let amt = 200; + + let (_, tx) = wlt_1.send( + &mut wlt_2, + TransferType::Witness, + contract_id, + &iface_type_name, + amt, + 1000, + None, + ); + let txid = tx.txid(); + + wlt_1.debug_history(contract_id, &iface_type_name, false); + wlt_2.debug_history(contract_id, &iface_type_name, false); + + wlt_1.check_history_operation( + &contract_id, + &iface_type_name, + Some(&txid), + OpDirection::Sent, + amt, + ); + + wlt_2.check_history_operation( + &contract_id, + &iface_type_name, + Some(&txid), + OpDirection::Received, + amt, + ); +} + +#[test] +fn send_to_oneself() { + initialize(); + + let mut wlt = get_wallet(&DescriptorType::Wpkh); + + let issue_supply = 600; + + let (contract_id, iface_type_name) = wlt.issue_nia(issue_supply, wlt.close_method(), None); + + let amt = 200; + + let invoice = wlt.invoice( + contract_id, + &iface_type_name, + amt, + wlt.close_method(), + InvoiceType::Witness, + ); + + let (consignment, tx) = wlt.transfer(invoice.clone(), None, None, true, None); + wlt.mine_tx(&tx.txid(), false); + wlt.accept_transfer(consignment, None); + wlt.sync(); + + wlt.debug_history(contract_id, &iface_type_name, false); + let history = wlt.history(contract_id, &iface_type_name); + // only issue operation is found, because self-transfers should not appear in history + assert_eq!(history.len(), 1); + + wlt.debug_logs( + contract_id, + &iface_type_name.clone(), + AllocationFilter::WalletAll, + ); + wlt.check_allocations( + contract_id, + &iface_type_name, + AssetSchema::Nia, + vec![amt, issue_supply - amt], + true, + ); +} diff --git a/tests/utils/helpers.rs b/tests/utils/helpers.rs index 570f4ac..63f79cc 100644 --- a/tests/utils/helpers.rs +++ b/tests/utils/helpers.rs @@ -1001,6 +1001,19 @@ impl TestWallet { .collect() } + pub fn history(&self, contract_id: ContractId, iface_type_name: &TypeName) -> Vec { + self.wallet + .history(contract_id, iface_type_name.clone()) + .unwrap() + } + + pub fn debug_contracts(&self) { + println!("Contracts:"); + for info in self.wallet.stock().contracts().unwrap() { + println!("{}", info.to_string().replace("\n", "\t")); + } + } + pub fn debug_logs( &self, contract_id: ContractId, @@ -1098,6 +1111,57 @@ impl TestWallet { println!("\nWallet total balance: {} ṩ", bp_runtime.balance()); } + pub fn debug_history( + &self, + contract_id: ContractId, + iface_type_name: &TypeName, + details: bool, + ) { + let mut history = self.history(contract_id, iface_type_name); + history.sort_by_key(|op| op.witness.map(|w| w.ord).unwrap_or(WitnessOrd::Archived)); + if details { + println!("Operation\tValue \tState\t{:78}\tWitness", "Seal"); + } else { + println!("Operation\tValue \t{:78}\tWitness", "Seal"); + } + for ContractOp { + direction, + ty, + opids, + state, + to, + witness, + } in history + { + print!("{:9}\t", direction.to_string()); + if let AllocatedState::Amount(amount) = state { + print!("{: >9}", amount.value()); + } else { + print!("{state:>9}"); + } + if details { + print!("\t{ty}"); + } + println!( + "\t{}\t{}", + to.first().expect("at least one receiver is always present"), + witness + .map(|info| format!("{} ({})", info.id, info.ord)) + .unwrap_or_else(|| s!("~")) + ); + if details { + println!( + "\topid={}", + opids + .iter() + .map(OpId::to_string) + .collect::>() + .join("\n\topid=") + ) + } + } + } + #[allow(clippy::too_many_arguments)] pub fn send( &mut self, @@ -1188,6 +1252,27 @@ impl TestWallet { } } + pub fn check_history_operation( + &self, + contract_id: &ContractId, + iface_type_name: &TypeName, + txid: Option<&Txid>, + direction: OpDirection, + amount: u64, + ) { + let operation = self + .history(*contract_id, iface_type_name) + .into_iter() + .find(|co| { + co.direction == direction + && co + .witness + .map_or(true, |w| Some(w.id.as_reduced_unsafe()) == txid) + }) + .unwrap(); + assert!(matches!(operation.state, AllocatedState::Amount(amt) if amt.value() == amount)); + } + fn _construct_psbt_offchain( &mut self, input_outpoints: Vec<(Outpoint, u64, Terminal)>, diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs index a70f820..7d3837a 100644 --- a/tests/utils/mod.rs +++ b/tests/utils/mod.rs @@ -63,14 +63,14 @@ pub use psbt::{ pub use psrgbt::{RgbExt, RgbInExt, RgbPsbt, TxParams}; pub use rand::RngCore; pub use rgb::{ - interface::AssignmentsFilter, + interface::{AllocatedState, AssignmentsFilter, ContractOp, OpDirection}, invoice::Pay2Vout, persistence::{MemContract, MemContractState, Stock}, resolvers::AnyResolver, stl::ContractTerms, validation::{Failure, ResolveWitness, Scripts, Validity, WitnessResolverError}, vm::{WitnessOrd, WitnessPos, XWitnessTx}, - BlindingFactor, DescriptorRgb, GenesisSeal, GraphSeal, Identity, RgbDescr, RgbKeychain, + BlindingFactor, DescriptorRgb, GenesisSeal, GraphSeal, Identity, OpId, RgbDescr, RgbKeychain, RgbWallet, TapretKey, TransferParams, Transition, WalletProvider, XOutpoint, XWitnessId, }; pub use rgbstd::{