Add PSBT-specific Error data type
- Implement psbt::Error data type - Implement conversion from psbt::Error to util::Error - Create util::psbt module - Create non-public util::psbt::error module
This commit is contained in:
parent
919bbeae4a
commit
4fa39c4a3e
|
@ -45,6 +45,7 @@ use bitcoin_hashes::{sha256d, Hash as HashTrait};
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
|
|
||||||
use util::base58;
|
use util::base58;
|
||||||
|
use util::psbt;
|
||||||
|
|
||||||
/// Encoding error
|
/// Encoding error
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -59,6 +60,8 @@ pub enum Error {
|
||||||
ByteOrder(io::Error),
|
ByteOrder(io::Error),
|
||||||
/// secp-related error
|
/// secp-related error
|
||||||
Secp256k1(secp256k1::Error),
|
Secp256k1(secp256k1::Error),
|
||||||
|
/// PSBT-related error
|
||||||
|
Psbt(psbt::Error),
|
||||||
/// Network magic was not expected
|
/// Network magic was not expected
|
||||||
UnexpectedNetworkMagic {
|
UnexpectedNetworkMagic {
|
||||||
/// The expected network magic
|
/// The expected network magic
|
||||||
|
@ -102,6 +105,7 @@ impl fmt::Display for Error {
|
||||||
Error::Bech32(ref e) => fmt::Display::fmt(e, f),
|
Error::Bech32(ref e) => fmt::Display::fmt(e, f),
|
||||||
Error::ByteOrder(ref e) => fmt::Display::fmt(e, f),
|
Error::ByteOrder(ref e) => fmt::Display::fmt(e, f),
|
||||||
Error::Secp256k1(ref e) => fmt::Display::fmt(e, f),
|
Error::Secp256k1(ref e) => fmt::Display::fmt(e, f),
|
||||||
|
Error::Psbt(ref e) => fmt::Display::fmt(e, f),
|
||||||
Error::UnexpectedNetworkMagic { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e, a),
|
Error::UnexpectedNetworkMagic { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e, a),
|
||||||
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "{}: requested {}, maximum {}", error::Error::description(self), r, m),
|
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "{}: requested {}, maximum {}", error::Error::description(self), r, m),
|
||||||
Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), hex_encode(e), hex_encode(a)),
|
Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), hex_encode(e), hex_encode(a)),
|
||||||
|
@ -123,6 +127,7 @@ impl error::Error for Error {
|
||||||
Error::Bech32(ref e) => Some(e),
|
Error::Bech32(ref e) => Some(e),
|
||||||
Error::ByteOrder(ref e) => Some(e),
|
Error::ByteOrder(ref e) => Some(e),
|
||||||
Error::Secp256k1(ref e) => Some(e),
|
Error::Secp256k1(ref e) => Some(e),
|
||||||
|
Error::Psbt(ref e) => Some(e),
|
||||||
Error::UnexpectedNetworkMagic { .. }
|
Error::UnexpectedNetworkMagic { .. }
|
||||||
| Error::OversizedVectorAllocation { .. }
|
| Error::OversizedVectorAllocation { .. }
|
||||||
| Error::InvalidChecksum { .. }
|
| Error::InvalidChecksum { .. }
|
||||||
|
@ -142,6 +147,7 @@ impl error::Error for Error {
|
||||||
Error::Bech32(ref e) => e.description(),
|
Error::Bech32(ref e) => e.description(),
|
||||||
Error::ByteOrder(ref e) => e.description(),
|
Error::ByteOrder(ref e) => e.description(),
|
||||||
Error::Secp256k1(ref e) => e.description(),
|
Error::Secp256k1(ref e) => e.description(),
|
||||||
|
Error::Psbt(ref e) => e.description(),
|
||||||
Error::UnexpectedNetworkMagic { .. } => "unexpected network magic",
|
Error::UnexpectedNetworkMagic { .. } => "unexpected network magic",
|
||||||
Error::OversizedVectorAllocation { .. } => "allocation of oversized vector requested",
|
Error::OversizedVectorAllocation { .. } => "allocation of oversized vector requested",
|
||||||
Error::InvalidChecksum { .. } => "invalid checksum",
|
Error::InvalidChecksum { .. } => "invalid checksum",
|
||||||
|
@ -183,6 +189,13 @@ impl From<io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
impl From<psbt::Error> for Error {
|
||||||
|
fn from(e: psbt::Error) -> Error {
|
||||||
|
Error::Psbt(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Encode an object into a vector
|
/// Encode an object into a vector
|
||||||
pub fn serialize<T: ?Sized>(data: &T) -> Vec<u8>
|
pub fn serialize<T: ?Sized>(data: &T) -> Vec<u8>
|
||||||
where T: Encodable<Cursor<Vec<u8>>>,
|
where T: Encodable<Cursor<Vec<u8>>>,
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub mod contracthash;
|
||||||
pub mod decimal;
|
pub mod decimal;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
pub mod misc;
|
pub mod misc;
|
||||||
|
pub mod psbt;
|
||||||
pub mod uint;
|
pub mod uint;
|
||||||
|
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
use std::error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use blockdata::transaction::Transaction;
|
||||||
|
|
||||||
|
/// Ways that a Partially Signed Transaction might fail.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most
|
||||||
|
/// significant byte order.
|
||||||
|
InvalidMagic,
|
||||||
|
/// The separator for a PSBT must be `0xff`.
|
||||||
|
InvalidSeparator,
|
||||||
|
/// Known keys must be according to spec.
|
||||||
|
InvalidKey,
|
||||||
|
/// Keys within key-value map should never be duplicated.
|
||||||
|
DuplicateKey,
|
||||||
|
/// 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,
|
||||||
|
/// Attempting to merge with a PSBT describing a different unsigned
|
||||||
|
/// transaction.
|
||||||
|
UnexpectedUnsignedTx {
|
||||||
|
/// Expected
|
||||||
|
expected: Transaction,
|
||||||
|
/// Actual
|
||||||
|
actual: Transaction,
|
||||||
|
},
|
||||||
|
/// Unable to parse as a standard SigHash type.
|
||||||
|
NonStandardSigHashType(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
Error::UnexpectedUnsignedTx { expected: ref e, actual: ref a } => write!(f, "{}: expected {}, actual {}", error::Error::description(self), e.txid(), a.txid()),
|
||||||
|
Error::NonStandardSigHashType(ref sht) => write!(f, "{}: {}", error::Error::description(self), sht),
|
||||||
|
Error::InvalidMagic
|
||||||
|
| Error::InvalidSeparator
|
||||||
|
| Error::InvalidKey
|
||||||
|
| Error::DuplicateKey
|
||||||
|
| Error::UnsignedTxHasScriptSigs
|
||||||
|
| Error::UnsignedTxHasScriptWitnesses
|
||||||
|
| Error::MustHaveUnsignedTx
|
||||||
|
| Error::NoMorePairs => f.write_str(error::Error::description(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for Error {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
Error::InvalidMagic => "invalid magic",
|
||||||
|
Error::InvalidSeparator => "invalid separator",
|
||||||
|
Error::InvalidKey => "invalid key",
|
||||||
|
Error::DuplicateKey => "duplicate key",
|
||||||
|
Error::UnsignedTxHasScriptSigs => "the unsigned transaction has script sigs",
|
||||||
|
Error::UnsignedTxHasScriptWitnesses => "the unsigned transaction has script witnesses",
|
||||||
|
Error::MustHaveUnsignedTx => {
|
||||||
|
"partially signed transactions must have an unsigned transaction"
|
||||||
|
}
|
||||||
|
Error::NoMorePairs => "no more key-value pairs for this psbt map",
|
||||||
|
Error::UnexpectedUnsignedTx { .. } => "different unsigned transaction",
|
||||||
|
Error::NonStandardSigHashType(..) => "non-standard sighash type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
//! # Partially Signed Transactions
|
||||||
|
//!
|
||||||
|
//! Implementation of BIP174 Partially Signed Bitcoin Transaction Format as
|
||||||
|
//! defined at https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
|
||||||
|
//! except we define PSBTs containing non-standard SigHash types as invalid.
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
pub use self::error::Error;
|
Loading…
Reference in New Issue