Skip to content

Commit 44c9733

Browse files
committed
Reintroduce space output exclusion
1 parent 8731272 commit 44c9733

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

node/src/wallets.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,10 @@ impl RpcWallet {
153153
skip_tx_check: bool,
154154
fee_rate: FeeRate,
155155
) -> anyhow::Result<Vec<TxResponse>> {
156+
let unspendables = wallet.list_spaces_outpoints(state)?;
156157
let tx_events = wallet.get_tx_events(txid)?;
157158
let builder =
158-
wallet.build_fee_bump(txid, fee_rate)?;
159+
wallet.build_fee_bump(unspendables, txid, fee_rate)?;
159160

160161
let psbt = builder.finish()?;
161162
let replacement = wallet.sign(psbt, None)?;
@@ -859,6 +860,7 @@ impl RpcWallet {
859860
}
860861
}
861862

863+
let unspendables = wallet.list_spaces_outpoints(store)?;
862864
let median_time = source.get_median_time()?;
863865
let mut checker = TxChecker::new(store);
864866

@@ -875,8 +877,7 @@ impl RpcWallet {
875877
}
876878
}
877879

878-
879-
let mut tx_iter = builder.build_iter(tx.dust, median_time, wallet, bid_replacement)?;
880+
let mut tx_iter = builder.build_iter(tx.dust, median_time, wallet, unspendables, bid_replacement)?;
880881
let mut result_set = Vec::new();
881882

882883
while let Some(tx_result) = tx_iter.next() {

wallet/src/builder.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub struct BuilderIterator<'a> {
6060
force: bool,
6161
median_time: u64,
6262
confirmed_only: bool,
63+
unspendables: Vec<OutPoint>
6364
}
6465

