1use std::collections::BTreeMap;
16use std::collections::btree_map::Entry;
17use std::io::{self, Cursor, Read};
18use std::cmp;
19use secp256k1::{ContextFlag, Secp256k1};
20
21use blockdata::transaction::Transaction;
22use consensus::{encode, Encodable, Decodable};
23use util::psbt::map::Map;
24use util::psbt::raw;
25use util::psbt;
26use util::psbt::Error;
27use util::endian::u32_to_array_le;
28use util::bip32::{ExtendedPubKey, KeySource, Fingerprint, DerivationPath, ChildNumber};
29
30const PSBT_GLOBAL_UNSIGNED_TX: u8 = 0x00;
32const PSBT_GLOBAL_XPUB: u8 = 0x01;
34const PSBT_GLOBAL_VERSION: u8 = 0xFB;
36const PSBT_GLOBAL_PROPRIETARY: u8 = 0xFC;
38
39#[derive(Clone, Debug, PartialEq)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42pub struct Global {
43 pub unsigned_tx: Transaction,
46 pub version: u32,
48 pub xpub: BTreeMap<ExtendedPubKey, KeySource>,
51 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
53 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
54 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
56 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
57}
58
59impl Global {
60 pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, psbt::Error> {
62 for txin in &tx.input {
63 if !txin.script_sig.is_empty() {
64 return Err(Error::UnsignedTxHasScriptSigs);
65 }
66
67 if !txin.witness.is_empty() {
68 return Err(Error::UnsignedTxHasScriptWitnesses);
69 }
70 }
71
72 Ok(Global {
73 unsigned_tx: tx,
74 xpub: Default::default(),
75 version: 0,
76 proprietary: Default::default(),
77 unknown: Default::default(),
78 })
79 }
80}
81
82impl Map for Global {
83 fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error> {
84 let raw::Pair {
85 key: raw_key,
86 value: raw_value,
87 } = pair;
88
89 match raw_key.type_value {
90 PSBT_GLOBAL_UNSIGNED_TX => return Err(Error::DuplicateKey(raw_key).into()),
91 PSBT_GLOBAL_PROPRIETARY => match self.proprietary.entry(raw::ProprietaryKey::from_key(raw_key.clone())?) {
92 Entry::Vacant(empty_key) => {empty_key.insert(raw_value);},
93 Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key).into()),
94 }
95 _ => match self.unknown.entry(raw_key) {
96 Entry::Vacant(empty_key) => {empty_key.insert(raw_value);},
97 Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()),
98 }
99 }
100
101 Ok(())
102 }
103
104 fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
105 let mut rv: Vec<raw::Pair> = Default::default();
106
107 rv.push(raw::Pair {
108 key: raw::Key {
109 type_value: PSBT_GLOBAL_UNSIGNED_TX,
110 key: vec![],
111 },
112 value: {
113 let mut ret = Vec::new();
116 self.unsigned_tx.version.consensus_encode(&mut ret)?;
117 self.unsigned_tx.input.consensus_encode(&mut ret)?;
118 self.unsigned_tx.output.consensus_encode(&mut ret)?;
119 self.unsigned_tx.lock_time.consensus_encode(&mut ret)?;
120 ret
121 },
122 });
123
124 let secp = Secp256k1::with_caps(ContextFlag::None);
125
126 for (xpub, (fingerprint, derivation)) in &self.xpub {
127 rv.push(raw::Pair {
128 key: raw::Key {
129 type_value: PSBT_GLOBAL_XPUB,
130 key: xpub.encode(&secp).to_vec(),
131 },
132 value: {
133 let mut ret = Vec::with_capacity(4 + derivation.len() * 4);
134 ret.extend(fingerprint.as_bytes());
135 derivation.into_iter().for_each(|n| ret.extend(&u32_to_array_le((*n).into())));
136 ret
137 }
138 });
139 }
140
141 if self.version > 0 {
143 rv.push(raw::Pair {
144 key: raw::Key {
145 type_value: PSBT_GLOBAL_VERSION,
146 key: vec![],
147 },
148 value: u32_to_array_le(self.version).to_vec()
149 });
150 }
151
152 for (key, value) in self.proprietary.iter() {
153 rv.push(raw::Pair {
154 key: key.to_key(),
155 value: value.clone(),
156 });
157 }
158
159 for (key, value) in self.unknown.iter() {
160 rv.push(raw::Pair {
161 key: key.clone(),
162 value: value.clone(),
163 });
164 }
165
166 Ok(rv)
167 }
168
169 fn merge(&mut self, other: Self) -> Result<(), psbt::Error> {
172 if self.unsigned_tx != other.unsigned_tx {
173 return Err(psbt::Error::UnexpectedUnsignedTx {
174 expected: self.unsigned_tx.clone(),
175 actual: other.unsigned_tx,
176 });
177 }
178
179 self.version = cmp::max(self.version, other.version);
184
185 for (xpub, (fingerprint1, derivation1)) in other.xpub {
187 match self.xpub.entry(xpub.clone()) {
188 Entry::Vacant(entry) => {
189 entry.insert((fingerprint1, derivation1));
190 },
191 Entry::Occupied(mut entry) => {
192 let (fingerprint2, derivation2) = entry.get().clone();
202
203 if derivation1 == derivation2 && fingerprint1 == fingerprint2
204 {
205 continue
206 }
207 else if
208 derivation1.len() < derivation2.len() &&
209 derivation1[..] == derivation2[derivation2.len() - derivation1.len()..]
210 {
211 continue
212 }
213 else if derivation2[..] == derivation1[derivation1.len() - derivation2.len()..]
214 {
215 entry.insert((fingerprint1, derivation1));
216 continue
217 }
218 return Err(psbt::Error::MergeConflict(format!(
219 "global xpub {} has inconsistent key sources", xpub
220 ).to_owned()));
221 }
222 }
223 }
224
225 self.proprietary.extend(other.proprietary);
226 self.unknown.extend(other.unknown);
227 Ok(())
228 }
229}
230
231impl_psbtmap_consensus_encoding!(Global);
232
233impl Decodable for Global {
234 fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
235
236 let mut tx: Option<Transaction> = None;
237 let mut version: Option<u32> = None;
238 let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default();
239 let mut xpub_map: BTreeMap<ExtendedPubKey, (Fingerprint, DerivationPath)> = Default::default();
240 let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default();
241
242 let secp = Secp256k1::with_caps(ContextFlag::None);
243
244 loop {
245 match raw::Pair::consensus_decode(&mut d) {
246 Ok(pair) => {
247 match pair.key.type_value {
248 PSBT_GLOBAL_UNSIGNED_TX => {
249 if pair.key.key.is_empty() {
251 if tx.is_none() {
253 let vlen: usize = pair.value.len();
254 let mut decoder = Cursor::new(pair.value);
255
256 tx = Some(Transaction {
260 version: Decodable::consensus_decode(&mut decoder)?,
261 input: Decodable::consensus_decode(&mut decoder)?,
262 output: Decodable::consensus_decode(&mut decoder)?,
263 lock_time: Decodable::consensus_decode(&mut decoder)?,
264 });
265
266 if decoder.position() != vlen as u64 {
267 return Err(encode::Error::ParseFailed("data not consumed entirely when explicitly deserializing"))
268 }
269 } else {
270 return Err(Error::DuplicateKey(pair.key).into())
271 }
272 } else {
273 return Err(Error::InvalidKey(pair.key).into())
274 }
275 }
276 PSBT_GLOBAL_XPUB => {
277 if !pair.key.key.is_empty() {
278 let xpub = ExtendedPubKey::decode(&secp, &pair.key.key)
279 .map_err(|_| encode::Error::ParseFailed(
280 "Can't deserialize ExtendedPublicKey from global XPUB key data"
281 ))?;
282
283 if pair.value.is_empty() || pair.value.len() % 4 != 0 {
284 return Err(encode::Error::ParseFailed("Incorrect length of global xpub derivation data"))
285 }
286
287 let child_count = pair.value.len() / 4 - 1;
288 let mut decoder = Cursor::new(pair.value);
289 let mut fingerprint = [0u8; 4];
290 decoder.read_exact(&mut fingerprint[..])?;
291 let mut path = Vec::<ChildNumber>::with_capacity(child_count);
292 while let Ok(index) = u32::consensus_decode(&mut decoder) {
293 path.push(ChildNumber::from(index))
294 }
295 let derivation = DerivationPath::from(path);
296 if xpub_map.insert(xpub, (Fingerprint::from(&fingerprint[..]), derivation)).is_some() {
298 return Err(encode::Error::ParseFailed("Repeated global xpub key"))
299 }
300 } else {
301 return Err(encode::Error::ParseFailed("Xpub global key must contain serialized Xpub data"))
302 }
303 }
304 PSBT_GLOBAL_VERSION => {
305 if pair.key.key.is_empty() {
307 if version.is_none() {
309 let vlen: usize = pair.value.len();
310 let mut decoder = Cursor::new(pair.value);
311 if vlen != 4 {
312 return Err(encode::Error::ParseFailed("Wrong global version value length (must be 4 bytes)"))
313 }
314 version = Some(Decodable::consensus_decode(&mut decoder)?);
315 if version != Some(0) {
318 return Err(encode::Error::ParseFailed("PSBT versions greater than 0 are not supported"))
319 }
320 } else {
321 return Err(Error::DuplicateKey(pair.key).into())
322 }
323 } else {
324 return Err(Error::InvalidKey(pair.key).into())
325 }
326 }
327 PSBT_GLOBAL_PROPRIETARY => match proprietary.entry(raw::ProprietaryKey::from_key(pair.key.clone())?) {
328 Entry::Vacant(empty_key) => {empty_key.insert(pair.value);},
329 Entry::Occupied(_) => return Err(Error::DuplicateKey(pair.key).into()),
330 }
331 _ => match unknowns.entry(pair.key) {
332 Entry::Vacant(empty_key) => {empty_key.insert(pair.value);},
333 Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()),
334 }
335 }
336 }
337 Err(::consensus::encode::Error::Psbt(::util::psbt::Error::NoMorePairs)) => break,
338 Err(e) => return Err(e),
339 }
340 }
341
342 if let Some(tx) = tx {
343 let mut rv: Global = Global::from_unsigned_tx(tx)?;
344 rv.version = version.unwrap_or(0);
345 rv.xpub = xpub_map;
346 rv.unknown = unknowns;
347 Ok(rv)
348 } else {
349 Err(Error::MustHaveUnsignedTx.into())
350 }
351 }
352}