Skip to content
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

Upgrade to rust-bitcoin 0.28 #606

Merged
merged 2 commits into from
May 12, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- added `OldestFirstCoinSelection` impl to `CoinSelectionAlgorithm`
- New MSRV set to `1.56`
- Add traits to reuse `Blockchain`s across multiple wallets (`BlockchainFactory` and `StatelessBlockchain`).
- Upgrade to rust-bitcoin `0.28`


## [v0.18.0] - [v0.17.0]
Expand Down
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ license = "MIT OR Apache-2.0"
[dependencies]
bdk-macros = "^0.6"
log = "^0.4"
miniscript = { version = "^6.1", features = ["use-serde"] }
bitcoin = { version = "^0.27", features = ["use-serde", "base64"] }
miniscript = { version = "7.0", features = ["use-serde"] }
bitcoin = { version = "0.28", features = ["use-serde", "base64"] }
serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1.0" }
rand = "^0.7"

# Optional dependencies
sled = { version = "0.34", optional = true }
electrum-client = { version = "0.8", optional = true }
electrum-client = { version = "0.10", optional = true }
rusqlite = { version = "0.25.3", optional = true }
ahash = { version = "=0.7.4", optional = true }
reqwest = { version = "0.11", optional = true, default-features = false, features = ["json"] }
Expand All @@ -37,8 +37,8 @@ lazy_static = { version = "1.4", optional = true }
bip39 = { version = "1.0.1", optional = true }
bitcoinconsensus = { version = "0.19.0-3", optional = true }

# Needed by bdk_blockchain_tests macro
bitcoincore-rpc = { version = "0.14", optional = true }
# Needed by bdk_blockchain_tests macro and the `rpc` feature
bitcoincore-rpc = { version = "0.15", optional = true }

# Platform-specific dependencies
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down Expand Up @@ -97,7 +97,7 @@ test-md-docs = ["electrum"]
lazy_static = "1.4"
env_logger = "0.7"
clap = "2.33"
electrsd = { version= "0.15", features = ["trigger", "bitcoind_22_0"] }
electrsd = { version= "0.19.1", features = ["bitcoind_22_0"] }

[[example]]
name = "address_validator"
Expand Down
9 changes: 5 additions & 4 deletions src/blockchain/compact_filters/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// licenses.

use std::collections::HashMap;
use std::io::BufReader;
use std::net::{TcpStream, ToSocketAddrs};
use std::sync::{Arc, Condvar, Mutex, RwLock};
use std::thread;
Expand All @@ -19,14 +20,13 @@ use socks::{Socks5Stream, ToTargetAddr};

use rand::{thread_rng, Rng};

use bitcoin::consensus::Encodable;
use bitcoin::consensus::{Decodable, Encodable};
use bitcoin::hash_types::BlockHash;
use bitcoin::network::constants::ServiceFlags;
use bitcoin::network::message::{NetworkMessage, RawNetworkMessage};
use bitcoin::network::message_blockdata::*;
use bitcoin::network::message_filter::*;
use bitcoin::network::message_network::VersionMessage;
use bitcoin::network::stream_reader::StreamReader;
use bitcoin::network::Address;
use bitcoin::{Block, Network, Transaction, Txid, Wtxid};

Expand Down Expand Up @@ -327,9 +327,10 @@ impl Peer {
};
}

