Repository: rust-bitcoin/rust-bitcoin
Pull request #1399 (2022-11-18 02:55:49)

Drop Network arg from max_money()
Amount of coins available stay in the same across Bitcoin network: signet, testnet, mainet. From my understanding this is a leftover from some potential multi-chain support.

For more context: https://github.com/lightningdevkit/rust-lightning/pull/1839#discussion_r1019753069

If there is already an existent PR, it can be closed, however didn't find one.


Patch:
diff --git a/bitcoin/examples/bip32.rs b/bitcoin/examples/bip32.rs
index fadae07f..47cdb9d5 100644
--- a/bitcoin/examples/bip32.rs
+++ b/bitcoin/examples/bip32.rs
@@ -7,7 +7,7 @@
 use bitcoin::hashes::hex::FromHex;
 use bitcoin::secp256k1::ffi::types::AlignedType;
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey};
+use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey};
 use bitcoin::PublicKey;
 
 fn main() {
diff --git a/bitcoin/examples/ecdsa-psbt.rs b/bitcoin/examples/ecdsa-psbt.rs
index 60a0a129..1b256723 100644
--- a/bitcoin/examples/ecdsa-psbt.rs
+++ b/bitcoin/examples/ecdsa-psbt.rs
@@ -37,10 +37,10 @@
 use bitcoin::hashes::hex::FromHex;
 use bitcoin::locktime::absolute;
 use bitcoin::secp256k1::{Secp256k1, Signing, Verification};
-use bitcoin::bip32::{
+use bitcoin::util::bip32::{
     ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath,
 };
-use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
+use bitcoin::util::psbt::{self, Input, Psbt, PsbtSighashType};
 use bitcoin::{
     Address, Amount, Network, OutPoint, PublicKey, Script, Sequence, Transaction, TxIn, TxOut,
     Txid, Witness,
@@ -236,7 +236,7 @@ fn update_psbt(&self, mut psbt: Psbt) -> Result<Psbt> {
     /// Finalizes the PSBT, in BIP174 parlance this is the 'Finalizer'.
     /// This is just an example. For a production-ready PSBT Finalizer, use [rust-miniscript](https://docs.rs/miniscript/latest/miniscript/psbt/trait.PsbtExt.html#tymethod.finalize)
     fn finalize_psbt(&self, mut psbt: Psbt) -> Result<Psbt> {
-        use bitcoin::psbt::serialize::Serialize;
+        use bitcoin::util::psbt::serialize::Serialize;
 
         if psbt.inputs.is_empty() {
             return Err(psbt::SignError::MissingInputUtxo.into());
diff --git a/bitcoin/examples/taproot-psbt.rs b/bitcoin/examples/taproot-psbt.rs
index c3ba70bd..2ab15b66 100644
--- a/bitcoin/examples/taproot-psbt.rs
+++ b/bitcoin/examples/taproot-psbt.rs
@@ -87,7 +87,7 @@
 use bitcoin::psbt::{self, Input, Output, Psbt, PsbtSighashType};
 use bitcoin::schnorr::TapTweak;
 use bitcoin::secp256k1::{Message, Secp256k1};
-use bitcoin::bip32::{
+use bitcoin::util::bip32::{
     ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint,
 };
 use bitcoin::sighash::{self, SighashCache, SchnorrSighashType};
diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs
index dee8ddd6..6a5e3e3d 100644
--- a/bitcoin/src/address.rs
+++ b/bitcoin/src/address.rs
@@ -523,13 +523,13 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                 let mut prefixed = [0; 21];
                 prefixed[0] = self.p2pkh_prefix;
                 prefixed[1..].copy_from_slice(&hash[..]);
-                base58::encode_check_to_fmt(fmt, &prefixed[..])
+                base58::check_encode_slice_to_fmt(fmt, &prefixed[..])
             }
             Payload::ScriptHash(hash) => {
                 let mut prefixed = [0; 21];
                 prefixed[0] = self.p2sh_prefix;
                 prefixed[1..].copy_from_slice(&hash[..]);
-                base58::encode_check_to_fmt(fmt, &prefixed[..])
+                base58::check_encode_slice_to_fmt(fmt, &prefixed[..])
             }
             Payload::WitnessProgram { version, program: prog } => {
                 let mut upper_writer;
@@ -839,7 +839,7 @@ fn from_str(s: &str) -> Result<Address, Error> {
         if s.len() > 50 {
             return Err(Error::Base58(base58::Error::InvalidLength(s.len() * 11 / 15)));
         }
-        let data = base58::decode_check(s)?;
+        let data = base58::from_check(s)?;
         if data.len() != 21 {
             return Err(Error::Base58(base58::Error::InvalidLength(data.len())));
         }
diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs
index f272b888..f631f4b7 100644
--- a/bitcoin/src/bip32.rs
+++ b/bitcoin/src/bip32.rs
@@ -388,7 +388,7 @@ pub fn hardened_children(&self) -> DerivationPathIterator {
     /// Concatenate `self` with `path` and return the resulting new path.
     ///
     /// ```
-    /// use bitcoin::bip32::{DerivationPath, ChildNumber};
+    /// use bitcoin::util::bip32::{DerivationPath, ChildNumber};
     /// use std::str::FromStr;
     ///
     /// let base = DerivationPath::from_str("m/42").unwrap();
@@ -780,7 +780,7 @@ pub fn fingerprint(&self) -> Fingerprint { Fingerprint::from(&self.identifier()[
 
 impl fmt::Display for ExtendedPrivKey {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        base58::encode_check_to_fmt(fmt, &self.encode()[..])
+        base58::check_encode_slice_to_fmt(fmt, &self.encode()[..])
     }
 }
 
@@ -788,7 +788,7 @@ impl FromStr for ExtendedPrivKey {
     type Err = Error;
 
     fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
-        let data = base58::decode_check(inp)?;
+        let data = base58::from_check(inp)?;
 
         if data.len() != 78 {
             return Err(base58::Error::InvalidLength(data.len()).into());
@@ -800,7 +800,7 @@ fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
 
 impl fmt::Display for ExtendedPubKey {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        base58::encode_check_to_fmt(fmt, &self.encode()[..])
+        base58::check_encode_slice_to_fmt(fmt, &self.encode()[..])
     }
 }
 
@@ -808,7 +808,7 @@ impl FromStr for ExtendedPubKey {
     type Err = Error;
 
     fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> {
-        let data = base58::decode_check(inp)?;
+        let data = base58::from_check(inp)?;
 
         if data.len() != 78 {
             return Err(base58::Error::InvalidLength(data.len()).into());
diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs
index 1fde7047..1d652efc 100644
--- a/bitcoin/src/blockdata/block.rs
+++ b/bitcoin/src/blockdata/block.rs
@@ -13,8 +13,8 @@
 
 use core::fmt;
 
-use crate::merkle_tree;
-use crate::error::Error::{self, BlockBadTarget, BlockBadProofOfWork};
+use crate::{merkle_tree, util};
+use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork};
 use crate::hashes::{Hash, HashEngine};
 use crate::hash_types::{Wtxid, TxMerkleNode, WitnessMerkleNode, WitnessCommitment};
 use crate::consensus::{encode, Encodable, Decodable};
@@ -77,7 +77,7 @@ pub fn difficulty(&self) -> u128 {
     }
 
     /// Checks that the proof-of-work for the block is valid, returning the block hash.
-    pub fn validate_pow(&self, required_target: Target) -> Result<BlockHash, Error> {
+    pub fn validate_pow(&self, required_target: Target) -> Result<BlockHash, util::Error> {
         let target = self.target();
         if target != required_target {
             return Err(BlockBadTarget);
diff --git a/bitcoin/src/blockdata/constants.rs b/bitcoin/src/blockdata/constants.rs
index c74fd88f..ce5fc24c 100644
--- a/bitcoin/src/blockdata/constants.rs
+++ b/bitcoin/src/blockdata/constants.rs
@@ -60,7 +60,7 @@
 /// The maximum value allowed in an output (useful for sanity checking,
 /// since keeping everything below this value should prevent overflows
 /// if you are doing anything remotely sane with monetary values).
-pub fn max_money(_: Network) -> u64 {
+pub fn max_money() -> u64 {
     21_000_000 * COIN_VALUE
 }
 
diff --git a/bitcoin/src/blockdata/script.rs b/bitcoin/src/blockdata/script.rs
index 2768b303..7f836f53 100644
--- a/bitcoin/src/blockdata/script.rs
+++ b/bitcoin/src/blockdata/script.rs
@@ -831,7 +831,7 @@ fn from(script: &Script) -> WScriptHash {
 }
 
 /// A "parsed opcode" which allows iterating over a [`Script`] in a more sensible way.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+#[derive(Debug, PartialEq, Eq, Clone)]
 pub enum Instruction<'a> {
     /// Push a bunch of data.
     PushBytes(&'a [u8]),
@@ -1183,7 +1183,7 @@ mod test {
     use crate::consensus::encode::{deserialize, serialize};
     use crate::blockdata::opcodes;
     use crate::util::key::PublicKey;
-    use crate::psbt::serialize::Serialize;
+    use crate::util::psbt::serialize::Serialize;
     use crate::internal_macros::hex_script;
 
     #[test]
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index a43d6b12..1581587c 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -1396,7 +1396,7 @@ fn test_transaction_verify () {
         // test that we get a failure if we corrupt a signature
         let mut witness: Vec<_> = spending.input[1].witness.to_vec();
         witness[0][10] = 42;
-        spending.input[1].witness = Witness::from_slice(&witness);
+        spending.input[1].witness = Witness::from_vec(witness);
         match spending.verify(|point: &OutPoint| {
             if let Some(tx) = spent3.remove(&point.txid) {
                 return tx.output.get(point.vout as usize).cloned();
diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs
index 8a416c86..5305315b 100644
--- a/bitcoin/src/blockdata/witness.rs
+++ b/bitcoin/src/blockdata/witness.rs
@@ -16,20 +16,20 @@
 use crate::io::{self, Read, Write};
 use crate::prelude::*;
 use crate::VarInt;
-use crate::util::taproot::TAPROOT_ANNEX_PREFIX;
+
+const U32_SIZE: usize = core::mem::size_of::<u32>();
 
 /// The Witness is the data used to unlock bitcoins since the [segwit upgrade](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki)
 ///
-/// Can be logically seen as an array of bytestrings, i.e. `Vec<Vec<u8>>`, and it is serialized on the wire
-/// in that format. You can convert between this type and `Vec<Vec<u8>>` by using [`Witness::from_slice`]
-/// and [`Witness::to_vec`].
+/// Can be logically seen as an array of byte-arrays `Vec<Vec<u8>>` and indeed you can convert from
+/// it [`Witness::from_vec`] and convert into it [`Witness::to_vec`].
 ///
 /// For serialization and deserialization performance it is stored internally as a single `Vec`,
 /// saving some allocations.
 ///
 #[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Witness {
-    /// Contains the witness Vec<Vec<u8>> serialization without the initial varint indicating the
+    /// contains the witness Vec<Vec<u8>> serialization without the initial varint indicating the
     /// number of elements (which is stored in `witness_elements`)
     content: Vec<u8>,
 
@@ -66,7 +66,7 @@ fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
         } else {
             // Leave space at the head for element positions.
             // We will rotate them to the end of the Vec later.
-            let witness_index_space = witness_elements * 4;
+            let witness_index_space = witness_elements * U32_SIZE;
             let mut cursor = witness_index_space;
 
             // this number should be determined as high enough to cover most witness, and low enough
@@ -120,18 +120,18 @@ fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
 }
 
 
-/// Correctness Requirements: value must always fit within u32
+/// Safety Requirements: value must always fit within u32
 #[inline]
 fn encode_cursor(bytes: &mut [u8], start_of_indices: usize, index: usize, value: usize) {
-    let start = start_of_indices + index * 4;
-    let end = start + 4;
-    bytes[start..end].copy_from_slice(&u32::to_ne_bytes(value.try_into().expect("Larger than u32")));
+    let start = start_of_indices + index * U32_SIZE;
+    let end = start + U32_SIZE;
+    bytes[start..end].copy_from_slice(&(value as u32).to_ne_bytes()[..]);
 }
 
 #[inline]
 fn decode_cursor(bytes: &[u8], start_of_indices: usize, index: usize) -> Option<usize> {
-    let start = start_of_indices + index * 4;
-    let end = start + 4;
+    let start = start_of_indices + index * U32_SIZE;
+    let end = start + U32_SIZE;
     if end > bytes.len() {
         None
     } else {
@@ -154,7 +154,7 @@ fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Er
         let len = VarInt(self.witness_elements as u64);
         len.consensus_encode(w)?;
         let content_with_indices_len = self.content.len();
-        let indices_size = self.witness_elements * 4;
+        let indices_size = self.witness_elements * U32_SIZE;
         let content_len = content_with_indices_len - indices_size;
         w.emit_slice(&self.content[..content_len])?;
         Ok(content_len + len.len())
@@ -168,31 +168,26 @@ pub fn new() -> Self {
     }
 
     /// Creates [`Witness`] object from an array of byte-arrays
-    #[deprecated(since="0.30.0", note="use `Witness::from_slice()` instead")]
     pub fn from_vec(vec: Vec<Vec<u8>>) -> Self {
-        Witness::from_slice(&vec)
-    }
+        let witness_elements = vec.len();
+        let index_size = witness_elements * U32_SIZE;
 
-    /// Creates a [`Witness`] object from a slice of bytes slices where each slice is a witness item.
-    pub fn from_slice<T: AsRef<[u8]>>(slice: &[T]) -> Self {
-        let witness_elements = slice.len();
-        let index_size = witness_elements * 4;
-        let content_size = slice
+        let content_size: usize = vec
             .iter()
-            .map(|elem| elem.as_ref().len() + VarInt(elem.as_ref().len() as u64).len())
+            .map(|el| el.len() + VarInt(el.len() as u64).len())
             .sum();
-
         let mut content = vec![0u8; content_size + index_size];
         let mut cursor = 0usize;
-        for (i, elem) in slice.iter().enumerate() {
+        for (i, el) in vec.into_iter().enumerate() {
             encode_cursor(&mut content, content_size, i, cursor);
-            let elem_len_varint = VarInt(elem.as_ref().len() as u64);
-            elem_len_varint
-                .consensus_encode(&mut &mut content[cursor..cursor + elem_len_varint.len()])
+
+            let el_len_varint = VarInt(el.len() as u64);
+            el_len_varint
+                .consensus_encode(&mut &mut content[cursor..cursor + el_len_varint.len()])
                 .expect("writers on vec don't errors, space granted by content_size");
-            cursor += elem_len_varint.len();
-            content[cursor..cursor + elem.as_ref().len()].copy_from_slice(elem.as_ref());
-            cursor += elem.as_ref().len();
+            cursor += el_len_varint.len();
+            content[cursor..cursor + el.len()].copy_from_slice(&el);
+            cursor += el.len();
         }
 
         Witness {
@@ -243,18 +238,14 @@ pub fn clear(&mut self) {
 
     /// Push a new element on the witness, requires an allocation
     pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) {
-        self.push_slice(new_element.as_ref());
-    }
-
-    /// Push a new element slice onto the witness stack.
-    fn push_slice(&mut self, new_element: &[u8]) {
+        let new_element = new_element.as_ref();
         self.witness_elements += 1;
         let previous_content_end = self.indices_start;
         let element_len_varint = VarInt(new_element.len() as u64);
         let current_content_len = self.content.len();
         let new_item_total_len = element_len_varint.len() + new_element.len();
         self.content
-            .resize(current_content_len + new_item_total_len + 4, 0);
+            .resize(current_content_len + new_item_total_len + U32_SIZE, 0);
 
         self.content[previous_content_end..].rotate_right(new_item_total_len);
         self.indices_start += new_item_total_len;
@@ -313,7 +304,7 @@ pub fn nth(&self, index: usize) -> Option<&[u8]> {
     /// This does not guarantee that this represents a P2TR [`Witness`].
     /// It merely gets the second to last or third to last element depending
     /// on the first byte of the last element being equal to 0x50.
-    pub fn tapscript(&self) -> Option<&[u8]> {
+    pub fn get_tapscript(&self) -> Option<&[u8]> {
         let len = self.len();
         self
             .last()
@@ -322,7 +313,7 @@ pub fn tapscript(&self) -> Option<&[u8]> {
                 // If there are at least two witness elements, and the first byte of
                 // the last element is 0x50, this last element is called annex a
                 // and is removed from the witness stack.
-                if len >= 2 && last_elem.first() == Some(&TAPROOT_ANNEX_PREFIX) {
+                if len >= 2 && last_elem.first().filter(|&&v| v == 0x50).is_some() {
                     // account for the extra item removed from the end
                     3
                 } else {
@@ -359,7 +350,7 @@ fn next(&mut self) -> Option<Self::Item> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let total_count = (self.inner.len() - self.indices_start) / 4;
+        let total_count = (self.inner.len() - self.indices_start) / U32_SIZE;
         let remaining = total_count - self.current_index;
         (remaining, Some(remaining))
     }
@@ -444,7 +435,7 @@ fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut a: A) -> Result<Self::Value
                     })?;
                     ret.push(vec);
                 }
-                Ok(Witness::from_slice(&ret))
+                Ok(Witness::from_vec(ret))
             }
         }
 
@@ -452,35 +443,11 @@ fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut a: A) -> Result<Self::Value
             deserializer.deserialize_seq(Visitor)
         } else {
             let vec: Vec<Vec<u8>> = serde::Deserialize::deserialize(deserializer)?;
-            Ok(Witness::from_slice(&vec))
+            Ok(Witness::from_vec(vec))
         }
     }
 }
 
-impl From<Vec<Vec<u8>>> for Witness {
-    fn from(vec: Vec<Vec<u8>>) -> Self {
-        Witness::from_slice(&vec)
-    }
-}
-
-impl From<&[&[u8]]> for Witness {
-    fn from(slice: &[&[u8]]) -> Self {
-        Witness::from_slice(slice)
-    }
-}
-
-impl From<&[Vec<u8>]> for Witness {
-    fn from(slice: &[Vec<u8>]) -> Self {
-        Witness::from_slice(slice)
-    }
-}
-
-impl From<Vec<&[u8]>> for Witness {
-    fn from(vec: Vec<&[u8]>) -> Self {
-        Witness::from_slice(&vec)
-    }
-}
-
 #[cfg(test)]
 mod test {
     use super::*;
@@ -492,7 +459,7 @@ mod test {
 
     fn append_u32_vec(mut v: Vec<u8>, n: &[u32]) -> Vec<u8> {
         for &num in n {
-            v.extend_from_slice(&num.to_ne_bytes());
+            v.extend_from_slice(&num.to_ne_bytes()[..]);
         }
         v
     }
@@ -606,7 +573,7 @@ fn test_witness() {
         assert_eq!(&witness[0], &w0[..]);
         assert_eq!(&witness[1], &w1[..]);
 
-        let w_into = Witness::from_slice(&witness_vec);
+        let w_into = Witness::from_vec(witness_vec);
         assert_eq!(w_into, witness);
 
         assert_eq!(witness_serialized, serialize(&witness));
@@ -637,8 +604,8 @@ fn test_get_tapscript() {
         };
 
         // With or without annex, the tapscript should be returned.
-        assert_eq!(witness.tapscript(), Some(&tapscript[..]));
-        assert_eq!(witness_annex.tapscript(), Some(&tapscript[..]));
+        assert_eq!(witness.get_tapscript(), Some(&tapscript[..]));
+        assert_eq!(witness_annex.get_tapscript(), Some(&tapscript[..]));
     }
 
     #[test]
@@ -680,7 +647,7 @@ fn test_serde_bincode() {
         use bincode;
 
         let old_witness_format = vec![vec![0u8], vec![2]];
-        let new_witness_format = Witness::from_slice(&old_witness_format);
+        let new_witness_format = Witness::from_vec(old_witness_format.clone());
 
         let old = bincode::serialize(&old_witness_format).unwrap();
         let new = bincode::serialize(&new_witness_format).unwrap();
@@ -696,7 +663,7 @@ fn test_serde_bincode() {
     fn test_serde_human() {
         use serde_json;
 
-        let witness = Witness::from_slice(&[vec![0u8, 123, 75], vec![2u8, 6, 3, 7, 8]]);
+        let witness = Witness::from_vec(vec![vec![0u8, 123, 75], vec![2u8, 6, 3, 7, 8]]);
 
         let json = serde_json::to_string(&witness).unwrap();
 
@@ -715,8 +682,8 @@ mod benches {
 
     #[bench]
     pub fn bench_big_witness_to_vec(bh: &mut Bencher) {
-        let raw_witness = [[1u8]; 5];
-        let witness = Witness::from_slice(&raw_witness);
+        let raw_witness = vec![vec![1u8]; 5];
+        let witness = Witness::from_vec(raw_witness);
 
         bh.iter(|| {
             black_box(witness.to_vec());
@@ -726,7 +693,7 @@ pub fn bench_big_witness_to_vec(bh: &mut Bencher) {
     #[bench]
     pub fn bench_witness_to_vec(bh: &mut Bencher) {
         let raw_witness = vec![vec![1u8]; 3];
-        let witness = Witness::from_slice(&raw_witness);
+        let witness = Witness::from_vec(raw_witness);
 
         bh.iter(|| {
             black_box(witness.to_vec());
diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs
index ac450b39..20f9d306 100644
--- a/bitcoin/src/consensus/encode.rs
+++ b/bitcoin/src/consensus/encode.rs
@@ -26,7 +26,7 @@
 use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
 use crate::io::{self, Cursor, Read};
 
-use crate::psbt;
+use crate::util::psbt;
 use crate::bip152::{ShortId, PrefilledTransaction};
 use crate::util::taproot::TapLeafHash;
 use crate::hashes::hex::ToHex;
diff --git a/bitcoin/src/error.rs b/bitcoin/src/error.rs
index d31c09f8..58bbb2d1 100644
--- a/bitcoin/src/error.rs
+++ b/bitcoin/src/error.rs
@@ -1,53 +1,7 @@
 //! Contains error types and other error handling tools.
 
-use core::fmt;
-
-use bitcoin_internals::write_err;
-
-use crate::consensus::encode;
 pub use crate::parse::ParseIntError;
 
-/// A general error code, other errors should implement conversions to/from this
-/// if appropriate.
-#[derive(Debug)]
-#[non_exhaustive]
-pub enum Error {
-    /// Encoding error
-    Encode(encode::Error),
-    /// The header hash is not below the target
-    BlockBadProofOfWork,
-    /// The `target` field of a block header did not match the expected difficulty
-    BlockBadTarget,
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Error::Encode(ref e) => write_err!(f, "encoding error"; e),
-            Error::BlockBadProofOfWork => f.write_str("block target correct but not attained"),
-            Error::BlockBadTarget => f.write_str("block target incorrect"),
-        }
-    }
-}
-
-#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-impl std::error::Error for Error {
-    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-        use self::Error::*;
-
-        match self {
-            Encode(e) => Some(e),
-            BlockBadProofOfWork | BlockBadTarget => None,
-        }
-    }
-}
-
-#[doc(hidden)]
-impl From<encode::Error> for Error {
-    fn from(e: encode::Error) -> Error { Error::Encode(e) }
-}
-
 /// Impls std::error::Error for the specified type with appropriate attributes, possibly returning
 /// source.
 macro_rules! impl_std_error {
diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs
index a9abadcb..faff0e9c 100644
--- a/bitcoin/src/lib.rs
+++ b/bitcoin/src/lib.rs
@@ -104,7 +104,6 @@
 pub mod merkle_tree;
 pub mod policy;
 pub mod pow;
-pub mod psbt;
 pub mod sighash;
 pub mod sign_message;
 pub mod util;
@@ -123,15 +122,15 @@
 pub use crate::blockdata::witness::{self, Witness};
 pub use crate::blockdata::{constants, opcodes};
 pub use crate::consensus::encode::VarInt;
-pub use crate::error::Error;
 pub use crate::hash_types::*;
 pub use crate::network::constants::Network;
 pub use crate::pow::{CompactTarget, Target, Work};
 pub use crate::amount::{Amount, Denomination, SignedAmount};
 pub use crate::util::ecdsa::{self, EcdsaSig, EcdsaSigError};
 pub use crate::util::key::{KeyPair, PrivateKey, PublicKey, XOnlyPublicKey};
-pub use crate::merkle_tree::MerkleBlock;
+pub use crate::util::merkleblock::MerkleBlock;
 pub use crate::util::schnorr::{self, SchnorrSig, SchnorrSigError};
+pub use crate::util::{psbt, Error};
 
 #[cfg(not(feature = "std"))]
 mod io_extras {
diff --git a/bitcoin/src/merkle_tree/mod.rs b/bitcoin/src/merkle_tree.rs
similarity index 93%
rename from bitcoin/src/merkle_tree/mod.rs
rename to bitcoin/src/merkle_tree.rs
index b7b515f2..a9cfb385 100644
--- a/bitcoin/src/merkle_tree/mod.rs
+++ b/bitcoin/src/merkle_tree.rs
@@ -14,17 +14,15 @@
 //! let root = merkle_tree::calculate_root(tx_hashes.into_iter());
 //! ```
 
-mod block;
-
-use core::cmp::min;
 use core::iter;
 
-pub use block::{MerkleBlock, MerkleBlockError, PartialMerkleTree};
+use crate::prelude::*;
 
-use crate::consensus::encode::Encodable;
-use crate::hashes::Hash;
 use crate::io;
-use crate::prelude::*;
+use core::cmp::min;
+
+use crate::hashes::Hash;
+use crate::consensus::encode::Encodable;
 
 /// Calculates the merkle root of a list of *hashes*, inline (in place) in `hashes`.
 ///
@@ -39,7 +37,7 @@
 pub fn calculate_root_inline<T>(hashes: &mut [T]) -> Option<T>
 where
     T: Hash + Encodable,
-    <T as Hash>::Engine: io::Write,
+          <T as Hash>::Engine: io::Write,
 {
     match hashes.len() {
         0 => None,
@@ -58,7 +56,7 @@ pub fn calculate_root<T, I>(mut hashes: I) -> Option<T>
 where
     T: Hash + Encodable,
     <T as Hash>::Engine: io::Write,
-    I: Iterator<Item = T>,
+    I: Iterator<Item=T>,
 {
     let first = hashes.next()?;
     let second = match hashes.next() {
@@ -92,7 +90,7 @@ fn merkle_root_r<T>(hashes: &mut [T]) -> T
     <T as Hash>::Engine: io::Write,
 {
     if hashes.len() == 1 {
-        return hashes[0];
+        return hashes[0]
     }
 
     for idx in 0..((hashes.len() + 1) / 2) {
@@ -110,15 +108,16 @@ fn merkle_root_r<T>(hashes: &mut [T]) -> T
 
 #[cfg(test)]
 mod tests {
-    use super::*;
-    use crate::blockdata::block::Block;
     use crate::consensus::encode::deserialize;
     use crate::hashes::sha256d;
 
+    use crate::blockdata::block::Block;
+    use super::*;
+
     #[test]
     fn both_merkle_root_functions_return_the_same_result() {
         // testnet block 000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b
-        let segwit_block = include_bytes!("../../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw");
+        let segwit_block = include_bytes!("../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw");
         let block: Block = deserialize(&segwit_block[..]).expect("Failed to deserialize block");
         assert!(block.check_merkle_root()); // Sanity check.
 
diff --git a/bitcoin/src/network/message.rs b/bitcoin/src/network/message.rs
index a64df614..5a6e3d43 100644
--- a/bitcoin/src/network/message.rs
+++ b/bitcoin/src/network/message.rs
@@ -24,7 +24,7 @@
 use crate::network::constants::Magic;
 use crate::consensus::encode::{CheckedData, Decodable, Encodable, VarInt};
 use crate::consensus::{encode, serialize};
-use crate::merkle_tree::MerkleBlock;
+use crate::util::merkleblock::MerkleBlock;
 
 /// The maximum number of [super::message_blockdata::Inventory] items in an `inv` message.
 ///
@@ -469,8 +469,6 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Err
 
 #[cfg(test)]
 mod test {
-    use super::*;
-
     use std::net::Ipv4Addr;
     use super::{RawNetworkMessage, NetworkMessage, CommandString};
     use crate::network::constants::{ServiceFlags, Magic, Network};
@@ -486,6 +484,7 @@ mod test {
     use crate::blockdata::transaction::Transaction;
     use crate::blockdata::script::Script;
     use crate::network::message_bloom::{FilterAdd, FilterLoad, BloomFlags};
+    use crate::MerkleBlock;
     use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct};
     use crate::bip152::BlockTransactionsRequest;
 
diff --git a/bitcoin/src/util/base58.rs b/bitcoin/src/util/base58.rs
index e6c86e7b..1f878a78 100644
--- a/bitcoin/src/util/base58.rs
+++ b/bitcoin/src/util/base58.rs
@@ -12,7 +12,107 @@
 use core::{fmt, str, iter, slice};
 use core::convert::TryInto;
 
-use crate::hashes::{sha256d, Hash};
+use bitcoin_internals::write_err;
+use crate::hashes::{sha256d, Hash, hex};
+use secp256k1;
+
+use crate::util::key;
+
+/// An error that might occur during base58 decoding
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
+#[non_exhaustive]
+pub enum Error {
+    /// Invalid character encountered
+    BadByte(u8),
+    /// Checksum was not correct (expected, actual)
+    BadChecksum(u32, u32),
+    /// The length (in bytes) of the object was not correct
+    /// Note that if the length is excessively long the provided length may be
+    /// an estimate (and the checksum step may be skipped).
+    InvalidLength(usize),
+    /// Extended Key version byte(s) were not recognized
+    InvalidExtendedKeyVersion([u8; 4]),
+    /// Address version byte were not recognized
+    InvalidAddressVersion(u8),
+    /// Checked data was less than 4 bytes
+    TooShort(usize),
+    /// Secp256k1 error while parsing a secret key
+    Secp256k1(secp256k1::Error),
+    /// Hex decoding error
+    // TODO: Remove this as part of crate-smashing, there should not be any key related errors in this module
+    Hex(hex::Error)
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::BadByte(b) => write!(f, "invalid base58 character 0x{:x}", b),
+            Error::BadChecksum(exp, actual) => write!(f, "base58ck checksum 0x{:x} does not match expected 0x{:x}", actual, exp),
+            Error::InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell),
+            Error::InvalidExtendedKeyVersion(ref v) => write!(f, "extended key version {:#04x?} is invalid for this base58 type", v),
+            Error::InvalidAddressVersion(ref v) => write!(f, "address version {} is invalid for this base58 type", v),
+            Error::TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"),
+            Error::Secp256k1(ref e) => write_err!(f, "secp256k1 error while parsing secret key"; e),
+            Error::Hex(ref e) => write_err!(f, "hexadecimal decoding error"; e)
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl std::error::Error for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        use self::Error::*;
+
+        match self {
+            BadByte(_)
+            | BadChecksum(_, _)
+            | InvalidLength(_)
+            | InvalidExtendedKeyVersion(_)
+            | InvalidAddressVersion(_)
+            | TooShort(_) => None,
+            Secp256k1(e) => Some(e),
+            Hex(e) => Some(e),
+        }
+    }
+}
+
+/// Vector-like object that holds the first 100 elements on the stack. If more space is needed it
+/// will be allocated on the heap.
+struct SmallVec<T> {
+    len: usize,
+    stack: [T; 100],
+    heap: Vec<T>,
+}
+
+impl<T: Default + Copy> SmallVec<T> {
+    pub fn new() -> SmallVec<T> {
+        SmallVec {
+            len: 0,
+            stack: [T::default(); 100],
+            heap: Vec::new(),
+        }
+    }
+
+    pub fn push(&mut self, val: T) {
+        if self.len < 100 {
+            self.stack[self.len] = val;
+            self.len += 1;
+        } else {
+            self.heap.push(val);
+        }
+    }
+
+    pub fn iter(&self) -> iter::Chain<slice::Iter<T>, slice::Iter<T>> {
+        // If len<100 then we just append an empty vec
+        self.stack[0..self.len].iter().chain(self.heap.iter())
+    }
+
+    pub fn iter_mut(&mut self) -> iter::Chain<slice::IterMut<T>, slice::IterMut<T>> {
+        // If len<100 then we just append an empty vec
+        self.stack[0..self.len].iter_mut().chain(self.heap.iter_mut())
+    }
+}
 
 static BASE58_CHARS: &[u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
@@ -35,14 +135,8 @@
     Some(55), Some(56), Some(57), None,     None,     None,     None,     None,     // 120-127
 ];
 
-/// Decodes a base58-encoded string into a byte vector.
-#[deprecated(since = "0.30.0", note = "Use base58::decode() instead")]
+/// Decode base58-encoded string into a byte vector
 pub fn from(data: &str) -> Result<Vec<u8>, Error> {
-    decode(data)
-}
-
-/// Decodes a base58-encoded string into a byte vector.
-pub fn decode(data: &str) -> Result<Vec<u8>, Error> {
     // 11/15 is just over log_256(58)
     let mut scratch = vec![0u8; 1 + data.len() * 11 / 15];
     // Build in base 256
@@ -72,15 +166,9 @@ pub fn decode(data: &str) -> Result<Vec<u8>, Error> {
     Ok(ret)
 }
 
-/// Decodes a base58check-encoded string into a byte vector verifying the checksum.
-#[deprecated(since = "0.30.0", note = "Use base58::decode_check() instead")]
+/// Decode a base58check-encoded string
 pub fn from_check(data: &str) -> Result<Vec<u8>, Error> {
-    decode_check(data)
-}
-
-/// Decodes a base58check-encoded string into a byte vector verifying the checksum.
-pub fn decode_check(data: &str) -> Result<Vec<u8>, Error> {
-    let mut ret: Vec<u8> = decode(data)?;
+    let mut ret: Vec<u8> = from(data)?;
     if ret.len() < 4 {
         return Err(Error::TooShort(ret.len()));
     }
@@ -100,65 +188,6 @@ pub fn decode_check(data: &str) -> Result<Vec<u8>, Error> {
     Ok(ret)
 }
 
-/// Encodes `data` as a base58 string.
-#[deprecated(since = "0.30.0", note = "Use base58::encode() instead")]
-pub fn encode_slice(data: &[u8]) -> String {
-    encode(data)
-}
-
-/// Encodes `data` as a base58 string (see also `base58::encode_check()`).
-pub fn encode(data: &[u8]) -> String {
-    encode_iter(data.iter().cloned())
-}
-
-/// Encodes `data` as a base58 string including the checksum.
-///
-/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
-#[deprecated(since = "0.30.0", note = "Use base58::encode_check() instead")]
-pub fn check_encode_slice(data: &[u8]) -> String {
-    encode_check(data)
-}
-
-/// Encodes `data` as a base58 string including the checksum.
-///
-/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
-pub fn encode_check(data: &[u8]) -> String {
-    let checksum = sha256d::Hash::hash(data);
-    encode_iter(
-        data.iter()
-            .cloned()
-            .chain(checksum[0..4].iter().cloned())
-    )
-}
-
-/// Encodes `data` as base58, including the checksum, into a formatter.
-///
-/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
-#[deprecated(since = "0.30.0", note = "Use base58::encode_check_to_fmt() instead")]
-pub fn check_encode_slice_to_fmt(fmt: &mut fmt::Formatter, data: &[u8]) -> fmt::Result {
-    encode_check_to_fmt(fmt, data)
-}
-
-/// Encodes a slice as base58, including the checksum, into a formatter.
-///
-/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
-pub fn encode_check_to_fmt(fmt: &mut fmt::Formatter, data: &[u8]) -> fmt::Result {
-    let checksum = sha256d::Hash::hash(data);
-    let iter = data.iter()
-        .cloned()
-        .chain(checksum[0..4].iter().cloned());
-    format_iter(fmt, iter)
-}
-
-fn encode_iter<I>(data: I) -> String
-where
-    I: Iterator<Item=u8> + Clone,
-{
-    let mut ret = String::new();
-    format_iter(&mut ret, data).expect("writing into string shouldn't fail");
-    ret
-}
-
 fn format_iter<I, W>(writer: &mut W, data: I) -> Result<(), fmt::Error>
 where
     I: Iterator<Item=u8> + Clone,
@@ -200,90 +229,50 @@ fn format_iter<I, W>(writer: &mut W, data: I) -> Result<(), fmt::Error>
     Ok(())
 }
 
-/// Vector-like object that holds the first 100 elements on the stack. If more space is needed it
-/// will be allocated on the heap.
-struct SmallVec<T> {
-    len: usize,
-    stack: [T; 100],
-    heap: Vec<T>,
+fn encode_iter<I>(data: I) -> String
+where
+    I: Iterator<Item=u8> + Clone,
+{
+    let mut ret = String::new();
+    format_iter(&mut ret, data).expect("writing into string shouldn't fail");
+    ret
 }
 
-impl<T: Default + Copy> SmallVec<T> {
-    fn new() -> SmallVec<T> {
-        SmallVec {
-            len: 0,
-            stack: [T::default(); 100],
-            heap: Vec::new(),
-        }
-    }
-
-    fn push(&mut self, val: T) {
-        if self.len < 100 {
-            self.stack[self.len] = val;
-            self.len += 1;
-        } else {
-            self.heap.push(val);
-        }
-    }
-
-    fn iter(&self) -> iter::Chain<slice::Iter<T>, slice::Iter<T>> {
-        // If len<100 then we just append an empty vec
-        self.stack[0..self.len].iter().chain(self.heap.iter())
-    }
 
-    fn iter_mut(&mut self) -> iter::Chain<slice::IterMut<T>, slice::IterMut<T>> {
-        // If len<100 then we just append an empty vec
-        self.stack[0..self.len].iter_mut().chain(self.heap.iter_mut())
-    }
+/// Directly encode a slice as base58
+pub fn encode_slice(data: &[u8]) -> String {
+    encode_iter(data.iter().cloned())
 }
 
-/// An error that might occur during base58 decoding.
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
-#[non_exhaustive]
-pub enum Error {
-    /// Invalid character encountered.
-    BadByte(u8),
-    /// Checksum was not correct (expected, actual).
-    BadChecksum(u32, u32),
-    /// The length (in bytes) of the object was not correct.
-    ///
-    /// Note that if the length is excessively long the provided length may be an estimate (and the
-    /// checksum step may be skipped).
-    InvalidLength(usize),
-    /// Extended Key version byte(s) were not recognized.
-    InvalidExtendedKeyVersion([u8; 4]),
-    /// Address version byte were not recognized.
-    InvalidAddressVersion(u8),
-    /// Checked data was less than 4 bytes.
-    TooShort(usize),
+/// Obtain a string with the base58check encoding of a slice
+/// (Tack the first 4 256-digits of the object's Bitcoin hash onto the end.)
+pub fn check_encode_slice(data: &[u8]) -> String {
+    let checksum = sha256d::Hash::hash(data);
+    encode_iter(
+        data.iter()
+            .cloned()
+            .chain(checksum[0..4].iter().cloned())
+    )
 }
 
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Error::BadByte(b) => write!(f, "invalid base58 character {:#x}", b),
-            Error::BadChecksum(exp, actual) => write!(f, "base58ck checksum {:#x} does not match expected {:#x}", actual, exp),
-            Error::InvalidLength(ell) => write!(f, "length {} invalid for this base58 type", ell),
-            Error::InvalidExtendedKeyVersion(ref v) => write!(f, "extended key version {:#04x?} is invalid for this base58 type", v),
-            Error::InvalidAddressVersion(ref v) => write!(f, "address version {} is invalid for this base58 type", v),
-            Error::TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"),
-        }
-    }
+/// Obtain a string with the base58check encoding of a slice
+/// (Tack the first 4 256-digits of the object's Bitcoin hash onto the end.)
+pub fn check_encode_slice_to_fmt(fmt: &mut fmt::Formatter, data: &[u8]) -> fmt::Result {
+    let checksum = sha256d::Hash::hash(data);
+    let iter = data.iter()
+        .cloned()
+        .chain(checksum[0..4].iter().cloned());
+    format_iter(fmt, iter)
 }
 
-#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-impl std::error::Error for Error {
-    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-        use self::Error::*;
-
-        match self {
-            BadByte(_)
-            | BadChecksum(_, _)
-            | InvalidLength(_)
-            | InvalidExtendedKeyVersion(_)
-            | InvalidAddressVersion(_)
-            | TooShort(_) => None,
+#[doc(hidden)]
+impl From<key::Error> for Error {
+    fn from(e: key::Error) -> Self {
+        match e {
+            key::Error::Secp256k1(e) => Error::Secp256k1(e),
+            key::Error::Base58(e) => e,
+            key::Error::InvalidKeyPrefix(_) => Error::Secp256k1(secp256k1::Error::InvalidPublicKey),
+            key::Error::Hex(e) => Error::Hex(e)
         }
     }
 }
@@ -296,17 +285,17 @@ mod tests {
     #[test]
     fn test_base58_encode() {
         // Basics
-        assert_eq!(&encode(&[0][..]), "1");
-        assert_eq!(&encode(&[1][..]), "2");
-        assert_eq!(&encode(&[58][..]), "21");
-        assert_eq!(&encode(&[13, 36][..]), "211");
+        assert_eq!(&encode_slice(&[0][..]), "1");
+        assert_eq!(&encode_slice(&[1][..]), "2");
+        assert_eq!(&encode_slice(&[58][..]), "21");
+        assert_eq!(&encode_slice(&[13, 36][..]), "211");
 
         // Leading zeroes
-        assert_eq!(&encode(&[0, 13, 36][..]), "1211");
-        assert_eq!(&encode(&[0, 0, 0, 0, 13, 36][..]), "1111211");
+        assert_eq!(&encode_slice(&[0, 13, 36][..]), "1211");
+        assert_eq!(&encode_slice(&[0, 0, 0, 0, 13, 36][..]), "1111211");
 
         // Long input (>100 bytes => has to use heap)
-        let res = encode("BitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBit\
+        let res = encode_slice("BitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBit\
         coinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoinBitcoin".as_bytes());
         let exp = "ZqC5ZdfpZRi7fjA8hbhX5pEE96MdH9hEaC1YouxscPtbJF16qVWksHWR4wwvx7MotFcs2ChbJqK8KJ9X\
         wZznwWn1JFDhhTmGo9v6GjAVikzCsBWZehu7bm22xL8b5zBR5AsBygYRwbFJsNwNkjpyFuDKwmsUTKvkULCvucPJrN5\
@@ -315,39 +304,39 @@ fn test_base58_encode() {
 
         // Addresses
         let addr = Vec::from_hex("00f8917303bfa8ef24f292e8fa1419b20460ba064d").unwrap();
-        assert_eq!(&encode_check(&addr[..]), "1PfJpZsjreyVrqeoAfabrRwwjQyoSQMmHH");
+        assert_eq!(&check_encode_slice(&addr[..]), "1PfJpZsjreyVrqeoAfabrRwwjQyoSQMmHH");
     }
 
     #[test]
     fn test_base58_decode() {
         // Basics
-        assert_eq!(decode("1").ok(), Some(vec![0u8]));
-        assert_eq!(decode("2").ok(), Some(vec![1u8]));
-        assert_eq!(decode("21").ok(), Some(vec![58u8]));
-        assert_eq!(decode("211").ok(), Some(vec![13u8, 36]));
+        assert_eq!(from("1").ok(), Some(vec![0u8]));
+        assert_eq!(from("2").ok(), Some(vec![1u8]));
+        assert_eq!(from("21").ok(), Some(vec![58u8]));
+        assert_eq!(from("211").ok(), Some(vec![13u8, 36]));
 
         // Leading zeroes
-        assert_eq!(decode("1211").ok(), Some(vec![0u8, 13, 36]));
-        assert_eq!(decode("111211").ok(), Some(vec![0u8, 0, 0, 13, 36]));
+        assert_eq!(from("1211").ok(), Some(vec![0u8, 13, 36]));
+        assert_eq!(from("111211").ok(), Some(vec![0u8, 0, 0, 13, 36]));
 
         // Addresses
-        assert_eq!(decode_check("1PfJpZsjreyVrqeoAfabrRwwjQyoSQMmHH").ok(),
+        assert_eq!(from_check("1PfJpZsjreyVrqeoAfabrRwwjQyoSQMmHH").ok(),
                    Some(Vec::from_hex("00f8917303bfa8ef24f292e8fa1419b20460ba064d").unwrap()));
         // Non Base58 char.
-        assert_eq!(decode("¢").unwrap_err(), Error::BadByte(194));
+        assert_eq!(from("¢").unwrap_err(), Error::BadByte(194));
     }
 
     #[test]
     fn test_base58_roundtrip() {
         let s = "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs";
-        let v: Vec<u8> = decode_check(s).unwrap();
-        assert_eq!(encode_check(&v[..]), s);
-        assert_eq!(decode_check(&encode_check(&v[..])).ok(), Some(v));
+        let v: Vec<u8> = from_check(s).unwrap();
+        assert_eq!(check_encode_slice(&v[..]), s);
+        assert_eq!(from_check(&check_encode_slice(&v[..])).ok(), Some(v));
 
         // Check that empty slice passes roundtrip.
-        assert_eq!(decode_check(&encode_check(&[])), Ok(vec![]));
+        assert_eq!(from_check(&check_encode_slice(&[])), Ok(vec![]));
         // Check that `len > 4` is enforced.
-        assert_eq!(decode_check(&encode(&[1,2,3])), Err(Error::TooShort(3)));
+        assert_eq!(from_check(&encode_slice(&[1,2,3])), Err(Error::TooShort(3)));
 
     }
 }
diff --git a/bitcoin/src/util/key.rs b/bitcoin/src/util/key.rs
index b8f06ff1..c53d648f 100644
--- a/bitcoin/src/util/key.rs
+++ b/bitcoin/src/util/key.rs
@@ -360,9 +360,9 @@ pub fn fmt_wif(&self, fmt: &mut dyn fmt::Write) -> fmt::Result {
         ret[1..33].copy_from_slice(&self.inner[..]);
         let privkey = if self.compressed {
             ret[33] = 1;
-            base58::encode_check(&ret[..])
+            base58::check_encode_slice(&ret[..])
         } else {
-            base58::encode_check(&ret[..33])
+            base58::check_encode_slice(&ret[..33])
         };
         fmt.write_str(&privkey)
     }
@@ -377,7 +377,7 @@ pub fn to_wif(self) -> String {
 
     /// Parse WIF encoded private key.
     pub fn from_wif(wif: &str) -> Result<PrivateKey, Error> {
-        let data = base58::decode_check(wif)?;
+        let data = base58::from_check(wif)?;
 
         let compressed = match data.len() {
             33 => false,
diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/util/merkleblock.rs
similarity index 94%
rename from bitcoin/src/merkle_tree/block.rs
rename to bitcoin/src/util/merkleblock.rs
index 39abae83..d6a7baff 100644
--- a/bitcoin/src/merkle_tree/block.rs
+++ b/bitcoin/src/util/merkleblock.rs
@@ -42,15 +42,18 @@
 
 use core::fmt;
 
+use crate::prelude::*;
+
+use crate::io;
+
+use crate::hashes::Hash;
+use crate::hash_types::{Txid, TxMerkleNode};
+
 use crate::blockdata::block::{self, Block};
-use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
 use crate::blockdata::transaction::Transaction;
+use crate::blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
 use crate::consensus::encode::{self, Decodable, Encodable};
-use crate::hash_types::{TxMerkleNode, Txid};
-use crate::hashes::Hash;
-use crate::io;
-use crate::merkle_tree::MerkleBlockError::*;
-use crate::prelude::*;
+use crate::util::merkleblock::MerkleBlockError::*;
 
 /// An error when verifying the merkle block.
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -136,13 +139,19 @@ pub struct PartialMerkleTree {
 
 impl PartialMerkleTree {
     /// Returns the total number of transactions in the block.
-    pub fn num_transactions(&self) -> u32 { self.num_transactions }
+    pub fn num_transactions(&self) -> u32 {
+        self.num_transactions
+    }
 
     /// Returns the node-is-parent-of-matched-txid bits of the partial merkle tree.
-    pub fn bits(&self) -> &Vec<bool> { &self.bits }
+    pub fn bits(&self) -> &Vec<bool> {
+        &self.bits
+    }
 
     /// Returns the transaction ids and internal hashes of the partial merkle tree.
-    pub fn hashes(&self) -> &Vec<TxMerkleNode> { &self.hashes }
+    pub fn hashes(&self) -> &Vec<TxMerkleNode> {
+        &self.hashes
+    }
 
     /// Construct a partial merkle tree
     /// The `txids` are the transaction hashes of the block and the `matches` is the contains flags
@@ -155,7 +164,7 @@ pub fn hashes(&self) -> &Vec<TxMerkleNode> { &self.hashes }
     /// ```rust
     /// use bitcoin::hash_types::Txid;
     /// use bitcoin::hashes::hex::FromHex;
-    /// use bitcoin::merkle_tree::{MerkleBlock, PartialMerkleTree};
+    /// use bitcoin::util::merkleblock::PartialMerkleTree;
     ///
     /// // Block 80000
     /// let txids: Vec<Txid> = [
@@ -363,7 +372,8 @@ fn parent_hash(left: TxMerkleNode, right: TxMerkleNode) -> TxMerkleNode {
 
 impl Encodable for PartialMerkleTree {
     fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
-        let ret = self.num_transactions.consensus_encode(w)? + self.hashes.consensus_encode(w)?;
+        let ret = self.num_transactions.consensus_encode(w)?
+            + self.hashes.consensus_encode(w)?;
         let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
         for p in 0..self.bits.len() {
             bytes[p / 8] |= (self.bits[p] as u8) << (p % 8) as u8;
@@ -383,7 +393,11 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Err
         for (p, bit) in bits.iter_mut().enumerate() {
             *bit = (bytes[p / 8] & (1 << (p % 8) as u8)) != 0;
         }
-        Ok(PartialMerkleTree { num_transactions, hashes, bits })
+        Ok(PartialMerkleTree {
+            num_transactions,
+            hashes,
+            bits,
+        })
     }
 }
 
@@ -439,7 +453,7 @@ impl MerkleBlock {
     /// ```
     pub fn from_block_with_predicate<F>(block: &Block, match_txids: F) -> Self
     where
-        F: Fn(&Txid) -> bool,
+        F: Fn(&Txid) -> bool
     {
         let block_txids: Vec<_> = block.txdata.iter().map(Transaction::txid).collect();
         Self::from_header_txids_with_predicate(&block.header, &block_txids, match_txids)
@@ -455,12 +469,18 @@ pub fn from_header_txids_with_predicate<F>(
         match_txids: F,
     ) -> Self
     where
-        F: Fn(&Txid) -> bool,
+        F: Fn(&Txid) -> bool
     {
-        let matches: Vec<bool> = block_txids.iter().map(match_txids).collect();
+        let matches: Vec<bool> = block_txids
+            .iter()
+            .map(match_txids)
+            .collect();
 
         let pmt = PartialMerkleTree::from_txids(block_txids, &matches);
-        MerkleBlock { header: *header, txn: pmt }
+        MerkleBlock {
+            header: *header,
+            txn: pmt,
+        }
     }
 
     /// Extract the matching txid's represented by this partial merkle tree
@@ -483,7 +503,8 @@ pub fn extract_matches(
 
 impl Encodable for MerkleBlock {
     fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
-        let len = self.header.consensus_encode(w)? + self.txn.consensus_encode(w)?;
+        let len = self.header.consensus_encode(w)?
+            + self.txn.consensus_encode(w)?;
         Ok(len)
     }
 }
@@ -501,17 +522,19 @@ fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Err
 mod tests {
     use core::cmp::min;
 
+    use crate::hashes::Hash;
+    use crate::hashes::hex::{FromHex, ToHex};
+    use crate::hash_types::{Txid, TxMerkleNode};
     use secp256k1::rand::prelude::*;
 
-    use super::*;
     use crate::consensus::encode::{deserialize, serialize};
-    use crate::hash_types::{TxMerkleNode, Txid};
-    use crate::hashes::hex::{FromHex, ToHex};
-    use crate::hashes::Hash;
+    use crate::util::merkleblock::{MerkleBlock, PartialMerkleTree};
     use crate::{merkle_tree, Block};
 
     /// accepts `pmt_test_$num`
-    fn pmt_test_from_name(name: &str) { pmt_test(name[9..].parse().unwrap()) }
+    fn pmt_test_from_name(name: &str) {
+        pmt_test(name[9..].parse().unwrap())
+    }
 
     macro_rules! pmt_tests {
     ($($name:ident),* $(,)?) => {
@@ -523,20 +546,8 @@ fn $name() {
          )*
     }
 }
-    pmt_tests!(
-        pmt_test_1,
-        pmt_test_4,
-        pmt_test_7,
-        pmt_test_17,
-        pmt_test_56,
-        pmt_test_100,
-        pmt_test_127,
-        pmt_test_256,
-        pmt_test_312,
-        pmt_test_513,
-        pmt_test_1000,
-        pmt_test_4095
-    );
+    pmt_tests!(pmt_test_1, pmt_test_4, pmt_test_7, pmt_test_17, pmt_test_56, pmt_test_100,
+        pmt_test_127, pmt_test_256, pmt_test_312, pmt_test_513, pmt_test_1000, pmt_test_4095);
 
     fn pmt_test(tx_count: usize) {
         let mut rng = thread_rng();
@@ -547,8 +558,7 @@ fn pmt_test(tx_count: usize) {
 
         // Calculate the merkle root and height
         let hashes = tx_ids.iter().map(|t| t.as_hash());
-        let merkle_root_1: TxMerkleNode =
-            merkle_tree::calculate_root(hashes).expect("hashes is not empty").into();
+        let merkle_root_1: TxMerkleNode = merkle_tree::calculate_root(hashes).expect("hashes is not empty").into();
         let mut height = 1;
         let mut ntx = tx_count;
         while ntx > 1 {
@@ -605,7 +615,9 @@ fn pmt_test(tx_count: usize) {
                 let mut pmt3: PartialMerkleTree = deserialize(&serialized).unwrap();
                 pmt3.damage(&mut rng);
                 let mut match_txid3 = vec![];
-                let merkle_root_3 = pmt3.extract_matches(&mut match_txid3, &mut indexes).unwrap();
+                let merkle_root_3 = pmt3
+                    .extract_matches(&mut match_txid3, &mut indexes)
+                    .unwrap();
                 assert_ne!(merkle_root_3, merkle_root_1);
             }
         }
@@ -619,8 +631,9 @@ fn pmt_malleability() {
             .map(|i| Txid::from_hex(&format!("{:064x}", i)).unwrap())
             .collect();
 
-        let matches =
-            vec![false, false, false, false, false, false, false, false, false, true, true, false];
+        let matches = vec![
+            false, false, false, false, false, false, false, false, false, true, true, false,
+        ];
 
         let tree = PartialMerkleTree::from_txids(&txids, &matches);
         // Should fail due to duplicate txs found
@@ -676,7 +689,10 @@ fn merkleblock_construct_from_txids_found() {
         let mut index: Vec<u32> = vec![];
 
         assert_eq!(
-            merkle_block.txn.extract_matches(&mut matches, &mut index).unwrap(),
+            merkle_block
+                .txn
+                .extract_matches(&mut matches, &mut index)
+                .unwrap(),
             block.header.merkle_root
         );
         assert_eq!(matches.len(), 2);
@@ -706,7 +722,10 @@ fn merkleblock_construct_from_txids_not_found() {
         let mut index: Vec<u32> = vec![];
 
         assert_eq!(
-            merkle_block.txn.extract_matches(&mut matches, &mut index).unwrap(),
+            merkle_block
+                .txn
+                .extract_matches(&mut matches, &mut index)
+                .unwrap(),
             block.header.merkle_root
         );
         assert_eq!(matches.len(), 0);
diff --git a/bitcoin/src/util/mod.rs b/bitcoin/src/util/mod.rs
index d9a6580c..81da7cd5 100644
--- a/bitcoin/src/util/mod.rs
+++ b/bitcoin/src/util/mod.rs
@@ -10,8 +10,117 @@
 pub mod ecdsa;
 pub mod schnorr;
 pub mod base58;
+pub mod merkleblock;
+pub mod psbt;
 pub mod taproot;
 
+use crate::prelude::*;
+use crate::io;
+use core::fmt;
+
+use bitcoin_internals::write_err;
+
+use crate::consensus::encode;
+
+/// A general error code, other errors should implement conversions to/from this
+/// if appropriate.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum Error {
+    /// Encoding error
+    Encode(encode::Error),
+    /// The header hash is not below the target
+    BlockBadProofOfWork,
+    /// The `target` field of a block header did not match the expected difficulty
+    BlockBadTarget,
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Error::Encode(ref e) => write_err!(f, "encoding error"; e),
+            Error::BlockBadProofOfWork => f.write_str("block target correct but not attained"),
+            Error::BlockBadTarget => f.write_str("block target incorrect"),
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl std::error::Error for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        use self::Error::*;
+
+        match self {
+            Encode(e) => Some(e),
+            BlockBadProofOfWork | BlockBadTarget => None
+        }
+    }
+}
+
+#[doc(hidden)]
+impl From<encode::Error> for Error {
+    fn from(e: encode::Error) -> Error {
+        Error::Encode(e)
+    }
+}
+
+// core2 doesn't have read_to_end
+pub(crate) fn read_to_end<D: io::Read>(mut d: D) -> Result<Vec<u8>, io::Error> {
+    let mut result = vec![];
+    let mut buf = [0u8; 64];
+    loop {
+        match d.read(&mut buf) {
+            Ok(0) => break,
+            Ok(n) => result.extend_from_slice(&buf[0..n]),
+            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
+            Err(e) => return Err(e),
+        };
+    }
+    Ok(result)
+}
+
+/// The `address` module now lives at the crate root, re-export everything so as not to break the
+/// API, however deprecate the re-exports so folks know to upgrade sooner or later.
+#[deprecated(since = "0.30.0", note = "Please use crate::address")]
+pub mod address {
+    pub use crate::address::*;
+}
+
+#[deprecated(since = "0.30.0", note = "Please use crate::bip32")]
+pub use crate::bip32;
+
+#[deprecated(since = "0.30.0", note = "Please use crate::bip158")]
+pub use crate::bip158;
+
+/// Functions from the `hash` module were renamed and moved to `../merkle_tree`.
+pub mod hash {
+    use crate::consensus::encode::Encodable;
+    use crate::hashes::Hash;
+    use crate::{io, merkle_tree};
+
+    /// Calculates the merkle root of a list of *hashes*, inline (in place) in `hashes`.
+    #[deprecated(since = "0.30.0", note = "Please use crate::merkle_tree::calculate_root_inline")]
+    pub fn bitcoin_merkle_root_inline<T>(hashes: &mut [T]) -> Option<T>
+    where
+        T: Hash + Encodable,
+    <T as Hash>::Engine: io::Write,
+    {
+        crate::merkle_tree::calculate_root_inline(hashes)
+    }
+
+    /// Calculates the merkle root of an iterator of *hashes*.
+    #[deprecated(since = "0.30.0", note = "Please use crate::merkle_tree::calculate_root")]
+    pub fn bitcoin_merkle_root<T, I>(hashes: I) -> Option<T>
+    where
+        T: Hash + Encodable,
+    <T as Hash>::Engine: io::Write,
+        I: Iterator<Item=T>,
+    {
+        merkle_tree::calculate_root(hashes)
+    }
+}
+
 /// The `misc` module was moved and re-named to `sign_message`.
 pub mod misc {
     use crate::prelude::*;
diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/util/psbt/error.rs
similarity index 98%
rename from bitcoin/src/psbt/error.rs
rename to bitcoin/src/util/psbt/error.rs
index e9079e8e..c2ca9b60 100644
--- a/bitcoin/src/psbt/error.rs
+++ b/bitcoin/src/util/psbt/error.rs
@@ -8,10 +8,10 @@
 
 use crate::blockdata::transaction::Transaction;
 use crate::consensus::encode;
-use crate::psbt::raw;
+use crate::util::psbt::raw;
 
 use crate::hashes;
-use crate::bip32::ExtendedPubKey;
+use crate::util::bip32::ExtendedPubKey;
 
 /// Enum for marking psbt hash error.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
diff --git a/bitcoin/src/psbt/macros.rs b/bitcoin/src/util/psbt/macros.rs
similarity index 71%
rename from bitcoin/src/psbt/macros.rs
rename to bitcoin/src/util/psbt/macros.rs
index ddfce8aa..49760550 100644
--- a/bitcoin/src/psbt/macros.rs
+++ b/bitcoin/src/util/psbt/macros.rs
@@ -2,7 +2,7 @@
 
 #[allow(unused_macros)]
 macro_rules! hex_psbt {
-    ($s:expr) => { $crate::consensus::deserialize::<$crate::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
+    ($s:expr) => { $crate::consensus::deserialize::<$crate::util::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
 }
 
 macro_rules! combine {
@@ -22,7 +22,7 @@ macro_rules! impl_psbt_de_serialize {
 
 macro_rules! impl_psbt_deserialize {
     ($thing:ty) => {
-        impl $crate::psbt::serialize::Deserialize for $thing {
+        impl $crate::util::psbt::serialize::Deserialize for $thing {
             fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
                 $crate::consensus::deserialize(&bytes[..])
             }
@@ -32,7 +32,7 @@ fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
 
 macro_rules! impl_psbt_serialize {
     ($thing:ty) => {
-        impl $crate::psbt::serialize::Serialize for $thing {
+        impl $crate::util::psbt::serialize::Serialize for $thing {
             fn serialize(&self) -> $crate::prelude::Vec<u8> {
                 $crate::consensus::serialize(self)
             }
@@ -64,7 +64,7 @@ fn consensus_decode<R: $crate::io::Read + ?Sized>(
                 loop {
                     match $crate::consensus::Decodable::consensus_decode(r) {
                         Ok(pair) => rv.insert_pair(pair)?,
-                        Err($crate::consensus::encode::Error::Psbt($crate::psbt::Error::NoMorePairs)) => return Ok(rv),
+                        Err($crate::consensus::encode::Error::Psbt($crate::util::psbt::Error::NoMorePairs)) => return Ok(rv),
                         Err(e) => return Err(e),
                     }
                 }
@@ -85,27 +85,27 @@ macro_rules! impl_psbt_insert_pair {
     ($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => {
         if $raw_key.key.is_empty() {
             if $slf.$unkeyed_name.is_none() {
-                let val: $unkeyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
+                let val: $unkeyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
                 $slf.$unkeyed_name = Some(val)
             } else {
-                return Err($crate::psbt::Error::DuplicateKey($raw_key).into());
+                return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into());
             }
         } else {
-            return Err($crate::psbt::Error::InvalidKey($raw_key).into());
+            return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
         }
     };
     ($slf:ident.$keyed_name:ident <= <$raw_key:ident: $keyed_key_type:ty>|<$raw_value:ident: $keyed_value_type:ty>) => {
         if !$raw_key.key.is_empty() {
-            let key_val: $keyed_key_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?;
+            let key_val: $keyed_key_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?;
             match $slf.$keyed_name.entry(key_val) {
                 $crate::prelude::btree_map::Entry::Vacant(empty_key) => {
-                    let val: $keyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
+                    let val: $keyed_value_type = $crate::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?;
                     empty_key.insert(val);
                 }
-                $crate::prelude::btree_map::Entry::Occupied(_) => return Err($crate::psbt::Error::DuplicateKey($raw_key).into()),
+                $crate::prelude::btree_map::Entry::Occupied(_) => return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into()),
             }
         } else {
-            return Err($crate::psbt::Error::InvalidKey($raw_key).into());
+            return Err($crate::util::psbt::Error::InvalidKey($raw_key).into());
         }
     };
 }
@@ -114,23 +114,23 @@ macro_rules! impl_psbt_insert_pair {
 macro_rules! impl_psbt_get_pair {
     ($rv:ident.push($slf:ident.$unkeyed_name:ident, $unkeyed_typeval:ident)) => {
         if let Some(ref $unkeyed_name) = $slf.$unkeyed_name {
-            $rv.push($crate::psbt::raw::Pair {
-                key: $crate::psbt::raw::Key {
+            $rv.push($crate::util::psbt::raw::Pair {
+                key: $crate::util::psbt::raw::Key {
                     type_value: $unkeyed_typeval,
                     key: vec![],
                 },
-                value: $crate::psbt::serialize::Serialize::serialize($unkeyed_name),
+                value: $crate::util::psbt::serialize::Serialize::serialize($unkeyed_name),
             });
         }
     };
     ($rv:ident.push_map($slf:ident.$keyed_name:ident, $keyed_typeval:ident)) => {
         for (key, val) in &$slf.$keyed_name {
-            $rv.push($crate::psbt::raw::Pair {
-                key: $crate::psbt::raw::Key {
+            $rv.push($crate::util::psbt::raw::Pair {
+                key: $crate::util::psbt::raw::Key {
                     type_value: $keyed_typeval,
-                    key: $crate::psbt::serialize::Serialize::serialize(key),
+                    key: $crate::util::psbt::serialize::Serialize::serialize(key),
                 },
-                value: $crate::psbt::serialize::Serialize::serialize(val),
+                value: $crate::util::psbt::serialize::Serialize::serialize(val),
             });
         }
     };
@@ -146,10 +146,10 @@ macro_rules! impl_psbt_hash_de_serialize {
 
 macro_rules! impl_psbt_hash_deserialize {
     ($hash_type:ty) => {
-        impl $crate::psbt::serialize::Deserialize for $hash_type {
+        impl $crate::util::psbt::serialize::Deserialize for $hash_type {
             fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
                 <$hash_type>::from_slice(&bytes[..]).map_err(|e| {
-                    $crate::psbt::Error::from(e).into()
+                    $crate::util::psbt::Error::from(e).into()
                 })
             }
         }
@@ -158,7 +158,7 @@ fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
 
 macro_rules! impl_psbt_hash_serialize {
     ($hash_type:ty) => {
-        impl $crate::psbt::serialize::Serialize for $hash_type {
+        impl $crate::util::psbt::serialize::Serialize for $hash_type {
             fn serialize(&self) -> $crate::prelude::Vec<u8> {
                 self.into_inner().to_vec()
             }
diff --git a/bitcoin/src/psbt/map/global.rs b/bitcoin/src/util/psbt/map/global.rs
similarity index 97%
rename from bitcoin/src/psbt/map/global.rs
rename to bitcoin/src/util/psbt/map/global.rs
index a337e7c6..eec7eecd 100644
--- a/bitcoin/src/psbt/map/global.rs
+++ b/bitcoin/src/util/psbt/map/global.rs
@@ -9,9 +9,10 @@
 use crate::blockdata::transaction::Transaction;
 use crate::consensus::{encode, Encodable, Decodable};
 use crate::consensus::encode::MAX_VEC_SIZE;
-use crate::psbt::map::Map;
-use crate::psbt::{raw, Error, PartiallySignedTransaction};
-use crate::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
+use crate::util::psbt::map::Map;
+use crate::util::psbt::{raw, PartiallySignedTransaction};
+use crate::util::psbt::Error;
+use crate::util::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
 
 /// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00
 const PSBT_GLOBAL_UNSIGNED_TX: u8 = 0x00;
@@ -193,7 +194,7 @@ pub(crate) fn consensus_decode_global<R: io::Read + ?Sized>(r: &mut R) -> Result
                         }
                     }
                 }
-                Err(crate::consensus::encode::Error::Psbt(crate::psbt::Error::NoMorePairs)) => break,
+                Err(crate::consensus::encode::Error::Psbt(crate::util::psbt::Error::NoMorePairs)) => break,
                 Err(e) => return Err(e),
             }
         }
diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/util/psbt/map/input.rs
similarity index 98%
rename from bitcoin/src/psbt/map/input.rs
rename to bitcoin/src/util/psbt/map/input.rs
index 25e56f69..5314ea0d 100644
--- a/bitcoin/src/psbt/map/input.rs
+++ b/bitcoin/src/util/psbt/map/input.rs
@@ -14,10 +14,12 @@
 use crate::blockdata::transaction::{Transaction, TxOut};
 use crate::consensus::encode;
 use crate::hashes::{self, hash160, ripemd160, sha256, sha256d};
-use crate::bip32::KeySource;
-use crate::psbt::map::Map;
-use crate::psbt::serialize::Deserialize;
-use crate::psbt::{self, error, raw, Error};
+use crate::util::bip32::KeySource;
+use crate::util::psbt;
+use crate::util::psbt::map::Map;
+use crate::util::psbt::raw;
+use crate::util::psbt::serialize::Deserialize;
+use crate::util::psbt::{Error, error};
 use crate::util::key::PublicKey;
 use crate::sighash::{NonStandardSighashType, SighashTypeParseError, EcdsaSighashType, SchnorrSighashType};
 use crate::util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash};
@@ -143,7 +145,7 @@ pub struct Input {
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
 pub struct PsbtSighashType {
-    pub (in crate::psbt) inner: u32,
+    pub (in crate::util::psbt) inner: u32,
 }
 
 impl fmt::Display for PsbtSighashType {
diff --git a/bitcoin/src/psbt/map/mod.rs b/bitcoin/src/util/psbt/map/mod.rs
similarity index 96%
rename from bitcoin/src/psbt/map/mod.rs
rename to bitcoin/src/util/psbt/map/mod.rs
index d22dc226..7ac8325a 100644
--- a/bitcoin/src/psbt/map/mod.rs
+++ b/bitcoin/src/util/psbt/map/mod.rs
@@ -5,7 +5,7 @@
 use crate::io;
 
 use crate::consensus::encode;
-use crate::psbt::raw;
+use crate::util::psbt::raw;
 
 mod global;
 mod input;
diff --git a/bitcoin/src/psbt/map/output.rs b/bitcoin/src/util/psbt/map/output.rs
similarity index 98%
rename from bitcoin/src/psbt/map/output.rs
rename to bitcoin/src/util/psbt/map/output.rs
index 1f8f45e1..0a745e2b 100644
--- a/bitcoin/src/psbt/map/output.rs
+++ b/bitcoin/src/util/psbt/map/output.rs
@@ -9,11 +9,11 @@
 use crate::blockdata::script::Script;
 use crate::consensus::encode;
 use secp256k1::XOnlyPublicKey;
-use crate::bip32::KeySource;
+use crate::util::bip32::KeySource;
 use secp256k1;
-use crate::psbt::map::Map;
-use crate::psbt::raw;
-use crate::psbt::Error;
+use crate::util::psbt::map::Map;
+use crate::util::psbt::raw;
+use crate::util::psbt::Error;
 
 use crate::util::taproot::{ScriptLeaf, TapLeafHash};
 
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/util/psbt/mod.rs
similarity index 98%
rename from bitcoin/src/psbt/mod.rs
rename to bitcoin/src/util/psbt/mod.rs
index 88948b9c..304e641d 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/util/psbt/mod.rs
@@ -22,7 +22,7 @@
 use crate::blockdata::script::Script;
 use crate::blockdata::transaction::{Transaction, TxOut};
 use crate::consensus::{encode, Encodable, Decodable};
-use crate::bip32::{self, ExtendedPrivKey, ExtendedPubKey, KeySource};
+use crate::util::bip32::{self, ExtendedPrivKey, ExtendedPubKey, KeySource};
 use crate::util::ecdsa::{EcdsaSig, EcdsaSigError};
 use crate::util::key::{PublicKey, PrivateKey};
 use crate::sighash::{self, EcdsaSighashType, SighashCache};
@@ -894,9 +894,9 @@ mod tests {
     use crate::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence};
     use crate::network::constants::Network::Bitcoin;
     use crate::consensus::encode::{deserialize, serialize, serialize_hex};
-    use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
-    use crate::psbt::map::{Output, Input};
-    use crate::psbt::raw;
+    use crate::util::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
+    use crate::util::psbt::map::{Output, Input};
+    use crate::util::psbt::raw;
     use crate::internal_macros::hex_script;
 
     use std::collections::BTreeMap;
@@ -1044,7 +1044,7 @@ fn deserialize_and_serialize_psbt_with_two_partial_sigs() {
     fn test_serde_psbt() {
         //! Create a full PSBT value with various fields filled and make sure it can be JSONized.
         use crate::hashes::sha256d;
-        use crate::psbt::map::Input;
+        use crate::util::psbt::map::Input;
         use crate::sighash::EcdsaSighashType;
 
         // create some values to use in the PSBT
@@ -1058,7 +1058,7 @@ fn test_serde_psbt() {
                 },
                 script_sig: hex_script!("160014be18d152a9b012039daf3da7de4f53349eecb985"),
                 sequence: Sequence::MAX,
-                witness: Witness::from_slice(&[Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105").unwrap()]),
+                witness: Witness::from_vec(vec![Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105").unwrap()]),
             }],
             output: vec![
                 TxOut {
@@ -1117,7 +1117,7 @@ fn test_serde_psbt() {
                     "304402204f67e2afb76142d44fae58a2495d33a3419daa26cd0db8d04f3452b63289ac0f022010762a9fb67e94cc5cad9026f6dc99ff7f070f4278d30fbc7d0c869dd38c7fe701".parse().unwrap(),
                 )].into_iter().collect(),
                 bip32_derivation: keypaths.clone(),
-                final_script_witness: Some(Witness::from_slice(&[vec![1, 3], vec![5]])),
+                final_script_witness: Some(Witness::from_vec(vec![vec![1, 3], vec![5]])),
                 ripemd160_preimages: vec![(ripemd160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
                 sha256_preimages: vec![(sha256::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
                 hash160_preimages: vec![(hash160::Hash::hash(&[]), vec![1, 2])].into_iter().collect(),
@@ -1149,8 +1149,9 @@ mod bip_vectors {
         use crate::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence};
         use crate::consensus::encode::serialize_hex;
         use crate::blockdata::locktime::absolute;
-        use crate::psbt::map::{Map, Input, Output};
-        use crate::psbt::{raw, PartiallySignedTransaction, Error};
+        use crate::util::psbt::map::{Map, Input, Output};
+        use crate::util::psbt::raw;
+        use crate::util::psbt::{PartiallySignedTransaction, Error};
         use crate::sighash::EcdsaSighashType;
         use std::collections::BTreeMap;
         use crate::blockdata::witness::Witness;
@@ -1182,7 +1183,7 @@ fn invalid_vector_2() {
         #[test]
         #[should_panic(expected = "ConsensusEncoding")]
         fn invalid_vector_2_base64() {
-            use crate::psbt::PsbtParseError;
+            use crate::util::psbt::PsbtParseError;
             PartiallySignedTransaction::from_str("cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==")
                 // This weird thing is necessary since rustc 0.29 prints out I/O error in a different format than later versions
                 .map_err(|err| match err {
@@ -1278,7 +1279,7 @@ fn valid_vector_1() {
                             },
                             script_sig: hex_script!("160014be18d152a9b012039daf3da7de4f53349eecb985"),
                             sequence: Sequence::MAX,
-                            witness: Witness::from_slice(&[
+                            witness: Witness::from_vec(vec![
                                 Vec::from_hex("304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c01").unwrap(),
                                 Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105").unwrap(),
                             ]),
@@ -1292,7 +1293,7 @@ fn valid_vector_1() {
                             },
                             script_sig: hex_script!("160014fe3e9ef1a745e974d902c4355943abcb34bd5353"),
                             sequence: Sequence::MAX,
-                            witness: Witness::from_slice(&[
+                            witness: Witness::from_vec(vec![
                                 Vec::from_hex("3045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01").unwrap(),
                                 Vec::from_hex("0223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab3").unwrap(),
                             ]),
@@ -1590,7 +1591,7 @@ fn serialize_and_deserialize_preimage_psbt() {
                         },
                         script_sig: hex_script!("160014be18d152a9b012039daf3da7de4f53349eecb985"),
                         sequence: Sequence::MAX,
-                        witness: Witness::from_slice(&[
+                        witness: Witness::from_vec(vec![
                             Vec::from_hex("304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c01").unwrap(),
                             Vec::from_hex("03d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f2105").unwrap(),
                         ]),
@@ -1604,7 +1605,7 @@ fn serialize_and_deserialize_preimage_psbt() {
                         },
                         script_sig: hex_script!("160014fe3e9ef1a745e974d902c4355943abcb34bd5353"),
                         sequence: Sequence::MAX,
-                        witness: Witness::from_slice(&[
+                        witness: Witness::from_vec(vec![
                             Vec::from_hex("3045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01").unwrap(),
                             Vec::from_hex("0223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab3").unwrap(),
                         ]),
@@ -1663,9 +1664,9 @@ fn serialize_and_deserialize_proprietary() {
     // PSBTs taken from BIP 174 test vectors.
     #[test]
     fn combine_psbts() {
-        let mut psbt1 = hex_psbt!(include_str!("../../tests/data/psbt1.hex")).unwrap();
-        let psbt2 = hex_psbt!(include_str!("../../tests/data/psbt2.hex")).unwrap();
-        let psbt_combined = hex_psbt!(include_str!("../../tests/data/psbt2.hex")).unwrap();
+        let mut psbt1 = hex_psbt!(include_str!("../../../tests/data/psbt1.hex")).unwrap();
+        let psbt2 = hex_psbt!(include_str!("../../../tests/data/psbt2.hex")).unwrap();
+        let psbt_combined = hex_psbt!(include_str!("../../../tests/data/psbt2.hex")).unwrap();
 
         psbt1.combine(psbt2).expect("psbt combine to succeed");
         assert_eq!(psbt1, psbt_combined);
@@ -1673,8 +1674,8 @@ fn combine_psbts() {
 
     #[test]
     fn combine_psbts_commutative() {
-        let mut psbt1 = hex_psbt!(include_str!("../../tests/data/psbt1.hex")).unwrap();
-        let mut psbt2 = hex_psbt!(include_str!("../../tests/data/psbt2.hex")).unwrap();
+        let mut psbt1 = hex_psbt!(include_str!("../../../tests/data/psbt1.hex")).unwrap();
+        let mut psbt2 = hex_psbt!(include_str!("../../../tests/data/psbt2.hex")).unwrap();
 
         let psbt1_clone = psbt1.clone();
         let psbt2_clone = psbt2.clone();
@@ -1814,7 +1815,7 @@ fn test_fee() {
     #[cfg(feature = "rand")]
     fn sign_psbt() {
         use crate::WPubkeyHash;
-        use crate::bip32::{Fingerprint, DerivationPath};
+        use crate::util::bip32::{Fingerprint, DerivationPath};
 
         let unsigned_tx = Transaction {
             version: 2,
diff --git a/bitcoin/src/psbt/raw.rs b/bitcoin/src/util/psbt/raw.rs
similarity index 92%
rename from bitcoin/src/psbt/raw.rs
rename to bitcoin/src/util/psbt/raw.rs
index 0d2e4202..99d8d0ce 100644
--- a/bitcoin/src/psbt/raw.rs
+++ b/bitcoin/src/util/psbt/raw.rs
@@ -13,7 +13,8 @@
 use crate::io;
 use crate::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
 use crate::hashes::hex;
-use crate::psbt::Error;
+use crate::util::psbt::Error;
+use crate::util::read_to_end;
 
 /// A PSBT key in its raw byte form.
 #[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)]
@@ -172,18 +173,3 @@ fn try_from(key: Key) -> Result<Self, Self::Error> {
         Ok(deserialize(&key.key)?)
     }
 }
-
-// core2 doesn't have read_to_end
-pub(crate) fn read_to_end<D: io::Read>(mut d: D) -> Result<Vec<u8>, io::Error> {
-    let mut result = vec![];
-    let mut buf = [0u8; 64];
-    loop {
-        match d.read(&mut buf) {
-            Ok(0) => break,
-            Ok(n) => result.extend_from_slice(&buf[0..n]),
-            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
-            Err(e) => return Err(e),
-        };
-    }
-    Ok(result)
-}
diff --git a/bitcoin/src/psbt/serialize.rs b/bitcoin/src/util/psbt/serialize.rs
similarity index 99%
rename from bitcoin/src/psbt/serialize.rs
rename to bitcoin/src/util/psbt/serialize.rs
index 492abb04..c10b98f2 100644
--- a/bitcoin/src/psbt/serialize.rs
+++ b/bitcoin/src/util/psbt/serialize.rs
@@ -15,10 +15,10 @@
 use crate::blockdata::transaction::{Transaction, TxOut};
 use crate::consensus::encode::{self, serialize, Decodable, Encodable, deserialize_partial};
 use secp256k1::{self, XOnlyPublicKey};
-use crate::bip32::{ChildNumber, Fingerprint, KeySource};
+use crate::util::bip32::{ChildNumber, Fingerprint, KeySource};
 use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
 use crate::util::ecdsa::{EcdsaSig, EcdsaSigError};
-use crate::psbt;
+use crate::util::psbt;
 use crate::util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion};
 use crate::schnorr;
 use crate::util::key::PublicKey;
diff --git a/bitcoin/src/util/taproot.rs b/bitcoin/src/util/taproot.rs
index 3bd24d28..9d61ad72 100644
--- a/bitcoin/src/util/taproot.rs
+++ b/bitcoin/src/util/taproot.rs
@@ -402,7 +402,7 @@ pub fn new() -> Self {
     /// If the script weight calculations overflow, a sub-optimal tree may be generated. This should
     /// not happen unless you are dealing with billions of branches with weights close to 2^32.
     ///
-    /// [`TapTree`]: crate::psbt::TapTree
+    /// [`TapTree`]: crate::util::psbt::TapTree
     pub fn with_huffman_tree<I>(
         script_weights: I,
     ) -> Result<Self, TaprootBuilderError>
diff --git a/fuzz/fuzz_targets/deserialize_psbt.rs b/fuzz/fuzz_targets/deserialize_psbt.rs
index 7556679b..abbeedfa 100644
--- a/fuzz/fuzz_targets/deserialize_psbt.rs
+++ b/fuzz/fuzz_targets/deserialize_psbt.rs
@@ -1,12 +1,12 @@
 extern crate bitcoin;
 
 fn do_test(data: &[u8]) {
-    let psbt: Result<bitcoin::psbt::PartiallySignedTransaction, _> = bitcoin::consensus::encode::deserialize(data);
+    let psbt: Result<bitcoin::util::psbt::PartiallySignedTransaction, _> = bitcoin::consensus::encode::deserialize(data);
     match psbt {
         Err(_) => {},
         Ok(psbt) => {
             let ser = bitcoin::consensus::encode::serialize(&psbt);
-            let deser: bitcoin::psbt::PartiallySignedTransaction  = bitcoin::consensus::encode::deserialize(&ser).unwrap();
+            let deser: bitcoin::util::psbt::PartiallySignedTransaction  = bitcoin::consensus::encode::deserialize(&ser).unwrap();
             // Since the fuzz data could order psbt fields differently, we compare to our deser/ser instead of data
             assert_eq!(ser, bitcoin::consensus::encode::serialize(&deser));
         }
diff --git a/rustfmt.toml b/rustfmt.toml
index 466114a8..a80a8e64 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -3,7 +3,6 @@ ignore = [
        "bitcoin/src/blockdata",
        "bitcoin/src/consensus",
        "bitcoin/src/network",
-       "bitcoin/src/psbt",
        "bitcoin/src/util",
 ]
 


Test patch:
diff --git a/bitcoin/tests/psbt.rs b/bitcoin/tests/psbt.rs
index 1d5e8de8..c00598b4 100644
--- a/bitcoin/tests/psbt.rs
+++ b/bitcoin/tests/psbt.rs
@@ -417,7 +417,7 @@ fn sign(mut psbt: Psbt, keys: BTreeMap<bitcoin::PublicKey, PrivateKey>) -> Psbt
 /// Finalizes a PSBT accord to the Input Finalizer role described in BIP 174.
 /// This is just a test. For a production-ready PSBT Finalizer, use [rust-miniscript](https://docs.rs/miniscript/latest/miniscript/psbt/trait.PsbtExt.html#tymethod.finalize)
 fn finalize_psbt(mut psbt: Psbt) -> Psbt {
-    use bitcoin::psbt::serialize::Serialize;
+    use bitcoin::util::psbt::serialize::Serialize;
 
     // Input 0: legacy UTXO