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 bitcoin 0.32 #209

Merged
merged 2 commits into from
Aug 26, 2024
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
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
5 changes: 5 additions & 0 deletions contrib/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 ..
)
Expand Down
4 changes: 2 additions & 2 deletions elementsd-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

43 changes: 5 additions & 38 deletions elementsd-tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -33,7 +32,10 @@ trait Call {

impl Call for ElementsD {
fn call(&self, cmd: &str, args: &[Value]) -> Value {
self.client().call::<Value>(cmd, args).unwrap()
match self.client().call::<Value>(cmd, args) {
Ok(v) => v,
Err(e) => panic!("error {} while calling {} with {:?}", e, cmd, args),
}
}

fn decode_psbt(&self, psbt: &str) -> Option<Value> {
Expand Down Expand Up @@ -132,45 +134,10 @@ impl Call for ElementsD {
.unwrap()
.to_string()
}

}

#[cfg(test)]
fn setup(validate_pegin: bool) -> (ElementsD, Option<BitcoinD>) {
// 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();
Expand Down
17 changes: 7 additions & 10 deletions src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -70,8 +70,8 @@ pub enum AddressError {
InvalidAddressVersion(u8),
}

impl From<crate::bech32::primitives::decode::SegwitHrpstringError> for AddressError {
fn from(e: crate::bech32::primitives::decode::SegwitHrpstringError) -> Self {
impl From<bech32::primitives::decode::SegwitHrpstringError> for AddressError {
fn from(e: bech32::primitives::decode::SegwitHrpstringError) -> Self {
AddressError::Bech32(e)
}
}
Expand Down Expand Up @@ -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())
};

Expand Down Expand Up @@ -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<Address, _> = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9jfn0gypaj".parse();
Expand All @@ -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<Address, _> = "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]
Expand Down
14 changes: 7 additions & 7 deletions src/blech32/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -150,7 +150,7 @@ impl<'s> UncheckedHrpstring<'s> {
}

let mut checksum_eng = checksum::Engine::<Ck>::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()) {
Expand Down Expand Up @@ -881,7 +881,7 @@ mod tests {
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio";

let hrp = Hrp::parse_unchecked(hrps);
let s = crate::bech32::encode::<Blech32>(hrp, &[]).expect("failed to encode empty buffer");
let s = bech32::encode::<Blech32>(hrp, &[]).expect("failed to encode empty buffer");

let unchecked = UncheckedHrpstring::new(&s).expect("failed to parse address");
assert_eq!(unchecked.hrp(), hrp);
Expand Down
9 changes: 6 additions & 3 deletions src/blech32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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] = [
Expand All @@ -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] = [
Expand All @@ -54,5 +56,6 @@ impl crate::bech32::Checksum for Blech32m {
0x7093e5a608865b,
];
const TARGET_RESIDUE: u64 = 0x455972a3350f7a1;
}

const CODE_LENGTH: usize = 1024;
}
6 changes: 3 additions & 3 deletions src/blind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1466,7 +1466,7 @@ mod tests {
SECP256K1,
&PrivateKey {
compressed: true,
network: Network::Regtest,
network: bitcoin::NetworkKind::Test,
inner: sk,
},
);
Expand All @@ -1475,7 +1475,7 @@ mod tests {
SECP256K1,
&PrivateKey {
compressed: true,
network: Network::Regtest,
network: bitcoin::NetworkKind::Test,
inner: blinding_sk,
},
);
Expand Down
27 changes: 12 additions & 15 deletions src/hash_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,39 @@
//! 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<W: std::io::Write>(&self, w: W) -> Result<usize, crate::encode::Error> {
fn consensus_encode<W: std::io::Write>(
&self,
w: W,
) -> Result<usize, crate::encode::Error> {
self.0.consensus_encode(w)
}
}

impl $crate::encode::Decodable for $hashtype {
fn consensus_decode<R: std::io::Read>(r: R) -> Result<Self, $crate::encode::Error> {
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)?,
))
}
}
};
}

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);
Expand All @@ -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()
}
}
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
2 changes: 1 addition & 1 deletion src/pset/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 5 additions & 5 deletions src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<C: Verification>(secp: &Secp256k1<C>, internal_key: UntweakedPublicKey, merkle_root: Option<TapNodeHash>) -> 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 {
Expand Down
Loading