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) => { ($thing:ty) => {
impl $crate::consensus::Decodable for $thing { impl $crate::psbt::serialize::Deserialize for $thing {
fn consensus_decode<R: $crate::io::Read + ?Sized>( 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, r: &mut R,
) -> Result<Self, $crate::consensus::encode::Error> { ) -> Result<Self, $crate::consensus::encode::Error> {
let mut rv: Self = core::default::Default::default(); let mut rv: Self = core::default::Default::default();
loop { loop {
match $crate::consensus::Decodable::consensus_decode(r) { match $crate::psbt::raw::Pair::decode(r) {
Ok(pair) => rv.insert_pair(pair)?, Ok(pair) => rv.insert_pair(pair)?,
Err($crate::consensus::encode::Error::Psbt($crate::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),
@ -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] #[rustfmt::skip]
macro_rules! impl_psbt_insert_pair { 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>) => {

View File

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

View File

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

View File

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

View File

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

View File

@ -10,12 +10,12 @@ use crate::prelude::*;
use core::fmt; use core::fmt;
use core::convert::TryFrom; 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::consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
use crate::hashes::hex; use crate::hashes::hex;
use crate::psbt::Error; use crate::psbt::Error;
use super::serialize::Serialize; use super::serialize::{Serialize, Deserialize};
/// 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)]
@ -71,8 +71,8 @@ impl fmt::Display for Key {
} }
} }
impl Decodable for Key { impl Key {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> { pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?; let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
if byte_size == 0 { if byte_size == 0 {
@ -124,10 +124,17 @@ impl Serialize for Pair {
} }
} }
impl Decodable for Pair { impl Deserialize for Pair {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> { 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 { Ok(Pair {
key: Decodable::consensus_decode(r)?, key: Key::decode(r)?,
value: Decodable::consensus_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. /// 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. /// Deserialize a value from raw data.
fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error>; 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 { impl PartiallySignedTransaction {
/// Serialize a value as bytes in hex. /// Serialize a value as bytes in hex.
pub fn serialize_hex(&self) -> String { pub fn serialize_hex(&self) -> String {
@ -89,28 +82,28 @@ impl PartiallySignedTransaction {
let mut d = bytes.get(5..).ok_or(Error::NoMorePairs)?; 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()?; global.unsigned_tx_checks()?;
let inputs: Vec<Input> = { 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); let mut inputs: Vec<Input> = Vec::with_capacity(inputs_len);
for _ in 0..inputs_len { for _ in 0..inputs_len {
inputs.push(Decodable::consensus_decode(&mut d)?); inputs.push(Input::decode(&mut d)?);
} }
inputs inputs
}; };
let outputs: Vec<Output> = { 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); let mut outputs: Vec<Output> = Vec::with_capacity(outputs_len);
for _ in 0..outputs_len { for _ in 0..outputs_len {
outputs.push(Decodable::consensus_decode(&mut d)?); outputs.push(Output::decode(&mut d)?);
} }
outputs 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_opcode(OP_0) // OP_CHECKMULTISIG bug pops +1 value when evaluating so push OP_0.
.push_slice(&sigs[0].to_vec()) .push_slice(&sigs[0].to_vec())
.push_slice(&sigs[1].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(); .into_script();
psbt.inputs[0].final_script_sig = Some(script_sig); psbt.inputs[0].final_script_sig = Some(script_sig);
@ -437,7 +437,7 @@ fn finalize_psbt(mut psbt: Psbt) -> Psbt {
// Input 1: SegWit UTXO // Input 1: SegWit UTXO
let script_sig = script::Builder::new() 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(); .into_script();
psbt.inputs[1].final_script_sig = Some(script_sig); 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([]); // Push 0x00 to the stack.
script_witness.push(&sigs[1].to_vec()); script_witness.push(&sigs[1].to_vec());
script_witness.push(&sigs[0].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 script_witness
}; };