Skip to content

Bitcoin 0.28.0-rc.2 #324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "miniscript"
version = "7.0.0-rc.1"
version = "7.0.0-rc.2"
authors = ["Andrew Poelstra <[email protected]>, Sanket Kanjalkar <[email protected]>"]
repository = "https://github.com/apoelstra/miniscript"
description = "Miniscript: a subset of Bitcoin Script designed for analysis"
Expand All @@ -15,8 +15,7 @@ use-serde = ["bitcoin/use-serde", "serde"]
rand = ["bitcoin/rand"]

[dependencies]
# bitcoin = "0.27"
bitcoin = "0.28.0-rc.1"
bitcoin = "0.28.0-rc.2"

[dependencies.serde]
version = "1.0"
Expand Down
4 changes: 2 additions & 2 deletions examples/verify_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ extern crate bitcoin;
extern crate miniscript;

use bitcoin::consensus::Decodable;
use bitcoin::secp256k1; // secp256k1 re-exported from rust-bitcoin
use bitcoin::util::sighash;
use bitcoin::{secp256k1, TxOut}; // secp256k1 re-exported from rust-bitcoin
use miniscript::interpreter::KeySigPair;
use std::str::FromStr;

Expand Down Expand Up @@ -139,7 +139,7 @@ fn main() {

// We can set prevouts to be empty list because this is a legacy transaction
// and this information is not required for sighash computation.
let prevouts = sighash::Prevouts::All(&[]);
let prevouts = sighash::Prevouts::All::<TxOut>(&[]);

println!("\nExample two");
for elem in interpreter.iter(&secp, &transaction, 0, &prevouts) {
Expand Down
2 changes: 1 addition & 1 deletion integration_test/src/test_cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
let sig = secp.sign_ecdsa(&msg, &sk);
let pk = pks[sks.iter().position(|&x| x == sk).unwrap()];
psbts[i].inputs[0].partial_sigs.insert(
pk.inner,
pk,
bitcoin::EcdsaSig {
sig,
hash_ty: sighash_ty,
Expand Down
2 changes: 1 addition & 1 deletion integration_test/src/test_desc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
let pk = pks[sks.iter().position(|&x| x == sk).unwrap()];
assert!(secp.verify_ecdsa(&msg, &sig, &pk.inner).is_ok());
psbt.inputs[0].partial_sigs.insert(
pk.inner,
pk,
bitcoin::EcdsaSig {
sig,
hash_ty: hash_ty,
Expand Down
7 changes: 1 addition & 6 deletions src/interpreter/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use bitcoin;
use bitcoin::blockdata::witness::Witness;
use bitcoin::hashes::{hash160, sha256, Hash};
use bitcoin::schnorr::TapTweak;
use bitcoin::util::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX};

use {BareCtx, Legacy, Segwitv0, Tap};
Expand Down Expand Up @@ -241,11 +240,7 @@ pub(super) fn from_txdata<'txin>(
let tap_script = tap_script.encode();
// Should not really need to call dangerous assumed tweaked here.
// Should be fixed after RC
if ctrl_blk.verify_taproot_commitment(
&secp,
&output_key.dangerous_assume_tweaked(),
&tap_script,
) {
if ctrl_blk.verify_taproot_commitment(&secp, output_key, &tap_script) {
Ok((
Inner::Script(ms, ScriptType::Tr),
wit_stack,
Expand Down
21 changes: 11 additions & 10 deletions src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@

use bitcoin::blockdata::witness::Witness;
use bitcoin::util::{sighash, taproot};
use std::borrow::Borrow;
use std::fmt;
use std::str::FromStr;

use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
use bitcoin::{self, secp256k1};
use bitcoin::{self, secp256k1, TxOut};
use miniscript::context::NoChecks;
use miniscript::ScriptContext;
use Miniscript;
Expand Down Expand Up @@ -224,18 +225,18 @@ impl<'txin> Interpreter<'txin> {
/// - Insufficient sighash information is present
/// - sighash single without corresponding output
// TODO: Create a good first isse to change this to error
pub fn verify_sig<C: secp256k1::Verification>(
pub fn verify_sig<C: secp256k1::Verification, T: Borrow<TxOut>>(
&self,
secp: &secp256k1::Secp256k1<C>,
tx: &bitcoin::Transaction,
input_idx: usize,
prevouts: &sighash::Prevouts,
prevouts: &sighash::Prevouts<T>,
sig: &KeySigPair,
) -> bool {
fn get_prevout<'u>(
prevouts: &sighash::Prevouts<'u>,
fn get_prevout<'u, T: Borrow<TxOut>>(
prevouts: &'u sighash::Prevouts<'u, T>,
input_index: usize,
) -> Option<&'u bitcoin::TxOut> {
) -> Option<&'u T> {
match prevouts {
sighash::Prevouts::One(index, prevout) => {
if input_index == *index {
Expand All @@ -252,11 +253,11 @@ impl<'txin> Interpreter<'txin> {
KeySigPair::Ecdsa(key, ecdsa_sig) => {
let script_pubkey = self.script_code.as_ref().expect("Legacy have script code");
let sighash = if self.is_legacy() {
let sighash_u32 = ecdsa_sig.hash_ty.as_u32();
let sighash_u32 = ecdsa_sig.hash_ty.to_u32();
cache.legacy_signature_hash(input_idx, &script_pubkey, sighash_u32)
} else if self.is_segwit_v0() {
let amt = match get_prevout(prevouts, input_idx) {
Some(txout) => txout.value,
Some(txout) => txout.borrow().value,
None => return false,
};
cache.segwit_signature_hash(input_idx, &script_pubkey, amt, ecdsa_sig.hash_ty)
Expand Down Expand Up @@ -318,12 +319,12 @@ impl<'txin> Interpreter<'txin> {
/// - For legacy outputs, no information about prevouts is required
/// - For segwitv0 outputs, prevout at corresponding index with correct amount must be provided
/// - For taproot outputs, information about all prevouts must be supplied
pub fn iter<'iter, C: secp256k1::Verification>(
pub fn iter<'iter, C: secp256k1::Verification, T: Borrow<TxOut>>(
&'iter self,
secp: &'iter secp256k1::Secp256k1<C>,
tx: &'txin bitcoin::Transaction,
input_idx: usize,
prevouts: &'iter sighash::Prevouts, // actually a 'prevouts, but 'prevouts: 'iter
prevouts: &'iter sighash::Prevouts<T>, // actually a 'prevouts, but 'prevouts: 'iter
) -> Iter<'txin, 'iter> {
self.iter_custom(Box::new(move |sig| {
self.verify_sig(secp, tx, input_idx, prevouts, sig)
Expand Down
2 changes: 1 addition & 1 deletion src/miniscript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ mod tests {
));
assert_eq!(
ms.unwrap_err().to_string(),
"unexpected «Key secp256k1 error: secp: malformed public key»"
"unexpected «Key hex decoding error: bad hex string length 64 (expected 66)»"
);
Tapscript::from_str_insane(&format!(
"pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)"
Expand Down
22 changes: 9 additions & 13 deletions src/psbt/finalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
//!

use bitcoin::util::sighash::Prevouts;
use std::borrow::Borrow;
use util::witness_size;

use super::{sanity_check, Psbt};
Expand All @@ -28,7 +29,7 @@ use bitcoin::blockdata::witness::Witness;
use bitcoin::secp256k1::{self, Secp256k1};
use bitcoin::util::key::XOnlyPublicKey;
use bitcoin::util::taproot::LeafVersion;
use bitcoin::{self, PublicKey, Script};
use bitcoin::{self, PublicKey, Script, TxOut};
use descriptor::DescriptorTrait;
use interpreter;
use Descriptor;
Expand Down Expand Up @@ -116,11 +117,11 @@ pub(super) fn get_utxo(psbt: &Psbt, index: usize) -> Result<&bitcoin::TxOut, Inp
}

/// Get the Prevouts for the psbt
pub(super) fn prevouts<'a>(psbt: &'a Psbt) -> Result<Vec<bitcoin::TxOut>, super::Error> {
pub(super) fn prevouts<'a>(psbt: &'a Psbt) -> Result<Vec<&bitcoin::TxOut>, super::Error> {
let mut utxos = vec![];
for i in 0..psbt.inputs.len() {
let utxo_ref = get_utxo(psbt, i).map_err(|e| Error::InputError(e, i))?;
utxos.push(utxo_ref.clone()); // RC fix would allow references here instead of clone
utxos.push(utxo_ref);
}
Ok(utxos)
}
Expand Down Expand Up @@ -157,13 +158,12 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result<Descriptor<PublicKey>, In
// Partial sigs loses the compressed flag that is necessary
// TODO: See https://github.com/rust-bitcoin/rust-bitcoin/pull/836
// The type checker will fail again after we update to 0.28 and this can be removed
let pk = bitcoin::PublicKey::new(pk);
let addr = bitcoin::Address::p2pkh(&pk, bitcoin::Network::Bitcoin);
*script_pubkey == addr.script_pubkey()
})
.next();
match partial_sig_contains_pk {
Some((pk, _sig)) => Ok(Descriptor::new_pkh(bitcoin::PublicKey::new(*pk))),
Some((pk, _sig)) => Ok(Descriptor::new_pkh(*pk)),
None => Err(InputError::MissingPubkey),
}
} else if script_pubkey.is_v0_p2wpkh() {
Expand All @@ -174,14 +174,13 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result<Descriptor<PublicKey>, In
.filter(|&(&pk, _sig)| {
// Indirect way to check the equivalence of pubkey-hashes.
// Create a pubkey hash and check if they are the same.
let pk = bitcoin::PublicKey::new(pk);
let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin)
.expect("Address corresponding to valid pubkey");
*script_pubkey == addr.script_pubkey()
})
.next();
match partial_sig_contains_pk {
Some((pk, _sig)) => Ok(Descriptor::new_wpkh(bitcoin::PublicKey::new(*pk))?),
Some((pk, _sig)) => Ok(Descriptor::new_wpkh(*pk)?),
None => Err(InputError::MissingPubkey),
}
} else if script_pubkey.is_v0_p2wsh() {
Expand Down Expand Up @@ -233,16 +232,13 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result<Descriptor<PublicKey>, In
.partial_sigs
.iter()
.filter(|&(&pk, _sig)| {
let pk = bitcoin::PublicKey::new(pk);
let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin)
.expect("Address corresponding to valid pubkey");
*redeem_script == addr.script_pubkey()
})
.next();
match partial_sig_contains_pk {
Some((pk, _sig)) => {
Ok(Descriptor::new_sh_wpkh(bitcoin::PublicKey::new(*pk))?)
}
Some((pk, _sig)) => Ok(Descriptor::new_sh_wpkh(*pk)?),
None => Err(InputError::MissingPubkey),
}
} else {
Expand Down Expand Up @@ -300,11 +296,11 @@ pub fn interpreter_check<C: secp256k1::Verification>(
}

// Run the miniscript interpreter on a single psbt input
fn interpreter_inp_check<C: secp256k1::Verification>(
fn interpreter_inp_check<C: secp256k1::Verification, T: Borrow<TxOut>>(
psbt: &Psbt,
secp: &Secp256k1<C>,
index: usize,
utxos: &Prevouts,
utxos: &Prevouts<T>,
witness: &Witness,
script_sig: &Script,
) -> Result<(), Error> {
Expand Down
19 changes: 9 additions & 10 deletions src/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfie
fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option<bitcoin::EcdsaSig> {
self.psbt.inputs[self.index]
.partial_sigs
.get(&pk.to_public_key().inner)
.get(&pk.to_public_key())
.map(|sig| *sig)
}

Expand All @@ -298,11 +298,9 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfie
self.psbt.inputs[self.index]
.partial_sigs
.iter()
.filter(|&(pubkey, _sig)| {
bitcoin::PublicKey::new(*pubkey).to_pubkeyhash() == Pk::hash_to_hash160(pkh)
})
.filter(|&(pubkey, _sig)| pubkey.to_pubkeyhash() == Pk::hash_to_hash160(pkh))
.next()
.map(|(pk, sig)| (bitcoin::PublicKey::new(*pk), *sig))
.map(|(pk, sig)| (*pk, *sig))
}

fn check_after(&self, n: u32) -> bool {
Expand Down Expand Up @@ -393,21 +391,22 @@ fn sanity_check(psbt: &Psbt) -> Result<(), Error> {
None => EcdsaSigHashType::All,
};
for (key, ecdsa_sig) in &input.partial_sigs {
let flag = bitcoin::EcdsaSigHashType::from_u32_standard(ecdsa_sig.hash_ty as u32)
.map_err(|_| {
let flag = bitcoin::EcdsaSigHashType::from_standard(ecdsa_sig.hash_ty as u32).map_err(
|_| {
Error::InputError(
InputError::Interpreter(interpreter::Error::NonStandardSigHash(
ecdsa_sig.to_vec(),
)),
index,
)
})?;
},
)?;
if target_ecdsa_sighash_ty != flag {
return Err(Error::InputError(
InputError::WrongSigHashFlag {
required: target_ecdsa_sighash_ty,
got: flag,
pubkey: bitcoin::PublicKey::new(*key),
pubkey: *key,
},
index,
));
Expand Down Expand Up @@ -855,7 +854,7 @@ impl PsbtExt for Psbt {
} else {
inp_spk
};
let msg = cache.legacy_signature_hash(idx, script_code, hash_ty.as_u32())?;
let msg = cache.legacy_signature_hash(idx, script_code, hash_ty.to_u32())?;
Ok(PsbtSigHashMsg::EcdsaSigHash(msg))
}
}
Expand Down