Skip to content

Commit fde0d27

Browse files
committed
bitcoin: Depend on tip of master
1 parent d18e8ff commit fde0d27

File tree

10 files changed

+128
-45
lines changed

10 files changed

+128
-45
lines changed

Cargo.toml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ edition = "2018"
1313
[features]
1414
default = ["std"]
1515
std = ["bitcoin/std", "bitcoin/secp-recovery", "bech32/std"]
16-
no-std = ["bitcoin/no-std", "bech32/alloc"]
16+
no-std = ["bech32/alloc"]
1717
compiler = []
1818
trace = []
1919

@@ -23,15 +23,15 @@ base64 = ["bitcoin/base64"]
2323

2424
[dependencies]
2525
bech32 = { version = "0.11.0", default-features = false }
26-
bitcoin = { version = "0.31.0", default-features = false }
26+
bitcoin = { version = "0.32.0", default-features = false }
2727

2828
# Do NOT use this as a feature! Use the `serde` feature instead.
2929
actual-serde = { package = "serde", version = "1.0.103", optional = true }
3030

3131
[dev-dependencies]
3232
serde_test = "1.0.147"
33-
bitcoin = { version = "0.31.0", features = ["base64"] }
34-
secp256k1 = {version = "0.28.0", features = ["rand-std"]}
33+
bitcoin = { version = "0.32.0", features = ["base64"] }
34+
secp256k1 = {version = "0.29.0", features = ["rand-std"]}
3535

3636
[[example]]
3737
name = "htlc"
@@ -64,3 +64,30 @@ required-features = ["std", "base64"]
6464
[workspace]
6565
members = ["bitcoind-tests", "fuzz"]
6666
exclude = ["embedded"]
67+
68+
[patch.crates-io.secp256k1]
69+
path = "/home/tobin/build/github.com/tcharding/rust-secp256k1/test-bitcoin"
70+
71+
[patch.crates-io.bitcoind]
72+
path = "/home/tobin/build/github.com/tcharding/bitcoind/test-bitcoin"
73+
74+
[patch.crates-io.bitcoincore-rpc]
75+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoincore-rpc/test-bitcoin/client"
76+
77+
[patch.crates-io.base58ck]
78+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/base58"
79+
80+
[patch.crates-io.bitcoin]
81+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/bitcoin"
82+
83+
[patch.crates-io.bitcoin_hashes]
84+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/hashes"
85+
86+
[patch.crates-io.bitcoin-internals]
87+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/internals"
88+
89+
[patch.crates-io.bitcoin-io]
90+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/io"
91+
92+
[patch.crates-io.bitcoin-units]
93+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/units"

bitcoind-tests/Cargo.toml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@ publish = false
99

1010
[dependencies]
1111
miniscript = {path = "../"}
12-
bitcoind = { version = "0.34.0" }
12+
bitcoind = { version = "0.35.0" }
1313
actual-rand = { package = "rand", version = "0.8.4"}
14-
secp256k1 = {version = "0.28.0", features = ["rand-std"]}
14+
secp256k1 = {version = "0.29.0", features = ["rand-std"]}
15+
16+
[patch.crates-io.secp256k1]
17+
path = "/home/tobin/build/github.com/tcharding/rust-secp256k1/test-bitcoin"
18+
19+
[patch.crates-io.bitcoind]
20+
path = "/home/tobin/build/github.com/tcharding/bitcoind/test-bitcoin"
21+
22+
[patch.crates-io.bitcoincore-rpc]
23+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoincore-rpc/test-bitcoin/client"
24+
25+
[patch.crates-io.base58ck]
26+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/base58"
27+
28+
[patch.crates-io.bitcoin]
29+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/bitcoin"
30+
31+
[patch.crates-io.bitcoin_hashes]
32+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/hashes"
33+
34+
[patch.crates-io.bitcoin-internals]
35+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/internals"
36+
37+
[patch.crates-io.bitcoin-io]
38+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/io"
39+
40+
[patch.crates-io.bitcoin-units]
41+
path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/release/units"

src/descriptor/key.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use core::str::FromStr;
77
use std::error;
88

