Skip to content

Commit e26cf5e

Browse files
committed
feat(utxo-locking): Add tests for utxo locking
-add test for locking, unlocking and listing locked utxos
1 parent d3dde30 commit e26cf5e

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

tests/integration/online.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,92 @@ mod test_online {
965965
String::from_utf8_lossy(&out.stderr)
966966
);
967967
}
968+
969+
// lock → list → unlock cycle.
970+
#[test]
971+
fn test_lock_unlock_and_list_utxos() {
972+
let (cli, mut cmd_init, env) = setup_online_wallet();
973+
cmd_init.assert().success();
974+
fund_and_sync_wallet(&cli, &env);
975+
976+
let unspent = run_wallet_json(&cli, &["unspent"]);
977+
let outpoint = unspent["items"][0]["outpoint"]
978+
.as_str()
979+
.expect("one utxo")
980+
.to_string();
981+
982+
let locked = run_wallet_json(&cli, &["lock_utxo", "--utxo", &outpoint]);
983+
assert_eq!(locked["count"].as_u64(), Some(1), "lock output: {locked}");
984+
985+
// separate process — must still be locked (persistence)
986+
let listed = run_wallet_json(&cli, &["locked_utxos"]);
987+
assert_eq!(
988+
listed["count"].as_u64(),
989+
Some(1),
990+
"lock must persist across processes: {listed}"
991+
);
992+
assert!(
993+
listed["items"]
994+
.as_array()
995+
.unwrap()
996+
.iter()
997+
.any(|i| i.as_str() == Some(outpoint.as_str())),
998+
"locked_utxos should list {outpoint}: {listed}"
999+
);
1000+
1001+
let after = run_wallet_json(&cli, &["unlock_utxo", "--utxo", &outpoint]);
1002+
assert_eq!(
1003+
after["count"].as_u64(),
1004+
Some(0),
1005+
"unlock should clear it: {after}"
1006+
);
1007+
let final_list = run_wallet_json(&cli, &["locked_utxos"]);
1008+
assert_eq!(
1009+
final_list["count"].as_u64(),
1010+
Some(0),
1011+
"empty after unlock: {final_list}"
1012+
);
1013+
}
1014+
1015+
// a locked UTXO is excluded from coin selection.
1016+
#[test]
1017+
fn test_locked_utxo_excluded_from_coin_selection() {
1018+
let (cli, mut cmd_init, env) = setup_online_wallet();
1019+
cmd_init.assert().success();
1020+
fund_and_sync_wallet(&cli, &env);
1021+
1022+
let unspent = run_wallet_json(&cli, &["unspent"]);
1023+
let outpoint = unspent["items"][0]["outpoint"]
1024+
.as_str()
1025+
.unwrap()
1026+
.to_string();
1027+
1028+
run_wallet_json(&cli, &["lock_utxo", "--utxo", &outpoint]);
1029+
1030+
// only UTXO is locked → create_tx must fail
1031+
let out = cli
1032+
.wallet_cmd(&[
1033+
"--wallet",
1034+
WALLET_NAME,
1035+
"create_tx",
1036+
"--to",
1037+
&format!("{RECIPIENT}:20000"),
1038+
])
1039+
.output()
1040+
.unwrap();
1041+
assert!(
1042+
!out.status.success(),
1043+
"create_tx must fail when the only UTXO is locked"
1044+
);
1045+
1046+
// unlock → create_tx succeeds
1047+
run_wallet_json(&cli, &["unlock_utxo", "--utxo", &outpoint]);
1048+
let psbt = run_wallet_json(&cli, &["create_tx", "--to", &format!("{RECIPIENT}:20000")]);
1049+
assert!(
1050+
psbt["psbt"].as_str().is_some(),
1051+
"create_tx should succeed after unlock: {psbt}"
1052+
);
1053+
}
9681054
}
9691055

9701056
#[cfg(feature = "esplora")]

0 commit comments

Comments
 (0)