Change hex re-export in bitcoin to stable hex
What changed, and why it matters
This commit is a routine internal dependency cleanup. The project had been re-exporting an unstable version of a hex-encoding helper crate, but its policy says the main crate must only re-export stable versions. The change swaps the public re-export to the stable version while keeping the unstable version as a private internal dependency for code that still needs it. There is no security bug being fixed here.
No security action required. Treat as normal maintenance. Downstream users relying on `bitcoin::hex` being exactly `hex-conservative` 0.3.0 should note the re-export now points to 1.0.0.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit changes bitcoin crate’s public re-export of hex-conservative from the unstable 0.3.0 version to the stable 1.0.0 version (pub extern crate hex_stable as hex). Because the bitcoin crate still uses unstable-only APIs internally, it adds hex-unstable as a non-public dependency and updates internal imports from hex:: to hex_unstable::. The primitives crate already exported the stable version, so this aligns bitcoin with the repo policy that bitcoin’s exports must be a superset of primitives’s exports. The p2p crate doc example is updated to use the new stable re-export path.
Changed components
bitcoin/Cargo.toml dependency declarationsbitcoin/src/lib.rs public re-export of hex crateinternal imports across bitcoin crate modulesp2p/src/merkle_tree.rs doc exampleInspect captured patch +53 / −50
diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index c8a7abda..e8e6080e 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -63,6 +63,7 @@ dependencies = [
"bitcoin_hashes",
"bitcoinconsensus",
"hex-conservative 0.3.0",
+ "hex-conservative 1.0.0",
"hex_lit",
"secp256k1",
"serde",
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index 2bfaff84..8efab0b8 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -62,6 +62,7 @@ dependencies = [
"bitcoin_hashes",
"bitcoinconsensus",
"hex-conservative 0.3.0",
+ "hex-conservative 1.0.0",
"hex_lit",
"secp256k1",
"serde",
diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml
index 477e2b8a..f72228d6 100644
--- a/bitcoin/Cargo.toml
+++ b/bitcoin/Cargo.toml
@@ -16,7 +16,7 @@ exclude = ["tests", "contrib"]
# If you change features or optional dependencies in any way please update the "# Cargo features" section in lib.rs as well.
[features]
default = [ "std", "secp-recovery" ]
-std = ["base58/std", "bech32/std", "encoding/std", "hashes/std", "hex/std", "internals/std", "io/std", "network/std", "primitives/std", "secp256k1/std", "units/std", "base64?/std", "bitcoinconsensus?/std"]
+std = ["base58/std", "bech32/std", "encoding/std", "hashes/std", "hex-stable/std", "hex-unstable/std", "internals/std", "io/std", "network/std", "primitives/std", "secp256k1/std", "units/std", "base64?/std", "bitcoinconsensus?/std"]
rand = ["secp256k1/rand"]
serde = ["base64", "dep:serde", "hashes/serde", "internals/serde", "network/serde", "primitives/serde", "secp256k1/serde", "units/serde"]
secp-global-context = ["secp256k1/global-context"]
@@ -29,7 +29,8 @@ base58 = { package = "base58ck", path = "../base58", version = "0.3.0", default-
bech32 = { version = "0.11.0", default-features = false, features = ["alloc"] }
hashes = { package = "bitcoin_hashes", path = "../hashes", version = "0.19.0", default-features = false, features = ["alloc", "hex"] }
encoding = { package = "bitcoin-consensus-encoding", path = "../consensus_encoding", version = "=1.0.0-rc.3", default-features = false, features = ["alloc"] }
-hex = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] }
+hex-stable = { package = "hex-conservative", version = "1.0.0", default-features = false, features = ["alloc"] }
+hex-unstable = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] }
internals = { package = "bitcoin-internals", path = "../internals", version = "0.5.0", features = ["alloc", "hex"] }
io = { package = "bitcoin-io", path = "../io", version = "=0.4.0-rc.0", default-features = false, features = ["alloc", "hashes"] }
network = { package = "bitcoin-network-kind", path = "../network", version = "0.1.0", default-features = false, features = ["alloc"]}
diff --git a/bitcoin/examples/bip32.rs b/bitcoin/examples/bip32.rs
index 34c54bd0..0dd86afc 100644
--- a/bitcoin/examples/bip32.rs
+++ b/bitcoin/examples/bip32.rs
@@ -2,8 +2,8 @@ use std::env;
use bitcoin::address::{Address, KnownHrp};
use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv, Xpub};
-use bitcoin::hex::FromHex;
use bitcoin::{CompressedPublicKey, NetworkKind};
+use hex_unstable::FromHex;
fn main() {
// This example derives root xprv from a 32-byte seed,
diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs
index 88b31800..0277048e 100644
--- a/bitcoin/src/bip158.rs
+++ b/bitcoin/src/bip158.rs
@@ -544,7 +544,7 @@ mod test {
#[test]
fn blockfilters() {
- let hex = |b| <Vec<u8> as hex::FromHex>::from_hex(b).unwrap();
+ let hex = |b| <Vec<u8> as hex_unstable::FromHex>::from_hex(b).unwrap();
// test vectors from: https://github.com/jimpo/bitcoin/blob/c7efb652f3543b001b4dd22186a354605b14f47e/src/test/data/blockfilters.json
let data = include_str!("../tests/data/blockfilters.json");
diff --git a/bitcoin/src/blockdata/script/borrowed.rs b/bitcoin/src/blockdata/script/borrowed.rs
index 79cbf3c4..fbd2f65f 100644
--- a/bitcoin/src/blockdata/script/borrowed.rs
+++ b/bitcoin/src/blockdata/script/borrowed.rs
@@ -2,7 +2,7 @@
use core::fmt;
-use hex::DisplayHex as _;
+use hex_unstable::DisplayHex as _;
use internals::array::ArrayExt; // For `split_first`.
use internals::ToU64 as _;
diff --git a/bitcoin/src/blockdata/script/owned.rs b/bitcoin/src/blockdata/script/owned.rs
index b910dced..a0fccd9e 100644
--- a/bitcoin/src/blockdata/script/owned.rs
+++ b/bitcoin/src/blockdata/script/owned.rs
@@ -3,7 +3,7 @@
#[cfg(doc)]
use core::ops::Deref;
-use hex::FromHex as _;
+use hex_unstable::FromHex as _;
use internals::ToU64 as _;
use super::{
@@ -156,7 +156,7 @@ internal_macros::define_extension_trait! {
/// Constructs a new [`ScriptBuf`] from a hex string.
#[deprecated(since = "TBD", note = "use `from_hex_no_length_prefix()` instead")]
- fn from_hex(s: &str) -> Result<Self, hex::HexToBytesError>
+ fn from_hex(s: &str) -> Result<Self, hex_unstable::HexToBytesError>
where Self: Sized
{
Self::from_hex_no_length_prefix(s)
@@ -166,7 +166,7 @@ internal_macros::define_extension_trait! {
///
/// This is **not** consensus encoding. If your hex string is a consensus encoded script
/// then use `ScriptBuf::from_hex_prefixed`.
- fn from_hex_no_length_prefix(s: &str) -> Result<Self, hex::HexToBytesError>
+ fn from_hex_no_length_prefix(s: &str) -> Result<Self, hex_unstable::HexToBytesError>
where Self: Sized
{
let v = Vec::from_hex(s)?;
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index ba751ae7..cbe948a9 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -1274,7 +1274,7 @@ impl<'a> Arbitrary<'a> for InputWeightPrediction {
#[cfg(test)]
mod tests {
- use hex::FromHex;
+ use hex_unstable::FromHex;
use hex_lit::hex;
use super::*;
diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs
index 061db696..66b34eaf 100644
--- a/bitcoin/src/blockdata/witness.rs
+++ b/bitcoin/src/blockdata/witness.rs
@@ -238,10 +238,10 @@ mod sealed {
#[cfg(test)]
mod test {
use hex_lit::hex;
+ use hex_unstable::DisplayHex;
use super::*;
use crate::consensus::{deserialize, encode, serialize};
- use crate::hex::DisplayHex;
use crate::sighash::EcdsaSighashType;
use crate::taproot::LeafVersion;
use crate::Transaction;
diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs
index 5f398b5c..2b202c71 100644
--- a/bitcoin/src/consensus/encode.rs
+++ b/bitcoin/src/consensus/encode.rs
@@ -19,7 +19,7 @@ use core::{cmp, mem, slice};
use encoding::{CompactSizeEncoder, Encoder};
use hashes::{sha256, sha256d, Hash};
-use hex::DisplayHex as _;
+use hex_unstable::DisplayHex as _;
use internals::ToU64;
use io::{BufRead, Cursor, Read, Write};
@@ -59,7 +59,7 @@ pub fn deserialize<T: Decodable>(data: &[u8]) -> Result<T, DeserializeError> {
/// Deserializes any decodable type from a hex string, will error if said deserialization
/// doesn't consume the entire vector.
pub fn deserialize_hex<T: Decodable>(hex: &str) -> Result<T, FromHexError> {
- let iter = hex::HexSliceToBytesIter::new(hex)?;
+ let iter = hex_unstable::HexSliceToBytesIter::new(hex)?;
let reader = IterReader::new(iter);
Ok(reader.decode().map_err(FromHexError::Decode)?)
}
diff --git a/bitcoin/src/consensus/error.rs b/bitcoin/src/consensus/error.rs
index d16b1a3f..70ba90d1 100644
--- a/bitcoin/src/consensus/error.rs
+++ b/bitcoin/src/consensus/error.rs
@@ -5,7 +5,7 @@
use core::convert::Infallible;
use core::fmt;
-use hex::error::{InvalidCharError, OddLengthStringError};
+use hex_unstable::error::{InvalidCharError, OddLengthStringError};
use internals::write_err;
#[cfg(doc)]
diff --git a/bitcoin/src/consensus/serde.rs b/bitcoin/src/consensus/serde.rs
index 79a3e7d7..6a7fc22e 100644
--- a/bitcoin/src/consensus/serde.rs
+++ b/bitcoin/src/consensus/serde.rs
@@ -38,7 +38,7 @@ pub mod hex {
use core::fmt;
use core::marker::PhantomData;
- use hex::buf_encoder::BufEncoder;
+ use hex_unstable::buf_encoder::BufEncoder;
/// Marker for upper/lower case type-level flags ("type-level enum").
///
@@ -54,15 +54,15 @@ pub mod hex {
mod sealed {
pub trait Case {
/// Internal detail, don't depend on it!!!
- const INTERNAL_CASE: hex::Case;
+ const INTERNAL_CASE: hex_unstable::Case;
}
impl Case for super::Lower {
- const INTERNAL_CASE: hex::Case = hex::Case::Lower;
+ const INTERNAL_CASE: hex_unstable::Case = hex_unstable::Case::Lower;
}
impl Case for super::Upper {
- const INTERNAL_CASE: hex::Case = hex::Case::Upper;
+ const INTERNAL_CASE: hex_unstable::Case = hex_unstable::Case::Upper;
}
}
@@ -101,18 +101,18 @@ pub mod hex {
/// Error returned when a hex string decoder can't be created.
#[derive(Debug, Clone, PartialEq, Eq)]
- pub struct DecodeInitError(hex::OddLengthStringError);
+ pub struct DecodeInitError(hex_unstable::OddLengthStringError);
/// Error returned when a hex string contains invalid characters.
#[derive(Debug, Clone, PartialEq, Eq)]
- pub struct DecodeError(hex::InvalidCharError);
+ pub struct DecodeError(hex_unstable::InvalidCharError);
/// Hex decoder state.
- pub struct Decoder<'a>(hex::HexSliceToBytesIter<'a>);
+ pub struct Decoder<'a>(hex_unstable::HexSliceToBytesIter<'a>);
impl<'a> Decoder<'a> {
fn new(s: &'a str) -> Result<Self, DecodeInitError> {
- match hex::HexToBytesIter::new(s) {
+ match hex_unstable::HexToBytesIter::new(s) {
Ok(iter) => Ok(Decoder(iter)),
Err(error) => Err(DecodeInitError(error)),
}
diff --git a/bitcoin/src/crypto/ecdsa.rs b/bitcoin/src/crypto/ecdsa.rs
index feec3552..6be37463 100644
--- a/bitcoin/src/crypto/ecdsa.rs
+++ b/bitcoin/src/crypto/ecdsa.rs
@@ -12,7 +12,7 @@ use core::{fmt, iter};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
-use hex::FromHex;
+use hex_unstable::FromHex;
use internals::{impl_to_hex_from_lower_hex, write_err};
use io::Write;
@@ -282,7 +282,7 @@ impl From<NonStandardSighashTypeError> for DecodeError {
#[non_exhaustive]
pub enum ParseSignatureError {
/// Hex string decoding error.
- Hex(hex::HexToBytesError),
+ Hex(hex_unstable::HexToBytesError),
/// Signature byte slice decoding error.
Decode(DecodeError),
}
@@ -310,8 +310,8 @@ impl std::error::Error for ParseSignatureError {
}
}
-impl From<hex::HexToBytesError> for ParseSignatureError {
- fn from(e: hex::HexToBytesError) -> Self { Self::Hex(e) }
+impl From<hex_unstable::HexToBytesError> for ParseSignatureError {
+ fn from(e: hex_unstable::HexToBytesError) -> Self { Self::Hex(e) }
}
impl From<DecodeError> for ParseSignatureError {
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index d0b3ff33..ceed133a 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -11,7 +11,7 @@ use core::ops;
use core::str::FromStr;
use hashes::hash160;
-use hex::{FromHex, HexToArrayError};
+use hex_unstable::{FromHex, HexToArrayError};
use internals::array::ArrayExt;
use internals::array_vec::ArrayVec;
use internals::{impl_to_hex_from_lower_hex, write_err};
@@ -1310,7 +1310,7 @@ pub enum ParsePublicKeyError {
/// Error originated while parsing string.
Encoding(FromSliceError),
/// Hex decoding error.
- InvalidChar(hex::InvalidCharError),
+ InvalidChar(hex_unstable::InvalidCharError),
/// `PublicKey` hex should be 66 or 130 digits long.
InvalidHexLength(usize),
}
@@ -1351,7 +1351,7 @@ pub enum ParseCompressedPublicKeyError {
/// secp256k1 Error.
Secp256k1(secp256k1::Error),
/// hex to array conversion error.
- Hex(hex::HexToArrayError),
+ Hex(hex_unstable::HexToArrayError),
}
impl From<Infallible> for ParseCompressedPublicKeyError {
@@ -1381,8 +1381,8 @@ impl From<secp256k1::Error> for ParseCompressedPublicKeyError {
fn from(e: secp256k1::Error) -> Self { Self::Secp256k1(e) }
}
-impl From<hex::HexToArrayError> for ParseCompressedPublicKeyError {
- fn from(e: hex::HexToArrayError) -> Self { Self::Hex(e) }
+impl From<hex_unstable::HexToArrayError> for ParseCompressedPublicKeyError {
+ fn from(e: hex_unstable::HexToArrayError) -> Self { Self::Hex(e) }
}
/// SegWit public keys must always be compressed.
diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs
index da583184..58310706 100644
--- a/bitcoin/src/crypto/sighash.rs
+++ b/bitcoin/src/crypto/sighash.rs
@@ -1517,7 +1517,7 @@ impl<'a> Arbitrary<'a> for TapSighashType {
#[cfg(test)]
mod tests {
use hashes::HashEngine;
- use hex::FromHex;
+ use hex_unstable::FromHex;
use hex_lit::hex;
use super::*;
@@ -1848,7 +1848,7 @@ mod tests {
#[cfg(feature = "serde")]
#[test]
fn bip_341_sighash_tests() {
- use hex::DisplayHex;
+ use hex_unstable::DisplayHex;
fn sighash_deser_numeric<'de, D>(deserializer: D) -> Result<TapSighashType, D::Error>
where
diff --git a/bitcoin/src/crypto/taproot.rs b/bitcoin/src/crypto/taproot.rs
index c1e1abf9..7a7d5e1a 100644
--- a/bitcoin/src/crypto/taproot.rs
+++ b/bitcoin/src/crypto/taproot.rs
@@ -150,7 +150,7 @@ impl fmt::Debug for SerializedSignature {
impl fmt::Display for SerializedSignature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- hex::fmt_hex_exact!(f, MAX_LEN, self, hex::Case::Lower)
+ hex_unstable::fmt_hex_exact!(f, MAX_LEN, self, hex_unstable::Case::Lower)
}
}
diff --git a/bitcoin/src/internal_macros.rs b/bitcoin/src/internal_macros.rs
index 190a2b71..4f940be3 100644
--- a/bitcoin/src/internal_macros.rs
+++ b/bitcoin/src/internal_macros.rs
@@ -55,21 +55,21 @@ macro_rules! impl_array_newtype_stringify {
($t:ident, $len:literal) => {
impl $t {
/// Constructs a new `Self` from a hex string.
- pub fn from_hex(s: &str) -> Result<Self, hex::HexToArrayError> {
- Ok($t($crate::hex::FromHex::from_hex(s)?))
+ pub fn from_hex(s: &str) -> Result<Self, hex_unstable::HexToArrayError> {
+ Ok($t(hex_unstable::FromHex::from_hex(s)?))
}
}
impl core::fmt::LowerHex for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- use $crate::hex::{display, Case};
+ use hex_unstable::{display, Case};
display::fmt_hex_exact!(f, $len, &self.0, Case::Lower)
}
}
impl core::fmt::UpperHex for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- use $crate::hex::{display, Case};
+ use hex_unstable::{display, Case};
display::fmt_hex_exact!(f, $len, &self.0, Case::Upper)
}
}
@@ -87,7 +87,7 @@ macro_rules! impl_array_newtype_stringify {
}
impl core::str::FromStr for $t {
- type Err = $crate::hex::HexToArrayError;
+ type Err = hex_unstable::HexToArrayError;
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> { Self::from_hex(s) }
}
diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs
index 11478557..55d85929 100644
--- a/bitcoin/src/lib.rs
+++ b/bitcoin/src/lib.rs
@@ -69,7 +69,7 @@ pub extern crate bech32;
pub extern crate hashes;
/// Re-export the `hex-conservative` crate.
-pub extern crate hex;
+pub extern crate hex_stable as hex;
/// Re-export the `bitcoin-io` crate.
pub extern crate io;
@@ -219,7 +219,7 @@ mod prelude {
pub use crate::io::sink;
- pub use hex::DisplayHex;
+ pub use hex_unstable::DisplayHex;
}
pub mod amount {
diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs
index f8706e95..54e0c8c3 100644
--- a/bitcoin/src/pow.rs
+++ b/bitcoin/src/pow.rs
@@ -1131,13 +1131,13 @@ macro_rules! impl_hex {
($hex:path, $case:expr) => {
impl $hex for U256 {
fn fmt(&self, f: &mut fmt::Formatter) -> core::fmt::Result {
- hex::fmt_hex_exact!(f, 32, &self.to_be_bytes(), $case)
+ hex_unstable::fmt_hex_exact!(f, 32, &self.to_be_bytes(), $case)
}
}
};
}
-impl_hex!(fmt::LowerHex, hex::Case::Lower);
-impl_hex!(fmt::UpperHex, hex::Case::Upper);
+impl_hex!(fmt::LowerHex, hex_unstable::Case::Lower);
+impl_hex!(fmt::UpperHex, hex_unstable::Case::Upper);
#[cfg(feature = "serde")]
impl crate::serde::Serialize for U256 {
@@ -1163,7 +1163,7 @@ impl crate::serde::Serialize for U256 {
#[cfg(feature = "serde")]
impl<'de> crate::serde::Deserialize<'de> for U256 {
fn deserialize<D: crate::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
- use hex::FromHex;
+ use hex_unstable::FromHex;
use crate::serde::de;
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs
index bbbc890a..fc0e0282 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/psbt/mod.rs
@@ -1298,7 +1298,7 @@ mod tests {
use std::str::FromStr;
use hashes::{hash160, ripemd160, sha256};
- use hex::FromHex;
+ use hex_unstable::FromHex;
use hex_lit::hex;
#[cfg(all(feature = "rand", feature = "std"))]
use {
diff --git a/bitcoin/src/taproot/mod.rs b/bitcoin/src/taproot/mod.rs
index fa9303a0..945f11c3 100644
--- a/bitcoin/src/taproot/mod.rs
+++ b/bitcoin/src/taproot/mod.rs
@@ -12,7 +12,7 @@ use core::fmt;
use core::iter::FusedIterator;
use hashes::{hash_newtype, sha256t, sha256t_tag, HashEngine};
-use hex::{FromHex, HexToBytesError};
+use hex_unstable::{FromHex, HexToBytesError};
use internals::array::ArrayExt;
#[allow(unused)] // MSRV polyfill
use internals::slice::SliceExt;
@@ -1654,7 +1654,7 @@ impl std::error::Error for InvalidControlBlockSizeError {}
#[cfg(test)]
mod test {
use hashes::sha256;
- use hex::DisplayHex;
+ use hex_unstable::DisplayHex;
use super::*;
use crate::script::ScriptBufExt as _;
diff --git a/bitcoin/tests/bip_174.rs b/bitcoin/tests/bip_174.rs
index edcee741..9bf3a4e6 100644
--- a/bitcoin/tests/bip_174.rs
+++ b/bitcoin/tests/bip_174.rs
@@ -6,7 +6,6 @@ use std::collections::BTreeMap;
use bitcoin::amount::{Amount, Denomination};
use bitcoin::bip32::{Fingerprint, IntoDerivationPath, KeySource, Xpriv, Xpub};
use bitcoin::consensus::encode::{deserialize, serialize_hex};
-use bitcoin::hex::FromHex;
use bitcoin::opcodes::all::OP_0;
use bitcoin::psbt::{Psbt, PsbtSighashType};
use bitcoin::script::{PushBytes, ScriptBuf, ScriptBufExt as _};
@@ -14,6 +13,7 @@ use bitcoin::{
absolute, script, transaction, NetworkKind, OutPoint, PrivateKey, PublicKey, ScriptPubKeyBuf,
ScriptSigBuf, Sequence, Transaction, TxIn, TxOut, Witness,
};
+use hex_unstable::FromHex;
#[track_caller]
fn hex_psbt(s: &str) -> Psbt {
diff --git a/bitcoin/tests/serde.rs b/bitcoin/tests/serde.rs
index 213555a3..9b7e84c4 100644
--- a/bitcoin/tests/serde.rs
+++ b/bitcoin/tests/serde.rs
@@ -24,7 +24,6 @@ use std::collections::BTreeMap;
use bincode::serialize;
use bitcoin::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
-use bitcoin::hex::FromHex;
use bitcoin::locktime::{absolute, relative};
use bitcoin::psbt::{raw, Input, Output, Psbt, PsbtSighashType};
use bitcoin::script::ScriptBufExt as _;
@@ -36,6 +35,7 @@ use bitcoin::{
ScriptPubKeyBuf, ScriptSigBuf, Sequence, TapScriptBuf, Target, Transaction, TxIn, TxOut, Txid,
Work,
};
+use hex_unstable::FromHex;
#[test]
fn serde_regression_absolute_lock_time_height() {
diff --git a/p2p/src/merkle_tree.rs b/p2p/src/merkle_tree.rs
index 597999ff..7ac30efa 100644
--- a/p2p/src/merkle_tree.rs
+++ b/p2p/src/merkle_tree.rs
@@ -45,7 +45,7 @@ impl MerkleBlock {
/// # Examples
///
/// ```rust
- /// use bitcoin::hex::FromHex;
+ /// use hex::FromHex;
/// use bitcoin_p2p_messages::merkle_tree::MerkleBlock;
/// use primitives::{Block, Txid};
///
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.