psbt_v0/
raw.rs

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