Skip to content

update rust-bitcoin to 0.24.0 #130

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
Sep 18, 2020
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
8 changes: 5 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,17 @@ jobs:
- 1.22.0
- beta
- stable
steps:
- name: Checkout Crate
steps:
- name: Checkout Crate
uses: actions/checkout@v2
- name: Checkout Toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- name: Pin cc if rust 1.22
if: matrix.rust == '1.22.0'
run: cargo generate-lockfile --verbose && cargo update -p cc --precise "1.0.41" --verbose
- name: Running cargo
run: ./contrib/test.sh

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ unstable = []
default = []

[dependencies]
bitcoin = "0.23"
bitcoin = "0.24"

[dependencies.serde]
version = "1.0"
Expand Down
32 changes: 19 additions & 13 deletions src/descriptor/create_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ use ToPublicKey;
///
/// NOTE: Miniscript pushes should only be either boolean, 1 or 0, signatures, and hash preimages.
/// As per the current implementation, PUSH_NUM2 results in an error
fn instr_to_stackelem<'txin>(ins: &Instruction<'txin>) -> Result<StackElement<'txin>, Error> {
fn instr_to_stackelem<'txin>(
ins: &Result<Instruction<'txin>, bitcoin::blockdata::script::Error>,
) -> Result<StackElement<'txin>, Error> {
match *ins {
//Also covers the dissatisfied case as PushBytes0
Instruction::PushBytes(v) => Ok(StackElement::from(v)),
Instruction::Op(opcodes::all::OP_PUSHNUM_1) => Ok(StackElement::Satisfied),
Ok(Instruction::PushBytes(v)) => Ok(StackElement::from(v)),
Ok(Instruction::Op(opcodes::all::OP_PUSHNUM_1)) => Ok(StackElement::Satisfied),
_ => Err(Error::BadScriptSig),
}
}
Expand All @@ -39,7 +41,7 @@ fn parse_scriptsig_top<'txin>(
script_sig: &'txin bitcoin::Script,
) -> Result<(Vec<u8>, Stack<'txin>), Error> {
let stack: Result<Vec<StackElement>, Error> = script_sig
.iter(true)
.instructions_minimal()
.map(|instr| instr_to_stackelem(&instr))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not simply .map(instr_to_stackelem)? I tried locally, it compiles well with all versions, starting from MSRV

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unrelated to the intent of the PR. It is indeed a useful simplification. Can you raise another PR for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: #133

.collect();
let mut stack = stack?;
Expand All @@ -61,7 +63,7 @@ fn verify_p2pk<'txin>(
let pk_bytes = &script_pubkey.to_bytes();
if let Ok(pk) = bitcoin::PublicKey::from_slice(&pk_bytes[1..script_pubkey_len - 1]) {
let stack: Result<Vec<StackElement>, Error> = script_sig
.iter(true)
.instructions_minimal()
.map(|instr| instr_to_stackelem(&instr))
.collect();
if !witness.is_empty() {
Expand All @@ -87,7 +89,8 @@ fn verify_p2wpkh<'txin>(
}
if let Some((pk_bytes, witness)) = witness.split_last() {
if let Ok(pk) = bitcoin::PublicKey::from_slice(pk_bytes) {
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.map_err(|_| Error::InterpreterError(IntError::UncompressedPubkey))?;
if addr.script_pubkey() != *script_pubkey {
return Err(Error::InterpreterError(IntError::PkEvaluationError(pk)));
}
Expand Down Expand Up @@ -224,7 +227,7 @@ pub fn from_txin_with_witness_stack<'txin>(
} else {
//bare
let stack: Result<Vec<StackElement>, Error> = script_sig
.iter(true)
.instructions_minimal()
.map(|instr| instr_to_stackelem(&instr))
.collect();
if !witness.is_empty() {
Expand Down Expand Up @@ -318,8 +321,9 @@ mod tests {
assert_eq!(stack, stack![Push(&sigs[0])]);

//test wpkh
let script_pubkey =
bitcoin::Address::p2wpkh(&pks[1], bitcoin::Network::Bitcoin).script_pubkey();
let script_pubkey = bitcoin::Address::p2wpkh(&pks[1], bitcoin::Network::Bitcoin)
.unwrap()
.script_pubkey();
let script_sig = script::Builder::new().into_script();
let witness = vec![sigs[1].clone(), pks[1].clone().to_bytes()];
let (des, stack) = from_txin_with_witness_stack(&script_pubkey, &script_sig, &witness)
Expand Down Expand Up @@ -381,10 +385,12 @@ mod tests {
assert_eq!(stack, stack![Push(&sigs[1]), Push(&sigs[3])]);

//test shwpkh
let script_pubkey =
bitcoin::Address::p2shwpkh(&pks[2], bitcoin::Network::Bitcoin).script_pubkey();
let redeem_script =
bitcoin::Address::p2wpkh(&pks[2], bitcoin::Network::Bitcoin).script_pubkey();
let script_pubkey = bitcoin::Address::p2shwpkh(&pks[2], bitcoin::Network::Bitcoin)
.unwrap()
.script_pubkey();
let redeem_script = bitcoin::Address::p2wpkh(&pks[2], bitcoin::Network::Bitcoin)
.unwrap()
.script_pubkey();
let script_sig = script::Builder::new()
.push_slice(&redeem_script.to_bytes())
.into_script();
Expand Down
37 changes: 22 additions & 15 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,14 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
Descriptor::Bare(..) => None,
Descriptor::Pk(..) => None,
Descriptor::Pkh(ref pk) => Some(bitcoin::Address::p2pkh(&pk.to_public_key(), network)),
Descriptor::Wpkh(ref pk) => {
Some(bitcoin::Address::p2wpkh(&pk.to_public_key(), network))
}
Descriptor::ShWpkh(ref pk) => {
Some(bitcoin::Address::p2shwpkh(&pk.to_public_key(), network))
}
Descriptor::Wpkh(ref pk) => Some(
bitcoin::Address::p2wpkh(&pk.to_public_key(), network)
.expect("wpkh descriptors have compressed keys"),
),
Descriptor::ShWpkh(ref pk) => Some(
bitcoin::Address::p2shwpkh(&pk.to_public_key(), network)
.expect("shwpkh descriptors have compressed keys"),
),
Descriptor::Sh(ref miniscript) => {
Some(bitcoin::Address::p2sh(&miniscript.encode(), network))
}
Expand All @@ -152,12 +154,14 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
addr.script_pubkey()
}
Descriptor::Wpkh(ref pk) => {
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.expect("wpkh descriptors have compressed keys");
addr.script_pubkey()
}
Descriptor::ShWpkh(ref pk) => {
let addr =
bitcoin::Address::p2shwpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
bitcoin::Address::p2shwpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.expect("shwpkh descriptors have compressed keys");
addr.script_pubkey()
}
Descriptor::Sh(ref miniscript) => miniscript.encode().to_p2sh(),
Expand Down Expand Up @@ -185,7 +189,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
Descriptor::Wsh(..) | Descriptor::Wpkh(..) => Script::new(),
// segwit+p2sh
Descriptor::ShWpkh(ref pk) => {
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.expect("wpkh descriptors have compressed keys");
let redeem_script = addr.script_pubkey();
script::Builder::new()
.push_slice(&redeem_script[..])
Expand All @@ -211,7 +216,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
| Descriptor::Pkh(..)
| Descriptor::Wpkh(..) => self.script_pubkey(),
Descriptor::ShWpkh(ref pk) => {
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.expect("shwpkh descriptors have compressed keys");
addr.script_pubkey()
}
Descriptor::Sh(ref d) => d.encode(),
Expand Down Expand Up @@ -292,7 +298,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
let mut sig_vec = sig.0.serialize_der().to_vec();
sig_vec.push(sig.1.as_u32() as u8);
let addr =
bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
.expect("wpkh descriptors have compressed keys");
let redeem_script = addr.script_pubkey();

txin.script_sig = script::Builder::new()
Expand Down Expand Up @@ -926,21 +933,21 @@ mod tests {
let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(after(1000))").unwrap();
let script = descriptor.witness_script();

let actual_instructions: Vec<_> = script.iter(false).collect();
let actual_instructions: Vec<_> = script.instructions().collect();
let check = actual_instructions.last().unwrap();

assert_eq!(check, &Instruction::Op(OP_CLTV))
assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
}

#[test]
fn older_is_csv() {
let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(older(1000))").unwrap();
let script = descriptor.witness_script();

let actual_instructions: Vec<_> = script.iter(false).collect();
let actual_instructions: Vec<_> = script.instructions().collect();
let check = actual_instructions.last().unwrap();

assert_eq!(check, &Instruction::Op(OP_CSV))
assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions src/descriptor/satisfied_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ use {BitcoinSig, ToPublicKey};
/// Detailed Error type for Interpreter
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Error {
/// An uncompressed public key was encountered in a context where it is
/// disallowed (e.g. in a Segwit script or p2wpkh output)
UncompressedPubkey,
/// Unexpected Stack End, caused by popping extra elements from stack
UnexpectedStackEnd,
/// Unexpected Stack Push `StackElement::Push` element when the interpreter
Expand Down Expand Up @@ -95,6 +98,7 @@ impl error::Error for Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::UncompressedPubkey => f.write_str("Illegal use of uncompressed pubkey"),
Error::UnexpectedStackEnd => f.write_str("Unexpected Stack End"),
Error::UnexpectedStackElementPush => write!(f, "Got {}, expected Stack Boolean", 1),
Error::VerifyFailed => {
Expand Down
5 changes: 2 additions & 3 deletions src/miniscript/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ impl Iterator for TokenIter {
pub fn lex(script: &script::Script) -> Result<Vec<Token>, Error> {
let mut ret = Vec::with_capacity(script.len());

for ins in script.iter(true) {
match ins {
script::Instruction::Error(e) => return Err(Error::Script(e)),
for ins in script.instructions_minimal() {
match ins.map_err(Error::Script)? {
script::Instruction::Op(opcodes::all::OP_BOOLAND) => {
ret.push(Token::BoolAnd);
}
Expand Down