Skip to content

Commit 1b23bc5

Browse files
committed
update to latest bitcoin master
1 parent 92eda4d commit 1b23bc5

File tree

13 files changed

+110
-70
lines changed

13 files changed

+110
-70
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description = "Miniscript: a subset of Bitcoin Script designed for analysis"
77
license = "CC0-1.0"
88

99
[features]
10-
fuzztarget = ["bitcoin/fuzztarget"]
10+
fuzztarget = []
1111
compiler = []
1212
trace = []
1313
unstable = []
@@ -16,7 +16,8 @@ use-serde = ["bitcoin/use-serde", "serde"]
1616
rand = ["bitcoin/rand"]
1717

1818
[dependencies]
19-
bitcoin = "0.27"
19+
# bitcoin = "0.27"
20+
bitcoin = {git = "https://github.com/rust-bitcoin/rust-bitcoin", rev = "f9b3fc9ce8f7ab8a287bcf6ffb254b3480a109e6"}
2021

2122
[dependencies.serde]
2223
version = "1.0"

examples/sign_multisig.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn main() {
7171
531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177",
7272
)
7373
.unwrap(),
74-
bitcoin::SigHashType::All,
74+
bitcoin::EcdsaSigHashType::All,
7575
);
7676

7777
let descriptor_str = format!(

examples/verify_tx.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ fn main() {
134134

135135
// We can set the amount passed to `sighash_verify` to 0 because this is a legacy
136136
// transaction and so the amount won't actually be checked by the signature
137-
let vfyfn = interpreter.sighash_verify(&secp, &transaction, 0, 0);
137+
let vfyfn = interpreter
138+
.sighash_verify(&secp, &transaction, 0, 0)
139+
.expect("Can only fail in sighash single when corresponding output is not present");
138140
// Restrict to sighash_all just to demonstrate how to add additional filters
139141
// `&_` needed here because of https://github.com/rust-lang/rust/issues/79187
140142
let vfyfn = move |pk: &_, bitcoinsig: miniscript::BitcoinSig| {
141-
bitcoinsig.1 == bitcoin::SigHashType::All && vfyfn(pk, bitcoinsig)
143+
bitcoinsig.1 == bitcoin::EcdsaSigHashType::All && vfyfn(pk, bitcoinsig)
142144
};
143145

144146
println!("\nExample two");
@@ -166,7 +168,8 @@ fn main() {
166168
.unwrap();
167169

168170
let iter = interpreter.iter(|pk, (sig, sighashtype)| {
169-
sighashtype == bitcoin::SigHashType::All && secp.verify(&message, &sig, &pk.key).is_ok()
171+
sighashtype == bitcoin::EcdsaSigHashType::All
172+
&& secp.verify(&message, &sig, &pk.key).is_ok()
170173
});
171174
println!("\nExample three");
172175
for elem in iter {

integration_test/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ fn main() {
198198
// Get the required sighash message
199199
let amt = btc(1).as_sat();
200200
let mut sighash_cache = bip143::SigHashCache::new(&psbts[i].global.unsigned_tx);
201-
let sighash_ty = bitcoin::SigHashType::All;
201+
let sighash_ty = bitcoin::EcdsaSigHashType::All;
202202
let sighash = sighash_cache.signature_hash(0, &ms.encode(), amt, sighash_ty);
203203

204204
// requires both signing and verification because we check the tx

src/descriptor/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ mod tests {
951951
impl Satisfier<bitcoin::PublicKey> for SimpleSat {
952952
fn lookup_sig(&self, pk: &bitcoin::PublicKey) -> Option<BitcoinSig> {
953953
if *pk == self.pk {
954-
Some((self.sig, bitcoin::SigHashType::All))
954+
Some((self.sig, bitcoin::EcdsaSigHashType::All))
955955
} else {
956956
None
957957
}
@@ -1160,8 +1160,8 @@ mod tests {
11601160
let satisfier = {
11611161
let mut satisfier = HashMap::with_capacity(2);
11621162

1163-
satisfier.insert(a, (sig_a.clone(), ::bitcoin::SigHashType::All));
1164-
satisfier.insert(b, (sig_b.clone(), ::bitcoin::SigHashType::All));
1163+
satisfier.insert(a, (sig_a.clone(), ::bitcoin::EcdsaSigHashType::All));
1164+
satisfier.insert(b, (sig_b.clone(), ::bitcoin::EcdsaSigHashType::All));
11651165

11661166
satisfier
11671167
};

src/descriptor/sh.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,10 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Sh<Pk> {
209209
Pk: ToPublicKey,
210210
{
211211
match self.inner {
212-
ShInner::Wsh(ref wsh) => Ok(bitcoin::Address::p2sh(&wsh.script_pubkey(), network)),
213-
ShInner::Wpkh(ref wpkh) => Ok(bitcoin::Address::p2sh(&wpkh.script_pubkey(), network)),
214-
ShInner::SortedMulti(ref smv) => Ok(bitcoin::Address::p2sh(&smv.encode(), network)),
215-
ShInner::Ms(ref ms) => Ok(bitcoin::Address::p2sh(&ms.encode(), network)),
212+
ShInner::Wsh(ref wsh) => Ok(bitcoin::Address::p2sh(&wsh.script_pubkey(), network)?),
213+
ShInner::Wpkh(ref wpkh) => Ok(bitcoin::Address::p2sh(&wpkh.script_pubkey(), network)?),
214+
ShInner::SortedMulti(ref smv) => Ok(bitcoin::Address::p2sh(&smv.encode(), network)?),
215+
ShInner::Ms(ref ms) => Ok(bitcoin::Address::p2sh(&ms.encode(), network)?),
216216
}
217217
}
218218

src/interpreter/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pub enum Error {
7171
Secp(secp256k1::Error),
7272
/// Miniscript requires the entire top level script to be satisfied.
7373
ScriptSatisfactionError,
74+
/// Errors in signature hash calculations
75+
SighashError(bitcoin::util::sighash::Error),
7476
/// An uncompressed public key was encountered in a context where it is
7577
/// disallowed (e.g. in a Segwit script or p2wpkh output)
7678
UncompressedPubkey,
@@ -95,6 +97,13 @@ impl From<secp256k1::Error> for Error {
9597
}
9698
}
9799

100+
#[doc(hidden)]
101+
impl From<bitcoin::util::sighash::Error> for Error {
102+
fn from(e: bitcoin::util::sighash::Error) -> Error {
103+
Error::SighashError(e)
104+
}
105+
}
106+
98107
#[doc(hidden)]
99108
impl From<::Error> for Error {
100109
fn from(e: ::Error) -> Error {
@@ -152,6 +161,7 @@ impl fmt::Display for Error {
152161
}
153162
Error::ScriptSatisfactionError => f.write_str("Top level script must be satisfied"),
154163
Error::Secp(ref e) => fmt::Display::fmt(e, f),
164+
Error::SighashError(ref e) => fmt::Display::fmt(e, f),
155165
Error::UncompressedPubkey => {
156166
f.write_str("uncompressed pubkey in non-legacy descriptor")
157167
}

src/interpreter/mod.rs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//!
2121
2222
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
23-
use bitcoin::util::bip143;
23+
use bitcoin::util::sighash;
2424
use bitcoin::{self, secp256k1};
2525
use miniscript::context::NoChecks;
2626
use miniscript::ScriptContext;
@@ -169,17 +169,17 @@ impl<'txin> Interpreter<'txin> {
169169
unsigned_tx: &bitcoin::Transaction,
170170
input_idx: usize,
171171
amount: u64,
172-
sighash_type: bitcoin::SigHashType,
173-
) -> secp256k1::Message {
172+
sighash_type: bitcoin::EcdsaSigHashType,
173+
) -> Result<secp256k1::Message, Error> {
174+
let mut cache = sighash::SigHashCache::new(unsigned_tx);
174175
let hash = if self.is_legacy() {
175-
unsigned_tx.signature_hash(input_idx, &self.script_code, sighash_type.as_u32())
176+
cache.legacy_signature_hash(input_idx, &self.script_code, sighash_type.as_u32())?
176177
} else {
177-
let mut sighash_cache = bip143::SigHashCache::new(unsigned_tx);
178-
sighash_cache.signature_hash(input_idx, &self.script_code, amount, sighash_type)
178+
cache.segwit_signature_hash(input_idx, &self.script_code, amount, sighash_type)?
179179
};
180180

181-
secp256k1::Message::from_slice(&hash[..])
182-
.expect("cryptographically unreachable for this to fail")
181+
Ok(secp256k1::Message::from_slice(&hash[..])
182+
.expect("cryptographically unreachable for this to fail"))
183183
}
184184

185185
/// Returns a closure which can be given to the `iter` method to check all signatures
@@ -189,46 +189,61 @@ impl<'txin> Interpreter<'txin> {
189189
unsigned_tx: &'a bitcoin::Transaction,
190190
input_idx: usize,
191191
amount: u64,
192-
) -> impl Fn(&bitcoin::PublicKey, BitcoinSig) -> bool + 'a {
192+
) -> Result<impl Fn(&bitcoin::PublicKey, BitcoinSig) -> bool + 'a, Error> {
193193
// Precompute all sighash types because the borrowck doesn't like us
194194
// pulling self into the closure
195195
let sighashes = [
196-
self.sighash_message(unsigned_tx, input_idx, amount, bitcoin::SigHashType::All),
197-
self.sighash_message(unsigned_tx, input_idx, amount, bitcoin::SigHashType::None),
198-
self.sighash_message(unsigned_tx, input_idx, amount, bitcoin::SigHashType::Single),
199196
self.sighash_message(
200197
unsigned_tx,
201198
input_idx,
202199
amount,
203-
bitcoin::SigHashType::AllPlusAnyoneCanPay,
204-
),
200+
bitcoin::EcdsaSigHashType::All,
201+
)?,
205202
self.sighash_message(
206203
unsigned_tx,
207204
input_idx,
208205
amount,
209-
bitcoin::SigHashType::NonePlusAnyoneCanPay,
210-
),
206+
bitcoin::EcdsaSigHashType::None,
207+
)?,
211208
self.sighash_message(
212209
unsigned_tx,
213210
input_idx,
214211
amount,
215-
bitcoin::SigHashType::SinglePlusAnyoneCanPay,
216-
),
212+
bitcoin::EcdsaSigHashType::Single,
213+
)?,
214+
self.sighash_message(
215+
unsigned_tx,
216+
input_idx,
217+
amount,
218+
bitcoin::EcdsaSigHashType::AllPlusAnyoneCanPay,
219+
)?,
220+
self.sighash_message(
221+
unsigned_tx,
222+
input_idx,
223+
amount,
224+
bitcoin::EcdsaSigHashType::NonePlusAnyoneCanPay,
225+
)?,
226+
self.sighash_message(
227+
unsigned_tx,
228+
input_idx,
229+
amount,
230+
bitcoin::EcdsaSigHashType::SinglePlusAnyoneCanPay,
231+
)?,
217232
];
218233

219-
move |pk: &bitcoin::PublicKey, (sig, sighash_type)| {
234+
Ok(move |pk: &bitcoin::PublicKey, (sig, sighash_type)| {
220235
// This is an awkward way to do this lookup, but it lets us do exhaustiveness
221236
// checking in case future rust-bitcoin versions add new sighash types
222237
let sighash = match sighash_type {
223-
bitcoin::SigHashType::All => sighashes[0],
224-
bitcoin::SigHashType::None => sighashes[1],
225-
bitcoin::SigHashType::Single => sighashes[2],
226-
bitcoin::SigHashType::AllPlusAnyoneCanPay => sighashes[3],
227-
bitcoin::SigHashType::NonePlusAnyoneCanPay => sighashes[4],
228-
bitcoin::SigHashType::SinglePlusAnyoneCanPay => sighashes[5],
238+
bitcoin::EcdsaSigHashType::All => sighashes[0],
239+
bitcoin::EcdsaSigHashType::None => sighashes[1],
240+
bitcoin::EcdsaSigHashType::Single => sighashes[2],
241+
bitcoin::EcdsaSigHashType::AllPlusAnyoneCanPay => sighashes[3],
242+
bitcoin::EcdsaSigHashType::NonePlusAnyoneCanPay => sighashes[4],
243+
bitcoin::EcdsaSigHashType::SinglePlusAnyoneCanPay => sighashes[5],
229244
};
230245
secp.verify(&sighash, &sig, &pk.key).is_ok()
231-
}
246+
})
232247
}
233248
}
234249

@@ -757,7 +772,7 @@ where
757772
F: FnOnce(&bitcoin::PublicKey, BitcoinSig) -> bool,
758773
{
759774
if let Some((sighash_byte, sig)) = sigser.split_last() {
760-
let sighashtype = bitcoin::SigHashType::from_u32_standard(*sighash_byte as u32)
775+
let sighashtype = bitcoin::EcdsaSigHashType::from_u32_standard(*sighash_byte as u32)
761776
.map_err(|_| Error::NonStandardSigHash([sig, &[*sighash_byte]].concat().to_vec()))?;
762777
let sig = secp256k1::Signature::from_der(sig)?;
763778
if verify_sig(pk, (sig, sighashtype)) {

src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,8 @@ pub enum Error {
475475
InvalidPush(Vec<u8>),
476476
/// rust-bitcoin script error
477477
Script(script::Error),
478+
/// rust-bitcoin address error
479+
AddrError(bitcoin::util::address::Error),
478480
/// A `CHECKMULTISIG` opcode was preceded by a number > 20
479481
CmsTooManyKeys(u32),
480482
/// Encountered unprintable character in descriptor
@@ -582,6 +584,13 @@ impl From<bitcoin::secp256k1::Error> for Error {
582584
}
583585
}
584586

587+
#[doc(hidden)]
588+
impl From<bitcoin::util::address::Error> for Error {
589+
fn from(e: bitcoin::util::address::Error) -> Error {
590+
Error::AddrError(e)
591+
}
592+
}
593+
585594
fn errstr(s: &str) -> Error {
586595
Error::Unexpected(s.to_owned())
587596
}
@@ -607,6 +616,7 @@ impl fmt::Display for Error {
607616
Error::NonMinimalVerify(ref tok) => write!(f, "{} VERIFY", tok),
608617
Error::InvalidPush(ref push) => write!(f, "invalid push {:?}", push), // TODO hexify this
609618
Error::Script(ref e) => fmt::Display::fmt(e, f),
619+
Error::AddrError(ref e) => fmt::Display::fmt(e, f),
610620
Error::CmsTooManyKeys(n) => write!(f, "checkmultisig with {} keys", n),
611621
Error::Unprintable(x) => write!(f, "unprintable character 0x{:02x}", x),
612622
Error::ExpectedChar(c) => write!(f, "expected {}", c),

src/miniscript/satisfy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use ScriptContext;
3535
use Terminal;
3636

3737
/// Type alias for a signature/hashtype pair
38-
pub type BitcoinSig = (secp256k1::Signature, bitcoin::SigHashType);
38+
pub type BitcoinSig = (secp256k1::Signature, bitcoin::EcdsaSigHashType);
3939
/// Type alias for 32 byte Preimage.
4040
pub type Preimage32 = [u8; 32];
4141

@@ -44,7 +44,7 @@ pub type Preimage32 = [u8; 32];
4444
/// Returns underlying secp if the Signature is not of correct format
4545
pub fn bitcoinsig_from_rawsig(rawsig: &[u8]) -> Result<BitcoinSig, ::interpreter::Error> {
4646
let (flag, sig) = rawsig.split_last().unwrap();
47-
let flag = bitcoin::SigHashType::from_u32_standard(*flag as u32)
47+
let flag = bitcoin::EcdsaSigHashType::from_u32_standard(*flag as u32)
4848
.map_err(|_| ::interpreter::Error::NonStandardSigHash([sig, &[*flag]].concat().to_vec()))?;
4949
let sig = secp256k1::Signature::from_der(sig)?;
5050
Ok((sig, flag))

src/policy/compiler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,7 @@ where
11611161
mod tests {
11621162
use super::*;
11631163
use bitcoin::blockdata::{opcodes, script};
1164-
use bitcoin::{self, hashes, secp256k1, SigHashType};
1164+
use bitcoin::{self, hashes, secp256k1, EcdsaSigHashType};
11651165
use std::collections::HashMap;
11661166
use std::str::FromStr;
11671167
use std::string::String;
@@ -1364,7 +1364,7 @@ mod tests {
13641364
assert_eq!(abs.n_keys(), 5);
13651365
assert_eq!(abs.minimum_n_keys(), Some(3));
13661366

1367-
let bitcoinsig = (sig, SigHashType::All);
1367+
let bitcoinsig = (sig, EcdsaSigHashType::All);
13681368
let mut sigvec = sig.serialize_der().to_vec();
13691369
sigvec.push(1); // sighash all
13701370

src/psbt/finalizer.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn get_scriptpubkey(psbt: &Psbt, index: usize) -> Result<&Script, InputError> {
3535
if let Some(ref witness_utxo) = inp.witness_utxo {
3636
script_pubkey = &witness_utxo.script_pubkey;
3737
} else if let Some(ref non_witness_utxo) = inp.non_witness_utxo {
38-
let vout = psbt.global.unsigned_tx.input[index].previous_output.vout;
38+
let vout = psbt.unsigned_tx.input[index].previous_output.vout;
3939
script_pubkey = &non_witness_utxo.output[vout as usize].script_pubkey;
4040
} else {
4141
return Err(InputError::MissingUtxo);
@@ -50,7 +50,7 @@ fn get_amt(psbt: &Psbt, index: usize) -> Result<u64, InputError> {
5050
if let Some(ref witness_utxo) = inp.witness_utxo {
5151
amt = witness_utxo.value;
5252
} else if let Some(ref non_witness_utxo) = inp.non_witness_utxo {
53-
let vout = psbt.global.unsigned_tx.input[index].previous_output.vout;
53+
let vout = psbt.unsigned_tx.input[index].previous_output.vout;
5454
amt = non_witness_utxo.output[vout as usize].value;
5555
} else {
5656
return Err(InputError::MissingUtxo);
@@ -219,15 +219,17 @@ pub fn interpreter_check<C: secp256k1::Verification>(
219219
// Now look at all the satisfied constraints. If everything is filled in
220220
// corrected, there should be no errors
221221

222-
let cltv = psbt.global.unsigned_tx.lock_time;
223-
let csv = psbt.global.unsigned_tx.input[index].sequence;
222+
let cltv = psbt.unsigned_tx.lock_time;
223+
let csv = psbt.unsigned_tx.input[index].sequence;
224224
let amt = get_amt(psbt, index).map_err(|e| Error::InputError(e, index))?;
225225

226226
let mut interpreter =
227227
interpreter::Interpreter::from_txdata(spk, &script_sig, &witness, cltv, csv)
228228
.map_err(|e| Error::InputError(InputError::Interpreter(e), index))?;
229229

230-
let vfyfn = interpreter.sighash_verify(&secp, &psbt.global.unsigned_tx, index, amt);
230+
let vfyfn = interpreter
231+
.sighash_verify(&secp, &psbt.unsigned_tx, index, amt)
232+
.map_err(|e| Error::InputError(InputError::Interpreter(e), index))?;
231233
if let Some(error) = interpreter.iter(vfyfn).filter_map(Result::err).next() {
232234
return Err(Error::InputError(InputError::Interpreter(error), index));
233235
}
@@ -268,7 +270,7 @@ pub fn finalize_helper<C: secp256k1::Verification>(
268270

269271
// Check well-formedness of input data
270272
for (n, input) in psbt.inputs.iter().enumerate() {
271-
let target = input.sighash_type.unwrap_or(bitcoin::SigHashType::All);
273+
let target = input.sighash_type.unwrap_or(bitcoin::EcdsaSigHashType::All);
272274
for (key, rawsig) in &input.partial_sigs {
273275
if rawsig.is_empty() {
274276
return Err(Error::InputError(
@@ -280,14 +282,15 @@ pub fn finalize_helper<C: secp256k1::Verification>(
280282
));
281283
}
282284
let (flag, sig) = rawsig.split_last().unwrap();
283-
let flag = bitcoin::SigHashType::from_u32_standard(*flag as u32).map_err(|_| {
284-
super::Error::InputError(
285-
InputError::Interpreter(interpreter::Error::NonStandardSigHash(
286-
[sig, &[*flag]].concat().to_vec(),
287-
)),
288-
n,
289-
)
290-
})?;
285+
let flag =
286+
bitcoin::EcdsaSigHashType::from_u32_standard(*flag as u32).map_err(|_| {
287+
super::Error::InputError(
288+
InputError::Interpreter(interpreter::Error::NonStandardSigHash(
289+
[sig, &[*flag]].concat().to_vec(),
290+
)),
291+
n,
292+
)
293+
})?;
291294
if target != flag {
292295
return Err(Error::InputError(
293296
InputError::WrongSigHashFlag {

0 commit comments

Comments
 (0)