diff --git a/Cargo.toml b/Cargo.toml index d0f337a6..c04cc5c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,9 @@ json-contract = ["serde_json"] base64 = ["bitcoin/base64"] [dependencies] -bitcoin = "0.31.0" -secp256k1-zkp = { version = "0.10.0", features = ["global-context", "hashes"] } +bech32 = "0.11.0" +bitcoin = "0.32.2" +secp256k1-zkp = { version = "0.11.0", features = ["global-context", "hashes"] } # Used for ContractHash::from_json_contract. serde_json = { version = "1.0", optional = true } diff --git a/contrib/test.sh b/contrib/test.sh index eec63a16..13ca1f08 100755 --- a/contrib/test.sh +++ b/contrib/test.sh @@ -66,7 +66,12 @@ fi if [ "$DO_INTEGRATION" = true ] then ( + BITCOIND_EXE_DEFAULT="$(git rev-parse --show-toplevel)/elementsd-tests/bin/bitcoind" + ELEMENTSD_EXE_DEFAULT="$(git rev-parse --show-toplevel)/elementsd-tests/bin/elementsd" + cd elementsd-tests + BITCOIND_EXE=${BITCOIND_EXE:=${BITCOIND_EXE_DEFAULT}} \ + ELEMENTSD_EXE=${ELEMENTSD_EXE:=${ELEMENTSD_EXE_DEFAULT}} \ cargo test cd .. ) diff --git a/elementsd-tests/Cargo.toml b/elementsd-tests/Cargo.toml index 83ea1e43..52fc8620 100644 --- a/elementsd-tests/Cargo.toml +++ b/elementsd-tests/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitcoin = "0.31.0" +bitcoin = "0.32.2" elements = {path = "../", features = ["base64"]} -elementsd = "0.9.0" +elementsd = "0.11.0" rand = "0.8" diff --git a/elementsd-tests/src/lib.rs b/elementsd-tests/src/lib.rs index 8efdc5e5..5fda0064 100644 --- a/elementsd-tests/src/lib.rs +++ b/elementsd-tests/src/lib.rs @@ -1,11 +1,10 @@ - #[cfg(test)] mod pset; #[cfg(test)] mod taproot; -use elementsd::bitcoincore_rpc::RpcApi; use elementsd::bitcoincore_rpc::jsonrpc::serde_json::{json, Value}; +use elementsd::bitcoincore_rpc::RpcApi; #[cfg(test)] use elementsd::bitcoind::{self, BitcoinD}; use elementsd::ElementsD; @@ -33,7 +32,10 @@ trait Call { impl Call for ElementsD { fn call(&self, cmd: &str, args: &[Value]) -> Value { - self.client().call::(cmd, args).unwrap() + match self.client().call::(cmd, args) { + Ok(v) => v, + Err(e) => panic!("error {} while calling {} with {:?}", e, cmd, args), + } } fn decode_psbt(&self, psbt: &str) -> Option { @@ -132,45 +134,10 @@ impl Call for ElementsD { .unwrap() .to_string() } - } #[cfg(test)] fn setup(validate_pegin: bool) -> (ElementsD, Option) { - // Create env var BITCOIND_EXE_PATH to point to the ../bitcoind/bin/bitcoind binary - let key = "BITCOIND_EXE"; - if std::env::var(key).is_err() { - let mut root_path = std::env::current_dir().unwrap(); - while std::fs::metadata(root_path.join("LICENSE")).is_err() { - if !root_path.pop() { - panic!("Could not find LICENSE file; do not know where repo root is."); - } - } - - let bitcoind_path = root_path - .join("elementsd-tests") - .join("bin") - .join("bitcoind"); - std::env::set_var(key, bitcoind_path); - } - - // Create env var BITCOIND_EXE_PATH to point to the ../bitcoind/bin/bitcoind binary - let key = "ELEMENTSD_EXE"; - if std::env::var(key).is_err() { - let mut root_path = std::env::current_dir().unwrap(); - while std::fs::metadata(root_path.join("LICENSE")).is_err() { - if !root_path.pop() { - panic!("Could not find LICENSE file; do not know where repo root is."); - } - } - - let bitcoind_path = root_path - .join("elementsd-tests") - .join("bin") - .join("elementsd"); - std::env::set_var(key, bitcoind_path); - } - let mut bitcoind = None; if validate_pegin { let bitcoind_exe = bitcoind::exe_path().unwrap(); diff --git a/src/address.rs b/src/address.rs index edbe3006..9d21f134 100644 --- a/src/address.rs +++ b/src/address.rs @@ -21,7 +21,7 @@ use std::fmt; use std::fmt::Write as _; use std::str::FromStr; -use crate::bech32::{Bech32, Bech32m, ByteIterExt, Fe32, Fe32IterExt, Hrp}; +use bech32::{Bech32, Bech32m, ByteIterExt, Fe32, Fe32IterExt, Hrp}; use crate::blech32::{Blech32, Blech32m}; use crate::hashes::Hash; use bitcoin::base58; @@ -44,7 +44,7 @@ pub enum AddressError { /// Base58 encoding error Base58(base58::Error), /// Bech32 encoding error - Bech32(crate::bech32::primitives::decode::SegwitHrpstringError), + Bech32(bech32::primitives::decode::SegwitHrpstringError), /// Blech32 encoding error Blech32(crate::blech32::decode::SegwitHrpstringError), /// Was unable to parse the address. @@ -70,8 +70,8 @@ pub enum AddressError { InvalidAddressVersion(u8), } -impl From for AddressError { - fn from(e: crate::bech32::primitives::decode::SegwitHrpstringError) -> Self { +impl From for AddressError { + fn from(e: bech32::primitives::decode::SegwitHrpstringError) -> Self { AddressError::Bech32(e) } } @@ -458,7 +458,7 @@ impl Address { let hs = crate::blech32::decode::SegwitHrpstring::new(s)?; (hs.witness_version(), hs.byte_iter().collect()) } else { - let hs = crate::bech32::primitives::decode::SegwitHrpstring::new(s)?; + let hs = bech32::primitives::decode::SegwitHrpstring::new(s)?; (hs.witness_version(), hs.byte_iter().collect()) }; @@ -908,7 +908,7 @@ mod test { "ert130xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqqu2tys".parse(); assert_eq!( address.err().unwrap().to_string(), - "bech32 error: invalid segwit witness version: 3", // FIXME https://github.com/rust-bitcoin/rust-bech32/issues/162 should be 17 + "bech32 error: invalid segwit witness version: 17 (bech32 character: '3')", ); let address: Result = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9jfn0gypaj".parse(); @@ -920,10 +920,7 @@ mod test { // "invalid prefix" gives a weird error message because we do // a dumb prefix check before even attempting bech32 decoding let address: Result = "rrr1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfs2d9rp7meq4kg".parse(); - assert_eq!( - address.err().unwrap().to_string(), - "base58 error: invalid base58 character 0x30", - ); + assert_eq!(address.err().unwrap().to_string(), "base58 error: decode",); } #[test] diff --git a/src/blech32/decode.rs b/src/blech32/decode.rs index 4153b37a..5c517c89 100644 --- a/src/blech32/decode.rs +++ b/src/blech32/decode.rs @@ -66,11 +66,11 @@ use core::{fmt, iter, slice, str}; use crate::error::write_err; -use crate::bech32::primitives::checksum::{self, Checksum}; -use crate::bech32::primitives::gf32::Fe32; -use crate::bech32::primitives::hrp::{self, Hrp}; -use crate::bech32::primitives::iter::{Fe32IterExt, FesToBytes}; -use crate::bech32::primitives::segwit::{WitnessLengthError, VERSION_0}; +use bech32::primitives::checksum::{self, Checksum}; +use bech32::primitives::gf32::Fe32; +use bech32::primitives::hrp::{self, Hrp}; +use bech32::primitives::iter::{Fe32IterExt, FesToBytes}; +use bech32::primitives::segwit::{WitnessLengthError, VERSION_0}; use super::{Blech32, Blech32m}; /// Separator between the hrp and payload (as defined by BIP-173). @@ -150,7 +150,7 @@ impl<'s> UncheckedHrpstring<'s> { } let mut checksum_eng = checksum::Engine::::new(); - checksum_eng.input_hrp(&self.hrp()); + checksum_eng.input_hrp(self.hrp()); // Unwrap ok since we checked all characters in our constructor. for fe in self.data.iter().map(|&b| Fe32::from_char(b.into()).unwrap()) { @@ -881,7 +881,7 @@ mod tests { "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio"; let hrp = Hrp::parse_unchecked(hrps); - let s = crate::bech32::encode::(hrp, &[]).expect("failed to encode empty buffer"); + let s = bech32::encode::(hrp, &[]).expect("failed to encode empty buffer"); let unchecked = UncheckedHrpstring::new(&s).expect("failed to parse address"); assert_eq!(unchecked.hrp(), hrp); diff --git a/src/blech32/mod.rs b/src/blech32/mod.rs index 0fe75bba..69694dd3 100644 --- a/src/blech32/mod.rs +++ b/src/blech32/mod.rs @@ -26,7 +26,7 @@ pub mod decode; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Blech32 {} -impl crate::bech32::Checksum for Blech32 { +impl bech32::Checksum for Blech32 { type MidstateRepr = u64; const CHECKSUM_LENGTH: usize = 12; const GENERATOR_SH: [u64; 5] = [ @@ -37,13 +37,15 @@ impl crate::bech32::Checksum for Blech32 { 0x7093e5a608865b, ]; const TARGET_RESIDUE: u64 = 1; + + const CODE_LENGTH: usize = 1024; } /// The blech32m checksum algorithm. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Blech32m {} -impl crate::bech32::Checksum for Blech32m { +impl bech32::Checksum for Blech32m { type MidstateRepr = u64; const CHECKSUM_LENGTH: usize = 12; const GENERATOR_SH: [u64; 5] = [ @@ -54,5 +56,6 @@ impl crate::bech32::Checksum for Blech32m { 0x7093e5a608865b, ]; const TARGET_RESIDUE: u64 = 0x455972a3350f7a1; -} + const CODE_LENGTH: usize = 1024; +} diff --git a/src/blind.rs b/src/blind.rs index 0b7a533e..21727598 100644 --- a/src/blind.rs +++ b/src/blind.rs @@ -1375,7 +1375,7 @@ mod tests { use crate::encode::deserialize; use crate::hex::FromHex; use crate::Script; - use bitcoin::{Network, PrivateKey, PublicKey}; + use bitcoin::{PrivateKey, PublicKey}; use rand::thread_rng; use secp256k1_zkp::SECP256K1; use std::str::FromStr; @@ -1466,7 +1466,7 @@ mod tests { SECP256K1, &PrivateKey { compressed: true, - network: Network::Regtest, + network: bitcoin::NetworkKind::Test, inner: sk, }, ); @@ -1475,7 +1475,7 @@ mod tests { SECP256K1, &PrivateKey { compressed: true, - network: Network::Regtest, + network: bitcoin::NetworkKind::Test, inner: blinding_sk, }, ); diff --git a/src/hash_types.rs b/src/hash_types.rs index 050c43b3..6e4258ab 100644 --- a/src/hash_types.rs +++ b/src/hash_types.rs @@ -16,20 +16,24 @@ //! to avoid mixing data of the same hash format (like SHA256d) but of different meaning //! (transaction id, block hash etc). -use crate:: hashes::{hash_newtype, hash160, sha256, sha256d, Hash}; -use bitcoin::secp256k1::ThirtyTwoByteHash; +use crate::hashes::{hash160, hash_newtype, sha256, sha256d, Hash}; macro_rules! impl_hashencode { ($hashtype:ident) => { impl $crate::encode::Encodable for $hashtype { - fn consensus_encode(&self, w: W) -> Result { + fn consensus_encode( + &self, + w: W, + ) -> Result { self.0.consensus_encode(w) } } impl $crate::encode::Decodable for $hashtype { fn consensus_decode(r: R) -> Result { - Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?)) + Ok(Self::from_byte_array( + <<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?, + )) } } }; @@ -37,14 +41,14 @@ macro_rules! impl_hashencode { hash_newtype! { /// An elements transaction ID - pub struct Txid(sha256d::Hash); + pub struct Txid(sha256d::Hash); /// An elements witness transaction ID - pub struct Wtxid(sha256d::Hash); + pub struct Wtxid(sha256d::Hash); /// An elements blockhash - pub struct BlockHash(sha256d::Hash); + pub struct BlockHash(sha256d::Hash); /// "Hash of the transaction according to the signature algorithm" - pub struct Sighash(sha256d::Hash); + pub struct Sighash(sha256d::Hash); /// A hash of a public key. pub struct PubkeyHash(hash160::Hash); @@ -59,15 +63,8 @@ hash_newtype! { pub struct TxMerkleNode(sha256d::Hash); } - impl_hashencode!(Txid); impl_hashencode!(Wtxid); impl_hashencode!(Sighash); impl_hashencode!(BlockHash); impl_hashencode!(TxMerkleNode); - -impl ThirtyTwoByteHash for Sighash { - fn into_32(self) -> [u8; 32] { - self.0.to_byte_array() - } -} diff --git a/src/lib.rs b/src/lib.rs index 445e1bc4..b54fc1f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,6 @@ mod transaction; // consider making upstream public mod endian; // re-export bitcoin deps which we re-use -pub use bitcoin::bech32; pub use bitcoin::hashes; // export everything at the top level so it can be used as `elements::Transaction` etc. pub use crate::address::{Address, AddressError, AddressParams}; diff --git a/src/pset/error.rs b/src/pset/error.rs index 318bcece..de180750 100644 --- a/src/pset/error.rs +++ b/src/pset/error.rs @@ -117,7 +117,7 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { + match self { Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey), Error::InvalidProprietaryKey => write!( f, diff --git a/src/script.rs b/src/script.rs index ddf348dd..73b9af25 100644 --- a/src/script.rs +++ b/src/script.rs @@ -261,29 +261,29 @@ impl Script { /// Generates P2WPKH-type of scriptPubkey pub fn new_v0_wpkh(pubkey_hash: &WPubkeyHash) -> Script { - Script::new_witness_program(crate::bech32::Fe32::Q, &pubkey_hash.to_raw_hash().to_byte_array()) + Script::new_witness_program(bech32::Fe32::Q, &pubkey_hash.to_raw_hash().to_byte_array()) } /// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script pub fn new_v0_wsh(script_hash: &WScriptHash) -> Script { - Script::new_witness_program(crate::bech32::Fe32::Q, &script_hash.to_raw_hash().to_byte_array()) + Script::new_witness_program(bech32::Fe32::Q, &script_hash.to_raw_hash().to_byte_array()) } /// Generates P2TR for script spending path using an internal public key and some optional /// script tree merkle root. pub fn new_v1_p2tr(secp: &Secp256k1, internal_key: UntweakedPublicKey, merkle_root: Option) -> Script { let (output_key, _) = internal_key.tap_tweak(secp, merkle_root); - Script::new_witness_program(crate::bech32::Fe32::P, &output_key.as_inner().serialize()) + Script::new_witness_program(bech32::Fe32::P, &output_key.as_inner().serialize()) } /// Generates P2TR for key spending path for a known [`TweakedPublicKey`]. pub fn new_v1_p2tr_tweaked(output_key: TweakedPublicKey) -> Script { - Script::new_witness_program(crate::bech32::Fe32::P, &output_key.as_inner().serialize()) + Script::new_witness_program(bech32::Fe32::P, &output_key.as_inner().serialize()) } /// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script - pub fn new_witness_program(ver: crate::bech32::Fe32, program: &[u8]) -> Script { + pub fn new_witness_program(ver: bech32::Fe32, program: &[u8]) -> Script { let mut verop = ver.to_u8(); assert!(verop <= 16, "incorrect witness version provided: {}", verop); if verop > 0 {