6566
pub enum BuilderStack {
@@ -324,6 +325,7 @@ impl Builder {
324325
reveals: Option<&Vec<SpaceScriptSigningInfo>>,
325326
space_transfers: Vec<SpaceTransfer>,
326327
coin_transfers: Vec<CoinTransfer>,
328+
unspendables: Vec<OutPoint>,
327329
fee_rate: FeeRate,
328330
dust: Option<Amount>,
329331
confirmed_only: bool,
@@ -359,7 +361,7 @@ impl Builder {
359361
}
360362

361363
let commit_psbt = {
362-
let mut builder = w.build_tx(confirmed_only)?;
364+
let mut builder = w.build_tx(unspendables, confirmed_only)?;
363365
builder.nlocktime(magic_lock_time(median_time));
364366

365367
// handle transfers
@@ -478,9 +480,11 @@ impl Iterator for BuilderIterator<'_> {
478480
Some(&reveals),
479481
params.transfers.clone(),
480482
params.sends.clone(),
483+
self.unspendables.clone(),
481484
self.fee_rate,
482485
self.dust,
483486
self.confirmed_only,
487+
484488
) {
485489
Ok(prep) => prep,
486490
Err(err) => return Some(Err(err)),
@@ -571,6 +575,7 @@ impl Iterator for BuilderIterator<'_> {
571575
self.wallet,
572576
params.clone(),
573577
self.fee_rate,
578+
self.unspendables.clone(),
574579
self.confirmed_only,
575580
self.force,
576581
);
@@ -586,6 +591,7 @@ impl Iterator for BuilderIterator<'_> {
586591
self.wallet,
587592
params,
588593
self.fee_rate,
594+
self.unspendables.clone(),
589595
self.confirmed_only,
590596
self.force,
591597
);
@@ -607,6 +613,7 @@ impl Iterator for BuilderIterator<'_> {
607613
bid.space.clone(),
608614
bid.amount,
609615
self.fee_rate,
616+
self.unspendables.clone(),
610617
self.confirmed_only,
611618
self.force,
612619
);
@@ -692,6 +699,7 @@ impl Builder {
692699
dust: Option<Amount>,
693700
median_time: u64,
694701
wallet: &mut SpacesWallet,
702+
unspendables: Vec<OutPoint>,
695703
confirmed_only: bool,
696704
) -> anyhow::Result<BuilderIterator> {
697705
let fee_rate = self
@@ -799,6 +807,7 @@ impl Builder {
799807
fee_rate,
800808
wallet,
801809
force: self.force,
810+
unspendables,
802811
confirmed_only,
803812
median_time,
804813
})
@@ -809,12 +818,13 @@ impl Builder {
809818
prev: FullSpaceOut,
810819
bid: Amount,
811820
fee_rate: FeeRate,
821+
unspendables: Vec<OutPoint>,
812822
confirmed_only: bool,
813823
force: bool,
814824
) -> anyhow::Result<Transaction> {
815825
let (offer, placeholder) = w.new_bid_psbt(bid, confirmed_only)?;
816826
let bid_psbt = {
817-
let mut builder = w.build_tx(confirmed_only)?;
827+
let mut builder = w.build_tx(unspendables, confirmed_only)?;
818828
builder
819829
.nlocktime(LockTime::Blocks(Height::ZERO))
820830
.set_exact_sequence(BID_PSBT_INPUT_SEQUENCE)
@@ -838,13 +848,14 @@ impl Builder {
838848
w: &mut SpacesWallet,
839849
params: OpenRevealParams,
840850
fee_rate: FeeRate,
851+
unspendables: Vec<OutPoint>,
841852
confirmed_only: bool,
842853
force: bool,
843854
) -> anyhow::Result<Transaction> {
844855
let (offer, placeholder) = w.new_bid_psbt(params.initial_bid, confirmed_only)?;
845856
let mut extra_prevouts = BTreeMap::new();
846857
let open_psbt = {
847-
let mut builder = w.build_tx(confirmed_only)?;
858+
let mut builder = w.build_tx(unspendables, confirmed_only)?;
848859
builder.ordering(TxOrdering::Untouched).add_bid(
849860
None,
850861
offer,
@@ -871,6 +882,7 @@ impl Builder {
871882
w: &mut SpacesWallet,
872883
params: ExecuteParams,
873884
fee_rate: FeeRate,
885+
unspendables: Vec<OutPoint>,
874886
confirmed_only: bool,
875887
_force: bool,
876888
) -> anyhow::Result<(Transaction, usize)> {
@@ -881,7 +893,7 @@ impl Builder {
881893
.internal
882894
.next_unused_address(KeychainKind::Internal)
883895
.script_pubkey();
884-
let mut builder = w.build_tx(confirmed_only)?;
896+
let mut builder = w.build_tx(unspendables, confirmed_only)?;
885897

886898
builder
887899
// Added first to keep an odd number of outputs before adding transfers
@@ -935,7 +947,7 @@ pub struct SelectionOutput {
935947
pub struct SpacesAwareCoinSelection {
936948
pub default_algorithm: DefaultCoinSelectionAlgorithm,
937949
// Exclude outputs
938-
pub exclude_outputs: Vec<SelectionOutput>,
950+
pub exclude_outputs: Vec<OutPoint>,
939951
// Whether to use confirmed only outputs
940952
// to fund the transaction
941953
pub confirmed_only: bool,
@@ -945,7 +957,7 @@ impl SpacesAwareCoinSelection {
945957
// Will skip any outputs with value less than the dust threshold
946958
// to avoid accidentally spending space outputs
947959
pub const DUST_THRESHOLD: Amount = Amount::from_sat(1200);
948-
pub fn new(excluded: Vec<SelectionOutput>, confirmed_only: bool) -> Self {
960+
pub fn new(excluded: Vec<OutPoint>, confirmed_only: bool) -> Self {
949961
Self {
950962
default_algorithm: DefaultCoinSelectionAlgorithm::default(),
951963
exclude_outputs: excluded,
@@ -986,7 +998,7 @@ impl CoinSelectionAlgorithm for SpacesAwareCoinSelection {
986998
&& !self
987999
.exclude_outputs
9881000
.iter()
989-
.any(|o| o.outpoint == weighted_utxo.utxo.outpoint())
1001+
.any(|o| o == &weighted_utxo.utxo.outpoint())
9901002
});
9911003

9921004
let mut result = self.default_algorithm.coin_select(

wallet/src/lib.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{
44
fs,
55
path::PathBuf,
66
};
7-
87
use anyhow::{anyhow, Context};
98
use bdk_wallet::{chain, chain::BlockId, coin_selection::{CoinSelectionAlgorithm, CoinSelectionResult, Excess, InsufficientFunds}, rusqlite::Connection, tx_builder::TxOrdering, AddressInfo, KeychainKind, LocalOutput, PersistedWallet, SignOptions, TxBuilder, Update, Wallet, WalletTx, WeightedUtxo};
109
use bdk_wallet::chain::{ChainPosition, Indexer};
@@ -209,11 +208,6 @@ impl SpacesWallet {
209208
self.internal.get_utxo(outpoint)
210209
}
211210

212-
pub fn build_tx(&mut self, confirmed_only: bool)
213-
-> anyhow::Result<TxBuilder<SpacesAwareCoinSelection>> {
214-
self.create_builder(None, confirmed_only)
215-
}
216-
217211
pub fn next_unused_address(&mut self, keychain_kind: KeychainKind) -> AddressInfo {
218212
self.internal.next_unused_address(keychain_kind)
219213
}
@@ -245,7 +239,22 @@ impl SpacesWallet {
245239
self.internal.calculate_fee(tx)
246240
}
247241

248-
pub fn build_fee_bump(&mut self, txid: Txid, fee_rate: FeeRate) -> anyhow::Result<TxBuilder<'_, SpacesAwareCoinSelection>> {
242+
pub fn build_tx(&mut self, unspendables: Vec<OutPoint>, confirmed_only: bool)
243+
-> anyhow::Result<TxBuilder<SpacesAwareCoinSelection>> {
244+
self.create_builder(unspendables, None, confirmed_only)
245+
}
246+
247+
pub fn list_spaces_outpoints(&self, src: &mut impl DataSource) -> anyhow::Result<Vec<OutPoint>> {
248+
let mut outs = Vec::new();
249+
for unspent in self.list_unspent() {
250+
if src.get_spaceout(&unspent.outpoint)?.and_then(|out| out.space).is_some() {
251+
outs.push(unspent.outpoint);
252+
}
253+
}
254+
Ok(outs)
255+
}
256+
257+
pub fn build_fee_bump(&mut self, unspendables: Vec<OutPoint>, txid: Txid, fee_rate: FeeRate) -> anyhow::Result<TxBuilder<'_, SpacesAwareCoinSelection>> {
249258
let events = self.get_tx_events(txid)?;
250259
for event in events {
251260
match event.kind {
@@ -261,16 +270,18 @@ impl SpacesWallet {
261270
}
262271
}
263272

264-
self.create_builder(Some((txid, fee_rate)), false)
273+
self.create_builder(unspendables, Some((txid, fee_rate)), false)
265274
}
266275

267276
fn create_builder(
268277
&mut self,
278+
unspendables: Vec<OutPoint>,
269279
replace: Option<(Txid, FeeRate)>,
270280
confirmed_only: bool,
271281
) -> anyhow::Result<TxBuilder<'_, SpacesAwareCoinSelection>> {
272-
// TODO: fill excluded
273-
let selection = SpacesAwareCoinSelection::new(vec![], confirmed_only);
282+
let selection = SpacesAwareCoinSelection::new(
283+
unspendables, confirmed_only
284+
);
274285

275286
let mut builder = match replace {
276287
None => {
@@ -437,7 +448,6 @@ impl SpacesWallet {
437448
) -> anyhow::Result<()> {
438449
self.internal
439450
.apply_block_connected_to(&block, height, block_id)?;
440-
441451
Ok(())
442452
}
443453

0 commit comments

Comments
 (0)