diff --git a/tests/transfers.rs b/tests/transfers.rs index d949360..e59213c 100644 --- a/tests/transfers.rs +++ b/tests/transfers.rs @@ -444,7 +444,7 @@ fn transfer_loop( } #[test] -fn same_transfer_twice() { +fn rbf_transfer() { initialize(); let mut wlt_1 = get_wallet(&DescriptorType::Wpkh); @@ -464,19 +464,79 @@ fn same_transfer_twice() { wlt_2.close_method(), InvoiceType::Witness, ); - let _ = wlt_1.transfer(invoice.clone(), None, Some(500), None); + let _ = wlt_1.transfer(invoice.clone(), None, Some(500), true, None); // retry with higher fees, TX hasn't been mined let mid_height = get_height(); assert_eq!(initial_height, mid_height); - let _ = wlt_1.transfer(invoice, None, Some(1000), None); + let _ = wlt_1.transfer(invoice, None, Some(1000), true, None); let final_height = get_height(); assert_eq!(initial_height, final_height); resume_mining(); } +#[test] +fn same_transfer_twice_no_update_witnesses() { + initialize(); + + let mut wlt_1 = get_wallet(&DescriptorType::Wpkh); + let mut wlt_2 = get_wallet(&DescriptorType::Wpkh); + + let (contract_id, iface_type_name) = wlt_1.issue_nia(2000, wlt_1.close_method(), None); + + let amount = 100; + let invoice = wlt_2.invoice( + contract_id, + &iface_type_name, + amount, + wlt_2.close_method(), + InvoiceType::Blinded(None), + ); + let _ = wlt_1.transfer(invoice.clone(), None, Some(500), false, None); + + let (consignment, _) = wlt_1.transfer(invoice, None, Some(1000), true, None); + + wlt_2.accept_transfer(consignment, None); + + // this shows duplicated allocations + wlt_2.debug_logs(contract_id, &iface_type_name, AllocationFilter::WalletAll); + + // this fails because the wallet sees 2 allocations instead of 1 + wlt_2.check_allocations( + contract_id, + &iface_type_name, + AssetSchema::Nia, + vec![amount], + false, + ); +} + +#[test] +fn same_transfer_twice_update_witnesses() { + initialize(); + + let mut wlt_1 = get_wallet(&DescriptorType::Wpkh); + let mut wlt_2 = get_wallet(&DescriptorType::Wpkh); + + let (contract_id, iface_type_name) = wlt_1.issue_nia(2000, wlt_1.close_method(), None); + + let invoice = wlt_2.invoice( + contract_id, + &iface_type_name, + 100, + wlt_2.close_method(), + InvoiceType::Blinded(None), + ); + let _ = wlt_1.transfer(invoice.clone(), None, Some(500), false, None); + + wlt_1.update_witnesses(1); + + // this fails with an AbsentValidWitness error + let _ = wlt_1.transfer(invoice, None, Some(1000), true, None); +} + #[test] fn accept_0conf() { initialize(); @@ -495,7 +555,7 @@ fn accept_0conf() { wlt_2.close_method(), InvoiceType::Witness, ); - let (consignment, _) = wlt_1.transfer(invoice.clone(), None, None, None); + let (consignment, _) = wlt_1.transfer(invoice.clone(), None, None, true, None); wlt_2.accept_transfer(consignment.clone(), None); @@ -722,7 +782,7 @@ fn mainnet_wlt_receiving_test_asset() { wlt_2.close_method(), InvoiceType::Blinded(Some(utxo)), ); - let (consignment, tx) = wlt_1.transfer(invoice.clone(), None, Some(500), None); + let (consignment, tx) = wlt_1.transfer(invoice.clone(), None, Some(500), true, None); wlt_1.mine_tx(&tx.txid(), false); match consignment.validate(&wlt_2.get_resolver(), wlt_2.testnet()) { Err((status, _invalid_consignment)) => { diff --git a/tests/utils/helpers.rs b/tests/utils/helpers.rs index 624d4aa..d21869e 100644 --- a/tests/utils/helpers.rs +++ b/tests/utils/helpers.rs @@ -847,6 +847,7 @@ impl TestWallet { invoice: RgbInvoice, sats: Option, fee: Option, + broadcast: bool, report: Option<&Report>, ) -> (Transfer, Tx) { self.sync(); @@ -893,14 +894,17 @@ impl TestWallet { writeln!(file, "\n---\n").unwrap(); serde_yaml::to_writer(&mut file, &psbt).unwrap(); - self.broadcast_tx(&tx); + if broadcast { + self.broadcast_tx(&tx); + } (consignment, tx) } pub fn accept_transfer(&mut self, consignment: Transfer, report: Option<&Report>) { self.sync(); - let resolver = self.get_resolver(); + let mut resolver = self.get_resolver(); + resolver.add_terminals(&consignment); let validate_start = Instant::now(); let validated_consignment = consignment .validate(&resolver, self.testnet()) @@ -1100,7 +1104,7 @@ impl TestWallet { fee: Option, report: Option<&Report>, ) -> (Transfer, Tx) { - let (consignment, tx) = self.transfer(invoice, sats, fee, report); + let (consignment, tx) = self.transfer(invoice, sats, fee, true, report); self.mine_tx(&tx.txid(), false); recv_wlt.accept_transfer(consignment.clone(), report); self.sync();