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