Deserialize Psbt fields, don't consensus_encode
This commit is contained in:
parent
c1dd6ad8a2
commit
c4363e5ba1
|
@ -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>) => {
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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>>,
|
||||||
|
|
|
@ -322,5 +322,4 @@ impl Map for Output {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_psbtmap_serialize!(Output);
|
impl_psbtmap_ser_de_serialize!(Output);
|
||||||
impl_psbtmap_consensus_decoding!(Output);
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue