Skip to main content

psbt_v2/
raw.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Raw PSBT key-value pairs.
4//!
5//! [BIP-174] defines the following:
6//!
7//! - `<keypair> := <key> <value>`
8//! - `<key> := <keylen> <keytype> <keydata>`
9//!
10//! [BIP-174]: <https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki>
11
12use core::convert::TryFrom;
13use core::fmt;
14
15use bitcoin::consensus::encode as consensus;
16use bitcoin::consensus::encode::{
17    deserialize, serialize, Decodable, Encodable, ReadExt, VarInt, WriteExt, MAX_VEC_SIZE,
18};
19use bitcoin::hex::DisplayHex;
20
21use crate::io::{self, Write};
22use crate::prelude::*;
23use crate::serialize;
24use crate::serialize::{Deserialize, Serialize};
25
26/// A PSBT key-value pair in its raw byte form.
27///
28/// - `<keypair> := <key> <value>`
29#[derive(Debug, PartialEq, Eq)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31pub struct Pair {
32    /// The key of this key-value pair.
33    pub key: Key,
34    /// The value of this key-value pair in raw byte form.
35    ///
36    /// - `<value> := <valuelen> <valuedata>`
37    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))]
38    pub value: Vec<u8>,
39}
40
41impl Pair {
42    pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, serialize::Error> {
43        Ok(Pair { key: Key::decode(r)?, value: Decodable::consensus_decode(r)? })
44    }
45}
46
47impl fmt::Display for Key {
48    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49        write!(f, "type: {:#x}, key: {:x}", self.type_value, self.key.as_hex())
50    }
51}
52
53impl Serialize for Pair {
54    fn serialize(&self) -> Vec<u8> {
55        let mut buf = Vec::new();
56        buf.extend(self.key.serialize());
57        // <value> := <valuelen> <valuedata>
58        self.value.consensus_encode(&mut buf).unwrap();
59        buf
60    }
61}
62
63impl Deserialize for Pair {
64    fn deserialize(bytes: &[u8]) -> Result<Self, serialize::Error> {
65        let mut decoder = bytes;
66        Pair::decode(&mut decoder)
67    }
68}
69
70/// The key of a key-value PSBT pair, in its raw byte form.
71///
72/// - `<key> := <keylen> <keytype> <keydata>`
73///
74/// We do not carry the `keylen` around, we just create the `VarInt` length when serializing and
75/// deserializing.
76#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
77#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
78pub struct Key {
79    /// The `keytype` of this PSBT map key (`keytype`).
80    pub type_value: u8,
81    /// The `keydata` itself in raw byte form.
82    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))]
83    pub key: Vec<u8>,
84}
85
86impl Key {
87    pub(crate) fn decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, serialize::Error> {
88        let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
89
90        if byte_size == 0 {
91            return Err(serialize::Error::NoMorePairs);
92        }
93
94        let key_byte_size: u64 = byte_size - 1;
95
96        if key_byte_size > MAX_VEC_SIZE as u64 {
97            return Err(consensus::Error::OversizedVectorAllocation {
98                requested: key_byte_size as usize,
99                max: MAX_VEC_SIZE,
100            }
101            .into());
102        }
103
104        let type_value: u8 = Decodable::consensus_decode(r)?;
105
106        let mut key = Vec::with_capacity(key_byte_size as usize);
107        for _ in 0..key_byte_size {
108            key.push(Decodable::consensus_decode(r)?);
109        }
110
111        Ok(Key { type_value, key })
112    }
113}
114
115impl Serialize for Key {
116    fn serialize(&self) -> Vec<u8> {
117        let mut buf = Vec::new();
118        VarInt::from(self.key.len() + 1)
119            .consensus_encode(&mut buf)
120            .expect("in-memory writers don't error");
121
122        self.type_value.consensus_encode(&mut buf).expect("in-memory writers don't error");
123
124        for key in &self.key {
125            key.consensus_encode(&mut buf).expect("in-memory writers don't error");
126        }
127
128        buf
129    }
130}
131
132/// Default implementation for proprietary key subtyping
133pub type ProprietaryType = u8;
134
135/// Proprietary keys (i.e. keys starting with 0xFC byte) with their internal
136/// structure according to BIP 174.
137#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
138#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
139pub struct ProprietaryKey<Subtype = ProprietaryType>
140where
141    Subtype: Copy + From<u8> + Into<u8>,
142{
143    /// Proprietary type prefix used for grouping together keys under some
144    /// application and avoid namespace collision
145    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))]
146    pub prefix: Vec<u8>,
147    /// Custom proprietary subtype
148    pub subtype: Subtype,
149    /// Additional key bytes (like serialized public key data etc)
150    #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))]
151    pub key: Vec<u8>,
152}
153
154impl<Subtype> ProprietaryKey<Subtype>
155where
156    Subtype: Copy + From<u8> + Into<u8>,
157{
158    /// Constructs full [Key] corresponding to this proprietary key type
159    pub fn to_key(&self) -> Key { Key { type_value: 0xFC, key: serialize(self) } }
160}
161
162impl<Subtype> TryFrom<Key> for ProprietaryKey<Subtype>
163where
164    Subtype: Copy + From<u8> + Into<u8>,
165{
166    type Error = serialize::Error;
167
168    /// Constructs a [`ProprietaryKey`] from a [`Key`].
169    ///
170    /// # Errors
171    ///
172    /// Returns [`serialize::Error::InvalidProprietaryKey`] if `key` does not start with `0xFC`.
173    fn try_from(key: Key) -> Result<Self, Self::Error> {
174        if key.type_value != 0xFC {
175            return Err(serialize::Error::InvalidProprietaryKey);
176        }
177
178        Ok(deserialize(&key.key)?)
179    }
180}
181
182impl<Subtype> Encodable for ProprietaryKey<Subtype>
183where
184    Subtype: Copy + From<u8> + Into<u8>,
185{
186    fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
187        let mut len = self.prefix.consensus_encode(w)? + 1;
188        w.emit_u8(self.subtype.into())?;
189        w.write_all(&self.key)?;
190        len += self.key.len();
191        Ok(len)
192    }
193}
194
195impl<Subtype> Decodable for ProprietaryKey<Subtype>
196where
197    Subtype: Copy + From<u8> + Into<u8>,
198{
199    fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, consensus::Error> {
200        let prefix = Vec::<u8>::consensus_decode(r)?;
201        let subtype = Subtype::from(r.read_u8()?);
202
203        // The limit is a DOS protection mechanism the exact value is not
204        // important, 1024 bytes is bigger than any key should be.
205        let mut key = vec![];
206        let _ = r.read_to_limit(&mut key, 1024)?;
207
208        Ok(ProprietaryKey { prefix, subtype, key })
209    }
210}