Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions examples/anti_fee_sniping.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(dead_code)]
use bdk_testenv::{bitcoincore_rpc::RpcApi, TestEnv};
use bdk_tx::{
filter_unspendable, group_by_spk, selection_algorithm_lowest_fee_bnb, FeeStrategy, Output,
PsbtParams, ScriptSource, SelectorParams,
filter_unspendable, group_by_spk, selection_algorithm_lowest_fee_bnb, Output, PsbtParams,
SelectorParams,
};
use bitcoin::{absolute::LockTime, key::Secp256k1, Amount, FeeRate, Sequence};
use miniscript::Descriptor;
Expand Down Expand Up @@ -75,13 +75,13 @@ fn main() -> anyhow::Result<()> {
.into_selection(
selection_algorithm_lowest_fee_bnb(longterm_feerate, 100_000),
SelectorParams::new(
FeeStrategy::FeeRate(FeeRate::from_sat_per_vb_unchecked(10)),
FeeRate::from_sat_per_vb_unchecked(10),
vec![Output::with_script(
recipient_addr.script_pubkey(),
Amount::from_sat(50_000_000),
)],
ScriptSource::Descriptor(Box::new(internal.at_derivation_index(0)?)),
wallet.change_policy(),
bdk_tx::ChangeScript::from_descriptor(internal.at_derivation_index(0)?),
bdk_tx::ChangePolicy::no_dust_least_waste(longterm_feerate),
),
)?;

Expand Down
48 changes: 1 addition & 47 deletions examples/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ use bdk_bitcoind_rpc::{Emitter, NO_EXPECTED_MEMPOOL_TXIDS};
use bdk_chain::{
bdk_core, Anchor, Balance, CanonicalizationParams, ChainPosition, ConfirmationBlockTime,
};
use bdk_coin_select::{ChangePolicy, DrainWeights};
use bdk_testenv::{bitcoincore_rpc::RpcApi, TestEnv};
use bdk_tx::{
CanonicalUnspents, ConfirmationStatus, Input, InputCandidates, RbfParams, TxWithStatus,
};
use bitcoin::{absolute, Address, Amount, BlockHash, OutPoint, Transaction, TxOut, Txid};
use bitcoin::{absolute, Address, BlockHash, OutPoint, Transaction, Txid};
use miniscript::{
plan::{Assets, Plan},
Descriptor, DescriptorPublicKey, ForEachKey,
Expand Down Expand Up @@ -143,51 +142,6 @@ impl Wallet {
.map(|c_tx| (c_tx.tx_node.tx, status_from_position(c_tx.chain_position)))
}

/// Computes the weight of a change output plus the future weight to spend it.
pub fn drain_weights(&self) -> DrainWeights {
// Get descriptor of change keychain at a derivation index.
let desc = self
.graph
.index
.get_descriptor(INTERNAL)
.unwrap()
.at_derivation_index(0)
.unwrap();

// Compute the weight of a change output for this wallet.
let output_weight = TxOut {
script_pubkey: desc.script_pubkey(),
value: Amount::ZERO,
}
.weight()
.to_wu();

// The spend weight is the default input weight plus the plan satisfaction weight
// (this code assumes that we're only dealing with segwit transactions).
let plan = desc.plan(&self.assets()).expect("failed to create Plan");
let spend_weight =
bitcoin::TxIn::default().segwit_weight().to_wu() + plan.satisfaction_weight() as u64;

DrainWeights {
output_weight,
spend_weight,
n_outputs: 1,
}
}

/// Get the default change policy for this wallet.
pub fn change_policy(&self) -> ChangePolicy {
let spk_0 = self
.graph
.index
.spk_at_index(INTERNAL, 0)
.expect("spk should exist in wallet");
ChangePolicy {
min_value: spk_0.minimal_non_dust().to_sat(),
drain_weights: self.drain_weights(),
}
}

pub fn all_candidates(&self) -> bdk_tx::InputCandidates {
let index = &self.graph.index;
let assets = self.assets();
Expand Down
19 changes: 10 additions & 9 deletions examples/synopsis.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bdk_testenv::{bitcoincore_rpc::RpcApi, TestEnv};
use bdk_tx::{
filter_unspendable, group_by_spk, selection_algorithm_lowest_fee_bnb, FeeStrategy, Output,
PsbtParams, ScriptSource, SelectorParams, Signer,
filter_unspendable, group_by_spk, selection_algorithm_lowest_fee_bnb, Output, PsbtParams,
SelectorParams, Signer,
};
use bitcoin::{key::Secp256k1, Amount, FeeRate, Sequence};
use miniscript::Descriptor;
Expand Down Expand Up @@ -55,13 +55,13 @@ fn main() -> anyhow::Result<()> {
.into_selection(
selection_algorithm_lowest_fee_bnb(longterm_feerate, 100_000),
SelectorParams::new(
FeeStrategy::FeeRate(FeeRate::from_sat_per_vb_unchecked(10)),
FeeRate::from_sat_per_vb_unchecked(10),
vec![Output::with_script(
recipient_addr.script_pubkey(),
Amount::from_sat(21_000_000),
)],
ScriptSource::Descriptor(Box::new(internal.at_derivation_index(0)?)),
wallet.change_policy(),
bdk_tx::ChangeScript::from_descriptor(internal.at_derivation_index(0)?),
bdk_tx::ChangePolicy::no_dust_least_waste(longterm_feerate),
),
)?;

Expand Down Expand Up @@ -128,18 +128,19 @@ fn main() -> anyhow::Result<()> {
SelectorParams {
// This is just a lower-bound feerate. The actual result will be much higher to
// satisfy mempool-replacement policy.
fee_strategy: FeeStrategy::FeeRate(FeeRate::from_sat_per_vb_unchecked(1)),
target_feerate: FeeRate::from_sat_per_vb_unchecked(1),
// We cancel the tx by specifying no target outputs. This way, all excess returns
// to our change output (unless if the prevouts picked are so small that it will
// be less wasteful to have no output, however that will not be a valid tx).
// If you only want to fee bump, put the original txs' recipients here.
target_outputs: vec![],
change_script: ScriptSource::Descriptor(Box::new(
change_script: bdk_tx::ChangeScript::from_descriptor(
internal.at_derivation_index(1)?,
)),
change_policy: wallet.change_policy(),
),
change_policy: bdk_tx::ChangePolicy::no_dust_least_waste(longterm_feerate),
// This ensures that we satisfy mempool-replacement policy rules 4 and 6.
replace: Some(rbf_params),
dust_relay_feerate: None,
},
)?;

Expand Down
6 changes: 3 additions & 3 deletions src/input_candidates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use miniscript::bitcoin;

use crate::collections::{BTreeMap, HashSet};
use crate::{
cs_feerate, CannotMeetTarget, Input, InputGroup, Selection, Selector, SelectorError,
CannotMeetTarget, FeeRateExt, Input, InputGroup, Selection, Selector, SelectorError,
SelectorParams,
};

Expand Down Expand Up @@ -291,10 +291,10 @@ pub fn selection_algorithm_lowest_fee_bnb(
longterm_feerate: FeeRate,
max_rounds: usize,
) -> impl FnMut(&mut Selector) -> Result<(), NoBnbSolution> {
let long_term_feerate = cs_feerate(longterm_feerate);
let long_term_feerate = longterm_feerate.into_cs_feerate();
move |selector| {
let target = selector.target();
let change_policy = selector.change_policy();
let change_policy = selector.cs_change_policy();
selector
.inner_mut()
.run_bnb(
Expand Down
12 changes: 12 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,15 @@ pub(crate) mod collections {

/// Definite descriptor.
pub type DefiniteDescriptor = Descriptor<DefiniteDescriptorKey>;

/// Extension trait for converting [`bitcoin::FeeRate`] to [`bdk_coin_select::FeeRate`].
pub trait FeeRateExt {
/// Convert to a [`bdk_coin_select::FeeRate`].
fn into_cs_feerate(self) -> bdk_coin_select::FeeRate;
}

impl FeeRateExt for bitcoin::FeeRate {
fn into_cs_feerate(self) -> bdk_coin_select::FeeRate {
bdk_coin_select::FeeRate::from_sat_per_wu(self.to_sat_per_kwu() as f32 / 1000.0)
}
}
5 changes: 0 additions & 5 deletions src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt::{Debug, Display};

use bdk_coin_select::FeeRate;
use miniscript::bitcoin;
use miniscript::bitcoin::{
absolute::{self, LockTime},
Expand All @@ -15,10 +14,6 @@ use crate::{apply_anti_fee_sniping, Finalizer, Input, Output};

const FALLBACK_SEQUENCE: bitcoin::Sequence = bitcoin::Sequence::ENABLE_LOCKTIME_NO_RBF;

pub(crate) fn cs_feerate(feerate: bitcoin::FeeRate) -> bdk_coin_select::FeeRate {
FeeRate::from_sat_per_wu(feerate.to_sat_per_kwu() as f32 / 1000.0)
}

/// Final selection of inputs and outputs.
#[derive(Debug, Clone)]
pub struct Selection {
Expand Down
Loading