let mut reader = StreamReader::new(connection, None);
let mut reader = BufReader::new(connection);
loop {
let raw_message: RawNetworkMessage = check_disconnect!(reader.read_next());
let raw_message: RawNetworkMessage =
check_disconnect!(Decodable::consensus_decode(&mut reader));

let in_message = if raw_message.magic != network.magic() {
continue;
Expand Down
4 changes: 2 additions & 2 deletions src/blockchain/esplora/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! see: <https://github.com/Blockstream/esplora/blob/master/API.md>
use crate::BlockTime;
use bitcoin::{OutPoint, Script, Transaction, TxIn, TxOut, Txid};
use bitcoin::{OutPoint, Script, Transaction, TxIn, TxOut, Txid, Witness};

#[derive(serde::Deserialize, Clone, Debug)]
pub struct PrevOut {
Expand Down Expand Up @@ -63,7 +63,7 @@ impl Tx {
},
script_sig: vin.scriptsig,
sequence: vin.sequence,
witness: vin.witness,
witness: Witness::from_vec(vin.witness),
})
.collect(),
output: self
Expand Down
43 changes: 33 additions & 10 deletions src/descriptor/derived.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ use std::hash::{Hash, Hasher};
use std::ops::Deref;

use bitcoin::hashes::hash160;
use bitcoin::PublicKey;
use bitcoin::{PublicKey, XOnlyPublicKey};

use miniscript::{descriptor::Wildcard, Descriptor, DescriptorPublicKey};
use miniscript::{MiniscriptKey, ToPublicKey, TranslatePk};
use miniscript::descriptor::{DescriptorSinglePub, SinglePubKey, Wildcard};
use miniscript::{Descriptor, DescriptorPublicKey, MiniscriptKey, ToPublicKey, TranslatePk};

use crate::wallet::utils::SecpCtx;

Expand Down Expand Up @@ -128,21 +128,44 @@ impl<'s> MiniscriptKey for DerivedDescriptorKey<'s> {
fn is_uncompressed(&self) -> bool {
self.0.is_uncompressed()
}
fn serialized_len(&self) -> usize {
self.0.serialized_len()
}
}

impl<'s> ToPublicKey for DerivedDescriptorKey<'s> {
fn to_public_key(&self) -> PublicKey {
match &self.0 {
DescriptorPublicKey::SinglePub(ref spub) => spub.key.to_public_key(),
DescriptorPublicKey::XPub(ref xpub) => {
DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: SinglePubKey::XOnly(_),
..
}) => panic!("Found x-only public key in non-tr descriptor"),
DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: SinglePubKey::FullKey(ref pk),
..
}) => *pk,
DescriptorPublicKey::XPub(ref xpub) => PublicKey::new(
xpub.xkey
.derive_pub(self.1, &xpub.derivation_path)
.expect("Shouldn't fail, only normal derivations")
.public_key,
),
}
}

fn to_x_only_pubkey(&self) -> XOnlyPublicKey {
match &self.0 {
DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: SinglePubKey::XOnly(ref pk),
..
}) => *pk,
DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: SinglePubKey::FullKey(ref pk),
..
}) => XOnlyPublicKey::from(pk.inner),
DescriptorPublicKey::XPub(ref xpub) => XOnlyPublicKey::from(
xpub.xkey
.derive_pub(self.1, &xpub.derivation_path)
.expect("Shouldn't fail, only normal derivations")
.public_key
}
.public_key,
),
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/descriptor/dsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,9 @@ mod test {
}

