bitcoin/util/psbt/map/
output.rs1use std::io;
16use std::collections::BTreeMap;
17use std::collections::btree_map::Entry;
18
19use blockdata::script::Script;
20use consensus::encode;
21use util::bip32::KeySource;
22use util::key::PublicKey;
23use util::psbt;
24use util::psbt::map::Map;
25use util::psbt::raw;
26use util::psbt::Error;
27
28const PSBT_OUT_REDEEM_SCRIPT: u8 = 0x00;
30const PSBT_OUT_WITNESS_SCRIPT: u8 = 0x01;
32const PSBT_OUT_BIP32_DERIVATION: u8 = 0x02;
34const PSBT_OUT_PROPRIETARY: u8 = 0xFC;
36
37#[derive(Clone, Default, Debug, PartialEq)]
40#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
41pub struct Output {
42 pub redeem_script: Option<Script>,
44 pub witness_script: Option<Script>,
46 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq"))]
49 pub bip32_derivation: BTreeMap<PublicKey, KeySource>,
50 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
52 pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
53 #[cfg_attr(feature = "serde", serde(with = "::serde_utils::btreemap_as_seq_byte_values"))]
55 pub unknown: BTreeMap<raw::Key, Vec<u8>>,
56}
57
58impl Map for Output {
59 fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error> {
60 let raw::Pair {
61 key: raw_key,
62 value: raw_value,
63 } = pair;
64
65 match raw_key.type_value {
66 PSBT_OUT_REDEEM_SCRIPT => {
67 impl_psbt_insert_pair! {
68 self.redeem_script <= <raw_key: _>|<raw_value: Script>
69 }
70 }
71 PSBT_OUT_WITNESS_SCRIPT => {
72 impl_psbt_insert_pair! {
73 self.witness_script <= <raw_key: _>|<raw_value: Script>
74 }
75 }
76 PSBT_OUT_BIP32_DERIVATION => {
77 impl_psbt_insert_pair! {
78 self.bip32_derivation <= <raw_key: PublicKey>|<raw_value: KeySource>
79 }
80 }
81 PSBT_OUT_PROPRIETARY => match self.proprietary.entry(raw::ProprietaryKey::from_key(raw_key.clone())?) {
82 Entry::Vacant(empty_key) => {empty_key.insert(raw_value);},
83 Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key.clone()).into()),
84 }
85 _ => match self.unknown.entry(raw_key) {
86 Entry::Vacant(empty_key) => {empty_key.insert(raw_value);},
87 Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()),
88 }
89 }
90
91 Ok(())
92 }
93
94 fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
95 let mut rv: Vec<raw::Pair> = Default::default();
96
97 impl_psbt_get_pair! {
98 rv.push(self.redeem_script as <PSBT_OUT_REDEEM_SCRIPT, _>|<Script>)
99 }
100
101 impl_psbt_get_pair! {
102 rv.push(self.witness_script as <PSBT_OUT_WITNESS_SCRIPT, _>|<Script>)
103 }
104
105 impl_psbt_get_pair! {
106 rv.push(self.bip32_derivation as <PSBT_OUT_BIP32_DERIVATION, PublicKey>|<KeySource>)
107 }
108
109 for (key, value) in self.proprietary.iter() {
110 rv.push(raw::Pair {
111 key: key.to_key(),
112 value: value.clone(),
113 });
114 }
115
116 for (key, value) in self.unknown.iter() {
117 rv.push(raw::Pair {
118 key: key.clone(),
119 value: value.clone(),
120 });
121 }
122
123 Ok(rv)
124 }
125
126 fn merge(&mut self, other: Self) -> Result<(), psbt::Error> {
127 self.bip32_derivation.extend(other.bip32_derivation);
128 self.proprietary.extend(other.proprietary);
129 self.unknown.extend(other.unknown);
130
131 merge!(redeem_script, self, other);
132 merge!(witness_script, self, other);
133
134 Ok(())
135 }
136}
137
138impl_psbtmap_consensus_enc_dec_oding!(Output);