bitcoin: Remove uses of HexToBytesError
What changed, and why it matters
This commit swaps out an unstable, experimental hex-decoding helper for a stable, project-owned one. It is a cleanup/refactoring change to keep the public API from depending on a crate version that is not yet finalized. There is no direct security bug being fixed; the main risk is that if done incorrectly, error handling could change slightly for users parsing hex strings.
Treat as a normal refactoring/API-stabilization commit. Reviewers should verify that the new DecodeVariableLengthBytesError preserves the same error information as the old HexToBytesError and that no public trait bounds were accidentally tightened. No urgent security action is indicated.
Security signals we found
Dependency/API surface reduction: removes unstable hex_conservative error type from public API
Error-type substitution only; no new input validation or cryptographic logic introduced
No mention of vulnerability, CVE, bug, or security fix in commit message or diff
Evidence from the diff
The commit removes all direct uses of hex_unstable::FromHex and hex_unstable::HexToBytesError from the rust-bitcoin crate, replacing them with bitcoin::hex::decode_to_vec and bitcoin::hex::DecodeVariableLengthBytesError. This prevents the unstable hex-conservative crate from appearing in the public API. The changes span examples, library code, tests, and doc comments. Error types in public APIs (ParseSignatureError, TaprootError, ScriptBufExt::from_hex_no_length_prefix) are updated to use the stable error type. No logic changes to parsing or cryptographic operations are visible.
Changed components
bitcoin/src/crypto/ecdsa.rsbitcoin/src/taproot/mod.rsbitcoin/src/blockdata/script/owned.rsbitcoin/src/blockdata/transaction.rsbitcoin/src/crypto/sighash.rsbitcoin/src/psbt/mod.rsbitcoin/src/bip158.rsbitcoin/examples/bip32.rsbitcoin/tests/bip_174.rsbitcoin/tests/serde.rsInspect captured patch +54 / −51
diff --git a/bitcoin/examples/bip32.rs b/bitcoin/examples/bip32.rs
index 0dd86afc..dcb74b34 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;
use bitcoin::{CompressedPublicKey, NetworkKind};
-use hex_unstable::FromHex;
fn main() {
// This example derives root xprv from a 32-byte seed,
@@ -23,7 +23,7 @@ fn main() {
println!("Seed: {seed_hex}");
println!("Using mainnet network");
- let seed = Vec::from_hex(seed_hex).unwrap();
+ let seed = hex::decode_to_vec(seed_hex).unwrap();
// calculate root key from seed
let root = Xpriv::new_master(NetworkKind::Main, &seed);
diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs
index 4d1e0d18..89be8945 100644
--- a/bitcoin/src/bip158.rs
+++ b/bitcoin/src/bip158.rs
@@ -549,7 +549,7 @@ mod test {
#[test]
#[cfg(feature = "std")]
fn blockfilters() {
- let hex = |b| <Vec<u8> as hex_unstable::FromHex>::from_hex(b).unwrap();
+ let hex = |b| crate::hex::decode_to_vec(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/owned.rs b/bitcoin/src/blockdata/script/owned.rs
index d2df73aa..32227965 100644
--- a/bitcoin/src/blockdata/script/owned.rs
+++ b/bitcoin/src/blockdata/script/owned.rs
@@ -10,6 +10,7 @@ use super::{
opcode_to_verify, write_scriptint, Builder, Error, Instruction, PushBytes, ScriptBuf,
ScriptExtPriv as _, ScriptPubKeyBuf,
};
+use crate::hex;
use crate::key::{
PubkeyHash, PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey, WPubkeyHash,
};
@@ -159,17 +160,18 @@ internal_macros::define_extension_trait! {
fn from_hex(s: &str) -> Result<Self, hex_unstable::HexToBytesError>
where Self: Sized
{
- Self::from_hex_no_length_prefix(s)
+ let v = Vec::from_hex(s)?;
+ Ok(Self::from_bytes(v))
}
/// Constructs a new [`ScriptBuf`] from a hex string.
///
/// 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_unstable::HexToBytesError>
+ fn from_hex_no_length_prefix(s: &str) -> Result<Self, hex::DecodeVariableLengthBytesError>
where Self: Sized
{
- let v = Vec::from_hex(s)?;
+ let v = hex::decode_to_vec(s)?;
Ok(Self::from_bytes(v))
}
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index a2d4e27f..38510344 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -1277,11 +1277,11 @@ mod tests {
use alloc::string::ToString;
use hex_lit::hex;
- use hex_unstable::FromHex;
use super::*;
use crate::consensus::encode::{deserialize, serialize};
use crate::constants::WITNESS_SCALE_FACTOR;
+ use crate::hex;
use crate::parse_int;
use crate::script::ScriptSigBuf;
use crate::sighash::EcdsaSighashType;
@@ -1486,7 +1486,7 @@ mod tests {
let tx =
con_serde::With::<con_serde::Hex>::deserialize::<'_, Transaction, _>(&mut deserializer)
.unwrap();
- let tx_bytes = Vec::from_hex(&json[1..(json.len() - 1)]).unwrap();
+ let tx_bytes = hex::decode_to_vec(&json[1..(json.len() - 1)]).unwrap();
let expected = deserialize::<Transaction>(&tx_bytes).unwrap();
assert_eq!(tx, expected);
let mut bytes = Vec::new();
@@ -1639,7 +1639,7 @@ mod tests {
#[test]
fn huge_witness() {
- let hex = Vec::from_hex(include_str!("../../tests/data/huge_witness.hex").trim()).unwrap();
+ let hex = hex::decode_to_vec(include_str!("../../tests/data/huge_witness.hex").trim()).unwrap();
deserialize::<Transaction>(&hex).unwrap();
}
@@ -1812,7 +1812,7 @@ mod tests {
for (is_segwit, tx, expected_weight) in &txs {
let txin_weight = if *is_segwit { TxIn::segwit_weight } else { TxIn::legacy_weight };
- let tx: Transaction = deserialize(Vec::from_hex(tx).unwrap().as_slice()).unwrap();
+ let tx: Transaction = deserialize(hex::decode_to_vec(tx).unwrap().as_slice()).unwrap();
assert_eq!(*is_segwit, tx.uses_segwit_serialization());
let mut calculated_weight = empty_transaction_weight
@@ -1970,7 +1970,7 @@ mod tests {
fn return_none(_outpoint: &OutPoint) -> Option<TxOut> { None }
for (hx, expected, spent_fn, expected_none) in tx_hexes.iter() {
- let tx_bytes = Vec::from_hex(hx).unwrap();
+ let tx_bytes = hex::decode_to_vec(hx).unwrap();
let tx: Transaction = deserialize(&tx_bytes).unwrap();
assert_eq!(tx.total_sigop_cost(spent_fn), *expected);
assert_eq!(tx.total_sigop_cost(return_none), *expected_none);
diff --git a/bitcoin/src/crypto/ecdsa.rs b/bitcoin/src/crypto/ecdsa.rs
index 6be37463..1a2827a7 100644
--- a/bitcoin/src/crypto/ecdsa.rs
+++ b/bitcoin/src/crypto/ecdsa.rs
@@ -12,10 +12,10 @@ use core::{fmt, iter};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
-use hex_unstable::FromHex;
use internals::{impl_to_hex_from_lower_hex, write_err};
use io::Write;
+use crate::hex;
use crate::prelude::{DisplayHex, Vec};
#[cfg(doc)]
use crate::script::ScriptPubKeyBufExt as _;
@@ -91,7 +91,7 @@ impl FromStr for Signature {
type Err = ParseSignatureError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
- let bytes = Vec::from_hex(s)?;
+ let bytes = hex::decode_to_vec(s)?;
Ok(Self::from_slice(&bytes)?)
}
}
@@ -282,7 +282,7 @@ impl From<NonStandardSighashTypeError> for DecodeError {
#[non_exhaustive]
pub enum ParseSignatureError {
/// Hex string decoding error.
- Hex(hex_unstable::HexToBytesError),
+ Hex(hex::DecodeVariableLengthBytesError),
/// Signature byte slice decoding error.
Decode(DecodeError),
}
@@ -310,8 +310,8 @@ impl std::error::Error for ParseSignatureError {
}
}
-impl From<hex_unstable::HexToBytesError> for ParseSignatureError {
- fn from(e: hex_unstable::HexToBytesError) -> Self { Self::Hex(e) }
+impl From<hex::DecodeVariableLengthBytesError> for ParseSignatureError {
+ fn from(e: hex::DecodeVariableLengthBytesError) -> Self { Self::Hex(e) }
}
impl From<DecodeError> for ParseSignatureError {
diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs
index 56f4e2d6..886129cb 100644
--- a/bitcoin/src/crypto/sighash.rs
+++ b/bitcoin/src/crypto/sighash.rs
@@ -1397,15 +1397,16 @@ impl<E> EncodeSigningDataResult<E> {
///
/// ```rust
/// # use bitcoin::consensus::deserialize;
- /// # use bitcoin::hashes::{sha256d, hex::FromHex};
+ /// # use bitcoin::hashes::sha256d;
/// # use bitcoin::sighash::SighashCache;
/// # use bitcoin::Transaction;
+ /// # use bitcoin::hex;
/// # let mut writer = sha256d::Hash::engine();
/// # let input_index = 0;
/// # let script_pubkey = bitcoin::ScriptPubKeyBuf::new();
/// # let sighash_u32 = 0u32;
/// # const SOME_TX: &'static str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
- /// # let raw_tx = Vec::from_hex(SOME_TX).unwrap();
+ /// # let raw_tx = hex::decode_to_vec(SOME_TX).unwrap();
/// # let tx: Transaction = deserialize(&raw_tx).unwrap();
/// let cache = SighashCache::new(&tx);
/// if cache.legacy_encode_signing_data_to(&mut writer, input_index, &script_pubkey, sighash_u32)
@@ -1532,10 +1533,10 @@ mod tests {
use hashes::HashEngine;
use hex_lit::hex;
- use hex_unstable::FromHex;
use super::*;
use crate::consensus::deserialize;
+ use crate::hex;
use crate::locktime::absolute;
use crate::script::{
ScriptBufExt as _, ScriptPubKey, ScriptPubKeyBuf, TapScriptBuf, WitnessScriptBuf,
@@ -1584,9 +1585,9 @@ mod tests {
hash_type: i64,
expected_result: &str,
) {
- let tx: Transaction = deserialize(&Vec::from_hex(tx).unwrap()[..]).unwrap();
- let script = ScriptPubKeyBuf::from(Vec::from_hex(script).unwrap());
- let mut raw_expected = Vec::from_hex(expected_result).unwrap();
+ let tx: Transaction = deserialize(&hex::decode_to_vec(tx).unwrap()[..]).unwrap();
+ let script = ScriptPubKeyBuf::from(hex::decode_to_vec(script).unwrap());
+ let mut raw_expected = hex::decode_to_vec(expected_result).unwrap();
raw_expected.reverse();
let bytes = <[u8; 32]>::try_from(&raw_expected[..]).unwrap();
let want = LegacySighash::from_byte_array(bytes);
@@ -1818,14 +1819,14 @@ mod tests {
script_hex: Option<&str>,
script_leaf_hash: Option<&str>,
) {
- let tx_bytes = Vec::from_hex(tx_hex).unwrap();
+ let tx_bytes = hex::decode_to_vec(tx_hex).unwrap();
let tx: Transaction = deserialize(&tx_bytes).unwrap();
- let prevout_bytes = Vec::from_hex(prevout_hex).unwrap();
+ let prevout_bytes = hex::decode_to_vec(prevout_hex).unwrap();
let prevouts: Vec<TxOut> = deserialize(&prevout_bytes).unwrap();
let annex_inner;
let annex = match annex_hex {
Some(annex_hex) => {
- annex_inner = Vec::from_hex(annex_hex).unwrap();
+ annex_inner = hex::decode_to_vec(annex_hex).unwrap();
Some(Annex::new(&annex_inner).unwrap())
}
None => None,
@@ -1855,7 +1856,7 @@ mod tests {
let hash = sighash_cache
.taproot_signature_hash(input_index, &prevouts, annex, leaf_hash, sighash_type)
.unwrap();
- let expected = Vec::from_hex(expected_hash).unwrap();
+ let expected = hex::decode_to_vec(expected_hash).unwrap();
assert_eq!(expected, hash.to_byte_array());
}
@@ -2110,17 +2111,17 @@ mod tests {
// Parse hex into Vec because BIP-0143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!(
cache.prevouts.as_byte_array(),
- &Vec::from_hex("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
+ &hex::decode_to_vec("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
.unwrap()[..],
);
assert_eq!(
cache.sequences.as_byte_array(),
- &Vec::from_hex("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
+ &hex::decode_to_vec("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
.unwrap()[..],
);
assert_eq!(
cache.outputs.as_byte_array(),
- &Vec::from_hex("863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5")
+ &hex::decode_to_vec("863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5")
.unwrap()[..],
);
}
@@ -2153,17 +2154,17 @@ mod tests {
// Parse hex into Vec because BIP-0143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!(
cache.prevouts.as_byte_array(),
- &Vec::from_hex("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a")
+ &hex::decode_to_vec("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a")
.unwrap()[..],
);
assert_eq!(
cache.sequences.as_byte_array(),
- &Vec::from_hex("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198")
+ &hex::decode_to_vec("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198")
.unwrap()[..],
);
assert_eq!(
cache.outputs.as_byte_array(),
- &Vec::from_hex("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83")
+ &hex::decode_to_vec("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83")
.unwrap()[..],
);
}
@@ -2213,17 +2214,17 @@ mod tests {
// Parse hex into Vec because BIP-0143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!(
cache.prevouts.as_byte_array(),
- &Vec::from_hex("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
+ &hex::decode_to_vec("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
.unwrap()[..],
);
assert_eq!(
cache.sequences.as_byte_array(),
- &Vec::from_hex("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
+ &hex::decode_to_vec("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
.unwrap()[..],
);
assert_eq!(
cache.outputs.as_byte_array(),
- &Vec::from_hex("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
+ &hex::decode_to_vec("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
.unwrap()[..],
);
}
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs
index 41ca8a8f..7465d3e7 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/psbt/mod.rs
@@ -1300,7 +1300,6 @@ mod tests {
use hashes::{hash160, ripemd160, sha256};
use hex_lit::hex;
- use hex_unstable::FromHex;
#[cfg(all(feature = "rand", feature = "std"))]
use {
crate::bip32::Fingerprint, crate::locktime, crate::script::ScriptPubKeyBufExt as _,
@@ -1309,6 +1308,7 @@ mod tests {
use super::*;
use crate::bip32::{ChildNumber, DerivationPath};
+ use crate::hex;
use crate::locktime::absolute;
use crate::network::NetworkKind;
use crate::psbt::serialize::{Deserialize, Serialize};
@@ -1321,7 +1321,7 @@ mod tests {
#[track_caller]
pub fn hex_psbt(s: &str) -> Result<Psbt, crate::psbt::error::Error> {
- let r = Vec::from_hex(s);
+ let r = hex::decode_to_vec(s);
match r {
Err(_e) => panic!("unable to parse hex string {}", s),
Ok(v) => Psbt::deserialize(&v),
diff --git a/bitcoin/src/taproot/mod.rs b/bitcoin/src/taproot/mod.rs
index ce0b8073..1cb61b6b 100644
--- a/bitcoin/src/taproot/mod.rs
+++ b/bitcoin/src/taproot/mod.rs
@@ -12,7 +12,6 @@ use core::fmt;
use core::iter::FusedIterator;
use hashes::{hash_newtype, sha256t, sha256t_tag, HashEngine};
-use hex_unstable::{FromHex, HexToBytesError};
use internals::array::ArrayExt;
#[allow(unused)] // MSRV polyfill
use internals::slice::SliceExt;
@@ -24,6 +23,7 @@ use crate::consensus::Encodable;
use crate::crypto::key::{
SerializedXOnlyPublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey,
};
+use crate::hex::{self, DecodeVariableLengthBytesError};
use crate::key::ParseXOnlyPublicKeyError;
use crate::prelude::{BTreeMap, BTreeSet, BinaryHeap, Vec};
use crate::{TapScript, TapScriptBuf};
@@ -1185,7 +1185,7 @@ impl ControlBlock {
/// Constructs a new [`ControlBlock`] from a hex string.
pub fn from_hex(hex: &str) -> Result<Self, TaprootError> {
- let vec = Vec::from_hex(hex).map_err(TaprootError::InvalidControlBlockHex)?;
+ let vec = hex::decode_to_vec(hex).map_err(TaprootError::InvalidControlBlockHex)?;
Self::decode(vec.as_slice())
}
}
@@ -1501,7 +1501,7 @@ pub enum TaprootError {
/// Invalid Taproot internal key.
InvalidInternalKey(ParseXOnlyPublicKeyError),
/// Invalid control block hex
- InvalidControlBlockHex(HexToBytesError),
+ InvalidControlBlockHex(DecodeVariableLengthBytesError),
}
impl From<Infallible> for TaprootError {
diff --git a/bitcoin/tests/bip_174.rs b/bitcoin/tests/bip_174.rs
index 44c6387d..1106b25d 100644
--- a/bitcoin/tests/bip_174.rs
+++ b/bitcoin/tests/bip_174.rs
@@ -6,6 +6,7 @@ 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;
use bitcoin::opcodes::all::OP_0;
use bitcoin::psbt::{Psbt, PsbtSighashType};
use bitcoin::script::{PushBytes, ScriptBuf, ScriptBufExt as _};
@@ -13,11 +14,10 @@ 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 {
- let v: Vec<u8> = Vec::from_hex(s).expect("valid hex digits");
+ let v: Vec<u8> = hex::decode_to_vec(s).expect("valid hex digits");
Psbt::deserialize(&v).expect("valid magic and valid separators")
}
@@ -233,7 +233,7 @@ fn update_psbt(mut psbt: Psbt, fingerprint: Fingerprint) -> Psbt {
let mut input_0 = psbt.inputs[0].clone();
- let v = Vec::from_hex(previous_tx_1).unwrap();
+ let v = hex::decode_to_vec(previous_tx_1).unwrap();
let tx: Transaction = deserialize(&v).unwrap();
input_0.non_witness_utxo = Some(tx);
input_0.redeem_script = Some(hex_script(redeem_script_0));
@@ -241,7 +241,7 @@ fn update_psbt(mut psbt: Psbt, fingerprint: Fingerprint) -> Psbt {
let mut input_1 = psbt.inputs[1].clone();
- let v = Vec::from_hex(previous_tx_0).unwrap();
+ let v = hex::decode_to_vec(previous_tx_0).unwrap();
let tx: Transaction = deserialize(&v).unwrap();
input_1.witness_utxo = Some(tx.outputs[1].clone());
@@ -393,10 +393,10 @@ fn combine_lexicographically() {
let expected_psbt_hex = include_str!("data/lex_combine_psbt_hex");
let expected_psbt: Psbt = hex_psbt(expected_psbt_hex);
- let v = Vec::from_hex(psbt_1_hex).unwrap();
+ let v = hex::decode_to_vec(psbt_1_hex).unwrap();
let mut psbt_1 = Psbt::deserialize(&v).expect("failed to deserialize psbt 1");
- let v = Vec::from_hex(psbt_2_hex).unwrap();
+ let v = hex::decode_to_vec(psbt_2_hex).unwrap();
let psbt_2 = Psbt::deserialize(&v).expect("failed to deserialize psbt 2");
psbt_1.combine(psbt_2).expect("failed to combine PSBTs");
diff --git a/bitcoin/tests/serde.rs b/bitcoin/tests/serde.rs
index 0d950d72..c680e1e1 100644
--- a/bitcoin/tests/serde.rs
+++ b/bitcoin/tests/serde.rs
@@ -24,6 +24,7 @@ use std::collections::BTreeMap;
use bincode::serialize;
use bitcoin::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
+use bitcoin::hex;
use bitcoin::locktime::{absolute, relative};
use bitcoin::psbt::{raw, Input, Output, Psbt, PsbtSighashType};
use bitcoin::script::ScriptBufExt as _;
@@ -35,7 +36,6 @@ use bitcoin::{
ScriptPubKeyBuf, ScriptSigBuf, Sequence, TapScriptBuf, Target, Transaction, TxIn, TxOut, Txid,
Work,
};
-use hex_unstable::FromHex;
#[test]
fn serde_regression_absolute_lock_time_height() {
@@ -99,9 +99,9 @@ fn serde_regression_out_point() {
#[test]
fn serde_regression_witness() {
- let w0 = Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105")
+ let w0 = hex::decode_to_vec("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105")
.unwrap();
- let w1 = Vec::from_hex("000000").unwrap();
+ let w1 = hex::decode_to_vec("000000").unwrap();
let vec = [w0, w1];
let witness = Witness::from_slice(&vec);
@@ -157,7 +157,7 @@ fn serde_regression_ecdsa_sig() {
#[test]
fn serde_regression_control_block() {
let s = include_str!("data/serde/control_block_hex");
- let block = ControlBlock::decode(&Vec::<u8>::from_hex(s.trim()).unwrap()).unwrap();
+ let block = ControlBlock::decode(&hex::decode_to_vec(s.trim()).unwrap()).unwrap();
let got = serialize(&block).unwrap();
let want = include_bytes!("data/serde/control_block_bincode") as &[_];
@@ -209,7 +209,7 @@ fn serde_regression_psbt() {
)
.unwrap(),
sequence: Sequence::from_consensus(4294967295),
- witness: Witness::from_slice(&[Vec::from_hex(
+ witness: Witness::from_slice(&[hex::decode_to_vec(
"03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105",
)
.unwrap()]),
Why this scored 19/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.