Skip to content

Commit

Permalink
Fix error in Colored Coin transfer transaction without TPC transfer w…
Browse files Browse the repository at this point in the history
…hen TPC funds are low and no change output is needed.
  • Loading branch information
rantan committed Aug 13, 2024
1 parent 1d2476b commit 33e6cd5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
6 changes: 3 additions & 3 deletions crates/wallet/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,9 +1821,7 @@ impl Wallet {
}
});

if (color_id.is_default() && outgoings.len() > 1)
|| (params.drain_to.is_some() && (params.drain_wallet || utxo_exists))
{
if (params.drain_to.is_some() && (params.drain_wallet || utxo_exists)) {
if let NoChange {
dust_threshold,
remaining_amount,
Expand All @@ -1840,6 +1838,8 @@ impl Wallet {
available,
}));
}
} else if (color_id.is_default() && outgoings.len() > 1) {
// We have colored coin outputs but no TPC output
} else {
return Err(CreateTxError::NoRecipients);
}
Expand Down
66 changes: 66 additions & 0 deletions crates/wallet/tests/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,72 @@ fn test_create_tx_with_reissuable() {
assert_eq!(sent_received, (Amount::from_tap(100), Amount::from_tap(2)));
}

#[test]
fn test_create_tx_with_reissuable_no_tpc_change() {
let change_desc = "pkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)";
let (mut wallet, txid, color_id) =
get_funded_wallet_with_reissuable_and_change(get_test_pkh(), change_desc);
let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
.unwrap()
.assume_checked();

// Transfer all remaining funds, leaving a balance slightly greater than the dust limit 600 tapyrus.
let receive_address = wallet.peek_address(KeychainKind::External, 0).address;
let tx = Transaction {
version: transaction::Version::ONE,
lock_time: tapyrus::absolute::LockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint { txid, vout: 1 },
script_sig: Default::default(),
sequence: Default::default(),
witness: Default::default(),
}],
output: vec![
TxOut {
value: Amount::from_tap(600),
script_pubkey: receive_address.script_pubkey(),
},
TxOut {
value: Amount::from_tap(48_400),
script_pubkey: addr.script_pubkey(),
},
],
};
wallet
.insert_checkpoint(BlockId {
height: 3_000,
hash: BlockHash::all_zeros(),
})
.unwrap();
wallet
.insert_tx(
tx.clone(),
ConfirmationTime::Confirmed {
height: 3_000,
time: 300,
},
)
.unwrap();

let mut builder = wallet.build_tx();
builder.add_recipient_with_color(addr.script_pubkey(), Amount::from_tap(98), color_id);
let psbt = builder.finish().unwrap();

let fee = check_fee!(wallet, psbt);
let feerate = FeeRate::from_tap_per_kwu(250); // 1 sat/vb
assert_fee_rate!(psbt, fee.unwrap_or(Amount::ZERO), feerate, @add_signature);

// colored coin sending output and colored coin change output
assert_eq!(psbt.unsigned_tx.output.len(), 2);
assert_eq!(psbt.unsigned_tx.input.len(), 2);

let sent_received = wallet.sent_and_received(
&psbt.clone().extract_tx().expect("failed to extract tx"),
&color_id,
);
assert_eq!(sent_received, (Amount::from_tap(100), Amount::from_tap(2)));
}

#[test]
fn test_create_tx_multi_colored_coin_recipients() {
let change_desc = "pkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)";
Expand Down

0 comments on commit 33e6cd5

Please sign in to comment.