Merge rust-bitcoin/rust-bitcoin#2906: psbt: Encode keytype as a compact size unsigned integer
2f656f77ba
psbt: Use u64 for key type (Tobin C. Harding) Pull request description: Currently we use `u8` for key type but it was pointed out that we should be using a `u64` and encoding it as a compact type. The reason our code works now is because the compact type encoding for a `u8` (less than This breaks the `serde` impl, as shown by changes to the regression tests, Fix: #2891 ACKs for top commit: apoelstra: ACK2f656f77ba
successfully ran local tests Tree-SHA512: ce5fe46b54cb724a0b0f9f874c037e5b5d344e5d3c380f9cdb3fdb5cbc5e31e4e32c229f5f2f72547823238934f6b0c3640c2c2ce79d98aa57bac509d130cb82
This commit is contained in:
commit
88af71c81f
|
@ -12,13 +12,13 @@ use crate::psbt::{raw, Error, Psbt};
|
|||
use crate::transaction::Transaction;
|
||||
|
||||
/// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00
|
||||
const PSBT_GLOBAL_UNSIGNED_TX: u8 = 0x00;
|
||||
const PSBT_GLOBAL_UNSIGNED_TX: u64 = 0x00;
|
||||
/// Type: Extended Public Key PSBT_GLOBAL_XPUB = 0x01
|
||||
const PSBT_GLOBAL_XPUB: u8 = 0x01;
|
||||
const PSBT_GLOBAL_XPUB: u64 = 0x01;
|
||||
/// Type: Version Number PSBT_GLOBAL_VERSION = 0xFB
|
||||
const PSBT_GLOBAL_VERSION: u8 = 0xFB;
|
||||
const PSBT_GLOBAL_VERSION: u64 = 0xFB;
|
||||
/// Type: Proprietary Use Type PSBT_GLOBAL_PROPRIETARY = 0xFC
|
||||
const PSBT_GLOBAL_PROPRIETARY: u8 = 0xFC;
|
||||
const PSBT_GLOBAL_PROPRIETARY: u64 = 0xFC;
|
||||
|
||||
impl Map for Psbt {
|
||||
fn get_pairs(&self) -> Vec<raw::Pair> {
|
||||
|
|
|
@ -23,45 +23,45 @@ use crate::transaction::{Transaction, TxOut};
|
|||
use crate::witness::Witness;
|
||||
|
||||
/// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00
|
||||
const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
|
||||
const PSBT_IN_NON_WITNESS_UTXO: u64 = 0x00;
|
||||
/// Type: Witness UTXO PSBT_IN_WITNESS_UTXO = 0x01
|
||||
const PSBT_IN_WITNESS_UTXO: u8 = 0x01;
|
||||
const PSBT_IN_WITNESS_UTXO: u64 = 0x01;
|
||||
/// Type: Partial Signature PSBT_IN_PARTIAL_SIG = 0x02
|
||||
const PSBT_IN_PARTIAL_SIG: u8 = 0x02;
|
||||
const PSBT_IN_PARTIAL_SIG: u64 = 0x02;
|
||||
/// Type: Sighash Type PSBT_IN_SIGHASH_TYPE = 0x03
|
||||
const PSBT_IN_SIGHASH_TYPE: u8 = 0x03;
|
||||
const PSBT_IN_SIGHASH_TYPE: u64 = 0x03;
|
||||
/// Type: Redeem Script PSBT_IN_REDEEM_SCRIPT = 0x04
|
||||
const PSBT_IN_REDEEM_SCRIPT: u8 = 0x04;
|
||||
const PSBT_IN_REDEEM_SCRIPT: u64 = 0x04;
|
||||
/// Type: Witness Script PSBT_IN_WITNESS_SCRIPT = 0x05
|
||||
const PSBT_IN_WITNESS_SCRIPT: u8 = 0x05;
|
||||
const PSBT_IN_WITNESS_SCRIPT: u64 = 0x05;
|
||||
/// Type: BIP 32 Derivation Path PSBT_IN_BIP32_DERIVATION = 0x06
|
||||
const PSBT_IN_BIP32_DERIVATION: u8 = 0x06;
|
||||
const PSBT_IN_BIP32_DERIVATION: u64 = 0x06;
|
||||
/// Type: Finalized scriptSig PSBT_IN_FINAL_SCRIPTSIG = 0x07
|
||||
const PSBT_IN_FINAL_SCRIPTSIG: u8 = 0x07;
|
||||
const PSBT_IN_FINAL_SCRIPTSIG: u64 = 0x07;
|
||||
/// Type: Finalized scriptWitness PSBT_IN_FINAL_SCRIPTWITNESS = 0x08
|
||||
const PSBT_IN_FINAL_SCRIPTWITNESS: u8 = 0x08;
|
||||
const PSBT_IN_FINAL_SCRIPTWITNESS: u64 = 0x08;
|
||||
/// Type: RIPEMD160 preimage PSBT_IN_RIPEMD160 = 0x0a
|
||||
const PSBT_IN_RIPEMD160: u8 = 0x0a;
|
||||
const PSBT_IN_RIPEMD160: u64 = 0x0a;
|
||||
/// Type: SHA256 preimage PSBT_IN_SHA256 = 0x0b
|
||||
const PSBT_IN_SHA256: u8 = 0x0b;
|
||||
const PSBT_IN_SHA256: u64 = 0x0b;
|
||||
/// Type: HASH160 preimage PSBT_IN_HASH160 = 0x0c
|
||||
const PSBT_IN_HASH160: u8 = 0x0c;
|
||||
const PSBT_IN_HASH160: u64 = 0x0c;
|
||||
/// Type: HASH256 preimage PSBT_IN_HASH256 = 0x0d
|
||||
const PSBT_IN_HASH256: u8 = 0x0d;
|
||||
const PSBT_IN_HASH256: u64 = 0x0d;
|
||||
/// Type: Taproot Signature in Key Spend PSBT_IN_TAP_KEY_SIG = 0x13
|
||||
const PSBT_IN_TAP_KEY_SIG: u8 = 0x13;
|
||||
const PSBT_IN_TAP_KEY_SIG: u64 = 0x13;
|
||||
/// Type: Taproot Signature in Script Spend PSBT_IN_TAP_SCRIPT_SIG = 0x14
|
||||
const PSBT_IN_TAP_SCRIPT_SIG: u8 = 0x14;
|
||||
const PSBT_IN_TAP_SCRIPT_SIG: u64 = 0x14;
|
||||
/// Type: Taproot Leaf Script PSBT_IN_TAP_LEAF_SCRIPT = 0x14
|
||||
const PSBT_IN_TAP_LEAF_SCRIPT: u8 = 0x15;
|
||||
const PSBT_IN_TAP_LEAF_SCRIPT: u64 = 0x15;
|
||||
/// Type: Taproot Key BIP 32 Derivation Path PSBT_IN_TAP_BIP32_DERIVATION = 0x16
|
||||
const PSBT_IN_TAP_BIP32_DERIVATION: u8 = 0x16;
|
||||
const PSBT_IN_TAP_BIP32_DERIVATION: u64 = 0x16;
|
||||
/// Type: Taproot Internal Key PSBT_IN_TAP_INTERNAL_KEY = 0x17
|
||||
const PSBT_IN_TAP_INTERNAL_KEY: u8 = 0x17;
|
||||
const PSBT_IN_TAP_INTERNAL_KEY: u64 = 0x17;
|
||||
/// Type: Taproot Merkle Root PSBT_IN_TAP_MERKLE_ROOT = 0x18
|
||||
const PSBT_IN_TAP_MERKLE_ROOT: u8 = 0x18;
|
||||
const PSBT_IN_TAP_MERKLE_ROOT: u64 = 0x18;
|
||||
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
||||
const PSBT_IN_PROPRIETARY: u8 = 0xFC;
|
||||
const PSBT_IN_PROPRIETARY: u64 = 0xFC;
|
||||
|
||||
/// A key-value map for an input of the corresponding index in the unsigned
|
||||
/// transaction.
|
||||
|
|
|
@ -10,19 +10,19 @@ use crate::script::ScriptBuf;
|
|||
use crate::taproot::{TapLeafHash, TapTree};
|
||||
|
||||
/// Type: Redeem ScriptBuf PSBT_OUT_REDEEM_SCRIPT = 0x00
|
||||
const PSBT_OUT_REDEEM_SCRIPT: u8 = 0x00;
|
||||
const PSBT_OUT_REDEEM_SCRIPT: u64 = 0x00;
|
||||
/// Type: Witness ScriptBuf PSBT_OUT_WITNESS_SCRIPT = 0x01
|
||||
const PSBT_OUT_WITNESS_SCRIPT: u8 = 0x01;
|
||||
const PSBT_OUT_WITNESS_SCRIPT: u64 = 0x01;
|
||||
/// Type: BIP 32 Derivation Path PSBT_OUT_BIP32_DERIVATION = 0x02
|
||||
const PSBT_OUT_BIP32_DERIVATION: u8 = 0x02;
|
||||
const PSBT_OUT_BIP32_DERIVATION: u64 = 0x02;
|
||||
/// Type: Taproot Internal Key PSBT_OUT_TAP_INTERNAL_KEY = 0x05
|
||||
const PSBT_OUT_TAP_INTERNAL_KEY: u8 = 0x05;
|
||||
const PSBT_OUT_TAP_INTERNAL_KEY: u64 = 0x05;
|
||||
/// Type: Taproot Tree PSBT_OUT_TAP_TREE = 0x06
|
||||
const PSBT_OUT_TAP_TREE: u8 = 0x06;
|
||||
const PSBT_OUT_TAP_TREE: u64 = 0x06;
|
||||
/// Type: Taproot Key BIP 32 Derivation Path PSBT_OUT_TAP_BIP32_DERIVATION = 0x07
|
||||
const PSBT_OUT_TAP_BIP32_DERIVATION: u8 = 0x07;
|
||||
const PSBT_OUT_TAP_BIP32_DERIVATION: u64 = 0x07;
|
||||
/// Type: Proprietary Use Type PSBT_IN_PROPRIETARY = 0xFC
|
||||
const PSBT_OUT_PROPRIETARY: u8 = 0xFC;
|
||||
const PSBT_OUT_PROPRIETARY: u64 = 0xFC;
|
||||
|
||||
/// A key-value map for an output of the corresponding index in the unsigned
|
||||
/// transaction.
|
||||
|
|
|
@ -1440,7 +1440,7 @@ mod tests {
|
|||
#[test]
|
||||
fn serialize_then_deserialize_psbtkvpair() {
|
||||
let expected = raw::Pair {
|
||||
key: raw::Key { type_value: 0u8, key_data: vec![42u8, 69u8] },
|
||||
key: raw::Key { type_value: 0u64, key_data: vec![42u8, 69u8] },
|
||||
value: vec![69u8, 42u8, 4u8],
|
||||
};
|
||||
|
||||
|
@ -1850,7 +1850,7 @@ mod tests {
|
|||
|
||||
let mut unknown: BTreeMap<raw::Key, Vec<u8>> = BTreeMap::new();
|
||||
let key: raw::Key =
|
||||
raw::Key { type_value: 0x0fu8, key_data: hex!("010203040506070809") };
|
||||
raw::Key { type_value: 0x0fu64, key_data: hex!("010203040506070809") };
|
||||
let value: Vec<u8> = hex!("0102030405060708090a0b0c0d0e0f");
|
||||
|
||||
unknown.insert(key, value);
|
||||
|
@ -2080,7 +2080,7 @@ mod tests {
|
|||
fn serialize_and_deserialize_proprietary() {
|
||||
let mut psbt: Psbt = hex_psbt("70736274ff0100a00200000002ab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40000000000feffffffab0949a08c5af7c49b8212f417e2f15ab3f5c33dcf153821a8139f877a5b7be40100000000feffffff02603bea0b000000001976a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac8e240000000000001976a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac000000000001076a47304402204759661797c01b036b25928948686218347d89864b719e1f7fcf57d1e511658702205309eabf56aa4d8891ffd111fdf1336f3a29da866d7f8486d75546ceedaf93190121035cdc61fc7ba971c0b501a646a2a83b102cb43881217ca682dc86e2d73fa882920001012000e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787010416001485d13537f2e265405a34dbafa9e3dda01fb82308000000").unwrap();
|
||||
psbt.proprietary.insert(
|
||||
raw::ProprietaryKey { prefix: b"test".to_vec(), subtype: 0u8, key: b"test".to_vec() },
|
||||
raw::ProprietaryKey { prefix: b"test".to_vec(), subtype: 0u64, key: b"test".to_vec() },
|
||||
b"test".to_vec(),
|
||||
);
|
||||
assert!(!psbt.proprietary.is_empty());
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
use core::fmt;
|
||||
|
||||
use internals::ToU64 as _;
|
||||
use internals::{ToU64 as _};
|
||||
use io::{BufRead, Write};
|
||||
|
||||
use super::serialize::{Deserialize, Serialize};
|
||||
use crate::consensus::encode::{
|
||||
self, deserialize, serialize, Decodable, Encodable, ReadExt, WriteExt, MAX_VEC_SIZE,
|
||||
self, deserialize, serialize, Decodable, Encodable, MAX_VEC_SIZE, ReadExt, WriteExt,
|
||||
};
|
||||
use crate::prelude::{DisplayHex, Vec};
|
||||
use crate::psbt::Error;
|
||||
|
@ -24,7 +24,7 @@ use crate::psbt::Error;
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Key {
|
||||
/// The type of this PSBT key.
|
||||
pub type_value: u8,
|
||||
pub type_value: u64, // Encoded as a compact size.
|
||||
/// The key data itself in raw byte form.
|
||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))]
|
||||
pub key_data: Vec<u8>,
|
||||
|
@ -44,7 +44,7 @@ pub struct Pair {
|
|||
}
|
||||
|
||||
/// Default implementation for proprietary key subtyping
|
||||
pub type ProprietaryType = u8;
|
||||
pub type ProprietaryType = u64;
|
||||
|
||||
/// Proprietary keys (i.e. keys starting with 0xFC byte) with their internal
|
||||
/// structure according to BIP 174.
|
||||
|
@ -52,7 +52,7 @@ pub type ProprietaryType = u8;
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct ProprietaryKey<Subtype = ProprietaryType>
|
||||
where
|
||||
Subtype: Copy + From<u8> + Into<u8>,
|
||||
Subtype: Copy + From<u64> + Into<u64>,
|
||||
{
|
||||
/// Proprietary type prefix used for grouping together keys under some
|
||||
/// application and avoid namespace collision
|
||||
|
@ -89,7 +89,7 @@ impl Key {
|
|||
.into());
|
||||
}
|
||||
|
||||
let type_value: u8 = Decodable::consensus_decode(r)?;
|
||||
let type_value = r.read_compact_size()?;
|
||||
|
||||
let mut key_data = Vec::with_capacity(key_byte_size as usize);
|
||||
for _ in 0..key_byte_size {
|
||||
|
@ -105,7 +105,7 @@ impl Serialize for Key {
|
|||
let mut buf = Vec::new();
|
||||
buf.emit_compact_size(self.key_data.len() + 1).expect("in-memory writers don't error");
|
||||
|
||||
self.type_value.consensus_encode(&mut buf).expect("in-memory writers don't error");
|
||||
buf.emit_compact_size(self.type_value).expect("in-memory writers don't error");
|
||||
|
||||
for key in &self.key_data {
|
||||
key.consensus_encode(&mut buf).expect("in-memory writers don't error");
|
||||
|
@ -140,11 +140,11 @@ impl Pair {
|
|||
|
||||
impl<Subtype> Encodable for ProprietaryKey<Subtype>
|
||||
where
|
||||
Subtype: Copy + From<u8> + Into<u8>,
|
||||
Subtype: Copy + From<u64> + Into<u64>,
|
||||
{
|
||||
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||
let mut len = self.prefix.consensus_encode(w)? + 1;
|
||||
w.emit_u8(self.subtype.into())?;
|
||||
w.emit_compact_size(self.subtype.into())?;
|
||||
w.write_all(&self.key)?;
|
||||
len += self.key.len();
|
||||
Ok(len)
|
||||
|
@ -153,11 +153,11 @@ where
|
|||
|
||||
impl<Subtype> Decodable for ProprietaryKey<Subtype>
|
||||
where
|
||||
Subtype: Copy + From<u8> + Into<u8>,
|
||||
Subtype: Copy + From<u64> + Into<u64>,
|
||||
{
|
||||
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||
let prefix = Vec::<u8>::consensus_decode(r)?;
|
||||
let subtype = Subtype::from(r.read_u8()?);
|
||||
let subtype = Subtype::from(r.read_compact_size()?);
|
||||
|
||||
// The limit is a DOS protection mechanism the exact value is not
|
||||
// important, 1024 bytes is bigger than any key should be.
|
||||
|
@ -170,7 +170,7 @@ where
|
|||
|
||||
impl<Subtype> ProprietaryKey<Subtype>
|
||||
where
|
||||
Subtype: Copy + From<u8> + Into<u8>,
|
||||
Subtype: Copy + From<u64> + Into<u64>,
|
||||
{
|
||||
/// Constructs full [Key] corresponding to this proprietary key type
|
||||
pub fn to_key(&self) -> Key { Key { type_value: 0xFC, key_data: serialize(self) } }
|
||||
|
@ -178,7 +178,7 @@ where
|
|||
|
||||
impl<Subtype> TryFrom<Key> for ProprietaryKey<Subtype>
|
||||
where
|
||||
Subtype: Copy + From<u8> + Into<u8>,
|
||||
Subtype: Copy + From<u64> + Into<u64>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -325,7 +325,7 @@ fn serde_regression_psbt() {
|
|||
#[test]
|
||||
fn serde_regression_raw_pair() {
|
||||
let pair = Pair {
|
||||
key: Key { type_value: 1u8, key_data: vec![0u8, 1u8, 2u8, 3u8] },
|
||||
key: Key { type_value: 1u64, key_data: vec![0u8, 1u8, 2u8, 3u8] },
|
||||
value: vec![0u8, 1u8, 2u8, 3u8],
|
||||
};
|
||||
let got = serialize(&pair).unwrap();
|
||||
|
@ -337,7 +337,7 @@ fn serde_regression_raw_pair() {
|
|||
fn serde_regression_proprietary_key() {
|
||||
let key = ProprietaryKey {
|
||||
prefix: vec![0u8, 1u8, 2u8, 3u8],
|
||||
subtype: 1u8,
|
||||
subtype: 1u64,
|
||||
key: vec![0u8, 1u8, 2u8, 3u8],
|
||||
};
|
||||
let got = serialize(&key).unwrap();
|
||||
|
|
Loading…
Reference in New Issue