diff --git a/bitcoin/examples/ecdsa-psbt.rs b/bitcoin/examples/ecdsa-psbt.rs index 210fd614..60a0a129 100644 --- a/bitcoin/examples/ecdsa-psbt.rs +++ b/bitcoin/examples/ecdsa-psbt.rs @@ -40,7 +40,7 @@ use bitcoin::secp256k1::{Secp256k1, Signing, Verification}; use bitcoin::bip32::{ ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath, }; -use bitcoin::util::psbt::{self, Input, Psbt, PsbtSighashType}; +use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType}; use bitcoin::{ Address, Amount, Network, OutPoint, PublicKey, Script, Sequence, Transaction, TxIn, TxOut, Txid, Witness, @@ -236,7 +236,7 @@ impl WatchOnly { /// 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 { - use bitcoin::util::psbt::serialize::Serialize; + use bitcoin::psbt::serialize::Serialize; if psbt.inputs.is_empty() { return Err(psbt::SignError::MissingInputUtxo.into()); diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs index 1d652efc..1fde7047 100644 --- a/bitcoin/src/blockdata/block.rs +++ b/bitcoin/src/blockdata/block.rs @@ -13,8 +13,8 @@ use crate::prelude::*; use core::fmt; -use crate::{merkle_tree, util}; -use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork}; +use crate::merkle_tree; +use crate::error::Error::{self, 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 @@ impl Header { } /// Checks that the proof-of-work for the block is valid, returning the block hash. - pub fn validate_pow(&self, required_target: Target) -> Result { + pub fn validate_pow(&self, required_target: Target) -> Result { let target = self.target(); if target != required_target { return Err(BlockBadTarget); diff --git a/bitcoin/src/blockdata/script.rs b/bitcoin/src/blockdata/script.rs index 473d70b6..2768b303 100644 --- a/bitcoin/src/blockdata/script.rs +++ b/bitcoin/src/blockdata/script.rs @@ -1183,7 +1183,7 @@ mod test { use crate::consensus::encode::{deserialize, serialize}; use crate::blockdata::opcodes; use crate::util::key::PublicKey; - use crate::util::psbt::serialize::Serialize; + use crate::psbt::serialize::Serialize; use crate::internal_macros::hex_script; #[test] diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 20f9d306..ac450b39 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -26,7 +26,7 @@ use crate::hashes::{sha256d, Hash, sha256}; use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; use crate::io::{self, Cursor, Read}; -use crate::util::psbt; +use crate::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 58bbb2d1..d31c09f8 100644 --- a/bitcoin/src/error.rs +++ b/bitcoin/src/error.rs @@ -1,7 +1,53 @@ //! 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 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 06c78407..a9abadcb 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -104,6 +104,7 @@ pub mod hash_types; pub mod merkle_tree; pub mod policy; pub mod pow; +pub mod psbt; pub mod sighash; pub mod sign_message; pub mod util; @@ -122,6 +123,7 @@ pub use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, T 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}; @@ -130,7 +132,6 @@ 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::schnorr::{self, SchnorrSig, SchnorrSigError}; -pub use crate::util::{psbt, Error}; #[cfg(not(feature = "std"))] mod io_extras { diff --git a/bitcoin/src/util/psbt/error.rs b/bitcoin/src/psbt/error.rs similarity index 99% rename from bitcoin/src/util/psbt/error.rs rename to bitcoin/src/psbt/error.rs index df828cf3..e9079e8e 100644 --- a/bitcoin/src/util/psbt/error.rs +++ b/bitcoin/src/psbt/error.rs @@ -8,7 +8,7 @@ use bitcoin_internals::write_err; use crate::blockdata::transaction::Transaction; use crate::consensus::encode; -use crate::util::psbt::raw; +use crate::psbt::raw; use crate::hashes; use crate::bip32::ExtendedPubKey; diff --git a/bitcoin/src/util/psbt/macros.rs b/bitcoin/src/psbt/macros.rs similarity index 71% rename from bitcoin/src/util/psbt/macros.rs rename to bitcoin/src/psbt/macros.rs index 49760550..ddfce8aa 100644 --- a/bitcoin/src/util/psbt/macros.rs +++ b/bitcoin/src/psbt/macros.rs @@ -2,7 +2,7 @@ #[allow(unused_macros)] macro_rules! hex_psbt { - ($s:expr) => { $crate::consensus::deserialize::<$crate::util::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) }; + ($s:expr) => { $crate::consensus::deserialize::<$crate::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec 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::util::psbt::serialize::Deserialize for $thing { + impl $crate::psbt::serialize::Deserialize for $thing { fn deserialize(bytes: &[u8]) -> Result { $crate::consensus::deserialize(&bytes[..]) } @@ -32,7 +32,7 @@ macro_rules! impl_psbt_deserialize { macro_rules! impl_psbt_serialize { ($thing:ty) => { - impl $crate::util::psbt::serialize::Serialize for $thing { + impl $crate::psbt::serialize::Serialize for $thing { fn serialize(&self) -> $crate::prelude::Vec { $crate::consensus::serialize(self) } @@ -64,7 +64,7 @@ macro_rules! impl_psbtmap_consensus_decoding { loop { match $crate::consensus::Decodable::consensus_decode(r) { Ok(pair) => rv.insert_pair(pair)?, - Err($crate::consensus::encode::Error::Psbt($crate::util::psbt::Error::NoMorePairs)) => return Ok(rv), + Err($crate::consensus::encode::Error::Psbt($crate::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::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?; + let val: $unkeyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?; $slf.$unkeyed_name = Some(val) } else { - return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into()); + return Err($crate::psbt::Error::DuplicateKey($raw_key).into()); } } else { - return Err($crate::util::psbt::Error::InvalidKey($raw_key).into()); + return Err($crate::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::util::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?; + let key_val: $keyed_key_type = $crate::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::util::psbt::serialize::Deserialize::deserialize(&$raw_value)?; + let val: $keyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?; empty_key.insert(val); } - $crate::prelude::btree_map::Entry::Occupied(_) => return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into()), + $crate::prelude::btree_map::Entry::Occupied(_) => return Err($crate::psbt::Error::DuplicateKey($raw_key).into()), } } else { - return Err($crate::util::psbt::Error::InvalidKey($raw_key).into()); + return Err($crate::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::util::psbt::raw::Pair { - key: $crate::util::psbt::raw::Key { + $rv.push($crate::psbt::raw::Pair { + key: $crate::psbt::raw::Key { type_value: $unkeyed_typeval, key: vec![], }, - value: $crate::util::psbt::serialize::Serialize::serialize($unkeyed_name), + value: $crate::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::util::psbt::raw::Pair { - key: $crate::util::psbt::raw::Key { + $rv.push($crate::psbt::raw::Pair { + key: $crate::psbt::raw::Key { type_value: $keyed_typeval, - key: $crate::util::psbt::serialize::Serialize::serialize(key), + key: $crate::psbt::serialize::Serialize::serialize(key), }, - value: $crate::util::psbt::serialize::Serialize::serialize(val), + value: $crate::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::util::psbt::serialize::Deserialize for $hash_type { + impl $crate::psbt::serialize::Deserialize for $hash_type { fn deserialize(bytes: &[u8]) -> Result { <$hash_type>::from_slice(&bytes[..]).map_err(|e| { - $crate::util::psbt::Error::from(e).into() + $crate::psbt::Error::from(e).into() }) } } @@ -158,7 +158,7 @@ macro_rules! impl_psbt_hash_deserialize { macro_rules! impl_psbt_hash_serialize { ($hash_type:ty) => { - impl $crate::util::psbt::serialize::Serialize for $hash_type { + impl $crate::psbt::serialize::Serialize for $hash_type { fn serialize(&self) -> $crate::prelude::Vec { self.into_inner().to_vec() } diff --git a/bitcoin/src/util/psbt/map/global.rs b/bitcoin/src/psbt/map/global.rs similarity index 98% rename from bitcoin/src/util/psbt/map/global.rs rename to bitcoin/src/psbt/map/global.rs index bc1b11c5..a337e7c6 100644 --- a/bitcoin/src/util/psbt/map/global.rs +++ b/bitcoin/src/psbt/map/global.rs @@ -9,9 +9,8 @@ use crate::io::{self, Cursor, Read}; use crate::blockdata::transaction::Transaction; use crate::consensus::{encode, Encodable, Decodable}; use crate::consensus::encode::MAX_VEC_SIZE; -use crate::util::psbt::map::Map; -use crate::util::psbt::{raw, PartiallySignedTransaction}; -use crate::util::psbt::Error; +use crate::psbt::map::Map; +use crate::psbt::{raw, Error, PartiallySignedTransaction}; use crate::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber}; /// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00 @@ -194,7 +193,7 @@ impl PartiallySignedTransaction { } } } - Err(crate::consensus::encode::Error::Psbt(crate::util::psbt::Error::NoMorePairs)) => break, + Err(crate::consensus::encode::Error::Psbt(crate::psbt::Error::NoMorePairs)) => break, Err(e) => return Err(e), } } diff --git a/bitcoin/src/util/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs similarity index 99% rename from bitcoin/src/util/psbt/map/input.rs rename to bitcoin/src/psbt/map/input.rs index 2157d29a..25e56f69 100644 --- a/bitcoin/src/util/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -15,11 +15,9 @@ use crate::blockdata::transaction::{Transaction, TxOut}; use crate::consensus::encode; use crate::hashes::{self, hash160, ripemd160, sha256, sha256d}; use crate::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::psbt::map::Map; +use crate::psbt::serialize::Deserialize; +use crate::psbt::{self, error, raw, Error}; use crate::util::key::PublicKey; use crate::sighash::{NonStandardSighashType, SighashTypeParseError, EcdsaSighashType, SchnorrSighashType}; use crate::util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash}; @@ -145,7 +143,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::util::psbt) inner: u32, + pub (in crate::psbt) inner: u32, } impl fmt::Display for PsbtSighashType { diff --git a/bitcoin/src/util/psbt/map/mod.rs b/bitcoin/src/psbt/map/mod.rs similarity index 96% rename from bitcoin/src/util/psbt/map/mod.rs rename to bitcoin/src/psbt/map/mod.rs index 7ac8325a..d22dc226 100644 --- a/bitcoin/src/util/psbt/map/mod.rs +++ b/bitcoin/src/psbt/map/mod.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use crate::io; use crate::consensus::encode; -use crate::util::psbt::raw; +use crate::psbt::raw; mod global; mod input; diff --git a/bitcoin/src/util/psbt/map/output.rs b/bitcoin/src/psbt/map/output.rs similarity index 99% rename from bitcoin/src/util/psbt/map/output.rs rename to bitcoin/src/psbt/map/output.rs index 6f1522bd..1f8f45e1 100644 --- a/bitcoin/src/util/psbt/map/output.rs +++ b/bitcoin/src/psbt/map/output.rs @@ -11,9 +11,9 @@ use crate::consensus::encode; use secp256k1::XOnlyPublicKey; use crate::bip32::KeySource; use secp256k1; -use crate::util::psbt::map::Map; -use crate::util::psbt::raw; -use crate::util::psbt::Error; +use crate::psbt::map::Map; +use crate::psbt::raw; +use crate::psbt::Error; use crate::util::taproot::{ScriptLeaf, TapLeafHash}; diff --git a/bitcoin/src/util/psbt/mod.rs b/bitcoin/src/psbt/mod.rs similarity index 99% rename from bitcoin/src/util/psbt/mod.rs rename to bitcoin/src/psbt/mod.rs index 42c11630..88948b9c 100644 --- a/bitcoin/src/util/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -895,8 +895,8 @@ mod tests { use crate::network::constants::Network::Bitcoin; use crate::consensus::encode::{deserialize, serialize, serialize_hex}; use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource}; - use crate::util::psbt::map::{Output, Input}; - use crate::util::psbt::raw; + use crate::psbt::map::{Output, Input}; + use crate::psbt::raw; use crate::internal_macros::hex_script; use std::collections::BTreeMap; @@ -1044,7 +1044,7 @@ mod tests { 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::util::psbt::map::Input; + use crate::psbt::map::Input; use crate::sighash::EcdsaSighashType; // create some values to use in the PSBT @@ -1149,9 +1149,8 @@ mod tests { use crate::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence}; use crate::consensus::encode::serialize_hex; use crate::blockdata::locktime::absolute; - use crate::util::psbt::map::{Map, Input, Output}; - use crate::util::psbt::raw; - use crate::util::psbt::{PartiallySignedTransaction, Error}; + use crate::psbt::map::{Map, Input, Output}; + use crate::psbt::{raw, PartiallySignedTransaction, Error}; use crate::sighash::EcdsaSighashType; use std::collections::BTreeMap; use crate::blockdata::witness::Witness; @@ -1183,7 +1182,7 @@ mod tests { #[test] #[should_panic(expected = "ConsensusEncoding")] fn invalid_vector_2_base64() { - use crate::util::psbt::PsbtParseError; + use crate::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 { @@ -1664,9 +1663,9 @@ mod tests { // 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); @@ -1674,8 +1673,8 @@ mod tests { #[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(); diff --git a/bitcoin/src/util/psbt/raw.rs b/bitcoin/src/psbt/raw.rs similarity index 92% rename from bitcoin/src/util/psbt/raw.rs rename to bitcoin/src/psbt/raw.rs index 99d8d0ce..0d2e4202 100644 --- a/bitcoin/src/util/psbt/raw.rs +++ b/bitcoin/src/psbt/raw.rs @@ -13,8 +13,7 @@ use core::convert::TryFrom; use crate::io; use crate::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE}; use crate::hashes::hex; -use crate::util::psbt::Error; -use crate::util::read_to_end; +use crate::psbt::Error; /// A PSBT key in its raw byte form. #[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)] @@ -173,3 +172,18 @@ where Ok(deserialize(&key.key)?) } } + +// core2 doesn't have read_to_end +pub(crate) fn read_to_end(mut d: D) -> Result, 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/util/psbt/serialize.rs b/bitcoin/src/psbt/serialize.rs similarity index 99% rename from bitcoin/src/util/psbt/serialize.rs rename to bitcoin/src/psbt/serialize.rs index ef84e212..492abb04 100644 --- a/bitcoin/src/util/psbt/serialize.rs +++ b/bitcoin/src/psbt/serialize.rs @@ -18,7 +18,7 @@ use secp256k1::{self, XOnlyPublicKey}; use crate::bip32::{ChildNumber, Fingerprint, KeySource}; use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use crate::util::ecdsa::{EcdsaSig, EcdsaSigError}; -use crate::util::psbt; +use crate::psbt; use crate::util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion}; use crate::schnorr; use crate::util::key::PublicKey; diff --git a/bitcoin/src/util/mod.rs b/bitcoin/src/util/mod.rs index 52c5f3e8..d9a6580c 100644 --- a/bitcoin/src/util/mod.rs +++ b/bitcoin/src/util/mod.rs @@ -10,75 +10,8 @@ pub mod key; pub mod ecdsa; pub mod schnorr; pub mod base58; -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 for Error { - fn from(e: encode::Error) -> Error { - Error::Encode(e) - } -} - -// core2 doesn't have read_to_end -pub(crate) fn read_to_end(mut d: D) -> Result, 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 `misc` module was moved and re-named to `sign_message`. pub mod misc { use crate::prelude::*; diff --git a/bitcoin/src/util/taproot.rs b/bitcoin/src/util/taproot.rs index 9d61ad72..3bd24d28 100644 --- a/bitcoin/src/util/taproot.rs +++ b/bitcoin/src/util/taproot.rs @@ -402,7 +402,7 @@ impl TaprootBuilder { /// 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::util::psbt::TapTree + /// [`TapTree`]: crate::psbt::TapTree pub fn with_huffman_tree( script_weights: I, ) -> Result diff --git a/bitcoin/tests/psbt.rs b/bitcoin/tests/psbt.rs index c00598b4..1d5e8de8 100644 --- a/bitcoin/tests/psbt.rs +++ b/bitcoin/tests/psbt.rs @@ -417,7 +417,7 @@ fn sign(mut psbt: Psbt, keys: BTreeMap) -> 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::util::psbt::serialize::Serialize; + use bitcoin::psbt::serialize::Serialize; // Input 0: legacy UTXO diff --git a/fuzz/fuzz_targets/deserialize_psbt.rs b/fuzz/fuzz_targets/deserialize_psbt.rs index abbeedfa..7556679b 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::consensus::encode::deserialize(data); + let psbt: Result = bitcoin::consensus::encode::deserialize(data); match psbt { Err(_) => {}, Ok(psbt) => { let ser = bitcoin::consensus::encode::serialize(&psbt); - let deser: bitcoin::util::psbt::PartiallySignedTransaction = bitcoin::consensus::encode::deserialize(&ser).unwrap(); + let deser: bitcoin::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 a80a8e64..466114a8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -3,6 +3,7 @@ ignore = [ "bitcoin/src/blockdata", "bitcoin/src/consensus", "bitcoin/src/network", + "bitcoin/src/psbt", "bitcoin/src/util", ]