#[test]
#[should_panic(expected = "Miniscript(ContextError(CompressedOnly))")]
#[should_panic(
expected = "Miniscript(ContextError(CompressedOnly(\"04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4\")))"
)]
fn test_dsl_miniscript_checks() {
let mut uncompressed_pk =
PrivateKey::from_wif("L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6").unwrap();
Expand Down
35 changes: 22 additions & 13 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
use std::collections::{BTreeMap, HashMap, HashSet};
use std::ops::Deref;

use bitcoin::secp256k1;
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
use bitcoin::util::psbt;
use bitcoin::{Network, PublicKey, Script, TxOut};
use bitcoin::{Network, Script, TxOut};

use miniscript::descriptor::{DescriptorType, InnerXKey};
pub use miniscript::{
Expand Down Expand Up @@ -58,7 +59,7 @@ pub type DerivedDescriptor<'s> = Descriptor<DerivedDescriptorKey<'s>>;
///
/// [`psbt::Input`]: bitcoin::util::psbt::Input
/// [`psbt::Output`]: bitcoin::util::psbt::Output
pub type HdKeyPaths = BTreeMap<PublicKey, KeySource>;
pub type HdKeyPaths = BTreeMap<secp256k1::PublicKey, KeySource>;

/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
pub trait IntoWalletDescriptor {
Expand Down Expand Up @@ -306,6 +307,7 @@ pub(crate) trait DerivedDescriptorMeta {

pub(crate) trait DescriptorMeta {
fn is_witness(&self) -> bool;
fn is_taproot(&self) -> bool;
fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError>;
fn derive_from_hd_keypaths<'s>(
&self,
Expand All @@ -328,21 +330,21 @@ pub(crate) trait DescriptorScripts {
impl<'s> DescriptorScripts for DerivedDescriptor<'s> {
fn psbt_redeem_script(&self) -> Option<Script> {
match self.desc_type() {
DescriptorType::ShWpkh => Some(self.explicit_script()),
DescriptorType::ShWsh => Some(self.explicit_script().to_v0_p2wsh()),
DescriptorType::Sh => Some(self.explicit_script()),
DescriptorType::Bare => Some(self.explicit_script()),
DescriptorType::ShSortedMulti => Some(self.explicit_script()),
DescriptorType::ShWpkh => Some(self.explicit_script().unwrap()),
DescriptorType::ShWsh => Some(self.explicit_script().unwrap().to_v0_p2wsh()),
DescriptorType::Sh => Some(self.explicit_script().unwrap()),
DescriptorType::Bare => Some(self.explicit_script().unwrap()),
DescriptorType::ShSortedMulti => Some(self.explicit_script().unwrap()),
_ => None,
}
}

fn psbt_witness_script(&self) -> Option<Script> {
match self.desc_type() {
DescriptorType::Wsh => Some(self.explicit_script()),
DescriptorType::ShWsh => Some(self.explicit_script()),
DescriptorType::Wsh => Some(self.explicit_script().unwrap()),
DescriptorType::ShWsh => Some(self.explicit_script().unwrap()),
DescriptorType::WshSortedMulti | DescriptorType::ShWshSortedMulti => {
Some(self.explicit_script())
Some(self.explicit_script().unwrap())
}
_ => None,
}
Expand All @@ -362,6 +364,10 @@ impl DescriptorMeta for ExtendedDescriptor {
)
}

fn is_taproot(&self) -> bool {
self.desc_type() == DescriptorType::Tr
}

fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError> {
let mut answer = Vec::new();

Expand Down Expand Up @@ -448,15 +454,18 @@ impl DescriptorMeta for ExtendedDescriptor {
let descriptor = self.as_derived_fixed(secp);
match descriptor.desc_type() {
// TODO: add pk() here
DescriptorType::Pkh | DescriptorType::Wpkh | DescriptorType::ShWpkh
DescriptorType::Pkh
| DescriptorType::Wpkh
| DescriptorType::ShWpkh
| DescriptorType::Tr
if utxo.is_some()
&& descriptor.script_pubkey() == utxo.as_ref().unwrap().script_pubkey =>
{
Some(descriptor)
}
DescriptorType::Bare | DescriptorType::Sh | DescriptorType::ShSortedMulti
if psbt_input.redeem_script.is_some()
&& &descriptor.explicit_script()
&& &descriptor.explicit_script().unwrap()
== psbt_input.redeem_script.as_ref().unwrap() =>
{
Some(descriptor)
Expand All @@ -466,7 +475,7 @@ impl DescriptorMeta for ExtendedDescriptor {
| DescriptorType::ShWshSortedMulti
| DescriptorType::WshSortedMulti
if psbt_input.witness_script.is_some()
&& &descriptor.explicit_script()
&& &descriptor.explicit_script().unwrap()
== psbt_input.witness_script.as_ref().unwrap() =>
{
Some(descriptor)
Expand Down
Loading