99
use bitcoin::bip32::{self, XKeyIdentifier};
10-
use bitcoin::hashes::hex::FromHex;
1110
use bitcoin::hashes::{hash160, ripemd160, sha256, Hash, HashEngine};
1211
use bitcoin::key::XOnlyPublicKey;
1312
use bitcoin::secp256k1::{Secp256k1, Signing, Verification};

src/descriptor/segwitv0.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,15 +366,13 @@ impl<Pk: MiniscriptKey> Wpkh<Pk> {
366366
impl<Pk: MiniscriptKey + ToPublicKey> Wpkh<Pk> {
367367
/// Obtains the corresponding script pubkey for this descriptor.
368368
pub fn script_pubkey(&self) -> ScriptBuf {
369-
let addr = Address::p2wpkh(&self.pk.to_public_key(), Network::Bitcoin)
370-
.expect("wpkh descriptors have compressed keys");
369+
let addr = Address::p2wpkh(&self.pk.to_compressed_public_key(), Network::Bitcoin);
371370
addr.script_pubkey()
372371
}
373372

374373
/// Obtains the corresponding script pubkey for this descriptor.
375374
pub fn address(&self, network: Network) -> Address {
376-
Address::p2wpkh(&self.pk.to_public_key(), network)
377-
.expect("Rust Miniscript types don't allow uncompressed pks in segwit descriptors")
375+
Address::p2wpkh(&self.pk.to_compressed_public_key(), network)
378376
}
379377

380378
/// Obtains the underlying miniscript for this descriptor.

src/interpreter/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub enum Error {
9191
/// Schnorr Signature error
9292
SchnorrSig(bitcoin::taproot::SigFromSliceError),
9393
/// Errors in signature hash calculations
94-
SighashError(bitcoin::sighash::Error),
94+
SighashError(bitcoin::sighash::InvalidSighashTypeError),
9595
/// Taproot Annex Unsupported
9696
TapAnnexUnsupported,
9797
/// An uncompressed public key was encountered in a context where it is
@@ -234,8 +234,8 @@ impl From<secp256k1::Error> for Error {
234234
}
235235

236236
#[doc(hidden)]
237-
impl From<bitcoin::sighash::Error> for Error {
238-
fn from(e: bitcoin::sighash::Error) -> Error { Error::SighashError(e) }
237+
impl From<bitcoin::sighash::InvalidSighashTypeError> for Error {
238+
fn from(e: bitcoin::sighash::InvalidSighashTypeError) -> Error { Error::SighashError(e) }
239239
}
240240

241241
#[doc(hidden)]

src/interpreter/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'txin> Interpreter<'txin> {
211211
KeySigPair::Ecdsa(key, ecdsa_sig) => {
212212
let script_pubkey = self.script_code.as_ref().expect("Legacy have script code");
213213
let msg = if self.is_legacy() {
214-
let sighash_u32 = ecdsa_sig.hash_ty.to_u32();
214+
let sighash_u32 = ecdsa_sig.sighash_type.to_u32();
215215
let sighash =
216216
cache.legacy_signature_hash(input_idx, script_pubkey, sighash_u32);
217217
sighash.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array()))
@@ -220,11 +220,12 @@ impl<'txin> Interpreter<'txin> {
220220
Some(txout) => txout.borrow().value,
221221
None => return false,
222222
};
223-
let sighash = cache.segwit_signature_hash(
223+
// TODO: Don't manually handle the script code.
224+
let sighash = cache.p2wsh_signature_hash(
224225
input_idx,
225226
script_pubkey,
226227
amt,
227-
ecdsa_sig.hash_ty,
228+
ecdsa_sig.sighash_type,
228229
);
229230
sighash.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array()))
230231
} else {
@@ -233,12 +234,12 @@ impl<'txin> Interpreter<'txin> {
233234
};
234235

235236
let success =
236-
msg.map(|msg| secp.verify_ecdsa(&msg, &ecdsa_sig.sig, &key.inner).is_ok());
237+
msg.map(|msg| secp.verify_ecdsa(&msg, &ecdsa_sig.signature, &key.inner).is_ok());
237238
success.unwrap_or(false) // unwrap_or checks for errors, while success would have checksig results
238239
}
239240
KeySigPair::Schnorr(xpk, schnorr_sig) => {
240241
let sighash_msg = if self.is_taproot_v1_key_spend() {
241-
cache.taproot_key_spend_signature_hash(input_idx, prevouts, schnorr_sig.hash_ty)
242+
cache.taproot_key_spend_signature_hash(input_idx, prevouts, schnorr_sig.sighash_type)
242243
} else if self.is_taproot_v1_script_spend() {
243244
let tap_script = self.script_code.as_ref().expect(
244245
"Internal Hack: Saving leaf script instead\
@@ -252,7 +253,7 @@ impl<'txin> Interpreter<'txin> {
252253
input_idx,
253254
prevouts,
254255
leaf_hash,
255-
schnorr_sig.hash_ty,
256+
schnorr_sig.sighash_type,
256257
)
257258
} else {
258259
// schnorr sigs in ecdsa descriptors
@@ -261,7 +262,7 @@ impl<'txin> Interpreter<'txin> {
261262
let msg =
262263
sighash_msg.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array()));
263264
let success =
264-
msg.map(|msg| secp.verify_schnorr(&schnorr_sig.sig, &msg, xpk).is_ok());
265+
msg.map(|msg| secp.verify_schnorr(&schnorr_sig.signature, &msg, xpk).is_ok());
265266
success.unwrap_or(false) // unwrap_or_default checks for errors, while success would have checksig results
266267
}
267268
}

src/lib.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ pub trait ToPublicKey: MiniscriptKey {
217217
/// Converts an object to a public key
218218
fn to_public_key(&self) -> bitcoin::PublicKey;
219219

220+
/// Converts an object to a compressed public key.
221+
fn to_compressed_public_key(&self) -> bitcoin::CompressedPublicKey {
222+
use core::convert::TryFrom;
223+
// TODO: Can we remove to_public_key altogether?
224+
bitcoin::key::CompressedPublicKey::try_from(self.to_public_key()).expect("for now just panic for uncompressed keys")
225+
}
226+
220227
/// Convert an object to x-only pubkey
221228
fn to_x_only_pubkey(&self) -> bitcoin::secp256k1::XOnlyPublicKey {
222229
let pk = self.to_public_key();
@@ -423,7 +430,9 @@ pub enum Error {
423430
/// rust-bitcoin script error
424431
Script(script::Error),
425432
/// rust-bitcoin address error
426-
AddrError(bitcoin::address::Error),
433+
AddrError(bitcoin::address::ParseError),
434+
/// rust-bitcoin p2sh address error
435+
AddrP2shError(bitcoin::address::P2shError),
427436
/// A `CHECKMULTISIG` opcode was preceded by a number > 20
428437
CmsTooManyKeys(u32),
429438
/// A tapscript multi_a cannot support more than Weight::MAX_BLOCK/32 keys
@@ -451,7 +460,7 @@ pub enum Error {
451460
/// Parsed a miniscript but there were more script opcodes after it
452461
Trailing(String),
453462
/// Failed to parse a push as a public key
454-
BadPubkey(bitcoin::key::Error),
463+
BadPubkey(bitcoin::key::ParsePublicKeyError),
455464
/// Could not satisfy a script (fragment) because of a missing hash preimage
456465
MissingHash(sha256::Hash),
457466
/// Could not satisfy a script (fragment) because of a missing signature
@@ -518,6 +527,7 @@ impl fmt::Display for Error {
518527
},
519528
Error::Script(ref e) => fmt::Display::fmt(e, f),
520529
Error::AddrError(ref e) => fmt::Display::fmt(e, f),
530+
Error::AddrP2shError(ref e) => fmt::Display::fmt(e, f),
521531
Error::CmsTooManyKeys(n) => write!(f, "checkmultisig with {} keys", n),
522532
Error::Unprintable(x) => write!(f, "unprintable character 0x{:02x}", x),
523533
Error::ExpectedChar(c) => write!(f, "expected {}", c),
@@ -621,6 +631,7 @@ impl error::Error for Error {
621631
| MultipathDescLenMismatch => None,
622632
Script(e) => Some(e),
623633
AddrError(e) => Some(e),
634+
AddrP2shError(e) => Some(e),
624635
BadPubkey(e) => Some(e),
625636
Secp(e) => Some(e),
626637
#[cfg(feature = "compiler")]
@@ -664,8 +675,13 @@ impl From<bitcoin::secp256k1::Error> for Error {
664675
}
665676

666677
#[doc(hidden)]
667-
impl From<bitcoin::address::Error> for Error {
668-
fn from(e: bitcoin::address::Error) -> Error { Error::AddrError(e) }
678+
impl From<bitcoin::address::ParseError> for Error {
679+
fn from(e: bitcoin::address::ParseError) -> Error { Error::AddrError(e) }
680+
}
681+
682+
#[doc(hidden)]
683+
impl From<bitcoin::address::P2shError> for Error {
684+
fn from(e: bitcoin::address::P2shError) -> Error { Error::AddrP2shError(e) }
669685
}
670686

671687
#[doc(hidden)]

src/miniscript/decode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl ParseableKey for bitcoin::secp256k1::XOnlyPublicKey {
4747
#[derive(Debug, Clone, PartialEq, Eq)]
4848
pub enum KeyParseError {
4949
/// Bitcoin PublicKey parse error
50-
FullKeyParseError(bitcoin::key::Error),
50+
FullKeyParseError(bitcoin::key::FromSliceError),
5151
/// Xonly key parse Error
5252
XonlyKeyParseError(bitcoin::secp256k1::Error),
5353
}

src/psbt/finalizer.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,11 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result<Descriptor<PublicKey>, In
182182
} else if script_pubkey.is_p2wpkh() {
183183
// 3. `Wpkh`: creates a `wpkh` descriptor if the partial sig has corresponding pk.
184184
let partial_sig_contains_pk = inp.partial_sigs.iter().find(|&(&pk, _sig)| {
185+
use core::convert::TryFrom;
186+
let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key");
185187
// Indirect way to check the equivalence of pubkey-hashes.
186188
// Create a pubkey hash and check if they are the same.
187-
let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin)
188-
.expect("Address corresponding to valid pubkey");
189+
let addr = bitcoin::Address::p2wpkh(&compressed, bitcoin::Network::Bitcoin);
189190
*script_pubkey == addr.script_pubkey()
190191
});
191192
match partial_sig_contains_pk {
@@ -242,8 +243,9 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result<Descriptor<PublicKey>, In
242243
} else if redeem_script.is_p2wpkh() {
243244
// 6. `ShWpkh` case
244245
let partial_sig_contains_pk = inp.partial_sigs.iter().find(|&(&pk, _sig)| {
245-
let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin)
246-
.expect("Address corresponding to valid pubkey");
246+
use core::convert::TryFrom;
247+
let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key");
248+
let addr = bitcoin::Address::p2wpkh(&compressed, bitcoin::Network::Bitcoin);
247249
*redeem_script == addr.script_pubkey()
248250
});
249251
match partial_sig_contains_pk {

src/psbt/mod.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub enum InputError {
8686
/// Get the secp Errors directly
8787
SecpErr(bitcoin::secp256k1::Error),
8888
/// Key errors
89-
KeyErr(bitcoin::key::Error),
89+
KeyErr(bitcoin::key::FromSliceError),
9090
/// Could not satisfy taproot descriptor
9191
/// This error is returned when both script path and key paths could not be
9292
/// satisfied. We cannot return a detailed error because we try all miniscripts
@@ -229,8 +229,8 @@ impl From<bitcoin::secp256k1::Error> for InputError {
229229
}
230230

231231
#[doc(hidden)]
232-
impl From<bitcoin::key::Error> for InputError {
233-
fn from(e: bitcoin::key::Error) -> InputError { InputError::KeyErr(e) }
232+
impl From<bitcoin::key::FromSliceError> for InputError {
233+
fn from(e: bitcoin::key::FromSliceError) -> InputError { InputError::KeyErr(e) }
234234
}
235235

236236
/// Psbt satisfier for at inputs at a particular index
@@ -399,7 +399,7 @@ fn sanity_check(psbt: &Psbt) -> Result<(), Error> {
399399
None => sighash::EcdsaSighashType::All,
400400
};
401401
for (key, ecdsa_sig) in &input.partial_sigs {
402-
let flag = sighash::EcdsaSighashType::from_standard(ecdsa_sig.hash_ty as u32).map_err(
402+
let flag = sighash::EcdsaSighashType::from_standard(ecdsa_sig.sighash_type as u32).map_err(
403403
|_| {
404404
Error::InputError(
405405
InputError::Interpreter(interpreter::Error::NonStandardSighash(
@@ -740,7 +740,7 @@ impl PsbtExt for Psbt {
740740
let desc_type = desc.desc_type();
741741

742742
if let Some(non_witness_utxo) = &input.non_witness_utxo {
743-
if txin.previous_output.txid != non_witness_utxo.txid() {
743+
if txin.previous_output.txid != non_witness_utxo.compute_txid() {
744744
return Err(UtxoUpdateError::UtxoCheck);
745745
}
746746
}
@@ -1313,10 +1313,12 @@ pub enum SighashError {
13131313
MissingSpendUtxos,
13141314
/// Invalid Sighash type
13151315
InvalidSighashType,
1316-
/// Sighash computation error
1317-
/// Only happens when single does not have corresponding output as psbts
1318-
/// already have information to compute the sighash
1319-
SighashComputationError(sighash::Error),
1316+
/// Computation error for taproot sighash.
1317+
SighashTaproot(sighash::TaprootError),
1318+
/// Computation error for P2WPKH sighash.
1319+
SighashP2wpkh(sighash::P2wpkhError),
1320+
/// Computation error for P2WSH sighash.
1321+
TransactionInputsIndex(transaction::InputsIndexError),
13201322
/// Missing Witness script
13211323
MissingWitnessScript,
13221324
/// Missing Redeem script,
@@ -1332,11 +1334,11 @@ impl fmt::Display for SighashError {
13321334
SighashError::MissingInputUtxo => write!(f, "Missing input utxo in pbst"),
13331335
SighashError::MissingSpendUtxos => write!(f, "Missing Psbt spend utxos"),
13341336
SighashError::InvalidSighashType => write!(f, "Invalid Sighash type"),
1335-
SighashError::SighashComputationError(e) => {
1336-
write!(f, "Sighash computation error : {}", e)
1337-
}
13381337
SighashError::MissingWitnessScript => write!(f, "Missing Witness Script"),
13391338
SighashError::MissingRedeemScript => write!(f, "Missing Redeem Script"),
1339+
SighashError::SighashTaproot(ref e) => write!(f, "sighash taproot: {}", e),
1340+
SighashError::SighashP2wpkh(ref e) => write!(f, "sighash p2wpkh: {}", e),
1341+
SighashError::TransactionInputsIndex(ref e) => write!(f, "tx inputs index: {}", e),
13401342
}
13411343
}
13421344
}
@@ -1353,13 +1355,24 @@ impl error::Error for SighashError {
13531355
| InvalidSighashType
13541356
| MissingWitnessScript
13551357
| MissingRedeemScript => None,
1356-
SighashComputationError(e) => Some(e),
1358+
SighashTaproot(ref e) => Some(e),
1359+
SighashP2wpkh(ref e) => Some(e),
1360+
TransactionInputsIndex(ref e) => Some(e),
1361+
13571362
}
13581363
}
13591364
}
13601365

1361-
impl From<sighash::Error> for SighashError {
1362-
fn from(e: sighash::Error) -> Self { SighashError::SighashComputationError(e) }
1366+
impl From<sighash::TaprootError> for SighashError {
1367+
fn from(e: sighash::TaprootError) -> Self { SighashError::SighashTaproot(e) }
1368+
}
1369+
1370+
impl From<sighash::P2wpkhError> for SighashError {
1371+
fn from(e: sighash::P2wpkhError) -> Self { SighashError::SighashP2wpkh(e) }
1372+
}
1373+
1374+
impl From<transaction::InputsIndexError> for SighashError {
1375+
fn from(e: transaction::InputsIndexError) -> Self { SighashError::TransactionInputsIndex(e) }
13631376
}
13641377

13651378
/// Sighash message(signing data) for a given psbt transaction input.

0 commit comments

Comments
 (0)