Merge rust-bitcoin/rust-bitcoin#1169: Start to flatten `util`
30888f74c5
Move psbt module to crate root module (Tobin C. Harding)8a75ff450f
Move read_to_end out of util module (Tobin C. Harding)445b07c94c
Move util::Error to error module (Tobin C. Harding) Pull request description: In an effort to flatten `util` move things out that can/should be put in submodules of the crate root module. For each, configure `rustfmt` to ignore the module. This pushes the `rustfmt` review nightmare down the road. ACKs for top commit: apoelstra: ACK30888f74c5
Kixunil: ACK30888f74c5
Tree-SHA512: 0d93d60bec822d1dc82d4d67c25854364b0863488e4b35c9a0828a843fc3792286c18abde40a8e9d6ec535cfc7f0f0d6495d35961ce43af3f2605c92aaa0815d
This commit is contained in:
commit
130a5845bd
|
@ -40,7 +40,7 @@ use bitcoin::secp256k1::{Secp256k1, Signing, Verification};
|
||||||
use bitcoin::bip32::{
|
use bitcoin::bip32::{
|
||||||
ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath,
|
ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath,
|
||||||
};
|
};
|
||||||
use bitcoin::util::psbt::{self, Input, Psbt, PsbtSighashType};
|
use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
|
||||||
use bitcoin::{
|
use bitcoin::{
|
||||||
Address, Amount, Network, OutPoint, PublicKey, Script, Sequence, Transaction, TxIn, TxOut,
|
Address, Amount, Network, OutPoint, PublicKey, Script, Sequence, Transaction, TxIn, TxOut,
|
||||||
Txid, Witness,
|
Txid, Witness,
|
||||||
|
@ -236,7 +236,7 @@ impl WatchOnly {
|
||||||
/// Finalizes the PSBT, in BIP174 parlance this is the 'Finalizer'.
|
/// 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)
|
/// 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> {
|
fn finalize_psbt(&self, mut psbt: Psbt) -> Result<Psbt> {
|
||||||
use bitcoin::util::psbt::serialize::Serialize;
|
use bitcoin::psbt::serialize::Serialize;
|
||||||
|
|
||||||
if psbt.inputs.is_empty() {
|
if psbt.inputs.is_empty() {
|
||||||
return Err(psbt::SignError::MissingInputUtxo.into());
|
return Err(psbt::SignError::MissingInputUtxo.into());
|
||||||
|
|
|
@ -13,8 +13,8 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use crate::{merkle_tree, util};
|
use crate::merkle_tree;
|
||||||
use crate::util::Error::{BlockBadTarget, BlockBadProofOfWork};
|
use crate::error::Error::{self, BlockBadTarget, BlockBadProofOfWork};
|
||||||
use crate::hashes::{Hash, HashEngine};
|
use crate::hashes::{Hash, HashEngine};
|
||||||
use crate::hash_types::{Wtxid, TxMerkleNode, WitnessMerkleNode, WitnessCommitment};
|
use crate::hash_types::{Wtxid, TxMerkleNode, WitnessMerkleNode, WitnessCommitment};
|
||||||
use crate::consensus::{encode, Encodable, Decodable};
|
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.
|
/// 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, util::Error> {
|
pub fn validate_pow(&self, required_target: Target) -> Result<BlockHash, Error> {
|
||||||
let target = self.target();
|
let target = self.target();
|
||||||
if target != required_target {
|
if target != required_target {
|
||||||
return Err(BlockBadTarget);
|
return Err(BlockBadTarget);
|
||||||
|
|
|
@ -1183,7 +1183,7 @@ mod test {
|
||||||
use crate::consensus::encode::{deserialize, serialize};
|
use crate::consensus::encode::{deserialize, serialize};
|
||||||
use crate::blockdata::opcodes;
|
use crate::blockdata::opcodes;
|
||||||
use crate::util::key::PublicKey;
|
use crate::util::key::PublicKey;
|
||||||
use crate::util::psbt::serialize::Serialize;
|
use crate::psbt::serialize::Serialize;
|
||||||
use crate::internal_macros::hex_script;
|
use crate::internal_macros::hex_script;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::hashes::{sha256d, Hash, sha256};
|
||||||
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
|
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
|
||||||
use crate::io::{self, Cursor, Read};
|
use crate::io::{self, Cursor, Read};
|
||||||
|
|
||||||
use crate::util::psbt;
|
use crate::psbt;
|
||||||
use crate::bip152::{ShortId, PrefilledTransaction};
|
use crate::bip152::{ShortId, PrefilledTransaction};
|
||||||
use crate::util::taproot::TapLeafHash;
|
use crate::util::taproot::TapLeafHash;
|
||||||
use crate::hashes::hex::ToHex;
|
use crate::hashes::hex::ToHex;
|
||||||
|
|
|
@ -1,7 +1,53 @@
|
||||||
//! Contains error types and other error handling tools.
|
//! 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;
|
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
|
/// Impls std::error::Error for the specified type with appropriate attributes, possibly returning
|
||||||
/// source.
|
/// source.
|
||||||
macro_rules! impl_std_error {
|
macro_rules! impl_std_error {
|
||||||
|
|
|
@ -104,6 +104,7 @@ pub mod hash_types;
|
||||||
pub mod merkle_tree;
|
pub mod merkle_tree;
|
||||||
pub mod policy;
|
pub mod policy;
|
||||||
pub mod pow;
|
pub mod pow;
|
||||||
|
pub mod psbt;
|
||||||
pub mod sighash;
|
pub mod sighash;
|
||||||
pub mod sign_message;
|
pub mod sign_message;
|
||||||
pub mod util;
|
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::witness::{self, Witness};
|
||||||
pub use crate::blockdata::{constants, opcodes};
|
pub use crate::blockdata::{constants, opcodes};
|
||||||
pub use crate::consensus::encode::VarInt;
|
pub use crate::consensus::encode::VarInt;
|
||||||
|
pub use crate::error::Error;
|
||||||
pub use crate::hash_types::*;
|
pub use crate::hash_types::*;
|
||||||
pub use crate::network::constants::Network;
|
pub use crate::network::constants::Network;
|
||||||
pub use crate::pow::{CompactTarget, Target, Work};
|
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::util::key::{KeyPair, PrivateKey, PublicKey, XOnlyPublicKey};
|
||||||
pub use crate::merkle_tree::MerkleBlock;
|
pub use crate::merkle_tree::MerkleBlock;
|
||||||
pub use crate::util::schnorr::{self, SchnorrSig, SchnorrSigError};
|
pub use crate::util::schnorr::{self, SchnorrSig, SchnorrSigError};
|
||||||
pub use crate::util::{psbt, Error};
|
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
mod io_extras {
|
mod io_extras {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use bitcoin_internals::write_err;
|
||||||
|
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::consensus::encode;
|
use crate::consensus::encode;
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::raw;
|
||||||
|
|
||||||
use crate::hashes;
|
use crate::hashes;
|
||||||
use crate::bip32::ExtendedPubKey;
|
use crate::bip32::ExtendedPubKey;
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! hex_psbt {
|
macro_rules! hex_psbt {
|
||||||
($s:expr) => { $crate::consensus::deserialize::<$crate::util::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
|
($s:expr) => { $crate::consensus::deserialize::<$crate::psbt::PartiallySignedTransaction>(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! combine {
|
macro_rules! combine {
|
||||||
|
@ -22,7 +22,7 @@ macro_rules! impl_psbt_de_serialize {
|
||||||
|
|
||||||
macro_rules! impl_psbt_deserialize {
|
macro_rules! impl_psbt_deserialize {
|
||||||
($thing:ty) => {
|
($thing:ty) => {
|
||||||
impl $crate::util::psbt::serialize::Deserialize for $thing {
|
impl $crate::psbt::serialize::Deserialize for $thing {
|
||||||
fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
|
fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
|
||||||
$crate::consensus::deserialize(&bytes[..])
|
$crate::consensus::deserialize(&bytes[..])
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ macro_rules! impl_psbt_deserialize {
|
||||||
|
|
||||||
macro_rules! impl_psbt_serialize {
|
macro_rules! impl_psbt_serialize {
|
||||||
($thing:ty) => {
|
($thing:ty) => {
|
||||||
impl $crate::util::psbt::serialize::Serialize for $thing {
|
impl $crate::psbt::serialize::Serialize for $thing {
|
||||||
fn serialize(&self) -> $crate::prelude::Vec<u8> {
|
fn serialize(&self) -> $crate::prelude::Vec<u8> {
|
||||||
$crate::consensus::serialize(self)
|
$crate::consensus::serialize(self)
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ macro_rules! impl_psbtmap_consensus_decoding {
|
||||||
loop {
|
loop {
|
||||||
match $crate::consensus::Decodable::consensus_decode(r) {
|
match $crate::consensus::Decodable::consensus_decode(r) {
|
||||||
Ok(pair) => rv.insert_pair(pair)?,
|
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),
|
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>) => {
|
($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => {
|
||||||
if $raw_key.key.is_empty() {
|
if $raw_key.key.is_empty() {
|
||||||
if $slf.$unkeyed_name.is_none() {
|
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)
|
$slf.$unkeyed_name = Some(val)
|
||||||
} else {
|
} else {
|
||||||
return Err($crate::util::psbt::Error::DuplicateKey($raw_key).into());
|
return Err($crate::psbt::Error::DuplicateKey($raw_key).into());
|
||||||
}
|
}
|
||||||
} else {
|
} 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>) => {
|
($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() {
|
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) {
|
match $slf.$keyed_name.entry(key_val) {
|
||||||
$crate::prelude::btree_map::Entry::Vacant(empty_key) => {
|
$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);
|
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 {
|
} 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 {
|
macro_rules! impl_psbt_get_pair {
|
||||||
($rv:ident.push($slf:ident.$unkeyed_name:ident, $unkeyed_typeval:ident)) => {
|
($rv:ident.push($slf:ident.$unkeyed_name:ident, $unkeyed_typeval:ident)) => {
|
||||||
if let Some(ref $unkeyed_name) = $slf.$unkeyed_name {
|
if let Some(ref $unkeyed_name) = $slf.$unkeyed_name {
|
||||||
$rv.push($crate::util::psbt::raw::Pair {
|
$rv.push($crate::psbt::raw::Pair {
|
||||||
key: $crate::util::psbt::raw::Key {
|
key: $crate::psbt::raw::Key {
|
||||||
type_value: $unkeyed_typeval,
|
type_value: $unkeyed_typeval,
|
||||||
key: vec![],
|
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)) => {
|
($rv:ident.push_map($slf:ident.$keyed_name:ident, $keyed_typeval:ident)) => {
|
||||||
for (key, val) in &$slf.$keyed_name {
|
for (key, val) in &$slf.$keyed_name {
|
||||||
$rv.push($crate::util::psbt::raw::Pair {
|
$rv.push($crate::psbt::raw::Pair {
|
||||||
key: $crate::util::psbt::raw::Key {
|
key: $crate::psbt::raw::Key {
|
||||||
type_value: $keyed_typeval,
|
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 {
|
macro_rules! impl_psbt_hash_deserialize {
|
||||||
($hash_type:ty) => {
|
($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<Self, $crate::consensus::encode::Error> {
|
fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
|
||||||
<$hash_type>::from_slice(&bytes[..]).map_err(|e| {
|
<$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 {
|
macro_rules! impl_psbt_hash_serialize {
|
||||||
($hash_type:ty) => {
|
($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<u8> {
|
fn serialize(&self) -> $crate::prelude::Vec<u8> {
|
||||||
self.into_inner().to_vec()
|
self.into_inner().to_vec()
|
||||||
}
|
}
|
|
@ -9,9 +9,8 @@ use crate::io::{self, Cursor, Read};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::consensus::{encode, Encodable, Decodable};
|
use crate::consensus::{encode, Encodable, Decodable};
|
||||||
use crate::consensus::encode::MAX_VEC_SIZE;
|
use crate::consensus::encode::MAX_VEC_SIZE;
|
||||||
use crate::util::psbt::map::Map;
|
use crate::psbt::map::Map;
|
||||||
use crate::util::psbt::{raw, PartiallySignedTransaction};
|
use crate::psbt::{raw, Error, PartiallySignedTransaction};
|
||||||
use crate::util::psbt::Error;
|
|
||||||
use crate::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
|
use crate::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
|
||||||
|
|
||||||
/// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00
|
/// 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),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,11 +15,9 @@ use crate::blockdata::transaction::{Transaction, TxOut};
|
||||||
use crate::consensus::encode;
|
use crate::consensus::encode;
|
||||||
use crate::hashes::{self, hash160, ripemd160, sha256, sha256d};
|
use crate::hashes::{self, hash160, ripemd160, sha256, sha256d};
|
||||||
use crate::bip32::KeySource;
|
use crate::bip32::KeySource;
|
||||||
use crate::util::psbt;
|
use crate::psbt::map::Map;
|
||||||
use crate::util::psbt::map::Map;
|
use crate::psbt::serialize::Deserialize;
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::{self, error, raw, Error};
|
||||||
use crate::util::psbt::serialize::Deserialize;
|
|
||||||
use crate::util::psbt::{Error, error};
|
|
||||||
use crate::util::key::PublicKey;
|
use crate::util::key::PublicKey;
|
||||||
use crate::sighash::{NonStandardSighashType, SighashTypeParseError, EcdsaSighashType, SchnorrSighashType};
|
use crate::sighash::{NonStandardSighashType, SighashTypeParseError, EcdsaSighashType, SchnorrSighashType};
|
||||||
use crate::util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash};
|
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", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
pub struct PsbtSighashType {
|
pub struct PsbtSighashType {
|
||||||
pub (in crate::util::psbt) inner: u32,
|
pub (in crate::psbt) inner: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PsbtSighashType {
|
impl fmt::Display for PsbtSighashType {
|
|
@ -5,7 +5,7 @@ use crate::prelude::*;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
|
|
||||||
use crate::consensus::encode;
|
use crate::consensus::encode;
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::raw;
|
||||||
|
|
||||||
mod global;
|
mod global;
|
||||||
mod input;
|
mod input;
|
|
@ -11,9 +11,9 @@ use crate::consensus::encode;
|
||||||
use secp256k1::XOnlyPublicKey;
|
use secp256k1::XOnlyPublicKey;
|
||||||
use crate::bip32::KeySource;
|
use crate::bip32::KeySource;
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
use crate::util::psbt::map::Map;
|
use crate::psbt::map::Map;
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::raw;
|
||||||
use crate::util::psbt::Error;
|
use crate::psbt::Error;
|
||||||
|
|
||||||
use crate::util::taproot::{ScriptLeaf, TapLeafHash};
|
use crate::util::taproot::{ScriptLeaf, TapLeafHash};
|
||||||
|
|
|
@ -895,8 +895,8 @@ mod tests {
|
||||||
use crate::network::constants::Network::Bitcoin;
|
use crate::network::constants::Network::Bitcoin;
|
||||||
use crate::consensus::encode::{deserialize, serialize, serialize_hex};
|
use crate::consensus::encode::{deserialize, serialize, serialize_hex};
|
||||||
use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
|
use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
|
||||||
use crate::util::psbt::map::{Output, Input};
|
use crate::psbt::map::{Output, Input};
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::raw;
|
||||||
use crate::internal_macros::hex_script;
|
use crate::internal_macros::hex_script;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
@ -1044,7 +1044,7 @@ mod tests {
|
||||||
fn test_serde_psbt() {
|
fn test_serde_psbt() {
|
||||||
//! Create a full PSBT value with various fields filled and make sure it can be JSONized.
|
//! Create a full PSBT value with various fields filled and make sure it can be JSONized.
|
||||||
use crate::hashes::sha256d;
|
use crate::hashes::sha256d;
|
||||||
use crate::util::psbt::map::Input;
|
use crate::psbt::map::Input;
|
||||||
use crate::sighash::EcdsaSighashType;
|
use crate::sighash::EcdsaSighashType;
|
||||||
|
|
||||||
// create some values to use in the PSBT
|
// 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::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence};
|
||||||
use crate::consensus::encode::serialize_hex;
|
use crate::consensus::encode::serialize_hex;
|
||||||
use crate::blockdata::locktime::absolute;
|
use crate::blockdata::locktime::absolute;
|
||||||
use crate::util::psbt::map::{Map, Input, Output};
|
use crate::psbt::map::{Map, Input, Output};
|
||||||
use crate::util::psbt::raw;
|
use crate::psbt::{raw, PartiallySignedTransaction, Error};
|
||||||
use crate::util::psbt::{PartiallySignedTransaction, Error};
|
|
||||||
use crate::sighash::EcdsaSighashType;
|
use crate::sighash::EcdsaSighashType;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use crate::blockdata::witness::Witness;
|
use crate::blockdata::witness::Witness;
|
||||||
|
@ -1183,7 +1182,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "ConsensusEncoding")]
|
#[should_panic(expected = "ConsensusEncoding")]
|
||||||
fn invalid_vector_2_base64() {
|
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==")
|
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
|
// 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 {
|
.map_err(|err| match err {
|
||||||
|
@ -1664,9 +1663,9 @@ mod tests {
|
||||||
// PSBTs taken from BIP 174 test vectors.
|
// PSBTs taken from BIP 174 test vectors.
|
||||||
#[test]
|
#[test]
|
||||||
fn combine_psbts() {
|
fn combine_psbts() {
|
||||||
let mut psbt1 = hex_psbt!(include_str!("../../../tests/data/psbt1.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 psbt2 = hex_psbt!(include_str!("../../tests/data/psbt2.hex")).unwrap();
|
||||||
let psbt_combined = 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");
|
psbt1.combine(psbt2).expect("psbt combine to succeed");
|
||||||
assert_eq!(psbt1, psbt_combined);
|
assert_eq!(psbt1, psbt_combined);
|
||||||
|
@ -1674,8 +1673,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn combine_psbts_commutative() {
|
fn combine_psbts_commutative() {
|
||||||
let mut psbt1 = hex_psbt!(include_str!("../../../tests/data/psbt1.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 mut psbt2 = hex_psbt!(include_str!("../../tests/data/psbt2.hex")).unwrap();
|
||||||
|
|
||||||
let psbt1_clone = psbt1.clone();
|
let psbt1_clone = psbt1.clone();
|
||||||
let psbt2_clone = psbt2.clone();
|
let psbt2_clone = psbt2.clone();
|
|
@ -13,8 +13,7 @@ use core::convert::TryFrom;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
|
use crate::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
|
||||||
use crate::hashes::hex;
|
use crate::hashes::hex;
|
||||||
use crate::util::psbt::Error;
|
use crate::psbt::Error;
|
||||||
use crate::util::read_to_end;
|
|
||||||
|
|
||||||
/// A PSBT key in its raw byte form.
|
/// A PSBT key in its raw byte form.
|
||||||
#[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)]
|
#[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)]
|
||||||
|
@ -173,3 +172,18 @@ where
|
||||||
Ok(deserialize(&key.key)?)
|
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)
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ use secp256k1::{self, XOnlyPublicKey};
|
||||||
use crate::bip32::{ChildNumber, Fingerprint, KeySource};
|
use crate::bip32::{ChildNumber, Fingerprint, KeySource};
|
||||||
use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
|
use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
|
||||||
use crate::util::ecdsa::{EcdsaSig, EcdsaSigError};
|
use crate::util::ecdsa::{EcdsaSig, EcdsaSigError};
|
||||||
use crate::util::psbt;
|
use crate::psbt;
|
||||||
use crate::util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion};
|
use crate::util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion};
|
||||||
use crate::schnorr;
|
use crate::schnorr;
|
||||||
use crate::util::key::PublicKey;
|
use crate::util::key::PublicKey;
|
|
@ -10,75 +10,8 @@ pub mod key;
|
||||||
pub mod ecdsa;
|
pub mod ecdsa;
|
||||||
pub mod schnorr;
|
pub mod schnorr;
|
||||||
pub mod base58;
|
pub mod base58;
|
||||||
pub mod psbt;
|
|
||||||
pub mod taproot;
|
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 `misc` module was moved and re-named to `sign_message`.
|
/// The `misc` module was moved and re-named to `sign_message`.
|
||||||
pub mod misc {
|
pub mod misc {
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
|
@ -402,7 +402,7 @@ impl TaprootBuilder {
|
||||||
/// If the script weight calculations overflow, a sub-optimal tree may be generated. This should
|
/// 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.
|
/// 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<I>(
|
pub fn with_huffman_tree<I>(
|
||||||
script_weights: I,
|
script_weights: I,
|
||||||
) -> Result<Self, TaprootBuilderError>
|
) -> Result<Self, TaprootBuilderError>
|
||||||
|
|
|
@ -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.
|
/// 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)
|
/// 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 {
|
fn finalize_psbt(mut psbt: Psbt) -> Psbt {
|
||||||
use bitcoin::util::psbt::serialize::Serialize;
|
use bitcoin::psbt::serialize::Serialize;
|
||||||
|
|
||||||
// Input 0: legacy UTXO
|
// Input 0: legacy UTXO
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
extern crate bitcoin;
|
extern crate bitcoin;
|
||||||
|
|
||||||
fn do_test(data: &[u8]) {
|
fn do_test(data: &[u8]) {
|
||||||
let psbt: Result<bitcoin::util::psbt::PartiallySignedTransaction, _> = bitcoin::consensus::encode::deserialize(data);
|
let psbt: Result<bitcoin::psbt::PartiallySignedTransaction, _> = bitcoin::consensus::encode::deserialize(data);
|
||||||
match psbt {
|
match psbt {
|
||||||
Err(_) => {},
|
Err(_) => {},
|
||||||
Ok(psbt) => {
|
Ok(psbt) => {
|
||||||
let ser = bitcoin::consensus::encode::serialize(&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
|
// 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));
|
assert_eq!(ser, bitcoin::consensus::encode::serialize(&deser));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ ignore = [
|
||||||
"bitcoin/src/blockdata",
|
"bitcoin/src/blockdata",
|
||||||
"bitcoin/src/consensus",
|
"bitcoin/src/consensus",
|
||||||
"bitcoin/src/network",
|
"bitcoin/src/network",
|
||||||
|
"bitcoin/src/psbt",
|
||||||
"bitcoin/src/util",
|
"bitcoin/src/util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue