2022-06-29 04:05:31 +00:00
|
|
|
// SPDX-License-Identifier: CC0-1.0
|
2018-09-09 10:34:29 +00:00
|
|
|
|
2021-06-09 10:40:41 +00:00
|
|
|
use core::fmt;
|
2018-08-08 06:36:51 +00:00
|
|
|
|
2023-03-28 01:16:47 +00:00
|
|
|
use internals::write_err;
|
2022-09-05 02:19:28 +00:00
|
|
|
|
2022-12-05 23:03:19 +00:00
|
|
|
use crate::bip32::ExtendedPubKey;
|
2022-05-02 22:13:57 +00:00
|
|
|
use crate::blockdata::transaction::Transaction;
|
|
|
|
use crate::consensus::encode;
|
2022-12-05 23:03:19 +00:00
|
|
|
use crate::prelude::*;
|
2022-08-05 03:23:03 +00:00
|
|
|
use crate::psbt::raw;
|
2022-12-05 23:03:19 +00:00
|
|
|
use crate::{hashes, io};
|
2020-08-31 20:06:21 +00:00
|
|
|
|
2022-01-06 02:04:47 +00:00
|
|
|
/// Enum for marking psbt hash error.
|
2021-01-30 13:09:34 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
2020-08-31 20:06:21 +00:00
|
|
|
pub enum PsbtHash {
|
|
|
|
Ripemd,
|
|
|
|
Sha256,
|
|
|
|
Hash160,
|
|
|
|
Hash256,
|
|
|
|
}
|
2018-08-08 06:36:51 +00:00
|
|
|
/// Ways that a Partially Signed Transaction might fail.
|
2023-02-02 17:34:49 +00:00
|
|
|
#[derive(Debug)]
|
2022-05-31 04:29:50 +00:00
|
|
|
#[non_exhaustive]
|
2018-08-08 06:36:51 +00:00
|
|
|
pub enum Error {
|
|
|
|
/// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most
|
|
|
|
/// significant byte order.
|
|
|
|
InvalidMagic,
|
2022-02-28 14:01:02 +00:00
|
|
|
/// Missing both the witness and non-witness utxo.
|
|
|
|
MissingUtxo,
|
2018-08-08 06:36:51 +00:00
|
|
|
/// The separator for a PSBT must be `0xff`.
|
|
|
|
InvalidSeparator,
|
2022-02-28 14:01:02 +00:00
|
|
|
/// Returned when output index is out of bounds in relation to the output in non-witness UTXO.
|
|
|
|
PsbtUtxoOutOfbounds,
|
2018-08-08 06:36:51 +00:00
|
|
|
/// Known keys must be according to spec.
|
2018-08-10 15:28:48 +00:00
|
|
|
InvalidKey(raw::Key),
|
2020-12-05 14:10:44 +00:00
|
|
|
/// Non-proprietary key type found when proprietary key was expected
|
|
|
|
InvalidProprietaryKey,
|
2018-08-08 06:36:51 +00:00
|
|
|
/// Keys within key-value map should never be duplicated.
|
2018-08-10 15:28:48 +00:00
|
|
|
DuplicateKey(raw::Key),
|
2018-08-08 06:36:51 +00:00
|
|
|
/// The scriptSigs for the unsigned transaction must be empty.
|
|
|
|
UnsignedTxHasScriptSigs,
|
|
|
|
/// The scriptWitnesses for the unsigned transaction must be empty.
|
|
|
|
UnsignedTxHasScriptWitnesses,
|
|
|
|
/// A PSBT must have an unsigned transaction.
|
|
|
|
MustHaveUnsignedTx,
|
|
|
|
/// Signals that there are no more key-value pairs in a key-value map.
|
|
|
|
NoMorePairs,
|
2022-02-22 13:41:20 +00:00
|
|
|
/// Attempting to combine with a PSBT describing a different unsigned
|
2018-08-08 06:36:51 +00:00
|
|
|
/// transaction.
|
|
|
|
UnexpectedUnsignedTx {
|
|
|
|
/// Expected
|
2020-11-18 09:33:36 +00:00
|
|
|
expected: Box<Transaction>,
|
2018-08-08 06:36:51 +00:00
|
|
|
/// Actual
|
2020-11-18 09:33:36 +00:00
|
|
|
actual: Box<Transaction>,
|
2018-08-08 06:36:51 +00:00
|
|
|
},
|
2022-03-28 23:45:46 +00:00
|
|
|
/// Unable to parse as a standard sighash type.
|
2022-03-28 21:56:36 +00:00
|
|
|
NonStandardSighashType(u32),
|
2020-08-31 20:06:21 +00:00
|
|
|
/// Parsing errors from bitcoin_hashes
|
2023-05-24 03:29:30 +00:00
|
|
|
HashParse(hashes::FromSliceError),
|
2020-08-31 20:06:21 +00:00
|
|
|
/// The pre-image must hash to the correponding psbt hash
|
|
|
|
InvalidPreimageHashPair {
|
|
|
|
/// Hash-type
|
|
|
|
hash_type: PsbtHash,
|
|
|
|
/// Pre-image
|
2020-11-18 09:48:29 +00:00
|
|
|
preimage: Box<[u8]>,
|
2020-08-31 20:06:21 +00:00
|
|
|
/// Hash value
|
2020-11-18 09:48:29 +00:00
|
|
|
hash: Box<[u8]>,
|
2020-11-28 12:49:50 +00:00
|
|
|
},
|
2022-02-22 13:41:20 +00:00
|
|
|
/// Conflicting data during combine procedure:
|
2021-01-30 13:32:44 +00:00
|
|
|
/// global extended public key has inconsistent key sources
|
2022-05-19 15:05:42 +00:00
|
|
|
CombineInconsistentKeySources(Box<ExtendedPubKey>),
|
2020-12-05 14:10:44 +00:00
|
|
|
/// Serialization error in bitcoin consensus-encoded structures
|
2023-02-02 17:54:30 +00:00
|
|
|
ConsensusEncoding(encode::Error),
|
2022-10-22 18:27:49 +00:00
|
|
|
/// Negative fee
|
|
|
|
NegativeFee,
|
|
|
|
/// Integer overflow in fee calculation
|
|
|
|
FeeOverflow,
|
2023-01-17 16:21:52 +00:00
|
|
|
/// Parsing error indicating invalid public keys
|
|
|
|
InvalidPublicKey(crate::crypto::key::Error),
|
|
|
|
/// Parsing error indicating invalid secp256k1 public keys
|
|
|
|
InvalidSecp256k1PublicKey(secp256k1::Error),
|
|
|
|
/// Parsing error indicating invalid xonly public keys
|
|
|
|
InvalidXOnlyPublicKey,
|
|
|
|
/// Parsing error indicating invalid ECDSA signatures
|
|
|
|
InvalidEcdsaSignature(crate::crypto::ecdsa::Error),
|
2023-02-07 03:35:03 +00:00
|
|
|
/// Parsing error indicating invalid taproot signatures
|
2023-06-02 05:01:10 +00:00
|
|
|
InvalidTaprootSignature(crate::crypto::taproot::SigFromSliceError),
|
2023-01-17 16:21:52 +00:00
|
|
|
/// Parsing error indicating invalid control block
|
|
|
|
InvalidControlBlock,
|
|
|
|
/// Parsing error indicating invalid leaf version
|
|
|
|
InvalidLeafVersion,
|
2023-02-07 03:35:03 +00:00
|
|
|
/// Parsing error indicating a taproot error
|
2023-01-17 16:21:52 +00:00
|
|
|
Taproot(&'static str),
|
2023-01-11 12:25:08 +00:00
|
|
|
/// Taproot tree deserilaization error
|
|
|
|
TapTree(crate::taproot::IncompleteBuilder),
|
2023-01-17 16:21:52 +00:00
|
|
|
/// Error related to an xpub key
|
|
|
|
XPubKey(&'static str),
|
|
|
|
/// Error related to PSBT version
|
|
|
|
Version(&'static str),
|
|
|
|
/// PSBT data is not consumed entirely
|
|
|
|
PartialDataConsumption,
|
2023-02-02 17:34:49 +00:00
|
|
|
/// I/O error.
|
|
|
|
Io(io::Error),
|
2018-08-08 06:36:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2022-05-04 05:02:18 +00:00
|
|
|
Error::InvalidMagic => f.write_str("invalid magic"),
|
|
|
|
Error::MissingUtxo => f.write_str("UTXO information is not present in PSBT"),
|
|
|
|
Error::InvalidSeparator => f.write_str("invalid separator"),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::PsbtUtxoOutOfbounds =>
|
|
|
|
f.write_str("output index is out of bounds of non witness script output array"),
|
2020-03-29 13:49:48 +00:00
|
|
|
Error::InvalidKey(ref rkey) => write!(f, "invalid key: {}", rkey),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::InvalidProprietaryKey =>
|
|
|
|
write!(f, "non-proprietary key type found when proprietary key was expected"),
|
2020-03-29 13:49:48 +00:00
|
|
|
Error::DuplicateKey(ref rkey) => write!(f, "duplicate key: {}", rkey),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::UnsignedTxHasScriptSigs =>
|
|
|
|
f.write_str("the unsigned transaction has script sigs"),
|
|
|
|
Error::UnsignedTxHasScriptWitnesses =>
|
|
|
|
f.write_str("the unsigned transaction has script witnesses"),
|
|
|
|
Error::MustHaveUnsignedTx =>
|
|
|
|
f.write_str("partially signed transactions must have an unsigned transaction"),
|
2020-03-29 13:49:48 +00:00
|
|
|
Error::NoMorePairs => f.write_str("no more key-value pairs for this psbt map"),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(
|
|
|
|
f,
|
|
|
|
"different unsigned transaction: expected {}, actual {}",
|
|
|
|
e.txid(),
|
|
|
|
a.txid()
|
|
|
|
),
|
|
|
|
Error::NonStandardSighashType(ref sht) =>
|
|
|
|
write!(f, "non-standard sighash type: {}", sht),
|
2022-08-01 22:41:52 +00:00
|
|
|
Error::HashParse(ref e) => write_err!(f, "hash parse error"; e),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::InvalidPreimageHashPair { ref preimage, ref hash, ref hash_type } => {
|
2020-08-31 20:06:21 +00:00
|
|
|
// directly using debug forms of psbthash enums
|
2022-12-05 23:03:19 +00:00
|
|
|
write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash)
|
|
|
|
}
|
|
|
|
Error::CombineInconsistentKeySources(ref s) => {
|
|
|
|
write!(f, "combine conflict: {}", s)
|
|
|
|
}
|
2023-02-02 17:54:30 +00:00
|
|
|
Error::ConsensusEncoding(ref e) => write_err!(f, "bitcoin consensus encoding error"; e),
|
2022-10-22 18:27:49 +00:00
|
|
|
Error::NegativeFee => f.write_str("PSBT has a negative fee which is not allowed"),
|
|
|
|
Error::FeeOverflow => f.write_str("integer overflow in fee calculation"),
|
2023-01-17 16:21:52 +00:00
|
|
|
Error::InvalidPublicKey(ref e) => write_err!(f, "invalid public key"; e),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::InvalidSecp256k1PublicKey(ref e) =>
|
|
|
|
write_err!(f, "invalid secp256k1 public key"; e),
|
2023-01-17 16:21:52 +00:00
|
|
|
Error::InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"),
|
|
|
|
Error::InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e),
|
2023-02-07 03:35:03 +00:00
|
|
|
Error::InvalidTaprootSignature(ref e) => write_err!(f, "invalid taproot signature"; e),
|
2023-01-17 16:21:52 +00:00
|
|
|
Error::InvalidControlBlock => f.write_str("invalid control block"),
|
|
|
|
Error::InvalidLeafVersion => f.write_str("invalid leaf version"),
|
|
|
|
Error::Taproot(s) => write!(f, "taproot error - {}", s),
|
2023-01-11 12:25:08 +00:00
|
|
|
Error::TapTree(ref e) => write_err!(f, "taproot tree error"; e),
|
2023-01-17 16:21:52 +00:00
|
|
|
Error::XPubKey(s) => write!(f, "xpub key error - {}", s),
|
|
|
|
Error::Version(s) => write!(f, "version error {}", s),
|
2022-12-05 23:03:19 +00:00
|
|
|
Error::PartialDataConsumption =>
|
|
|
|
f.write_str("data not consumed entirely when explicitly deserializing"),
|
2023-02-02 17:34:49 +00:00
|
|
|
Error::Io(ref e) => write_err!(f, "I/O error"; e),
|
2018-08-08 06:36:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-09 10:34:44 +00:00
|
|
|
#[cfg(feature = "std")]
|
2022-05-04 05:56:24 +00:00
|
|
|
impl std::error::Error for Error {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
use self::Error::*;
|
|
|
|
|
|
|
|
match self {
|
2022-08-01 22:41:52 +00:00
|
|
|
HashParse(e) => Some(e),
|
2023-02-02 17:54:30 +00:00
|
|
|
ConsensusEncoding(e) => Some(e),
|
2023-02-02 17:34:49 +00:00
|
|
|
Io(e) => Some(e),
|
2022-12-05 23:03:19 +00:00
|
|
|
InvalidMagic
|
2022-05-04 05:56:24 +00:00
|
|
|
| MissingUtxo
|
|
|
|
| InvalidSeparator
|
|
|
|
| PsbtUtxoOutOfbounds
|
|
|
|
| InvalidKey(_)
|
|
|
|
| InvalidProprietaryKey
|
|
|
|
| DuplicateKey(_)
|
|
|
|
| UnsignedTxHasScriptSigs
|
|
|
|
| UnsignedTxHasScriptWitnesses
|
|
|
|
| MustHaveUnsignedTx
|
|
|
|
| NoMorePairs
|
|
|
|
| UnexpectedUnsignedTx { .. }
|
|
|
|
| NonStandardSighashType(_)
|
2022-12-05 23:03:19 +00:00
|
|
|
| InvalidPreimageHashPair { .. }
|
2022-05-04 05:56:24 +00:00
|
|
|
| CombineInconsistentKeySources(_)
|
2022-10-22 18:27:49 +00:00
|
|
|
| NegativeFee
|
2023-01-17 16:21:52 +00:00
|
|
|
| FeeOverflow
|
|
|
|
| InvalidPublicKey(_)
|
|
|
|
| InvalidSecp256k1PublicKey(_)
|
|
|
|
| InvalidXOnlyPublicKey
|
|
|
|
| InvalidEcdsaSignature(_)
|
2023-02-07 03:35:03 +00:00
|
|
|
| InvalidTaprootSignature(_)
|
2023-01-17 16:21:52 +00:00
|
|
|
| InvalidControlBlock
|
|
|
|
| InvalidLeafVersion
|
|
|
|
| Taproot(_)
|
2023-01-11 12:25:08 +00:00
|
|
|
| TapTree(_)
|
2023-01-17 16:21:52 +00:00
|
|
|
| XPubKey(_)
|
|
|
|
| Version(_)
|
2022-12-05 23:03:19 +00:00
|
|
|
| PartialDataConsumption => None,
|
2022-05-04 05:56:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-31 20:06:21 +00:00
|
|
|
|
2023-05-24 03:29:30 +00:00
|
|
|
impl From<hashes::FromSliceError> for Error {
|
|
|
|
fn from(e: hashes::FromSliceError) -> Error { Error::HashParse(e) }
|
2020-08-31 20:06:21 +00:00
|
|
|
}
|
2020-12-05 14:10:44 +00:00
|
|
|
|
|
|
|
impl From<encode::Error> for Error {
|
2022-12-05 23:03:19 +00:00
|
|
|
fn from(e: encode::Error) -> Self { Error::ConsensusEncoding(e) }
|
2020-12-05 14:10:44 +00:00
|
|
|
}
|
2023-02-02 17:34:49 +00:00
|
|
|
|
|
|
|
impl From<io::Error> for Error {
|
2022-12-05 23:03:19 +00:00
|
|
|
fn from(e: io::Error) -> Self { Error::Io(e) }
|
2023-02-02 17:34:49 +00:00
|
|
|
}
|