Skip to content

Commit 87294ff

Browse files
committed
types: don't implement Property for Malleability
See previous commit message for justification. In this case we can also change the signature of every method that returned a Result<Self, ErrorKind> to just return Self, since malleability computations don't error out. Worst case they just mark the final miniscript as being malleable.
1 parent dd0978d commit 87294ff

File tree

2 files changed

+135
-123
lines changed

2 files changed

+135
-123
lines changed

src/miniscript/types/malleability.rs

Lines changed: 91 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
//! Malleability-related Type properties
44
5-
use super::{ErrorKind, Property};
6-
use crate::ScriptContext;
5+
use super::ErrorKind;
76

87
/// Whether the fragment has a dissatisfaction, and if so, whether
98
/// it is unique. Affects both correctness and malleability-freeness,
@@ -27,11 +26,21 @@ pub enum Dissat {
2726
}
2827

2928
impl Dissat {
29+
// FIXME rustc should eventually support derived == on enums in constfns
30+
const fn constfn_eq(self, other: Self) -> bool {
31+
matches!(
32+
(self, other),
33+
(Dissat::None, Dissat::None)
34+
| (Dissat::Unique, Dissat::Unique)
35+
| (Dissat::Unknown, Dissat::Unknown)
36+
)
37+
}
38+
3039
/// Check whether given `Dissat` is a subtype of `other`. That is,
3140
/// if some Dissat is `Unique` then it must be `Unknown`.
32-
fn is_subtype(&self, other: Self) -> bool {
41+
const fn is_subtype(&self, other: Self) -> bool {
3342
match (*self, other) {
34-
(x, y) if x == y => true,
43+
(x, y) if x.constfn_eq(y) => true,
3544
(_, Dissat::Unknown) => true,
3645
_ => false,
3746
}
@@ -73,101 +82,101 @@ impl Malleability {
7382
}
7483
}
7584

76-
impl Property for Malleability {
77-
fn from_true() -> Self {
78-
Malleability { dissat: Dissat::None, safe: false, non_malleable: true }
79-
}
80-
81-
fn from_false() -> Self {
82-
Malleability { dissat: Dissat::Unique, safe: true, non_malleable: true }
83-
}
84-
85-
fn from_pk_k<Ctx: ScriptContext>() -> Self {
85+
impl Malleability {
86+
/// Constructor for the malleabilitiy properties of the `pk_k` fragment.
87+
pub const fn pk_k() -> Self {
8688
Malleability { dissat: Dissat::Unique, safe: true, non_malleable: true }
8789
}
8890

89-
fn from_pk_h<Ctx: ScriptContext>() -> Self {
91+
/// Constructor for the malleabilitiy properties of the `pk_h` fragment.
92+
pub const fn pk_h() -> Self {
9093
Malleability { dissat: Dissat::Unique, safe: true, non_malleable: true }
9194
}
9295

93-
fn from_multi(_: usize, _: usize) -> Self {
96+
/// Constructor for the malleabilitiy properties of the `multi` fragment.
97+
pub const fn multi() -> Self {
9498
Malleability { dissat: Dissat::Unique, safe: true, non_malleable: true }
9599
}
96100

97-
fn from_multi_a(_: usize, _: usize) -> Self {
101+
/// Constructor for the malleabilitiy properties of the `multi_a` fragment.
102+
pub const fn multi_a() -> Self {
98103
Malleability { dissat: Dissat::Unique, safe: true, non_malleable: true }
99104
}
100105

101-
fn from_hash() -> Self {
106+
/// Constructor for the malleabilitiy properties of any of the hash fragments.
107+
pub const fn hash() -> Self {
102108
Malleability { dissat: Dissat::Unknown, safe: false, non_malleable: true }
103109
}
104110

105-
fn from_time(_: u32) -> Self {
111+
/// Constructor for the malleabilitiy properties of either `after` or `older`.
112+
pub const fn time() -> Self {
106113
Malleability { dissat: Dissat::None, safe: false, non_malleable: true }
107114
}
108115

109-
fn cast_alt(self) -> Result<Self, ErrorKind> { Ok(self) }
116+
/// Constructor for the malleabilitiy properties of the `a:` fragment.
117+
pub const fn cast_alt(self) -> Self { self }
110118

111-
fn cast_swap(self) -> Result<Self, ErrorKind> { Ok(self) }
119+
/// Constructor for the malleabilitiy properties of the `s:` fragment.
120+
pub const fn cast_swap(self) -> Self { self }
112121

113-
fn cast_check(self) -> Result<Self, ErrorKind> { Ok(self) }
122+
/// Constructor for the malleabilitiy properties of the `c:` fragment.
123+
pub const fn cast_check(self) -> Self { self }
114124

115-
fn cast_dupif(self) -> Result<Self, ErrorKind> {
116-
Ok(Malleability {
117-
dissat: if self.dissat == Dissat::None {
125+
/// Constructor for the malleabilitiy properties of the `d:` fragment.
126+
pub const fn cast_dupif(self) -> Self {
127+
Malleability {
128+
dissat: if self.dissat.constfn_eq(Dissat::None) {
118129
Dissat::Unique
119130
} else {
120131
Dissat::Unknown
121132
},
122133
safe: self.safe,
123134
non_malleable: self.non_malleable,
124-
})
135+
}
125136
}
126137

127-
fn cast_verify(self) -> Result<Self, ErrorKind> {
128-
Ok(Malleability {
129-
dissat: Dissat::None,
130-
safe: self.safe,
131-
non_malleable: self.non_malleable,
132-
})
138+
/// Constructor for the malleabilitiy properties of the `v:` fragment.
139+
pub const fn cast_verify(self) -> Self {
140+
Malleability { dissat: Dissat::None, safe: self.safe, non_malleable: self.non_malleable }
133141
}
134142

135-
fn cast_nonzero(self) -> Result<Self, ErrorKind> {
136-
Ok(Malleability {
137-
dissat: if self.dissat == Dissat::None {
143+
/// Constructor for the malleabilitiy properties of the `j:` fragment.
144+
pub const fn cast_nonzero(self) -> Self {
145+
Malleability {
146+
dissat: if self.dissat.constfn_eq(Dissat::None) {
138147
Dissat::Unique
139148
} else {
140149
Dissat::Unknown
141150
},
142151
safe: self.safe,
143152
non_malleable: self.non_malleable,
144-
})
153+
}
145154
}
146155

147-
fn cast_zeronotequal(self) -> Result<Self, ErrorKind> { Ok(self) }
156+
/// Constructor for the malleabilitiy properties of the `n:` fragment.
157+
pub const fn cast_zeronotequal(self) -> Self { self }
148158

149-
fn cast_true(self) -> Result<Self, ErrorKind> {
150-
Ok(Malleability {
151-
dissat: Dissat::None,
152-
safe: self.safe,
153-
non_malleable: self.non_malleable,
154-
})
159+
/// Constructor for the malleabilitiy properties of the `t:` fragment.
160+
pub const fn cast_true(self) -> Self {
161+
Malleability { dissat: Dissat::None, safe: self.safe, non_malleable: self.non_malleable }
155162
}
156163

157-
fn cast_or_i_false(self) -> Result<Self, ErrorKind> {
158-
Ok(Malleability {
159-
dissat: if self.dissat == Dissat::None {
164+
/// Constructor for the malleabilitiy properties of the `l:` or `u:` fragments.
165+
pub const fn cast_or_i_false(self) -> Self {
166+
Malleability {
167+
dissat: if self.dissat.constfn_eq(Dissat::None) {
160168
Dissat::Unique
161169
} else {
162170
Dissat::Unknown
163171
},
164172
safe: self.safe,
165173
non_malleable: self.non_malleable,
166-
})
174+
}
167175
}
168176

169-
fn and_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
170-
Ok(Malleability {
177+
/// Constructor for the malleabilitiy properties of the `and_b` fragment.
178+
pub const fn and_b(left: Self, right: Self) -> Self {
179+
Malleability {
171180
dissat: match (left.dissat, right.dissat) {
172181
(Dissat::None, Dissat::None) => Dissat::None,
173182
(Dissat::None, _) if left.safe => Dissat::None,
@@ -183,57 +192,62 @@ impl Property for Malleability {
183192
},
184193
safe: left.safe || right.safe,
185194
non_malleable: left.non_malleable && right.non_malleable,
186-
})
195+
}
187196
}
188197

189-
fn and_v(left: Self, right: Self) -> Result<Self, ErrorKind> {
190-
Ok(Malleability {
198+
/// Constructor for the malleabilitiy properties of the `and_v` fragment.
199+
pub const fn and_v(left: Self, right: Self) -> Self {
200+
Malleability {
191201
dissat: match (left.safe, right.dissat) {
192202
(_, Dissat::None) => Dissat::None, // fy
193203
(true, _) => Dissat::None, // sx
194204
_ => Dissat::Unknown,
195205
},
196206
safe: left.safe || right.safe,
197207
non_malleable: left.non_malleable && right.non_malleable,
198-
})
208+
}
199209
}
200210

201-
fn or_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
202-
Ok(Malleability {
211+
/// Constructor for the malleabilitiy properties of the `or_b` fragment.
212+
pub const fn or_b(left: Self, right: Self) -> Self {
213+
Malleability {
203214
dissat: Dissat::Unique,
204215
safe: left.safe && right.safe,
205216
non_malleable: left.non_malleable
206-
&& left.dissat == Dissat::Unique
217+
&& left.dissat.constfn_eq(Dissat::Unique)
207218
&& right.non_malleable
208-
&& right.dissat == Dissat::Unique
219+
&& right.dissat.constfn_eq(Dissat::Unique)
209220
&& (left.safe || right.safe),
210-
})
221+
}
211222
}
212223

213-
fn or_d(left: Self, right: Self) -> Result<Self, ErrorKind> {
214-
Ok(Malleability {
224+
/// Constructor for the malleabilitiy properties of the `or_d` fragment.
225+
pub const fn or_d(left: Self, right: Self) -> Self {
226+
Malleability {
215227
dissat: right.dissat,
216228
safe: left.safe && right.safe,
217229
non_malleable: left.non_malleable
218-
&& left.dissat == Dissat::Unique
230+
&& left.dissat.constfn_eq(Dissat::Unique)
219231
&& right.non_malleable
220232
&& (left.safe || right.safe),
221-
})
233+
}
222234
}
223235

224-
fn or_c(left: Self, right: Self) -> Result<Self, ErrorKind> {
225-
Ok(Malleability {
236+
/// Constructor for the malleabilitiy properties of the `or_c` fragment.
237+
pub const fn or_c(left: Self, right: Self) -> Self {
238+
Malleability {
226239
dissat: Dissat::None,
227240
safe: left.safe && right.safe,
228241
non_malleable: left.non_malleable
229-
&& left.dissat == Dissat::Unique
242+
&& left.dissat.constfn_eq(Dissat::Unique)
230243
&& right.non_malleable
231244
&& (left.safe || right.safe),
232-
})
245+
}
233246
}
234247

235-
fn or_i(left: Self, right: Self) -> Result<Self, ErrorKind> {
236-
Ok(Malleability {
248+
/// Constructor for the malleabilitiy properties of the `or_i` fragment.
249+
pub const fn or_i(left: Self, right: Self) -> Self {
250+
Malleability {
237251
dissat: match (left.dissat, right.dissat) {
238252
(Dissat::None, Dissat::None) => Dissat::None,
239253
(Dissat::Unique, Dissat::None) => Dissat::Unique,
@@ -242,11 +256,12 @@ impl Property for Malleability {
242256
},
243257
safe: left.safe && right.safe,
244258
non_malleable: left.non_malleable && right.non_malleable && (left.safe || right.safe),
245-
})
259+
}
246260
}
247261

248-
fn and_or(a: Self, b: Self, c: Self) -> Result<Self, ErrorKind> {
249-
Ok(Malleability {
262+
/// Constructor for the malleabilitiy properties of the `andor` fragment.
263+
pub const fn and_or(a: Self, b: Self, c: Self) -> Self {
264+
Malleability {
250265
dissat: match (a.safe, b.dissat, c.dissat) {
251266
(_, Dissat::None, Dissat::Unique) => Dissat::Unique, //E: ez fy
252267
(true, _, Dissat::Unique) => Dissat::Unique, // E: ez sx
@@ -257,13 +272,15 @@ impl Property for Malleability {
257272
safe: (a.safe || b.safe) && c.safe,
258273
non_malleable: a.non_malleable
259274
&& c.non_malleable
260-
&& a.dissat == Dissat::Unique
275+
&& a.dissat.constfn_eq(Dissat::Unique)
261276
&& b.non_malleable
262277
&& (a.safe || b.safe || c.safe),
263-
})
278+
}
264279
}
265280

266-
fn threshold<S>(k: usize, n: usize, mut sub_ck: S) -> Result<Self, ErrorKind>
281+
/// Constructor for the malleabilitiy properties of the `thresh` fragment.
282+
// Cannot be constfn because it takes a closure.
283+
pub fn threshold<S>(k: usize, n: usize, mut sub_ck: S) -> Result<Self, ErrorKind>
267284
where
268285
S: FnMut(usize) -> Result<Self, ErrorKind>,
269286
{

0 commit comments

Comments
 (0)