Skip to content

Commit

Permalink
Temp 1: Add the TxBuilder method
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderbiscuit committed May 25, 2023
1 parent 3be2c04 commit 067e8ad
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
4 changes: 3 additions & 1 deletion bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,11 @@ interface TxBuilder {

TxBuilder add_unspendable(OutPoint unspendable);

TxBuilder add_utxos(sequence<OutPoint> outpoints);

TxBuilder add_utxo(OutPoint outpoint);

TxBuilder add_utxos(sequence<OutPoint> outpoints);
TxBuilder add_foreign_utxo(OutPoint outpoint, Input psbt_input, u64 satisfaction_weight);

TxBuilder do_not_spend_change();

Expand Down
45 changes: 45 additions & 0 deletions bdk-ffi/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub(crate) struct TxBuilder {
pub(crate) drain_to: Option<BdkScript>,
pub(crate) rbf: Option<RbfValue>,
pub(crate) data: Vec<u8>,
pub(crate) foreign_utxos: Vec<(OutPoint, Input, u64)>
}

impl TxBuilder {
Expand All @@ -265,6 +266,7 @@ impl TxBuilder {
drain_to: None,
rbf: None,
data: Vec::new(),
foreign_utxos: Vec::new(),
}
}

Expand Down Expand Up @@ -318,6 +320,49 @@ impl TxBuilder {
})
}

/// Add a foreign UTXO i.e. a UTXO not owned by this wallet.
/// At a minimum to add a foreign UTXO we need:
/// outpoint: To add it to the raw transaction.
/// psbt_input: To know the value.
/// satisfaction_weight: To know how much weight/vbytes the input will add to the transaction for fee calculation.
///
/// There are several security concerns about adding foreign UTXOs that application developers should consider.
/// First, how do you know the value of the input is correct? If a non_witness_utxo is provided in the
/// psbt_input then this method implicitly verifies the value by checking it against the transaction.
/// If only a witness_utxo is provided then this method does not verify the value but just takes it as a
/// given – it is up to you to check that whoever sent you the input_psbt was not lying!
///
/// Secondly, you must somehow provide satisfaction_weight of the input. Depending on your application
/// it may be important that this be known precisely. If not, a malicious counterparty may fool you into putting in
/// a value that is too low, giving the transaction a lower than expected feerate. They could also fool you
/// into putting a value that is too high causing you to pay a fee that is too high. The party who is broadcasting
/// the transaction can of course check the real input weight matches the expected weight prior to broadcasting.
///
/// To guarantee the satisfaction_weight is correct, you can require the party providing the psbt_input provide
/// a miniscript descriptor for the input so you can check it against the script_pubkey and then ask it for the
/// max_satisfaction_weight.
///
/// Errors
/// This method returns errors in the following circumstances:
/// The psbt_input does not contain a witness_utxo or non_witness_utxo.
/// The data in non_witness_utxo does not match what is in outpoint.
///
/// Note unless you set only_witness_utxo any non-taproot psbt_input you pass to this method must
/// have non_witness_utxo set otherwise you will get an error when finish is called.
pub fn add_foreign_utxo(
&mut self,
outpoint: OutPoint,
psbt_input: Input,
satisfaction_weight: u64
) -> Arc<Self> {
let mut foreign_utxos = self.foreign_utxos.to_vec();
foreign_utxos.append((outpoint, psbt_input, satisfaction_weight));
Arc::new(TxBuilder {
foreign_utxos: foreign_utxos,
..self.clone()
})
}

/// Do not spend change outputs. This effectively adds all the change outputs to the "unspendable" list. See TxBuilder.unspendable.
pub(crate) fn do_not_spend_change(&self) -> Arc<Self> {
Arc::new(TxBuilder {
Expand Down

0 comments on commit 067e8ad

Please sign in to comment.