Deserialize Psbt fields, don't consensus_encode

This commit is contained in:
DanGould 2022-12-08 18:16:56 -05:00
parent c1dd6ad8a2
commit c4363e5ba1
No known key found for this signature in database
GPG Key ID: B07290B28996AFE0
8 changed files with 54 additions and 38 deletions

View File

@ -50,16 +50,27 @@ macro_rules! impl_psbtmap_serialize {
};
}
macro_rules! impl_psbtmap_consensus_decoding {
macro_rules! impl_psbtmap_deserialize {
($thing:ty) => {
impl $crate::consensus::Decodable for $thing {
fn consensus_decode<R: $crate::io::Read + ?Sized>(
impl $crate::psbt::serialize::Deserialize for $thing {
fn deserialize(bytes: &[u8]) -> Result<Self, $crate::consensus::encode::Error> {
let mut decoder = crate::io::Cursor::new(bytes);
Self::decode(&mut decoder)
}
}
};
}
macro_rules! impl_psbtmap_decoding {
($thing:ty) => {
impl $thing {
pub(crate) fn decode<R: $crate::io::Read + ?Sized>(
r: &mut R,
) -> Result<Self, $crate::consensus::encode::Error> {
let mut rv: Self = core::default::Default::default();
loop {
match $crate::consensus::Decodable::consensus_decode(r) {
match $crate::psbt::raw::Pair::decode(r) {
Ok(pair) => rv.insert_pair(pair)?,
Err($crate::consensus::encode::Error::Psbt($crate::psbt::Error::NoMorePairs)) => return Ok(rv),
Err(e) => return Err(e),
@ -70,6 +81,14 @@ macro_rules! impl_psbtmap_consensus_decoding {
};
}
macro_rules! impl_psbtmap_ser_de_serialize {
($thing:ty) => {
impl_psbtmap_decoding!($thing);
impl_psbtmap_serialize!($thing);
impl_psbtmap_deserialize!($thing);
};
}
#[rustfmt::skip]
macro_rules! impl_psbt_insert_pair {
($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => {

View File

@ -7,8 +7,8 @@ use crate::prelude::*;
use crate::io::{self, Cursor, Read};
use crate::blockdata::transaction::Transaction;
use crate::consensus::{encode, Decodable};
use crate::consensus::encode::MAX_VEC_SIZE;
use crate::consensus::{encode, Decodable};
use crate::psbt::map::Map;
use crate::psbt::{raw, Error, PartiallySignedTransaction};
use crate::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
@ -88,7 +88,7 @@ impl Map for PartiallySignedTransaction {
}
impl PartiallySignedTransaction {
pub(crate) fn consensus_decode_global<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
pub(crate) fn decode_global<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let mut r = r.take(MAX_VEC_SIZE as u64);
let mut tx: Option<Transaction> = None;
let mut version: Option<u32> = None;
@ -97,7 +97,7 @@ impl PartiallySignedTransaction {
let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default();
loop {
match raw::Pair::consensus_decode(&mut r) {
match raw::Pair::decode(&mut r) {
Ok(pair) => {
match pair.key.type_value {
PSBT_GLOBAL_UNSIGNED_TX => {

View File

@ -489,8 +489,7 @@ impl Map for Input {
}
}
impl_psbtmap_serialize!(Input);
impl_psbtmap_consensus_decoding!(Input);
impl_psbtmap_ser_de_serialize!(Input);
fn psbt_insert_hash_pair<H>(
map: &mut BTreeMap<H, Vec<u8>>,

View File

@ -322,5 +322,4 @@ impl Map for Output {
}
}
impl_psbtmap_serialize!(Output);
impl_psbtmap_consensus_decoding!(Output);
impl_psbtmap_ser_de_serialize!(Output);

View File

@ -816,7 +816,7 @@ mod tests {
use crate::hashes::hex::FromHex;
use crate::hashes::{sha256, hash160, Hash, ripemd160};
use crate::hash_types::Txid;
use crate::psbt::serialize::Serialize;
use crate::psbt::serialize::{Serialize, Deserialize};
use secp256k1::{Secp256k1, self};
#[cfg(feature = "rand")]
@ -825,7 +825,6 @@ mod tests {
use crate::blockdata::script::ScriptBuf;
use crate::blockdata::transaction::{Transaction, TxIn, TxOut, OutPoint, Sequence};
use crate::network::constants::Network::Bitcoin;
use crate::consensus::encode::deserialize;
use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
use crate::psbt::map::{Output, Input};
use crate::psbt::raw;
@ -899,7 +898,7 @@ mod tests {
..Default::default()
};
let actual: Output = deserialize(&expected.serialize()).unwrap();
let actual = Output::deserialize(&expected.serialize()).unwrap();
assert_eq!(expected, actual);
}
@ -958,7 +957,7 @@ mod tests {
value: vec![69u8, 42u8, 4u8],
};
let actual: raw::Pair = deserialize(&expected.serialize()).unwrap();
let actual = raw::Pair::deserialize(&expected.serialize()).unwrap();
assert_eq!(expected, actual);
}

View File

@ -10,12 +10,12 @@ use crate::prelude::*;
use core::fmt;
use core::convert::TryFrom;
use crate::io;
use crate::io::{self, Cursor};
use crate::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
use crate::hashes::hex;
use crate::psbt::Error;
use super::serialize::Serialize;
use super::serialize::{Serialize, Deserialize};
/// A PSBT key in its raw byte form.
#[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)]
@ -71,8 +71,8 @@ impl fmt::Display for Key {
}
}
impl Decodable for Key {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
impl Key {
pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
if byte_size == 0 {
@ -124,10 +124,17 @@ impl Serialize for Pair {
}
}
impl Decodable for Pair {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
impl Deserialize for Pair {
fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
let mut decoder = Cursor::new(bytes);
Pair::decode(&mut decoder)
}
}
impl Pair {
pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(Pair {
key: Decodable::consensus_decode(r)?,
key: Key::decode(r)?,
value: Decodable::consensus_decode(r)?,
})
}

View File

@ -34,18 +34,11 @@ pub(crate) trait Serialize {
}
/// A trait for deserializing a value from raw data in PSBT key-value maps.
pub trait Deserialize: Sized {
pub(crate) trait Deserialize: Sized {
/// Deserialize a value from raw data.
fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error>;
}
impl Serialize for Psbt {
/// Serialize a value as raw binary data.
fn serialize(&self) -> Vec<u8> {
self.serialize()
}
}
impl PartiallySignedTransaction {
/// Serialize a value as bytes in hex.
pub fn serialize_hex(&self) -> String {
@ -89,28 +82,28 @@ impl PartiallySignedTransaction {
let mut d = bytes.get(5..).ok_or(Error::NoMorePairs)?;
let mut global = PartiallySignedTransaction::consensus_decode_global(&mut d)?;
let mut global = Psbt::decode_global(&mut d)?;
global.unsigned_tx_checks()?;
let inputs: Vec<Input> = {
let inputs_len: usize = (&global.unsigned_tx.input).len();
let inputs_len: usize = (global.unsigned_tx.input).len();
let mut inputs: Vec<Input> = Vec::with_capacity(inputs_len);
for _ in 0..inputs_len {
inputs.push(Decodable::consensus_decode(&mut d)?);
inputs.push(Input::decode(&mut d)?);
}
inputs
};
let outputs: Vec<Output> = {
let outputs_len: usize = (&global.unsigned_tx.output).len();
let outputs_len: usize = (global.unsigned_tx.output).len();
let mut outputs: Vec<Output> = Vec::with_capacity(outputs_len);
for _ in 0..outputs_len {
outputs.push(Decodable::consensus_decode(&mut d)?);
outputs.push(Output::decode(&mut d)?);
}
outputs

View File

@ -424,7 +424,7 @@ fn finalize_psbt(mut psbt: Psbt) -> Psbt {
.push_opcode(OP_0) // OP_CHECKMULTISIG bug pops +1 value when evaluating so push OP_0.
.push_slice(&sigs[0].to_vec())
.push_slice(&sigs[1].to_vec())
.push_slice(&psbt.inputs[0].redeem_script.clone().unwrap().as_bytes())
.push_slice(psbt.inputs[0].redeem_script.clone().unwrap().as_bytes())
.into_script();
psbt.inputs[0].final_script_sig = Some(script_sig);
@ -437,7 +437,7 @@ fn finalize_psbt(mut psbt: Psbt) -> Psbt {
// Input 1: SegWit UTXO
let script_sig = script::Builder::new()
.push_slice(&psbt.inputs[1].redeem_script.clone().unwrap().as_bytes())
.push_slice(psbt.inputs[1].redeem_script.clone().unwrap().as_bytes())
.into_script();
psbt.inputs[1].final_script_sig = Some(script_sig);
@ -448,7 +448,7 @@ fn finalize_psbt(mut psbt: Psbt) -> Psbt {
script_witness.push([]); // Push 0x00 to the stack.
script_witness.push(&sigs[1].to_vec());
script_witness.push(&sigs[0].to_vec());
script_witness.push(&psbt.inputs[1].witness_script.clone().unwrap().as_bytes());
script_witness.push(psbt.inputs[1].witness_script.clone().unwrap().as_bytes());
script_witness
};