diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock index aedf19dfd..afb80f59b 100644 --- a/Cargo-minimal.lock +++ b/Cargo-minimal.lock @@ -213,6 +213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4afe881d0527571892c4034822e59bb10c6c991cce6abe8199b6f5cf10766f55" dependencies = [ "arrayvec", + "serde", ] [[package]] diff --git a/Cargo-recent.lock b/Cargo-recent.lock index 4d452dcd2..f33ae82ee 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -215,6 +215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4afe881d0527571892c4034822e59bb10c6c991cce6abe8199b6f5cf10766f55" dependencies = [ "arrayvec", + "serde", ] [[package]] diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml index 85b7291f6..60f93fcd3 100644 --- a/bitcoin/Cargo.toml +++ b/bitcoin/Cargo.toml @@ -31,7 +31,7 @@ hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = fa hex = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] } internals = { package = "bitcoin-internals", path = "../internals", features = ["alloc", "hex"] } io = { package = "bitcoin-io", path = "../io", default-features = false, features = ["alloc", "hashes"] } -primitives = { package = "bitcoin-primitives", path = "../primitives", default-features = false, features = ["alloc"] } +primitives = { package = "bitcoin-primitives", path = "../primitives", default-features = false, features = ["alloc", "hex"] } secp256k1 = { version = "0.30.0", default-features = false, features = ["hashes", "alloc", "rand"] } units = { package = "bitcoin-units", path = "../units", default-features = false, features = ["alloc"] } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 6a5659547..d2ed52686 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -15,19 +15,20 @@ rust-version = "1.63.0" exclude = ["tests", "contrib"] [features] -default = ["std"] -std = ["alloc", "hashes/std", "hex/std", "internals/std", "units/std"] -alloc = ["hashes/alloc", "hex/alloc", "internals/alloc", "units/alloc"] -serde = ["dep:serde", "hashes/serde", "internals/serde", "units/serde", "alloc"] +default = ["std", "hex"] +std = ["alloc", "hashes/std", "hex?/std", "internals/std", "units/std"] +alloc = ["hashes/alloc", "hex?/alloc", "internals/alloc", "units/alloc"] +serde = ["dep:serde", "hashes/serde", "hex?/serde", "internals/serde", "units/serde", "alloc", "hex"] arbitrary = ["dep:arbitrary", "units/arbitrary"] +hex = ["dep:hex", "hashes/hex", "internals/hex"] [dependencies] -hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false, features = ["hex"] } -hex = { package = "hex-conservative", version = "0.3.0", default-features = false } -internals = { package = "bitcoin-internals", path = "../internals", features = ["hex"] } +hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false } +internals = { package = "bitcoin-internals", path = "../internals" } units = { package = "bitcoin-units", path = "../units", default-features = false } arbitrary = { version = "1.4", optional = true } +hex = { package = "hex-conservative", version = "0.3.0", default-features = false, optional = true } serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"], optional = true } [dev-dependencies] diff --git a/primitives/src/block.rs b/primitives/src/block.rs index a4d49b0ae..003e2d90e 100644 --- a/primitives/src/block.rs +++ b/primitives/src/block.rs @@ -310,7 +310,10 @@ hashes::hash_newtype! { pub struct WitnessCommitment(sha256d::Hash); } +#[cfg(feature = "hex")] hashes::impl_hex_for_newtype!(BlockHash, WitnessCommitment); +#[cfg(not(feature = "hex"))] +hashes::impl_debug_only_for_newtype!(BlockHash, WitnessCommitment); #[cfg(feature = "serde")] hashes::impl_serde_for_newtype!(BlockHash, WitnessCommitment); diff --git a/primitives/src/merkle_tree.rs b/primitives/src/merkle_tree.rs index 18a16a5a9..e5cc60101 100644 --- a/primitives/src/merkle_tree.rs +++ b/primitives/src/merkle_tree.rs @@ -11,6 +11,9 @@ hashes::hash_newtype! { pub struct WitnessMerkleNode(sha256d::Hash); } +#[cfg(feature = "hex")] hashes::impl_hex_for_newtype!(TxMerkleNode, WitnessMerkleNode); +#[cfg(not(feature = "hex"))] +hashes::impl_debug_only_for_newtype!(TxMerkleNode, WitnessMerkleNode); #[cfg(feature = "serde")] hashes::impl_serde_for_newtype!(TxMerkleNode, WitnessMerkleNode); diff --git a/primitives/src/script/mod.rs b/primitives/src/script/mod.rs index af9c4b429..0a1f7296e 100644 --- a/primitives/src/script/mod.rs +++ b/primitives/src/script/mod.rs @@ -10,6 +10,7 @@ use core::convert::Infallible; use core::fmt; use hashes::{hash160, sha256}; +#[cfg(feature = "hex")] use hex::DisplayHex; use internals::script::{self, PushDataLenLen}; @@ -49,7 +50,10 @@ hashes::hash_newtype! { pub struct WScriptHash(sha256::Hash); } +#[cfg(feature = "hex")] hashes::impl_hex_for_newtype!(ScriptHash, WScriptHash); +#[cfg(not(feature = "hex"))] +hashes::impl_debug_only_for_newtype!(ScriptHash, WScriptHash); #[cfg(feature = "serde")] hashes::impl_serde_for_newtype!(ScriptHash, WScriptHash); @@ -425,6 +429,7 @@ impl fmt::Display for ScriptBuf { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self.as_script(), f) } } +#[cfg(feature = "hex")] impl fmt::LowerHex for Script { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -432,15 +437,19 @@ impl fmt::LowerHex for Script { } } #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] internals::impl_to_hex_from_lower_hex!(Script, |script: &Self| script.len() * 2); +#[cfg(feature = "hex")] impl fmt::LowerHex for ScriptBuf { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self.as_script(), f) } } #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] internals::impl_to_hex_from_lower_hex!(ScriptBuf, |script_buf: &Self| script_buf.len() * 2); +#[cfg(feature = "hex")] impl fmt::UpperHex for Script { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -448,6 +457,7 @@ impl fmt::UpperHex for Script { } } +#[cfg(feature = "hex")] impl fmt::UpperHex for ScriptBuf { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(self.as_script(), f) } @@ -720,16 +730,24 @@ mod tests { fn script_display() { let script = Script::from_bytes(&[0xa1, 0xb2, 0xc3]); assert_eq!(format!("{}", script), "OP_LESSTHANOREQUAL OP_CSV OP_RETURN_195"); - assert_eq!(format!("{:x}", script), "a1b2c3"); - assert_eq!(format!("{:X}", script), "A1B2C3"); + + #[cfg(feature = "hex")] + { + assert_eq!(format!("{:x}", script), "a1b2c3"); + assert_eq!(format!("{:X}", script), "A1B2C3"); + } } #[test] fn scriptbuf_display() { let script_buf = ScriptBuf::from(vec![0xa1, 0xb2, 0xc3]); assert_eq!(format!("{}", script_buf), "OP_LESSTHANOREQUAL OP_CSV OP_RETURN_195"); - assert_eq!(format!("{:x}", script_buf), "a1b2c3"); - assert_eq!(format!("{:X}", script_buf), "A1B2C3"); + + #[cfg(feature = "hex")] + { + assert_eq!(format!("{:x}", script_buf), "a1b2c3"); + assert_eq!(format!("{:X}", script_buf), "A1B2C3"); + } } #[test] diff --git a/primitives/src/transaction.rs b/primitives/src/transaction.rs index 1c79a187d..53cd51a4f 100644 --- a/primitives/src/transaction.rs +++ b/primitives/src/transaction.rs @@ -13,6 +13,7 @@ #[cfg(feature = "alloc")] use core::cmp; #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] use core::convert::Infallible; use core::fmt; @@ -20,9 +21,13 @@ use core::fmt; use arbitrary::{Arbitrary, Unstructured}; use hashes::sha256d; #[cfg(feature = "alloc")] -use internals::{compact_size, write_err}; +use internals::compact_size; +#[cfg(feature = "hex")] +use internals::write_err; +#[cfg(feature = "hex")] +use units::parse; #[cfg(feature = "alloc")] -use units::{parse, Amount, Weight}; +use units::{Amount, Weight}; #[cfg(feature = "alloc")] use crate::locktime::absolute; @@ -389,6 +394,7 @@ impl OutPoint { pub const COINBASE_PREVOUT: Self = Self { txid: Txid::COINBASE_PREVOUT, vout: u32::MAX }; } +#[cfg(feature = "hex")] impl fmt::Display for OutPoint { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -397,6 +403,7 @@ impl fmt::Display for OutPoint { } #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] impl core::str::FromStr for OutPoint { type Err = ParseOutPointError; @@ -424,6 +431,7 @@ impl core::str::FromStr for OutPoint { /// /// Does not permit leading zeroes or non-digit characters. #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] fn parse_vout(s: &str) -> Result { if s.len() > 1 { let first = s.chars().next().unwrap(); @@ -438,6 +446,7 @@ fn parse_vout(s: &str) -> Result { #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] pub enum ParseOutPointError { /// Error in TXID part. Txid(hex::HexToArrayError), @@ -452,12 +461,14 @@ pub enum ParseOutPointError { } #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] impl From for ParseOutPointError { #[inline] fn from(never: Infallible) -> Self { match never {} } } #[cfg(feature = "alloc")] +#[cfg(feature = "hex")] impl fmt::Display for ParseOutPointError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use ParseOutPointError as E; @@ -473,6 +484,7 @@ impl fmt::Display for ParseOutPointError { } #[cfg(feature = "std")] +#[cfg(feature = "hex")] impl std::error::Error for ParseOutPointError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { use ParseOutPointError as E; @@ -500,7 +512,10 @@ hashes::hash_newtype! { pub struct Wtxid(sha256d::Hash); } +#[cfg(feature = "hex")] hashes::impl_hex_for_newtype!(Txid, Wtxid); +#[cfg(not(feature = "hex"))] +hashes::impl_debug_only_for_newtype!(Txid, Wtxid); #[cfg(feature = "serde")] hashes::impl_serde_for_newtype!(Txid, Wtxid); @@ -699,6 +714,7 @@ mod tests { } #[test] + #[cfg(feature = "hex")] fn outpoint_from_str() { // Check format errors let mut outpoint_str = "0".repeat(64); // No ":" @@ -725,6 +741,7 @@ mod tests { } #[test] + #[cfg(feature = "hex")] fn canonical_vout() { assert_eq!(parse_vout("0").unwrap(), 0); assert_eq!(parse_vout("1").unwrap(), 1); diff --git a/primitives/src/witness.rs b/primitives/src/witness.rs index 159a80c10..cf777ceee 100644 --- a/primitives/src/witness.rs +++ b/primitives/src/witness.rs @@ -9,7 +9,6 @@ use core::ops::Index; #[cfg(feature = "arbitrary")] use arbitrary::{Arbitrary, Unstructured}; -use hex::DisplayHex; use internals::compact_size; use internals::slice::SliceExt; use internals::wrap_debug::WrapDebug; @@ -314,7 +313,7 @@ impl> PartialEq for alloc::sync::Arc<[T]> /// Debug implementation that displays the witness as a structured output containing: /// - Number of witness elements /// - Total bytes across all elements -/// - List of hex-encoded witness elements +/// - List of hex-encoded witness elements if `hex` features is enabled. #[allow(clippy::missing_fields_in_debug)] // We don't want to show `indices_start`. impl fmt::Debug for Witness { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -326,7 +325,14 @@ impl fmt::Debug for Witness { .field( "elements", &WrapDebug(|f| { - f.debug_list().entries(self.iter().map(DisplayHex::as_hex)).finish() + #[cfg(feature = "hex")] + { + f.debug_list().entries(self.iter().map(hex::DisplayHex::as_hex)).finish() + } + #[cfg(not(feature = "hex"))] + { + f.debug_list().entries(self.iter()).finish() + } }), ) .finish()