bitcoin/util/psbt/
raw.rs

1// Rust Bitcoin Library
2// Written by
3//   The Rust Bitcoin developers
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! # Raw PSBT Key-Value Pairs
16//!
17//! Raw PSBT key-value pairs as defined at
18//! https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki.
19
20use std::{fmt, io};
21
22use consensus::encode::{self, ReadExt, WriteExt, Decodable, Encodable, VarInt, serialize, deserialize, MAX_VEC_SIZE};
23use hashes::hex;
24use util::psbt::Error;
25
26/// A PSBT key in its raw byte form.
27#[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29pub struct Key {
30    /// The type of this PSBT key.
31    pub type_value: u8,
32    /// The key itself in raw byte form.
33    #[cfg_attr(feature = "serde", serde(with = "::serde_utils::hex_bytes"))]
34    pub key: Vec<u8>,
35}
36
37/// A PSBT key-value pair in its raw byte form.
38#[derive(Debug, PartialEq)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub struct Pair {
41    /// The key of this key-value pair.
42    pub key: Key,
43    /// The value of this key-value pair in raw byte form.
44    #[cfg_attr(feature = "serde", serde(with = "::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))]
55pub struct ProprietaryKey<Subtype = ProprietaryType> where Subtype: Copy + From<u8> + Into<u8> {
56    /// Proprietary type prefix used for grouping together keys under some
57    /// application and avoid namespace collision
58    #[cfg_attr(feature = "serde", serde(with = "::serde_utils::hex_bytes"))]
59    pub prefix: Vec<u8>,
60    /// Custom proprietary subtype
61    pub subtype: Subtype,
62    /// Additional key bytes (like serialized public key data etc)
63    #[cfg_attr(feature = "serde", serde(with = "::serde_utils::hex_bytes"))]
64    pub key: Vec<u8>,
65}
66
67impl fmt::Display for Key {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        write!(f, "type: {:#x}, key: ", self.type_value)?;
70        hex::format_hex(&self.key[..], f)
71    }
72}
73
74impl Decodable for Key {
75    fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
76        let VarInt(byte_size): VarInt = Decodable::consensus_decode(&mut d)?;
77
78        if byte_size == 0 {
79            return Err(Error::NoMorePairs.into());
80        }
81
82        let key_byte_size: u64 = byte_size - 1;
83
84        if key_byte_size > MAX_VEC_SIZE as u64 {
85            return Err(encode::Error::OversizedVectorAllocation {
86                requested: key_byte_size as usize,
87                max: MAX_VEC_SIZE,
88            })
89        }
90
91        let type_value: u8 = Decodable::consensus_decode(&mut d)?;
92
93        let mut key = Vec::with_capacity(key_byte_size as usize);
94        for _ in 0..key_byte_size {
95            key.push(Decodable::consensus_decode(&mut d)?);
96        }
97
98        Ok(Key {
99            type_value: type_value,
100            key: key,
101        })
102    }
103}
104
105impl Encodable for Key {
106    fn consensus_encode<S: io::Write>(
107        &self,
108        mut s: S,
109    ) -> Result<usize, io::Error> {
110        let mut len = 0;
111        len += VarInt((self.key.len() + 1) as u64).consensus_encode(&mut s)?;
112
113        len += self.type_value.consensus_encode(&mut s)?;
114
115        for key in &self.key {
116            len += key.consensus_encode(&mut s)?
117        }
118
119        Ok(len)
120    }
121}
122
123impl Encodable for Pair {
124    fn consensus_encode<S: io::Write>(
125        &self,
126        mut s: S,
127    ) -> Result<usize, io::Error> {
128        let len = self.key.consensus_encode(&mut s)?;
129        Ok(len + self.value.consensus_encode(s)?)
130    }
131}
132
133impl Decodable for Pair {
134    fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
135        Ok(Pair {
136            key: Decodable::consensus_decode(&mut d)?,
137            value: Decodable::consensus_decode(d)?,
138        })
139    }
140}
141
142impl<Subtype> Encodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
143    fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, io::Error> {
144        let mut len = self.prefix.consensus_encode(&mut e)? + 1;
145        e.emit_u8(self.subtype.into())?;
146        len += e.write(&self.key)?;
147        Ok(len)
148    }
149}
150
151impl<Subtype> Decodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
152    fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
153        let prefix = Vec::<u8>::consensus_decode(&mut d)?;
154        let mut key = vec![];
155        let subtype = Subtype::from(d.read_u8()?);
156        d.read_to_end(&mut key)?;
157
158        Ok(ProprietaryKey {
159            prefix,
160            subtype,
161            key
162        })
163    }
164}
165
166impl<Subtype> ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
167    /// Constructs [ProprietaryKey] from [Key]; returns
168    /// [Error::InvalidProprietaryKey] if `key` do not starts with 0xFC byte
169    pub fn from_key(key: Key) -> Result<Self, Error> {
170        if key.type_value != 0xFC {
171            return Err(Error::InvalidProprietaryKey)
172        }
173
174        Ok(deserialize(&key.key)?)
175    }
176
177    /// Constructs full [Key] corresponding to this proprietary key type
178    pub fn to_key(&self) -> Key {
179        Key {
180            type_value: 0xFC,
181            key: serialize(self)
182        }
183    }
184}