Upgrade to rust-bitcoin 0.28 and miniscript 7.0
This commit is contained in:
@@ -24,11 +24,8 @@ use std::sync::Arc;
|
||||
use bitcoin::secp256k1::Secp256k1;
|
||||
|
||||
use bitcoin::consensus::encode::serialize;
|
||||
use bitcoin::util::base58;
|
||||
use bitcoin::util::psbt::raw::Key as PsbtKey;
|
||||
use bitcoin::util::psbt::Input;
|
||||
use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
|
||||
use bitcoin::{Address, Network, OutPoint, Script, SigHashType, Transaction, TxOut, Txid};
|
||||
use bitcoin::util::psbt;
|
||||
use bitcoin::{Address, Network, OutPoint, Script, SigHashType, Transaction, TxOut, Txid, Witness};
|
||||
|
||||
use miniscript::descriptor::DescriptorTrait;
|
||||
use miniscript::psbt::PsbtInputSatisfier;
|
||||
@@ -542,7 +539,7 @@ where
|
||||
&self,
|
||||
coin_selection: Cs,
|
||||
params: TxParams,
|
||||
) -> Result<(Psbt, TransactionDetails), Error> {
|
||||
) -> Result<(psbt::PartiallySignedTransaction, TransactionDetails), Error> {
|
||||
let external_policy = self
|
||||
.descriptor
|
||||
.extract_policy(&self.signers, BuildSatisfaction::None, &self.secp)?
|
||||
@@ -703,7 +700,7 @@ where
|
||||
let mut outgoing: u64 = 0;
|
||||
let mut received: u64 = 0;
|
||||
|
||||
fee_amount += fee_rate.fee_wu(tx.get_weight());
|
||||
fee_amount += fee_rate.fee_wu(tx.weight());
|
||||
|
||||
let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
|
||||
|
||||
@@ -761,7 +758,7 @@ where
|
||||
previous_output: u.outpoint(),
|
||||
script_sig: Script::default(),
|
||||
sequence: n_sequence,
|
||||
witness: vec![],
|
||||
witness: Witness::new(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -884,10 +881,7 @@ where
|
||||
return Err(Error::IrreplaceableTransaction);
|
||||
}
|
||||
|
||||
let feerate = FeeRate::from_wu(
|
||||
details.fee.ok_or(Error::FeeRateUnavailable)?,
|
||||
tx.get_weight(),
|
||||
);
|
||||
let feerate = FeeRate::from_wu(details.fee.ok_or(Error::FeeRateUnavailable)?, tx.weight());
|
||||
|
||||
// remove the inputs from the tx and process them
|
||||
let original_txin = tx.input.drain(..).collect::<Vec<_>>();
|
||||
@@ -1004,7 +998,11 @@ where
|
||||
/// let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
|
||||
/// assert!(finalized, "we should have signed all the inputs");
|
||||
/// # Ok::<(), bdk::Error>(())
|
||||
pub fn sign(&self, psbt: &mut Psbt, sign_options: SignOptions) -> Result<bool, Error> {
|
||||
pub fn sign(
|
||||
&self,
|
||||
psbt: &mut psbt::PartiallySignedTransaction,
|
||||
sign_options: SignOptions,
|
||||
) -> Result<bool, Error> {
|
||||
// this helps us doing our job later
|
||||
self.add_input_hd_keypaths(psbt)?;
|
||||
|
||||
@@ -1023,10 +1021,9 @@ where
|
||||
// If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
|
||||
// is using `SIGHASH_ALL`
|
||||
if !sign_options.allow_all_sighashes
|
||||
&& !psbt
|
||||
.inputs
|
||||
.iter()
|
||||
.all(|i| i.sighash_type.is_none() || i.sighash_type == Some(SigHashType::All))
|
||||
&& !psbt.inputs.iter().all(|i| {
|
||||
i.sighash_type.is_none() || i.sighash_type == Some(SigHashType::All.into())
|
||||
})
|
||||
{
|
||||
return Err(Error::Signer(signer::SignerError::NonStandardSighash));
|
||||
}
|
||||
@@ -1085,8 +1082,12 @@ where
|
||||
/// Try to finalize a PSBT
|
||||
///
|
||||
/// The [`SignOptions`] can be used to tweak the behavior of the finalizer.
|
||||
pub fn finalize_psbt(&self, psbt: &mut Psbt, sign_options: SignOptions) -> Result<bool, Error> {
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
pub fn finalize_psbt(
|
||||
&self,
|
||||
psbt: &mut psbt::PartiallySignedTransaction,
|
||||
sign_options: SignOptions,
|
||||
) -> Result<bool, Error> {
|
||||
let tx = &psbt.unsigned_tx;
|
||||
let mut finished = true;
|
||||
|
||||
for (n, input) in tx.input.iter().enumerate() {
|
||||
@@ -1383,10 +1384,8 @@ where
|
||||
tx: Transaction,
|
||||
selected: Vec<Utxo>,
|
||||
params: TxParams,
|
||||
) -> Result<Psbt, Error> {
|
||||
use bitcoin::util::psbt::serialize::Serialize;
|
||||
|
||||
let mut psbt = Psbt::from_unsigned_tx(tx)?;
|
||||
) -> Result<psbt::PartiallySignedTransaction, Error> {
|
||||
let mut psbt = psbt::PartiallySignedTransaction::from_unsigned_tx(tx)?;
|
||||
|
||||
if params.add_global_xpubs {
|
||||
let mut all_xpubs = self.descriptor.get_extended_keys()?;
|
||||
@@ -1395,13 +1394,6 @@ where
|
||||
}
|
||||
|
||||
for xpub in all_xpubs {
|
||||
let serialized_xpub = base58::from_check(&xpub.xkey.to_string())
|
||||
.expect("Internal serialization error");
|
||||
let key = PsbtKey {
|
||||
type_value: 0x01,
|
||||
key: serialized_xpub,
|
||||
};
|
||||
|
||||
let origin = match xpub.origin {
|
||||
Some(origin) => origin,
|
||||
None if xpub.xkey.depth == 0 => {
|
||||
@@ -1410,7 +1402,7 @@ where
|
||||
_ => return Err(Error::MissingKeyOrigin(xpub.xkey.to_string())),
|
||||
};
|
||||
|
||||
psbt.global.unknown.insert(key, origin.serialize());
|
||||
psbt.xpub.insert(xpub.xkey, origin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,11 +1412,7 @@ where
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
// add metadata for the inputs
|
||||
for (psbt_input, input) in psbt
|
||||
.inputs
|
||||
.iter_mut()
|
||||
.zip(psbt.global.unsigned_tx.input.iter())
|
||||
{
|
||||
for (psbt_input, input) in psbt.inputs.iter_mut().zip(psbt.unsigned_tx.input.iter()) {
|
||||
let utxo = match lookup_output.remove(&input.previous_output) {
|
||||
Some(utxo) => utxo,
|
||||
None => continue,
|
||||
@@ -1436,9 +1424,9 @@ where
|
||||
match self.get_psbt_input(utxo, params.sighash, params.only_witness_utxo) {
|
||||
Ok(psbt_input) => psbt_input,
|
||||
Err(e) => match e {
|
||||
Error::UnknownUtxo => Input {
|
||||
Error::UnknownUtxo => psbt::Input {
|
||||
sighash_type: params.sighash,
|
||||
..Input::default()
|
||||
..psbt::Input::default()
|
||||
},
|
||||
_ => return Err(e),
|
||||
},
|
||||
@@ -1463,10 +1451,7 @@ where
|
||||
self.add_input_hd_keypaths(&mut psbt)?;
|
||||
|
||||
// add metadata for the outputs
|
||||
for (psbt_output, tx_output) in psbt
|
||||
.outputs
|
||||
.iter_mut()
|
||||
.zip(psbt.global.unsigned_tx.output.iter())
|
||||
for (psbt_output, tx_output) in psbt.outputs.iter_mut().zip(psbt.unsigned_tx.output.iter())
|
||||
{
|
||||
if let Some((keychain, child)) = self
|
||||
.database
|
||||
@@ -1491,9 +1476,9 @@ where
|
||||
pub fn get_psbt_input(
|
||||
&self,
|
||||
utxo: LocalUtxo,
|
||||
sighash_type: Option<SigHashType>,
|
||||
sighash_type: Option<psbt::PsbtSighashType>,
|
||||
only_witness_utxo: bool,
|
||||
) -> Result<Input, Error> {
|
||||
) -> Result<psbt::Input, Error> {
|
||||
// Try to find the prev_script in our db to figure out if this is internal or external,
|
||||
// and the derivation index
|
||||
let (keychain, child) = self
|
||||
@@ -1502,9 +1487,9 @@ where
|
||||
.get_path_from_script_pubkey(&utxo.txout.script_pubkey)?
|
||||
.ok_or(Error::UnknownUtxo)?;
|
||||
|
||||
let mut psbt_input = Input {
|
||||
let mut psbt_input = psbt::Input {
|
||||
sighash_type,
|
||||
..Input::default()
|
||||
..psbt::Input::default()
|
||||
};
|
||||
|
||||
let desc = self.get_descriptor_for_keychain(keychain);
|
||||
@@ -1526,7 +1511,10 @@ where
|
||||
Ok(psbt_input)
|
||||
}
|
||||
|
||||
fn add_input_hd_keypaths(&self, psbt: &mut Psbt) -> Result<(), Error> {
|
||||
fn add_input_hd_keypaths(
|
||||
&self,
|
||||
psbt: &mut psbt::PartiallySignedTransaction,
|
||||
) -> Result<(), Error> {
|
||||
let mut input_utxos = Vec::with_capacity(psbt.inputs.len());
|
||||
for n in 0..psbt.inputs.len() {
|
||||
input_utxos.push(psbt.get_utxo_for(n).clone());
|
||||
@@ -1808,7 +1796,7 @@ pub(crate) mod test {
|
||||
$(
|
||||
$( $add_signature )*
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
}
|
||||
)*
|
||||
|
||||
@@ -1820,7 +1808,7 @@ pub(crate) mod test {
|
||||
dust_change = true;
|
||||
)*
|
||||
|
||||
let tx_fee_rate = FeeRate::from_wu($fees, tx.get_weight());
|
||||
let tx_fee_rate = FeeRate::from_wu($fees, tx.weight());
|
||||
let fee_rate = $fee_rate;
|
||||
|
||||
if !dust_change {
|
||||
@@ -1886,7 +1874,7 @@ pub(crate) mod test {
|
||||
.version(42);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.version, 42);
|
||||
assert_eq!(psbt.unsigned_tx.version, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1897,7 +1885,7 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 25_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.lock_time, 0);
|
||||
assert_eq!(psbt.unsigned_tx.lock_time, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1908,7 +1896,7 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 25_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.lock_time, 100_000);
|
||||
assert_eq!(psbt.unsigned_tx.lock_time, 100_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1921,7 +1909,7 @@ pub(crate) mod test {
|
||||
.nlocktime(630_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.lock_time, 630_000);
|
||||
assert_eq!(psbt.unsigned_tx.lock_time, 630_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1934,7 +1922,7 @@ pub(crate) mod test {
|
||||
.nlocktime(630_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.lock_time, 630_000);
|
||||
assert_eq!(psbt.unsigned_tx.lock_time, 630_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1959,7 +1947,7 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 25_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 6);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1973,7 +1961,7 @@ pub(crate) mod test {
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
// When CSV is enabled it takes precedence over the rbf value (unless forced by the user).
|
||||
// It will be set to the OP_CSV value, in this case 6
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 6);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1998,7 +1986,7 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 25_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 0xFFFFFFFE);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 0xFFFFFFFE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2023,7 +2011,7 @@ pub(crate) mod test {
|
||||
.enable_rbf_with_sequence(0xDEADBEEF);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 0xDEADBEEF);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 0xDEADBEEF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2034,7 +2022,7 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 25_000);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 0xFFFFFFFF);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2059,9 +2047,9 @@ pub(crate) mod test {
|
||||
builder.drain_to(addr.script_pubkey()).drain_wallet();
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output[0].value,
|
||||
psbt.unsigned_tx.output[0].value,
|
||||
50_000 - details.fee.unwrap_or(0)
|
||||
);
|
||||
}
|
||||
@@ -2078,7 +2066,7 @@ pub(crate) mod test {
|
||||
.drain_wallet();
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
dbg!(&psbt);
|
||||
let outputs = psbt.global.unsigned_tx.output;
|
||||
let outputs = psbt.unsigned_tx.output;
|
||||
|
||||
assert_eq!(outputs.len(), 2);
|
||||
let main_output = outputs
|
||||
@@ -2129,9 +2117,9 @@ pub(crate) mod test {
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(details.fee.unwrap_or(0), 100);
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output[0].value,
|
||||
psbt.unsigned_tx.output[0].value,
|
||||
50_000 - details.fee.unwrap_or(0)
|
||||
);
|
||||
}
|
||||
@@ -2148,9 +2136,9 @@ pub(crate) mod test {
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(details.fee.unwrap_or(0), 0);
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output[0].value,
|
||||
psbt.unsigned_tx.output[0].value,
|
||||
50_000 - details.fee.unwrap_or(0)
|
||||
);
|
||||
}
|
||||
@@ -2180,10 +2168,10 @@ pub(crate) mod test {
|
||||
.ordering(TxOrdering::Untouched);
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 2);
|
||||
assert_eq!(psbt.global.unsigned_tx.output[0].value, 25_000);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 2);
|
||||
assert_eq!(psbt.unsigned_tx.output[0].value, 25_000);
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output[1].value,
|
||||
psbt.unsigned_tx.output[1].value,
|
||||
25_000 - details.fee.unwrap_or(0)
|
||||
);
|
||||
}
|
||||
@@ -2196,8 +2184,8 @@ pub(crate) mod test {
|
||||
builder.add_recipient(addr.script_pubkey(), 49_800);
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(psbt.global.unsigned_tx.output[0].value, 49_800);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 1);
|
||||
assert_eq!(psbt.unsigned_tx.output[0].value, 49_800);
|
||||
assert_eq!(details.fee.unwrap_or(0), 200);
|
||||
}
|
||||
|
||||
@@ -2226,13 +2214,13 @@ pub(crate) mod test {
|
||||
.ordering(super::tx_builder::TxOrdering::Bip69Lexicographic);
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.output.len(), 3);
|
||||
assert_eq!(psbt.unsigned_tx.output.len(), 3);
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output[0].value,
|
||||
psbt.unsigned_tx.output[0].value,
|
||||
10_000 - details.fee.unwrap_or(0)
|
||||
);
|
||||
assert_eq!(psbt.global.unsigned_tx.output[1].value, 10_000);
|
||||
assert_eq!(psbt.global.unsigned_tx.output[2].value, 30_000);
|
||||
assert_eq!(psbt.unsigned_tx.output[1].value, 10_000);
|
||||
assert_eq!(psbt.unsigned_tx.output[2].value, 30_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2253,12 +2241,12 @@ pub(crate) mod test {
|
||||
let mut builder = wallet.build_tx();
|
||||
builder
|
||||
.add_recipient(addr.script_pubkey(), 30_000)
|
||||
.sighash(bitcoin::SigHashType::Single);
|
||||
.sighash(bitcoin::SigHashType::Single.into());
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
psbt.inputs[0].sighash_type,
|
||||
Some(bitcoin::SigHashType::Single)
|
||||
Some(bitcoin::SigHashType::Single.into())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2450,7 +2438,7 @@ pub(crate) mod test {
|
||||
let (psbt, details) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.input.len(),
|
||||
psbt.unsigned_tx.input.len(),
|
||||
2,
|
||||
"should add an additional input since 25_000 < 30_000"
|
||||
);
|
||||
@@ -2507,7 +2495,7 @@ pub(crate) mod test {
|
||||
.policy_path(path, KeychainKind::External);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 0xFFFFFFFF);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2526,14 +2514,13 @@ pub(crate) mod test {
|
||||
.policy_path(path, KeychainKind::External);
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unsigned_tx.input[0].sequence, 144);
|
||||
assert_eq!(psbt.unsigned_tx.input[0].sequence, 144);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_tx_global_xpubs_with_origin() {
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::util::base58;
|
||||
use bitcoin::util::psbt::raw::Key;
|
||||
use bitcoin::util::bip32;
|
||||
|
||||
let (wallet, _, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
|
||||
let addr = wallet.get_address(New).unwrap();
|
||||
@@ -2543,16 +2530,12 @@ pub(crate) mod test {
|
||||
.add_global_xpubs();
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
let type_value = 0x01;
|
||||
let key = base58::from_check("tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3").unwrap();
|
||||
let key = bip32::ExtendedPubKey::from_str("tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3").unwrap();
|
||||
let fingerprint = bip32::Fingerprint::from_hex("73756c7f").unwrap();
|
||||
let path = bip32::DerivationPath::from_str("m/48'/0'/0'/2'").unwrap();
|
||||
|
||||
let psbt_key = Key { type_value, key };
|
||||
|
||||
// This key has an explicit origin, so it will be encoded here
|
||||
let value_bytes = Vec::<u8>::from_hex("73756c7f30000080000000800000008002000080").unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unknown.len(), 1);
|
||||
assert_eq!(psbt.global.unknown.get(&psbt_key), Some(&value_bytes));
|
||||
assert_eq!(psbt.xpub.len(), 1);
|
||||
assert_eq!(psbt.xpub.get(&key), Some(&(fingerprint, path)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2588,8 +2571,7 @@ pub(crate) mod test {
|
||||
);
|
||||
|
||||
assert!(
|
||||
psbt.global
|
||||
.unsigned_tx
|
||||
psbt.unsigned_tx
|
||||
.input
|
||||
.iter()
|
||||
.any(|input| input.previous_output == utxo.outpoint),
|
||||
@@ -2794,8 +2776,7 @@ pub(crate) mod test {
|
||||
#[test]
|
||||
fn test_create_tx_global_xpubs_master_without_origin() {
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::util::base58;
|
||||
use bitcoin::util::psbt::raw::Key;
|
||||
use bitcoin::util::bip32;
|
||||
|
||||
let (wallet, _, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
|
||||
let addr = wallet.get_address(New).unwrap();
|
||||
@@ -2805,17 +2786,14 @@ pub(crate) mod test {
|
||||
.add_global_xpubs();
|
||||
let (psbt, _) = builder.finish().unwrap();
|
||||
|
||||
let type_value = 0x01;
|
||||
let key = base58::from_check("tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL").unwrap();
|
||||
let key = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL").unwrap();
|
||||
let fingerprint = bip32::Fingerprint::from_hex("997a323b").unwrap();
|
||||
|
||||
let psbt_key = Key { type_value, key };
|
||||
|
||||
// This key doesn't have an explicit origin, but it's a master key (depth = 0). So we encode
|
||||
// its fingerprint directly and an empty path
|
||||
let value_bytes = Vec::<u8>::from_hex("997a323b").unwrap();
|
||||
|
||||
assert_eq!(psbt.global.unknown.len(), 1);
|
||||
assert_eq!(psbt.global.unknown.get(&psbt_key), Some(&value_bytes));
|
||||
assert_eq!(psbt.xpub.len(), 1);
|
||||
assert_eq!(
|
||||
psbt.xpub.get(&key),
|
||||
Some(&(fingerprint, bip32::DerivationPath::default()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2937,7 +2915,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -2962,7 +2940,7 @@ pub(crate) mod test {
|
||||
);
|
||||
assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
tx.output
|
||||
@@ -2997,7 +2975,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3028,7 +3006,7 @@ pub(crate) mod test {
|
||||
original_details.fee.unwrap_or(0)
|
||||
);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
tx.output
|
||||
@@ -3063,7 +3041,7 @@ pub(crate) mod test {
|
||||
let mut tx = psbt.extract_tx();
|
||||
let txid = tx.txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3087,7 +3065,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent);
|
||||
assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.output.len(), 1);
|
||||
assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
|
||||
|
||||
@@ -3107,7 +3085,7 @@ pub(crate) mod test {
|
||||
let mut tx = psbt.extract_tx();
|
||||
let txid = tx.txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3131,7 +3109,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent);
|
||||
assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.output.len(), 1);
|
||||
assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
|
||||
|
||||
@@ -3163,7 +3141,7 @@ pub(crate) mod test {
|
||||
let mut tx = psbt.extract_tx();
|
||||
let txid = tx.txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3220,7 +3198,7 @@ pub(crate) mod test {
|
||||
let mut tx = psbt.extract_tx();
|
||||
let txid = tx.txid();
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3261,7 +3239,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3282,7 +3260,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent + 25_000);
|
||||
assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
@@ -3324,7 +3302,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3345,7 +3323,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent + 25_000);
|
||||
assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
@@ -3395,7 +3373,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3422,7 +3400,7 @@ pub(crate) mod test {
|
||||
75_000 - original_send_all_amount - details.fee.unwrap_or(0)
|
||||
);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
@@ -3466,7 +3444,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3493,7 +3471,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.fee.unwrap_or(0), 30_000);
|
||||
assert_eq!(details.received, 0);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 1);
|
||||
assert_eq!(
|
||||
@@ -3527,7 +3505,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3556,7 +3534,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent + 25_000);
|
||||
assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
@@ -3598,7 +3576,7 @@ pub(crate) mod test {
|
||||
let txid = tx.txid();
|
||||
// skip saving the new utxos, we know they can't be used anyways
|
||||
for txin in &mut tx.input {
|
||||
txin.witness.push([0x00; 108].to_vec()); // fake signature
|
||||
txin.witness.push([0x00; 108]); // fake signature
|
||||
wallet
|
||||
.database
|
||||
.borrow_mut()
|
||||
@@ -3627,7 +3605,7 @@ pub(crate) mod test {
|
||||
assert_eq!(details.sent, original_details.sent + 25_000);
|
||||
assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
|
||||
|
||||
let tx = &psbt.global.unsigned_tx;
|
||||
let tx = &psbt.unsigned_tx;
|
||||
assert_eq!(tx.input.len(), 2);
|
||||
assert_eq!(tx.output.len(), 2);
|
||||
assert_eq!(
|
||||
@@ -3785,7 +3763,7 @@ pub(crate) mod test {
|
||||
};
|
||||
|
||||
psbt.inputs.push(dud_input);
|
||||
psbt.global.unsigned_tx.input.push(bitcoin::TxIn::default());
|
||||
psbt.unsigned_tx.input.push(bitcoin::TxIn::default());
|
||||
let is_final = wallet
|
||||
.sign(
|
||||
&mut psbt,
|
||||
@@ -3814,7 +3792,7 @@ pub(crate) mod test {
|
||||
let mut builder = wallet.build_tx();
|
||||
builder
|
||||
.drain_to(addr.script_pubkey())
|
||||
.sighash(sighash)
|
||||
.sighash(sighash.into())
|
||||
.drain_wallet();
|
||||
let (mut psbt, _) = builder.finish().unwrap();
|
||||
|
||||
@@ -3847,8 +3825,8 @@ pub(crate) mod test {
|
||||
|
||||
let extracted = psbt.extract_tx();
|
||||
assert_eq!(
|
||||
*extracted.input[0].witness[0].last().unwrap(),
|
||||
sighash.as_u32() as u8,
|
||||
*extracted.input[0].witness.to_vec()[0].last().unwrap(),
|
||||
sighash.to_u32() as u8,
|
||||
"The signature should have been made with the right sighash"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,10 +91,11 @@ use std::sync::Arc;
|
||||
use bitcoin::blockdata::opcodes;
|
||||
use bitcoin::blockdata::script::Builder as ScriptBuilder;
|
||||
use bitcoin::hashes::{hash160, Hash};
|
||||
use bitcoin::secp256k1;
|
||||
use bitcoin::secp256k1::{Message, Secp256k1};
|
||||
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
|
||||
use bitcoin::util::{bip143, psbt};
|
||||
use bitcoin::{PrivateKey, Script, SigHash, SigHashType};
|
||||
use bitcoin::util::{bip143, ecdsa, psbt};
|
||||
use bitcoin::{PrivateKey, PublicKey, Script, SigHashType, Sighash};
|
||||
|
||||
use miniscript::descriptor::{DescriptorSecretKey, DescriptorSinglePriv, DescriptorXKey, KeyMap};
|
||||
use miniscript::{Legacy, MiniscriptKey, Segwitv0};
|
||||
@@ -153,6 +154,8 @@ pub enum SignerError {
|
||||
/// To enable signing transactions with non-standard sighashes set
|
||||
/// [`SignOptions::allow_all_sighashes`] to `true`.
|
||||
NonStandardSighash,
|
||||
/// Invalid SIGHASH for the signing context in use
|
||||
InvalidSighash,
|
||||
}
|
||||
|
||||
impl fmt::Display for SignerError {
|
||||
@@ -245,10 +248,16 @@ impl Signer for DescriptorXKey<ExtendedPrivKey> {
|
||||
None => self.xkey.derive_priv(secp, &full_path).unwrap(),
|
||||
};
|
||||
|
||||
if &derived_key.private_key.public_key(secp) != public_key {
|
||||
if &secp256k1::PublicKey::from_secret_key(secp, &derived_key.private_key) != public_key {
|
||||
Err(SignerError::InvalidKey)
|
||||
} else {
|
||||
derived_key.private_key.sign(psbt, Some(input_index), secp)
|
||||
// HD wallets imply compressed keys
|
||||
PrivateKey {
|
||||
compressed: true,
|
||||
network: self.xkey.network,
|
||||
inner: derived_key.private_key,
|
||||
}
|
||||
.sign(psbt, Some(input_index), secp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +282,7 @@ impl Signer for PrivateKey {
|
||||
secp: &SecpCtx,
|
||||
) -> Result<(), SignerError> {
|
||||
let input_index = input_index.unwrap();
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.global.unsigned_tx.input.len() {
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
|
||||
return Err(SignerError::InputIndexOutOfRange);
|
||||
}
|
||||
|
||||
@@ -283,7 +292,7 @@ impl Signer for PrivateKey {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let pubkey = self.public_key(secp);
|
||||
let pubkey = PublicKey::from_private_key(secp, &self);
|
||||
if psbt.inputs[input_index].partial_sigs.contains_key(&pubkey) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -297,15 +306,15 @@ impl Signer for PrivateKey {
|
||||
None => Legacy::sighash(psbt, input_index)?,
|
||||
};
|
||||
|
||||
let signature = secp.sign(
|
||||
let sig = secp.sign_ecdsa(
|
||||
&Message::from_slice(&hash.into_inner()[..]).unwrap(),
|
||||
&self.key,
|
||||
&self.inner,
|
||||
);
|
||||
|
||||
let mut final_signature = Vec::with_capacity(75);
|
||||
final_signature.extend_from_slice(&signature.serialize_der());
|
||||
final_signature.push(sighash.as_u32() as u8);
|
||||
|
||||
let final_signature = ecdsa::EcdsaSig {
|
||||
sig,
|
||||
hash_ty: sighash.ecdsa_hash_ty().unwrap(), // FIXME
|
||||
};
|
||||
psbt.inputs[input_index]
|
||||
.partial_sigs
|
||||
.insert(pubkey, final_signature);
|
||||
@@ -494,22 +503,22 @@ pub(crate) trait ComputeSighash {
|
||||
fn sighash(
|
||||
psbt: &psbt::PartiallySignedTransaction,
|
||||
input_index: usize,
|
||||
) -> Result<(SigHash, SigHashType), SignerError>;
|
||||
) -> Result<(Sighash, psbt::PsbtSighashType), SignerError>;
|
||||
}
|
||||
|
||||
impl ComputeSighash for Legacy {
|
||||
fn sighash(
|
||||
psbt: &psbt::PartiallySignedTransaction,
|
||||
input_index: usize,
|
||||
) -> Result<(SigHash, SigHashType), SignerError> {
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.global.unsigned_tx.input.len() {
|
||||
) -> Result<(Sighash, psbt::PsbtSighashType), SignerError> {
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
|
||||
return Err(SignerError::InputIndexOutOfRange);
|
||||
}
|
||||
|
||||
let psbt_input = &psbt.inputs[input_index];
|
||||
let tx_input = &psbt.global.unsigned_tx.input[input_index];
|
||||
let tx_input = &psbt.unsigned_tx.input[input_index];
|
||||
|
||||
let sighash = psbt_input.sighash_type.unwrap_or(SigHashType::All);
|
||||
let sighash = psbt_input.sighash_type.unwrap_or(SigHashType::All.into());
|
||||
let script = match psbt_input.redeem_script {
|
||||
Some(ref redeem_script) => redeem_script.clone(),
|
||||
None => {
|
||||
@@ -527,9 +536,8 @@ impl ComputeSighash for Legacy {
|
||||
};
|
||||
|
||||
Ok((
|
||||
psbt.global
|
||||
.unsigned_tx
|
||||
.signature_hash(input_index, &script, sighash.as_u32()),
|
||||
psbt.unsigned_tx
|
||||
.signature_hash(input_index, &script, sighash.to_u32()),
|
||||
sighash,
|
||||
))
|
||||
}
|
||||
@@ -549,15 +557,19 @@ impl ComputeSighash for Segwitv0 {
|
||||
fn sighash(
|
||||
psbt: &psbt::PartiallySignedTransaction,
|
||||
input_index: usize,
|
||||
) -> Result<(SigHash, SigHashType), SignerError> {
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.global.unsigned_tx.input.len() {
|
||||
) -> Result<(Sighash, psbt::PsbtSighashType), SignerError> {
|
||||
if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
|
||||
return Err(SignerError::InputIndexOutOfRange);
|
||||
}
|
||||
|
||||
let psbt_input = &psbt.inputs[input_index];
|
||||
let tx_input = &psbt.global.unsigned_tx.input[input_index];
|
||||
let tx_input = &psbt.unsigned_tx.input[input_index];
|
||||
|
||||
let sighash = psbt_input.sighash_type.unwrap_or(SigHashType::All);
|
||||
let sighash = psbt_input
|
||||
.sighash_type
|
||||
.unwrap_or(SigHashType::All.into())
|
||||
.ecdsa_hash_ty()
|
||||
.map_err(|_| SignerError::InvalidSighash)?;
|
||||
|
||||
// Always try first with the non-witness utxo
|
||||
let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
|
||||
@@ -600,13 +612,13 @@ impl ComputeSighash for Segwitv0 {
|
||||
};
|
||||
|
||||
Ok((
|
||||
bip143::SigHashCache::new(&psbt.global.unsigned_tx).signature_hash(
|
||||
bip143::SigHashCache::new(&psbt.unsigned_tx).signature_hash(
|
||||
input_index,
|
||||
&script,
|
||||
value,
|
||||
sighash,
|
||||
),
|
||||
sighash,
|
||||
sighash.into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -757,7 +769,7 @@ mod signers_container_tests {
|
||||
let secp: Secp256k1<All> = Secp256k1::new();
|
||||
let path = bip32::DerivationPath::from_str(PATH).unwrap();
|
||||
let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
|
||||
let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv);
|
||||
let tpub = bip32::ExtendedPubKey::from_priv(&secp, &tprv);
|
||||
let fingerprint = tprv.fingerprint(&secp);
|
||||
let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
|
||||
let pubkey = (tpub, path).into_descriptor_key().unwrap();
|
||||
|
||||
@@ -42,7 +42,7 @@ use std::default::Default;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
|
||||
use bitcoin::{OutPoint, Script, SigHashType, Transaction};
|
||||
use bitcoin::{OutPoint, Script, Transaction};
|
||||
|
||||
use miniscript::descriptor::DescriptorTrait;
|
||||
|
||||
@@ -103,10 +103,7 @@ impl TxBuilderContext for BumpFee {}
|
||||
/// builder.finish()?
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// psbt1.global.unsigned_tx.output[..2],
|
||||
/// psbt2.global.unsigned_tx.output[..2]
|
||||
/// );
|
||||
/// assert_eq!(psbt1.unsigned_tx.output[..2], psbt2.unsigned_tx.output[..2]);
|
||||
/// # Ok::<(), bdk::Error>(())
|
||||
/// ```
|
||||
///
|
||||
@@ -140,7 +137,7 @@ pub(crate) struct TxParams {
|
||||
pub(crate) utxos: Vec<WeightedUtxo>,
|
||||
pub(crate) unspendable: HashSet<OutPoint>,
|
||||
pub(crate) manually_selected_only: bool,
|
||||
pub(crate) sighash: Option<SigHashType>,
|
||||
pub(crate) sighash: Option<psbt::PsbtSighashType>,
|
||||
pub(crate) ordering: TxOrdering,
|
||||
pub(crate) locktime: Option<u32>,
|
||||
pub(crate) rbf: Option<RbfValue>,
|
||||
@@ -412,7 +409,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
|
||||
/// Sign with a specific sig hash
|
||||
///
|
||||
/// **Use this option very carefully**
|
||||
pub fn sighash(&mut self, sighash: SigHashType) -> &mut Self {
|
||||
pub fn sighash(&mut self, sighash: psbt::PsbtSighashType) -> &mut Self {
|
||||
self.params.sighash = Some(sighash);
|
||||
self
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user