Skip to content

Commit c22b931

Browse files
committed
prioritise unused change addresses for split
1 parent b91e4fc commit c22b931

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

src/cmd/wallet.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,49 @@ pub fn run_split_cmd(wallet: &GunWallet, opt: SplitOpt) -> anyhow::Result<CmdOut
595595

596596
builder.unspendable(already_correct.map(|utxo| utxo.outpoint).collect());
597597

598+
let mut map: HashMap<Script, Vec<Transaction>> = HashMap::new();
599+
for txn in bdk_wallet
600+
.database()
601+
.iter_txs(true)?
602+
.iter()
603+
.flat_map(|tx_details| tx_details.transaction.as_ref())
604+
{
605+
for out in &txn.output {
606+
map.entry(out.script_pubkey.clone())
607+
.and_modify(|v| v.push(txn.clone()))
608+
.or_insert(vec![txn.clone()]);
609+
}
610+
}
611+
598612
match n {
599613
Some(n) => {
600-
for _ in 0..n {
614+
let last_unused_index = bdk_wallet
615+
.get_change_address(AddressIndex::LastUnused)?
616+
.index;
617+
let mut added_recipients = 0;
618+
// Check for unused change addresses up to most recent
619+
for check_used_index in 0..(last_unused_index + 1) {
620+
let check_script_pk = bdk_wallet
621+
.get_change_address(AddressIndex::Peek(check_used_index as u32))?
622+
.address
623+
.script_pubkey();
624+
625+
let used = match map.get(&check_script_pk) {
626+
Some(_) => true,
627+
None => false,
628+
};
629+
630+
// Keep adding unused recipients until we have n
631+
if !used {
632+
builder.add_recipient(check_script_pk, output_size.as_sat());
633+
added_recipients += 1;
634+
if added_recipients == n {
635+
break;
636+
};
637+
}
638+
}
639+
// If we don't have enough unused addresses, fill remaining n-added with new
640+
for _ in 0..(n - added_recipients) {
601641
builder.add_recipient(
602642
bdk_wallet
603643
.get_change_address(AddressIndex::New)?
@@ -613,7 +653,7 @@ pub fn run_split_cmd(wallet: &GunWallet, opt: SplitOpt) -> anyhow::Result<CmdOut
613653
// add one recipient so we at least get one split utxo of the correct size.
614654
.add_recipient(
615655
bdk_wallet
616-
.get_change_address(AddressIndex::New)?
656+
.get_change_address(AddressIndex::LastUnused)?
617657
.address
618658
.script_pubkey(),
619659
output_size.as_sat(),

0 commit comments

Comments
 (0)