Skip to main content

pczt/roles/redactor/
sapling.rs

1use crate::sapling::{Bundle, Output, Spend};
2
3impl super::Redactor {
4    /// Redacts the Sapling bundle with the given closure.
5    pub fn redact_sapling_with<F>(mut self, f: F) -> Self
6    where
7        F: FnOnce(SaplingRedactor<'_>),
8    {
9        f(SaplingRedactor(&mut self.pczt.sapling));
10        self
11    }
12}
13
14/// A Redactor for the Sapling bundle.
15pub struct SaplingRedactor<'a>(&'a mut Bundle);
16
17impl SaplingRedactor<'_> {
18    /// Redacts all spends in the same way.
19    pub fn redact_spends<F>(&mut self, f: F)
20    where
21        F: FnOnce(SpendRedactor<'_>),
22    {
23        f(SpendRedactor(Spends::All(&mut self.0.spends)));
24    }
25
26    /// Redacts the spend at the given index.
27    ///
28    /// Does nothing if the index is out of range.
29    pub fn redact_spend<F>(&mut self, index: usize, f: F)
30    where
31        F: FnOnce(SpendRedactor<'_>),
32    {
33        if let Some(spend) = self.0.spends.get_mut(index) {
34            f(SpendRedactor(Spends::One(spend)));
35        }
36    }
37
38    /// Redacts all outputs in the same way.
39    pub fn redact_outputs<F>(&mut self, f: F)
40    where
41        F: FnOnce(OutputRedactor<'_>),
42    {
43        f(OutputRedactor(Outputs::All(&mut self.0.outputs)));
44    }
45
46    /// Redacts the output at the given index.
47    ///
48    /// Does nothing if the index is out of range.
49    pub fn redact_output<F>(&mut self, index: usize, f: F)
50    where
51        F: FnOnce(OutputRedactor<'_>),
52    {
53        if let Some(output) = self.0.outputs.get_mut(index) {
54            f(OutputRedactor(Outputs::One(output)));
55        }
56    }
57
58    /// Removes the proof.
59    pub fn clear_bsk(&mut self) {
60        self.0.bsk = None;
61    }
62
63    /// Removes the bundle anchor.
64    ///
65    /// Parsed roles require the real anchor for Sapling spends, so a receiver
66    /// must restore it before parsing a bundle that contains spends.
67    pub fn clear_anchor(&mut self) {
68        self.0.anchor = None;
69    }
70}
71
72/// A Redactor for Sapling spends.
73pub struct SpendRedactor<'a>(Spends<'a>);
74
75enum Spends<'a> {
76    All(&'a mut [Spend]),
77    One(&'a mut Spend),
78}
79
80impl SpendRedactor<'_> {
81    fn redact<F>(&mut self, f: F)
82    where
83        F: Fn(&mut Spend),
84    {
85        match &mut self.0 {
86            Spends::All(spends) => {
87                for spend in spends.iter_mut() {
88                    f(spend);
89                }
90            }
91            Spends::One(spend) => {
92                f(spend);
93            }
94        }
95    }
96
97    /// Removes the proof.
98    pub fn clear_zkproof(&mut self) {
99        self.redact(|spend| {
100            spend.zkproof = None;
101        });
102    }
103
104    /// Removes the spend authorizing signature.
105    pub fn clear_spend_auth_sig(&mut self) {
106        self.redact(|spend| {
107            spend.spend_auth_sig = None;
108        });
109    }
110
111    /// Removes the recipient.
112    pub fn clear_recipient(&mut self) {
113        self.redact(|spend| {
114            spend.recipient = None;
115        });
116    }
117
118    /// Removes the value.
119    pub fn clear_value(&mut self) {
120        self.redact(|spend| {
121            spend.value = None;
122        });
123    }
124
125    /// Removes the note commitment randomness.
126    pub fn clear_rcm(&mut self) {
127        self.redact(|spend| {
128            spend.rcm = None;
129        });
130    }
131
132    /// Removes the seed randomness for the note being spent.
133    pub fn clear_rseed(&mut self) {
134        self.redact(|spend| {
135            spend.rseed = None;
136        });
137    }
138
139    /// Removes the value commitment randomness.
140    pub fn clear_rcv(&mut self) {
141        self.redact(|spend| {
142            spend.rcv = None;
143        });
144    }
145
146    /// Removes the proof generation key.
147    pub fn clear_proof_generation_key(&mut self) {
148        self.redact(|spend| {
149            spend.proof_generation_key = None;
150        });
151    }
152
153    /// Removes the witness from the note to the bundle's anchor.
154    pub fn clear_witness(&mut self) {
155        self.redact(|spend| {
156            spend.witness = None;
157        });
158    }
159
160    /// Removes the spend authorization randomizer.
161    pub fn clear_alpha(&mut self) {
162        self.redact(|spend| {
163            spend.alpha = None;
164        });
165    }
166
167    /// Removes the ZIP 32 derivation path at which the spending key can be found for the
168    /// note being spent.
169    pub fn clear_zip32_derivation(&mut self) {
170        self.redact(|spend| {
171            spend.zip32_derivation = None;
172        });
173    }
174
175    /// Removes the spend authorizing key for this spent note, if it is a dummy note.
176    pub fn clear_dummy_ask(&mut self) {
177        self.redact(|spend| {
178            spend.dummy_ask = None;
179        });
180    }
181
182    /// Redacts the proprietary value at the given key.
183    pub fn redact_proprietary(&mut self, key: &str) {
184        self.redact(|spend| {
185            spend.proprietary.remove(key);
186        });
187    }
188
189    /// Removes all proprietary values.
190    pub fn clear_proprietary(&mut self) {
191        self.redact(|spend| {
192            spend.proprietary.clear();
193        });
194    }
195}
196
197/// A Redactor for Sapling outputs.
198pub struct OutputRedactor<'a>(Outputs<'a>);
199
200enum Outputs<'a> {
201    All(&'a mut [Output]),
202    One(&'a mut Output),
203}
204
205impl OutputRedactor<'_> {
206    fn redact<F>(&mut self, f: F)
207    where
208        F: Fn(&mut Output),
209    {
210        match &mut self.0 {
211            Outputs::All(outputs) => {
212                for output in outputs.iter_mut() {
213                    f(output);
214                }
215            }
216            Outputs::One(output) => {
217                f(output);
218            }
219        }
220    }
221
222    /// Removes the proof.
223    pub fn clear_zkproof(&mut self) {
224        self.redact(|output| {
225            output.zkproof = None;
226        });
227    }
228
229    /// Removes the recipient.
230    pub fn clear_recipient(&mut self) {
231        self.redact(|output| {
232            output.recipient = None;
233        });
234    }
235
236    /// Removes the value.
237    pub fn clear_value(&mut self) {
238        self.redact(|output| {
239            output.value = None;
240        });
241    }
242
243    /// Removes the seed randomness for the note being created.
244    pub fn clear_rseed(&mut self) {
245        self.redact(|output| {
246            output.rseed = None;
247        });
248    }
249
250    /// Removes the value commitment randomness.
251    pub fn clear_rcv(&mut self) {
252        self.redact(|output| {
253            output.rcv = None;
254        });
255    }
256
257    /// Removes the `ock` value used to encrypt `out_ciphertext`.
258    pub fn clear_ock(&mut self) {
259        self.redact(|output| {
260            output.ock = None;
261        });
262    }
263
264    /// Removes the ZIP 32 derivation path at which the spending key can be found for the
265    /// note being created.
266    pub fn clear_zip32_derivation(&mut self) {
267        self.redact(|output| {
268            output.zip32_derivation = None;
269        });
270    }
271
272    /// Removes the user-facing address to which this output is being sent, if any.
273    pub fn clear_user_address(&mut self) {
274        self.redact(|output| {
275            output.user_address = None;
276        });
277    }
278
279    /// Redacts the proprietary value at the given key.
280    pub fn redact_proprietary(&mut self, key: &str) {
281        self.redact(|output| {
282            output.proprietary.remove(key);
283        });
284    }
285
286    /// Removes all proprietary values.
287    pub fn clear_proprietary(&mut self) {
288        self.redact(|output| {
289            output.proprietary.clear();
290        });
291    }
292}