// Rust Bitcoin Library
// Written by
// The Rust Bitcoin developers
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see .
//
//! PSBT serialization.
//!
//! Defines traits used for (de)serializing PSBT values into/from raw
//! bytes from/as PSBT key-value pairs.
//!
use prelude::*;
use io;
use blockdata::script::Script;
use blockdata::witness::Witness;
use blockdata::transaction::{Transaction, TxOut};
use consensus::encode::{self, serialize, Decodable, Encodable, deserialize_partial};
use secp256k1::{self, XOnlyPublicKey};
use util::bip32::{ChildNumber, Fingerprint, KeySource};
use hashes::{hash160, ripemd160, sha256, sha256d, Hash};
use util::ecdsa::{EcdsaSig, EcdsaSigError};
use util::psbt;
use util::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion};
use schnorr;
use util::key::PublicKey;
use super::map::{TapTree, PsbtSighashType};
use util::taproot::TaprootBuilder;
/// A trait for serializing a value as raw data for insertion into PSBT
/// key-value pairs.
pub trait Serialize {
/// Serialize a value as raw data.
fn serialize(&self) -> Vec;
}
/// A trait for deserializing a value from raw data in PSBT key-value pairs.
pub trait Deserialize: Sized {
/// Deserialize a value from raw data.
fn deserialize(bytes: &[u8]) -> Result;
}
impl_psbt_de_serialize!(Transaction);
impl_psbt_de_serialize!(TxOut);
impl_psbt_de_serialize!(Witness);
impl_psbt_hash_de_serialize!(ripemd160::Hash);
impl_psbt_hash_de_serialize!(sha256::Hash);
impl_psbt_hash_de_serialize!(TapLeafHash);
impl_psbt_hash_de_serialize!(TapBranchHash);
impl_psbt_hash_de_serialize!(hash160::Hash);
impl_psbt_hash_de_serialize!(sha256d::Hash);
// taproot
impl_psbt_de_serialize!(Vec);
impl Serialize for Script {
fn serialize(&self) -> Vec {
self.to_bytes()
}
}
impl Deserialize for Script {
fn deserialize(bytes: &[u8]) -> Result {
Ok(Self::from(bytes.to_vec()))
}
}
impl Serialize for PublicKey {
fn serialize(&self) -> Vec {
let mut buf = Vec::new();
self.write_into(&mut buf).expect("vecs don't error");
buf
}
}
impl Deserialize for PublicKey {
fn deserialize(bytes: &[u8]) -> Result {
PublicKey::from_slice(bytes)
.map_err(|_| encode::Error::ParseFailed("invalid public key"))
}
}
impl Serialize for secp256k1::PublicKey {
fn serialize(&self) -> Vec {
self.serialize().to_vec()
}
}
impl Deserialize for secp256k1::PublicKey {
fn deserialize(bytes: &[u8]) -> Result {
secp256k1::PublicKey::from_slice(bytes)
.map_err(|_| encode::Error::ParseFailed("invalid public key"))
}
}
impl Serialize for EcdsaSig {
fn serialize(&self) -> Vec {
self.to_vec()
}
}
impl Deserialize for EcdsaSig {
fn deserialize(bytes: &[u8]) -> Result {
// NB: Since BIP-174 says "the signature as would be pushed to the stack from
// a scriptSig or witness" we should ideally use a consensus deserialization and do
// not error on a non-standard values. However,
//
// 1) the current implementation of from_u32_consensus(`flag`) does not preserve
// the sighash byte `flag` mapping all unknown values to EcdsaSighashType::All or
// EcdsaSighashType::AllPlusAnyOneCanPay. Therefore, break the invariant
// EcdsaSig::from_slice(&sl[..]).to_vec = sl.
//
// 2) This would cause to have invalid signatures because the sighash message
// also has a field sighash_u32 (See BIP141). For example, when signing with non-standard
// 0x05, the sighash message would have the last field as 0x05u32 while, the verification
// would use check the signature assuming sighash_u32 as `0x01`.
EcdsaSig::from_slice(&bytes)
.map_err(|e| match e {
EcdsaSigError::EmptySignature => {
encode::Error::ParseFailed("Empty partial signature data")
}
EcdsaSigError::NonStandardSighashType(flag) => {
encode::Error::from(psbt::Error::NonStandardSighashType(flag))
}
EcdsaSigError::Secp256k1(..) => {
encode::Error::ParseFailed("Invalid Ecdsa signature")
}
EcdsaSigError::HexEncoding(..) => {
unreachable!("Decoding from slice, not hex")
}
})
}
}
impl Serialize for KeySource {
fn serialize(&self) -> Vec {
let mut rv: Vec = Vec::with_capacity(key_source_len(&self));
rv.append(&mut self.0.to_bytes().to_vec());
for cnum in self.1.into_iter() {
rv.append(&mut serialize(&u32::from(*cnum)))
}
rv
}
}
impl Deserialize for KeySource {
fn deserialize(bytes: &[u8]) -> Result {
if bytes.len() < 4 {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into())
}
let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]);
let mut dpath: Vec = Default::default();
let mut d = &bytes[4..];
while !d.is_empty() {
match u32::consensus_decode(&mut d) {
Ok(index) => dpath.push(index.into()),
Err(e) => return Err(e),
}
}
Ok((fprint, dpath.into()))
}
}
// partial sigs
impl Serialize for Vec {
fn serialize(&self) -> Vec {
self.clone()
}
}
impl Deserialize for Vec {
fn deserialize(bytes: &[u8]) -> Result {
Ok(bytes.to_vec())
}
}
impl Serialize for PsbtSighashType {
fn serialize(&self) -> Vec {
serialize(&self.to_u32())
}
}
impl Deserialize for PsbtSighashType {
fn deserialize(bytes: &[u8]) -> Result {
let raw: u32 = encode::deserialize(bytes)?;
Ok(PsbtSighashType { inner: raw })
}
}
// Taproot related ser/deser
impl Serialize for XOnlyPublicKey {
fn serialize(&self) -> Vec {
XOnlyPublicKey::serialize(&self).to_vec()
}
}
impl Deserialize for XOnlyPublicKey {
fn deserialize(bytes: &[u8]) -> Result {
XOnlyPublicKey::from_slice(bytes)
.map_err(|_| encode::Error::ParseFailed("Invalid xonly public key"))
}
}
impl Serialize for schnorr::SchnorrSig {
fn serialize(&self) -> Vec {
self.to_vec()
}
}
impl Deserialize for schnorr::SchnorrSig {
fn deserialize(bytes: &[u8]) -> Result {
schnorr::SchnorrSig::from_slice(&bytes)
.map_err(|e| match e {
schnorr::SchnorrSigError::InvalidSighashType(flag) => {
encode::Error::from(psbt::Error::NonStandardSighashType(flag as u32))
}
schnorr::SchnorrSigError::InvalidSchnorrSigSize(_) => {
encode::Error::ParseFailed("Invalid Schnorr signature length")
}
schnorr::SchnorrSigError::Secp256k1(..) => {
encode::Error::ParseFailed("Invalid Schnorr signature")
}
})
}
}
impl Serialize for (XOnlyPublicKey, TapLeafHash) {
fn serialize(&self) -> Vec {
let ser_pk = self.0.serialize();
let mut buf = Vec::with_capacity(ser_pk.len() + self.1.as_ref().len());
buf.extend(&ser_pk);
buf.extend(self.1.as_ref());
buf
}
}
impl Deserialize for (XOnlyPublicKey, TapLeafHash) {
fn deserialize(bytes: &[u8]) -> Result {
if bytes.len() < 32 {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into())
}
let a: XOnlyPublicKey = Deserialize::deserialize(&bytes[..32])?;
let b: TapLeafHash = Deserialize::deserialize(&bytes[32..])?;
Ok((a, b))
}
}
impl Serialize for ControlBlock {
fn serialize(&self) -> Vec {
ControlBlock::serialize(&self)
}
}
impl Deserialize for ControlBlock {
fn deserialize(bytes: &[u8]) -> Result {
Self::from_slice(bytes)
.map_err(|_| encode::Error::ParseFailed("Invalid control block"))
}
}
// Versioned Script
impl Serialize for (Script, LeafVersion) {
fn serialize(&self) -> Vec {
let mut buf = Vec::with_capacity(self.0.len() + 1);
buf.extend(self.0.as_bytes());
buf.push(self.1.to_consensus());
buf
}
}
impl Deserialize for (Script, LeafVersion) {
fn deserialize(bytes: &[u8]) -> Result {
if bytes.is_empty() {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into())
}
// The last byte is LeafVersion.
let script = Script::deserialize(&bytes[..bytes.len() - 1])?;
let leaf_ver = LeafVersion::from_consensus(bytes[bytes.len() - 1])
.map_err(|_| encode::Error::ParseFailed("invalid leaf version"))?;
Ok((script, leaf_ver))
}
}
impl Serialize for (Vec, KeySource) {
fn serialize(&self) -> Vec {
let mut buf = Vec::with_capacity( 32 * self.0.len() + key_source_len(&self.1));
self.0.consensus_encode(&mut buf).expect("Vecs don't error allocation");
// TODO: Add support for writing into a writer for key-source
buf.extend(self.1.serialize());
buf
}
}
impl Deserialize for (Vec, KeySource) {
fn deserialize(bytes: &[u8]) -> Result {
let (leafhash_vec, consumed) = deserialize_partial::>(&bytes)?;
let key_source = KeySource::deserialize(&bytes[consumed..])?;
Ok((leafhash_vec, key_source))
}
}
impl Serialize for TapTree {
fn serialize(&self) -> Vec {
match (self.0.branch().len(), self.0.branch().last()) {
(1, Some(Some(root))) => {
let mut buf = Vec::new();
for leaf_info in root.leaves.iter() {
// # Cast Safety:
//
// TaprootMerkleBranch can only have len atmost 128(TAPROOT_CONTROL_MAX_NODE_COUNT).
// safe to cast from usize to u8
buf.push(leaf_info.merkle_branch().as_inner().len() as u8);
buf.push(leaf_info.leaf_version().to_consensus());
leaf_info.script().consensus_encode(&mut buf).expect("Vecs dont err");
}
buf
}
// This should be unreachable as we Taptree is already finalized
_ => unreachable!(),
}
}
}
impl Deserialize for TapTree {
fn deserialize(bytes: &[u8]) -> Result {
let mut builder = TaprootBuilder::new();
let mut bytes_iter = bytes.iter();
while let Some(depth) = bytes_iter.next() {
let version = bytes_iter.next().ok_or(encode::Error::ParseFailed("Invalid Taproot Builder"))?;
let (script, consumed) = deserialize_partial::