Skip to content

Commit 7da0f37

Browse files
committedFeb 10, 2025··
Merge BlockstreamResearch#265: Remove WitnessNode
61b7ddc refactor: Remove WitnessNode (Christian Lewe) 3be0fd9 refactor: Remove Error::NoMoreWitnesses (Christian Lewe) Pull request description: Remove `WitnessNode` by merging its code with the nearly identical `ConstructNode`. ACKs for top commit: apoelstra: ACK 61b7ddc; successfully ran local tests Tree-SHA512: 1ab95ad4b73552cfa9285f7aeba10faa2c4936f708f722667c3c44f3ce1463351ca23319129fe0aa6640004ce665bb23fc6faa754c1c9ea81b71e83d06f62bb0
2 parents 211a30f + 61b7ddc commit 7da0f37

File tree

14 files changed

+199
-382
lines changed

14 files changed

+199
-382
lines changed
 

‎src/bit_encoding/decode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::dag::{Dag, DagLike, InternalSharing};
99
use crate::jet::Jet;
1010
use crate::merkle::cmr::Cmr;
1111
use crate::node::{
12-
ConstructNode, CoreConstructible, DisconnectConstructible, JetConstructible, NoWitness,
12+
ConstructNode, CoreConstructible, DisconnectConstructible, JetConstructible,
1313
WitnessConstructible,
1414
};
1515
use crate::types;
@@ -235,7 +235,7 @@ pub fn decode_expression<I: Iterator<Item = u8>, J: Jet>(
235235
converted[i].get()?,
236236
&Some(Arc::clone(converted[j].get()?)),
237237
)?),
238-
DecodeNode::Witness => Node(ArcNode::witness(&inference_context, NoWitness)),
238+
DecodeNode::Witness => Node(ArcNode::witness(&inference_context, None)),
239239
DecodeNode::Fail(entropy) => Node(ArcNode::fail(&inference_context, entropy)),
240240
DecodeNode::Hidden(cmr) => {
241241
if !hidden_set.insert(cmr) {

‎src/human_encoding/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod parse;
1313
use crate::dag::{DagLike, MaxSharing};
1414
use crate::jet::Jet;
1515
use crate::node::{self, CommitNode, NoWitness};
16-
use crate::{Cmr, Imr, Value, WitnessNode};
16+
use crate::{Cmr, ConstructNode, Imr, Value};
1717

1818
use std::collections::HashMap;
1919
use std::str;
@@ -213,9 +213,9 @@ impl<J: Jet> Forest<J> {
213213
pub fn to_witness_node(
214214
&self,
215215
witness: &HashMap<Arc<str>, Value>,
216-
) -> Option<Arc<WitnessNode<J>>> {
216+
) -> Option<Arc<ConstructNode<J>>> {
217217
let main = self.roots.get("main")?;
218-
Some(main.to_witness_node(witness, self.roots()))
218+
Some(main.to_construct_node(witness, self.roots()))
219219
}
220220
}
221221

‎src/human_encoding/named_node.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ use crate::dag::{InternalSharing, MaxSharing, PostOrderIterItem};
66
use crate::human_encoding::{Error, ErrorSet, Position, WitnessOrHole};
77
use crate::jet::Jet;
88
use crate::node::{
9-
self, Commit, CommitData, CommitNode, Converter, Inner, NoDisconnect, NoWitness, Node, Witness,
10-
WitnessData,
9+
self, Commit, CommitData, CommitNode, Construct, ConstructData, Constructible as _, Converter,
10+
CoreConstructible as _, Inner, NoDisconnect, NoWitness, Node,
1111
};
12-
use crate::node::{Construct, ConstructData, Constructible as _, CoreConstructible as _};
1312
use crate::types;
1413
use crate::types::arrow::{Arrow, FinalArrow};
15-
use crate::{encode, Value, WitnessNode};
14+
use crate::{encode, ConstructNode, Value};
1615
use crate::{BitWriter, Cmr, Imr};
1716

1817
use std::collections::HashMap;
@@ -108,19 +107,19 @@ impl<J: Jet> NamedCommitNode<J> {
108107
.unwrap()
109108
}
110109

111-
pub fn to_witness_node(
110+
pub fn to_construct_node(
112111
&self,
113112
witness: &HashMap<Arc<str>, Value>,
114113
disconnect: &HashMap<Arc<str>, Arc<NamedCommitNode<J>>>,
115-
) -> Arc<WitnessNode<J>> {
114+
) -> Arc<ConstructNode<J>> {
116115
struct Populator<'a, J: Jet> {
117116
witness_map: &'a HashMap<Arc<str>, Value>,
118117
disconnect_map: &'a HashMap<Arc<str>, Arc<NamedCommitNode<J>>>,
119118
inference_context: types::Context,
120119
phantom: PhantomData<J>,
121120
}
122121

123-
impl<J: Jet> Converter<Named<Commit<J>>, Witness<J>> for Populator<'_, J> {
122+
impl<J: Jet> Converter<Named<Commit<J>>, Construct<J>> for Populator<'_, J> {
124123
type Error = ();
125124

126125
fn convert_witness(
@@ -140,9 +139,9 @@ impl<J: Jet> NamedCommitNode<J> {
140139
fn convert_disconnect(
141140
&mut self,
142141
data: &PostOrderIterItem<&Node<Named<Commit<J>>>>,
143-
maybe_converted: Option<&Arc<Node<Witness<J>>>>,
142+
maybe_converted: Option<&Arc<Node<Construct<J>>>>,
144143
_: &Arc<str>,
145-
) -> Result<Option<Arc<Node<Witness<J>>>>, Self::Error> {
144+
) -> Result<Option<Arc<Node<Construct<J>>>>, Self::Error> {
146145
if let Some(converted) = maybe_converted {
147146
Ok(Some(converted.clone()))
148147
} else {
@@ -172,16 +171,16 @@ impl<J: Jet> NamedCommitNode<J> {
172171
&mut self,
173172
_: &PostOrderIterItem<&Node<Named<Commit<J>>>>,
174173
inner: Inner<
175-
&Arc<Node<Witness<J>>>,
174+
&Arc<Node<Construct<J>>>,
176175
J,
177-
&Option<Arc<WitnessNode<J>>>,
176+
&Option<Arc<ConstructNode<J>>>,
178177
&Option<Value>,
179178
>,
180-
) -> Result<WitnessData<J>, Self::Error> {
179+
) -> Result<ConstructData<J>, Self::Error> {
181180
let inner = inner
182181
.map(|node| node.cached_data())
183182
.map_witness(|maybe_value| maybe_value.clone());
184-
Ok(WitnessData::from_inner(&self.inference_context, inner)
183+
Ok(ConstructData::from_inner(&self.inference_context, inner)
185184
.expect("types are already finalized"))
186185
}
187186
}
@@ -260,7 +259,7 @@ impl<J: Jet> NamedConstructNode<J> {
260259
.as_ref()
261260
.map(|data| &data.cached_data().internal)
262261
.map_disconnect(|_| &None)
263-
.map_witness(|_| NoWitness),
262+
.map_witness(|_| None),
264263
)?;
265264
let named_data = NamedConstructData {
266265
internal: construct_data,

‎src/human_encoding/parse/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ mod tests {
591591
assert_eq!(main.cmr().to_string(), cmr);
592592

593593
let program = main
594-
.to_witness_node(witness, &forest)
594+
.to_construct_node(witness, &forest)
595595
.finalize_unpruned()
596596
.expect("finalize");
597597

‎src/lib.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub use crate::merkle::{
6565
tmr::Tmr,
6666
FailEntropy, HasCmr,
6767
};
68-
pub use crate::node::{CommitNode, ConstructNode, Hiding, RedeemNode, WitnessNode};
68+
pub use crate::node::{CommitNode, ConstructNode, Hiding, RedeemNode};
6969
pub use crate::value::{Value, Word};
7070
pub use simplicity_sys as ffi;
7171
use std::fmt;
@@ -88,8 +88,6 @@ pub enum Error {
8888
Type(types::Error),
8989
// Execution error
9090
Execution(bit_machine::ExecutionError),
91-
/// Witness iterator ended early
92-
NoMoreWitnesses,
9391
/// Tried to parse a jet but the name wasn't recognized
9492
InvalidJetName(String),
9593
/// Policy error
@@ -107,7 +105,6 @@ impl fmt::Display for Error {
107105
Error::Type(ref e) => fmt::Display::fmt(e, f),
108106
Error::Execution(ref e) => fmt::Display::fmt(e, f),
109107
Error::InvalidJetName(s) => write!(f, "unknown jet `{}`", s),
110-
Error::NoMoreWitnesses => f.write_str("no more witness data available"),
111108
#[cfg(feature = "elements")]
112109
Error::Policy(ref e) => fmt::Display::fmt(e, f),
113110
}
@@ -121,7 +118,6 @@ impl std::error::Error for Error {
121118
Error::DisconnectRedeemTime => None,
122119
Error::Type(ref e) => Some(e),
123120
Error::Execution(ref e) => Some(e),
124-
Error::NoMoreWitnesses => None,
125121
Error::InvalidJetName(..) => None,
126122
#[cfg(feature = "elements")]
127123
Error::Policy(ref e) => Some(e),

‎src/node/commit.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::dag::{DagLike, MaxSharing, NoSharing, PostOrderIterItem};
44
use crate::jet::Jet;
55
use crate::types::arrow::{Arrow, FinalArrow};
6-
use crate::{encode, types};
6+
use crate::{encode, types, Value};
77
use crate::{Amr, BitIter, BitWriter, Cmr, Error, FirstPassImr, Imr};
88

99
use super::{
@@ -213,8 +213,8 @@ impl<J: Jet> CommitNode<J> {
213213
&mut self,
214214
_: &PostOrderIterItem<&CommitNode<J>>,
215215
_: &NoWitness,
216-
) -> Result<NoWitness, Self::Error> {
217-
Ok(NoWitness)
216+
) -> Result<Option<Value>, Self::Error> {
217+
Ok(None)
218218
}
219219

220220
fn convert_disconnect(
@@ -229,7 +229,12 @@ impl<J: Jet> CommitNode<J> {
229229
fn convert_data(
230230
&mut self,
231231
_: &PostOrderIterItem<&CommitNode<J>>,
232-
inner: Inner<&Arc<ConstructNode<J>>, J, &Option<Arc<ConstructNode<J>>>, &NoWitness>,
232+
inner: Inner<
233+
&Arc<ConstructNode<J>>,
234+
J,
235+
&Option<Arc<ConstructNode<J>>>,
236+
&Option<Value>,
237+
>,
233238
) -> Result<ConstructData<J>, Self::Error> {
234239
let inner = inner
235240
.map(|node| node.arrow())

‎src/node/construct.rs

+106-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
// SPDX-License-Identifier: CC0-1.0
22

33
use crate::dag::{InternalSharing, PostOrderIterItem};
4-
use crate::encode;
54
use crate::jet::Jet;
65
use crate::types::{self, arrow::Arrow};
7-
use crate::{BitIter, BitWriter, Cmr, FailEntropy};
6+
use crate::{encode, BitIter, BitWriter, Cmr, FailEntropy, RedeemNode, Value, Word};
87

9-
use crate::value::Word;
108
use std::io;
119
use std::marker::PhantomData;
1210
use std::sync::Arc;
1311

1412
use super::{
1513
Commit, CommitData, CommitNode, Converter, Inner, Marker, NoDisconnect, NoWitness, Node,
14+
Redeem, RedeemData,
1615
};
1716
use super::{CoreConstructible, DisconnectConstructible, JetConstructible, WitnessConstructible};
1817

@@ -33,7 +32,7 @@ pub struct Construct<J> {
3332

3433
impl<J: Jet> Marker for Construct<J> {
3534
type CachedData = ConstructData<J>;
36-
type Witness = NoWitness;
35+
type Witness = Option<Value>;
3736
type Disconnect = Option<Arc<ConstructNode<J>>>;
3837
type SharingId = ConstructId;
3938
type Jet = J;
@@ -90,7 +89,7 @@ impl<J: Jet> ConstructNode<J> {
9089
fn convert_witness(
9190
&mut self,
9291
_: &PostOrderIterItem<&ConstructNode<J>>,
93-
_: &NoWitness,
92+
_: &Option<Value>,
9493
) -> Result<NoWitness, Self::Error> {
9594
Ok(NoWitness)
9695
}
@@ -119,6 +118,104 @@ impl<J: Jet> ConstructNode<J> {
119118
self.convert::<InternalSharing, _, _>(&mut FinalizeTypes(PhantomData))
120119
}
121120

121+
/// Finalize the witness program as an unpruned redeem program.
122+
///
123+
/// Witness nodes must be populated with sufficient data,
124+
/// to ensure that the resulting redeem program successfully runs on the Bit Machine.
125+
/// Furthermore, **all** disconnected branches must be populated,
126+
/// even those that are not executed.
127+
///
128+
/// The resulting redeem program is **not pruned**.
129+
///
130+
/// ## See
131+
///
132+
/// [`RedeemNode::prune`]
133+
pub fn finalize_unpruned(&self) -> Result<Arc<RedeemNode<J>>, crate::Error> {
134+
struct Finalizer<J>(PhantomData<J>);
135+
136+
impl<J: Jet> Converter<Construct<J>, Redeem<J>> for Finalizer<J> {
137+
type Error = crate::Error;
138+
139+
fn convert_witness(
140+
&mut self,
141+
data: &PostOrderIterItem<&ConstructNode<J>>,
142+
wit: &Option<Value>,
143+
) -> Result<Value, Self::Error> {
144+
if let Some(ref wit) = wit {
145+
Ok(wit.shallow_clone())
146+
} else {
147+
// We insert a zero value into unpopulated witness nodes,
148+
// assuming that this node will later be pruned out of the program.
149+
//
150+
// Pruning requires running a program on the Bit Machine,
151+
// which in turn requires a program with fully populated witness nodes.
152+
// It would be horrible UX to force the caller to provide witness data
153+
// even for unexecuted branches, so we insert zero values here.
154+
//
155+
// If this node is executed after all, then the caller can fix the witness
156+
// data based on the returned execution error.
157+
//
158+
// Zero values may "accidentally" satisfy a program even if the caller
159+
// didn't provide any witness data. However, this is only the case for the
160+
// most trivial programs. The only place where we must be careful is our
161+
// unit tests, which tend to include these kinds of trivial programs.
162+
let ty = data.node.arrow().target.finalize()?;
163+
Ok(Value::zero(&ty))
164+
}
165+
}
166+
167+
fn convert_disconnect(
168+
&mut self,
169+
_: &PostOrderIterItem<&ConstructNode<J>>,
170+
maybe_converted: Option<&Arc<RedeemNode<J>>>,
171+
_: &Option<Arc<ConstructNode<J>>>,
172+
) -> Result<Arc<RedeemNode<J>>, Self::Error> {
173+
if let Some(child) = maybe_converted {
174+
Ok(Arc::clone(child))
175+
} else {
176+
Err(crate::Error::DisconnectRedeemTime)
177+
}
178+
}
179+
180+
fn convert_data(
181+
&mut self,
182+
data: &PostOrderIterItem<&ConstructNode<J>>,
183+
inner: Inner<&Arc<RedeemNode<J>>, J, &Arc<RedeemNode<J>>, &Value>,
184+
) -> Result<Arc<RedeemData<J>>, Self::Error> {
185+
let converted_data = inner
186+
.map(|node| node.cached_data())
187+
.map_disconnect(|node| node.cached_data())
188+
.map_witness(Value::shallow_clone);
189+
Ok(Arc::new(RedeemData::new(
190+
data.node.arrow().finalize()?,
191+
converted_data,
192+
)))
193+
}
194+
}
195+
196+
self.convert::<InternalSharing, _, _>(&mut Finalizer(PhantomData))
197+
}
198+
199+
/// Finalize the witness program as a pruned redeem program.
200+
///
201+
/// Witness nodes must be populated with sufficient data,
202+
/// to ensure that the resulting redeem program successfully runs on the Bit Machine.
203+
/// Furthermore, **all** disconnected branches must be populated,
204+
/// even those that are not executed.
205+
///
206+
/// The resulting redeem program is **pruned** based on the given transaction environment.
207+
///
208+
/// ## See
209+
///
210+
/// [`RedeemNode::prune`]
211+
pub fn finalize_pruned(
212+
&self,
213+
env: &J::Environment,
214+
) -> Result<Arc<RedeemNode<J>>, crate::Error> {
215+
let unpruned = self.finalize_unpruned()?;
216+
unpruned.prune(env).map_err(crate::Error::Execution)
217+
}
218+
122219
/// Decode a Simplicity expression from bits, without witness data.
123220
///
124221
/// # Usage
@@ -278,10 +375,10 @@ impl<J: Jet> DisconnectConstructible<Option<Arc<ConstructNode<J>>>> for Construc
278375
}
279376
}
280377

281-
impl<J> WitnessConstructible<NoWitness> for ConstructData<J> {
282-
fn witness(inference_context: &types::Context, witness: NoWitness) -> Self {
378+
impl<J> WitnessConstructible<Option<Value>> for ConstructData<J> {
379+
fn witness(inference_context: &types::Context, _witness: Option<Value>) -> Self {
283380
ConstructData {
284-
arrow: Arrow::witness(inference_context, witness),
381+
arrow: Arrow::witness(inference_context, NoWitness),
285382
phantom: PhantomData,
286383
}
287384
}
@@ -340,7 +437,7 @@ mod tests {
340437
fn occurs_check_3() {
341438
let ctx = types::Context::new();
342439
// A similar example that caused a slightly different deadlock in the past.
343-
let wit = Arc::<ConstructNode<Core>>::witness(&ctx, NoWitness);
440+
let wit = Arc::<ConstructNode<Core>>::witness(&ctx, None);
344441
let drop = Arc::<ConstructNode<Core>>::drop_(&wit);
345442

346443
let comp1 = Arc::<ConstructNode<Core>>::comp(&drop, &drop).unwrap();

‎src/node/convert.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ pub trait Converter<N: Marker, M: Marker> {
152152
/// Does not do any type-checking and may attach an invalid witness to a combinator.
153153
///
154154
/// If it encounters a disconnect node, it simply returns an error.
155+
///
156+
/// **This finalizer should not be used in production.
157+
/// It introduces default values ([`Value::zero`]) to handle missing witness data,
158+
/// which might trigger unexpected spending paths.**
155159
// FIXME we should do type checking, but this would require a method to check
156160
// type compatibility between a Value and a type::Final.
157161
pub struct SimpleFinalizer<W: Iterator<Item = Value>> {
@@ -169,10 +173,13 @@ impl<W: Iterator<Item = Value>, J: Jet> Converter<Commit<J>, Redeem<J>> for Simp
169173

170174
fn convert_witness(
171175
&mut self,
172-
_: &PostOrderIterItem<&CommitNode<J>>,
176+
data: &PostOrderIterItem<&CommitNode<J>>,
173177
_: &NoWitness,
174178
) -> Result<Value, Self::Error> {
175-
self.iter.next().ok_or(crate::Error::NoMoreWitnesses)
179+
Ok(self
180+
.iter
181+
.next()
182+
.unwrap_or_else(|| Value::zero(&data.node.arrow().target)))
176183
}
177184

178185
fn convert_disconnect(

‎src/node/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ mod display;
7878
mod hiding;
7979
mod inner;
8080
mod redeem;
81-
mod witness;
8281

8382
use crate::value::Word;
8483
pub use commit::{Commit, CommitData, CommitNode};
@@ -89,7 +88,6 @@ use display::DisplayExpr;
8988
pub use hiding::Hiding;
9089
pub use inner::Inner;
9190
pub use redeem::{Redeem, RedeemData, RedeemNode};
92-
pub use witness::{Witness, WitnessData, WitnessNode};
9391

9492
// This trait should only be implemented on empty types, so we can demand
9593
// every trait bound under the sun. Doing so will make #[derive]s easier

‎src/node/redeem.rs

+33-28
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ use crate::bit_machine::{ExecutionError, SetTracker};
55
use crate::dag::{DagLike, InternalSharing, MaxSharing, PostOrderIterItem};
66
use crate::jet::Jet;
77
use crate::types::{self, arrow::FinalArrow};
8-
use crate::{encode, BitMachine, WitnessNode};
8+
use crate::{encode, BitMachine};
99
use crate::{Amr, BitIter, BitWriter, Cmr, Error, FirstPassImr, Imr, Value};
1010

1111
use super::{
12-
Commit, CommitData, CommitNode, Construct, ConstructNode, Constructible, Converter, Hide,
13-
Inner, Marker, NoDisconnect, NoWitness, Node, Witness, WitnessData,
12+
Commit, CommitData, CommitNode, Construct, ConstructData, ConstructNode, Constructible,
13+
Converter, Hide, Inner, Marker, NoDisconnect, NoWitness, Node,
1414
};
1515

1616
use std::collections::HashSet;
@@ -221,15 +221,15 @@ impl<J: Jet> RedeemNode<J> {
221221
self.convert::<MaxSharing<Redeem<J>>, _, _>(&mut Unfinalizer(PhantomData))
222222
}
223223

224-
/// Convert a [`RedeemNode`] back into a [`WitnessNode`]
224+
/// Convert a [`RedeemNode`] back into a [`ConstructNode`]
225225
/// by loosening the finalized types, witness data and disconnected branches.
226-
pub fn to_witness_node(&self) -> Arc<WitnessNode<J>> {
227-
struct ToWitness<J> {
226+
pub fn to_construct_node(&self) -> Arc<ConstructNode<J>> {
227+
struct ToConstruct<J> {
228228
inference_context: types::Context,
229229
phantom: PhantomData<J>,
230230
}
231231

232-
impl<J: Jet> Converter<Redeem<J>, Witness<J>> for ToWitness<J> {
232+
impl<J: Jet> Converter<Redeem<J>, Construct<J>> for ToConstruct<J> {
233233
type Error = ();
234234

235235
fn convert_witness(
@@ -243,31 +243,31 @@ impl<J: Jet> RedeemNode<J> {
243243
fn convert_disconnect(
244244
&mut self,
245245
_: &PostOrderIterItem<&Node<Redeem<J>>>,
246-
right: Option<&Arc<Node<Witness<J>>>>,
246+
right: Option<&Arc<Node<Construct<J>>>>,
247247
_: &Arc<RedeemNode<J>>,
248-
) -> Result<Option<Arc<Node<Witness<J>>>>, Self::Error> {
248+
) -> Result<Option<Arc<Node<Construct<J>>>>, Self::Error> {
249249
Ok(right.cloned())
250250
}
251251

252252
fn convert_data(
253253
&mut self,
254254
_: &PostOrderIterItem<&Node<Redeem<J>>>,
255255
inner: Inner<
256-
&Arc<Node<Witness<J>>>,
256+
&Arc<Node<Construct<J>>>,
257257
J,
258-
&Option<Arc<WitnessNode<J>>>,
258+
&Option<Arc<ConstructNode<J>>>,
259259
&Option<Value>,
260260
>,
261-
) -> Result<WitnessData<J>, Self::Error> {
261+
) -> Result<ConstructData<J>, Self::Error> {
262262
let inner = inner
263263
.map(|node| node.cached_data())
264264
.map_witness(|maybe_value| maybe_value.clone());
265-
Ok(WitnessData::from_inner(&self.inference_context, inner)
265+
Ok(ConstructData::from_inner(&self.inference_context, inner)
266266
.expect("types were already finalized"))
267267
}
268268
}
269269

270-
self.convert::<InternalSharing, _, _>(&mut ToWitness {
270+
self.convert::<InternalSharing, _, _>(&mut ToConstruct {
271271
inference_context: types::Context::new(),
272272
phantom: PhantomData,
273273
})
@@ -297,7 +297,7 @@ impl<J: Jet> RedeemNode<J> {
297297
phantom: PhantomData<J>,
298298
}
299299

300-
impl<J: Jet> Converter<Redeem<J>, Witness<J>> for Pruner<J> {
300+
impl<J: Jet> Converter<Redeem<J>, Construct<J>> for Pruner<J> {
301301
type Error = std::convert::Infallible;
302302

303303
fn convert_witness(
@@ -313,9 +313,9 @@ impl<J: Jet> RedeemNode<J> {
313313
fn convert_disconnect(
314314
&mut self,
315315
_: &PostOrderIterItem<&RedeemNode<J>>,
316-
right: Option<&Arc<WitnessNode<J>>>,
316+
right: Option<&Arc<ConstructNode<J>>>,
317317
_: &Arc<RedeemNode<J>>,
318-
) -> Result<Option<Arc<WitnessNode<J>>>, Self::Error> {
318+
) -> Result<Option<Arc<ConstructNode<J>>>, Self::Error> {
319319
debug_assert!(
320320
right.is_some(),
321321
"disconnected branch should exist in unpruned redeem program"
@@ -326,8 +326,8 @@ impl<J: Jet> RedeemNode<J> {
326326
fn prune_case(
327327
&mut self,
328328
data: &PostOrderIterItem<&RedeemNode<J>>,
329-
_left: &Arc<WitnessNode<J>>,
330-
_right: &Arc<WitnessNode<J>>,
329+
_left: &Arc<ConstructNode<J>>,
330+
_right: &Arc<ConstructNode<J>>,
331331
) -> Result<Hide, Self::Error> {
332332
// The IMR of the pruned program may change,
333333
// but the Converter trait gives us access to the unpruned node (`data`).
@@ -346,25 +346,30 @@ impl<J: Jet> RedeemNode<J> {
346346
fn convert_data(
347347
&mut self,
348348
_: &PostOrderIterItem<&RedeemNode<J>>,
349-
inner: Inner<&Arc<WitnessNode<J>>, J, &Option<Arc<WitnessNode<J>>>, &Option<Value>>,
350-
) -> Result<WitnessData<J>, Self::Error> {
349+
inner: Inner<
350+
&Arc<ConstructNode<J>>,
351+
J,
352+
&Option<Arc<ConstructNode<J>>>,
353+
&Option<Value>,
354+
>,
355+
) -> Result<ConstructData<J>, Self::Error> {
351356
let converted_inner = inner
352357
.map(|node| node.cached_data())
353358
.map_witness(Option::<Value>::clone);
354-
let retyped = WitnessData::from_inner(&self.inference_context, converted_inner)
359+
let retyped = ConstructData::from_inner(&self.inference_context, converted_inner)
355360
.expect("pruned types should check out if unpruned types check out");
356361
Ok(retyped)
357362
}
358363
}
359364

360365
struct Finalizer<J>(PhantomData<J>);
361366

362-
impl<J: Jet> Converter<Witness<J>, Redeem<J>> for Finalizer<J> {
367+
impl<J: Jet> Converter<Construct<J>, Redeem<J>> for Finalizer<J> {
363368
type Error = std::convert::Infallible;
364369

365370
fn convert_witness(
366371
&mut self,
367-
data: &PostOrderIterItem<&WitnessNode<J>>,
372+
data: &PostOrderIterItem<&ConstructNode<J>>,
368373
witness: &Option<Value>,
369374
) -> Result<Value, Self::Error> {
370375
let pruned_target_ty = data
@@ -383,9 +388,9 @@ impl<J: Jet> RedeemNode<J> {
383388

384389
fn convert_disconnect(
385390
&mut self,
386-
_: &PostOrderIterItem<&WitnessNode<J>>,
391+
_: &PostOrderIterItem<&ConstructNode<J>>,
387392
right: Option<&Arc<RedeemNode<J>>>,
388-
_: &Option<Arc<WitnessNode<J>>>,
393+
_: &Option<Arc<ConstructNode<J>>>,
389394
) -> Result<Arc<RedeemNode<J>>, Self::Error> {
390395
Ok(right
391396
.map(Arc::clone)
@@ -394,7 +399,7 @@ impl<J: Jet> RedeemNode<J> {
394399

395400
fn convert_data(
396401
&mut self,
397-
data: &PostOrderIterItem<&WitnessNode<J>>,
402+
data: &PostOrderIterItem<&ConstructNode<J>>,
398403
inner: Inner<&Arc<RedeemNode<J>>, J, &Arc<RedeemNode<J>>, &Value>,
399404
) -> Result<Arc<RedeemData<J>>, Self::Error> {
400405
// Finalize target types of witness nodes in advance so we can prune their values.
@@ -457,7 +462,7 @@ impl<J: Jet> RedeemNode<J> {
457462
fn convert_witness(
458463
&mut self,
459464
data: &PostOrderIterItem<&ConstructNode<J>>,
460-
_: &NoWitness,
465+
_: &Option<Value>,
461466
) -> Result<Value, Self::Error> {
462467
let arrow = data.node.data.arrow();
463468
let target_ty = arrow.target.finalize()?;

‎src/node/witness.rs

-284
This file was deleted.

‎src/policy/ast.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@ use std::sync::Arc;
1313
use std::{fmt, iter, mem};
1414

1515
use crate::jet::Elements;
16-
use crate::node::{
17-
ConstructNode, CoreConstructible, JetConstructible, NoWitness, WitnessConstructible,
18-
};
16+
use crate::node::{ConstructNode, CoreConstructible, JetConstructible, WitnessConstructible};
1917
use crate::policy::serialize::{self, AssemblyConstructible};
20-
use crate::types;
18+
use crate::{types, Value};
2119
use crate::{Cmr, CommitNode, FailEntropy};
2220
use crate::{SimplicityKey, ToXOnlyPubkey, Translator};
2321

@@ -63,7 +61,7 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
6361
where
6462
N: CoreConstructible
6563
+ JetConstructible<Elements>
66-
+ WitnessConstructible<NoWitness>
64+
+ WitnessConstructible<Option<Value>>
6765
+ AssemblyConstructible,
6866
{
6967
match *self {
@@ -73,12 +71,10 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
7371
Policy::Trivial => Some(serialize::trivial(inference_context)),
7472
Policy::After(n) => Some(serialize::after(inference_context, n)),
7573
Policy::Older(n) => Some(serialize::older(inference_context, n)),
76-
Policy::Key(ref key) => Some(serialize::key(inference_context, key, NoWitness)),
77-
Policy::Sha256(ref hash) => Some(serialize::sha256::<Pk, _, _>(
78-
inference_context,
79-
hash,
80-
NoWitness,
81-
)),
74+
Policy::Key(ref key) => Some(serialize::key(inference_context, key, None)),
75+
Policy::Sha256(ref hash) => {
76+
Some(serialize::sha256::<Pk, _, _>(inference_context, hash, None))
77+
}
8278
Policy::And {
8379
ref left,
8480
ref right,
@@ -93,17 +89,15 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
9389
} => {
9490
let left = left.serialize_no_witness(inference_context)?;
9591
let right = right.serialize_no_witness(inference_context)?;
96-
Some(serialize::or(&left, &right, NoWitness))
92+
Some(serialize::or(&left, &right, None))
9793
}
9894
Policy::Threshold(k, ref subs) => {
9995
let k = u32::try_from(k).expect("can have k at most 2^32 in a threshold");
10096
let subs = subs
10197
.iter()
10298
.map(|sub| sub.serialize_no_witness(inference_context))
10399
.collect::<Option<Vec<N>>>()?;
104-
let wits = iter::repeat(NoWitness)
105-
.take(subs.len())
106-
.collect::<Vec<NoWitness>>();
100+
let wits = iter::repeat(None).take(subs.len()).collect::<Vec<_>>();
107101
Some(serialize::threshold(k, &subs, &wits))
108102
}
109103
Policy::Assembly(cmr) => N::assembly(inference_context, cmr),

‎src/policy/satisfy.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::analysis::Cost;
44
use crate::jet::Elements;
5-
use crate::node::{Hiding, RedeemNode, WitnessNode};
5+
use crate::node::{ConstructNode, Hiding, RedeemNode};
66
use crate::policy::ToXOnlyPubkey;
77
use crate::types;
88
use crate::{Cmr, Policy, Value};
@@ -57,7 +57,7 @@ pub trait Satisfier<Pk: ToXOnlyPubkey> {
5757
///
5858
/// If the assembly program fails to run for the current transaction environment,
5959
/// then implementations should return `None`.
60-
fn lookup_asm_program(&self, _: Cmr) -> Option<Arc<WitnessNode<Elements>>> {
60+
fn lookup_asm_program(&self, _: Cmr) -> Option<Arc<ConstructNode<Elements>>> {
6161
None
6262
}
6363
}
@@ -105,7 +105,7 @@ pub enum SatisfierError {
105105
AssemblyFailed(crate::bit_machine::ExecutionError),
106106
}
107107

108-
type SatResult = Hiding<Arc<WitnessNode<Elements>>>;
108+
type SatResult = Hiding<Arc<ConstructNode<Elements>>>;
109109

110110
fn ok_if(condition: bool, expr: SatResult) -> SatResult {
111111
match condition {
@@ -278,7 +278,7 @@ mod tests {
278278
pub struct PolicySatisfier<'a, Pk: SimplicityKey> {
279279
pub preimages: HashMap<Pk::Sha256, Preimage32>,
280280
pub signatures: HashMap<Pk, elements::SchnorrSig>,
281-
pub assembly: HashMap<Cmr, Arc<WitnessNode<Elements>>>,
281+
pub assembly: HashMap<Cmr, Arc<ConstructNode<Elements>>>,
282282
pub tx: &'a elements::Transaction,
283283
pub index: usize,
284284
}
@@ -305,7 +305,7 @@ mod tests {
305305
<elements::LockTime as Satisfier<Pk>>::check_after(&self.tx.lock_time, locktime)
306306
}
307307

308-
fn lookup_asm_program(&self, cmr: Cmr) -> Option<Arc<WitnessNode<Elements>>> {
308+
fn lookup_asm_program(&self, cmr: Cmr) -> Option<Arc<ConstructNode<Elements>>> {
309309
self.assembly.get(&cmr).cloned()
310310
}
311311
}
@@ -681,12 +681,12 @@ mod tests {
681681

682682
let mut assert_branch = |witness0: Value, witness1: Value| {
683683
let asm_program = serialize::verify_bexp(
684-
&Arc::<WitnessNode<Elements>>::pair(
685-
&Arc::<WitnessNode<Elements>>::witness(&ctx, Some(witness0.clone())),
686-
&Arc::<WitnessNode<Elements>>::witness(&ctx, Some(witness1.clone())),
684+
&Arc::<ConstructNode<Elements>>::pair(
685+
&Arc::<ConstructNode<Elements>>::witness(&ctx, Some(witness0.clone())),
686+
&Arc::<ConstructNode<Elements>>::witness(&ctx, Some(witness1.clone())),
687687
)
688688
.expect("sound types"),
689-
&Arc::<WitnessNode<Elements>>::jet(&ctx, Elements::Eq8),
689+
&Arc::<ConstructNode<Elements>>::jet(&ctx, Elements::Eq8),
690690
);
691691
let cmr = asm_program.cmr();
692692
satisfier.assembly.insert(cmr, asm_program);

‎src/types/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ mod tests {
440440
use super::*;
441441

442442
use crate::jet::Core;
443-
use crate::node::{ConstructNode, CoreConstructible, WitnessNode};
443+
use crate::node::{ConstructNode, CoreConstructible};
444444

445445
#[test]
446446
fn inference_failure() {
@@ -464,9 +464,9 @@ mod tests {
464464
#[test]
465465
fn memory_leak() {
466466
let ctx = Context::new();
467-
let iden = Arc::<WitnessNode<Core>>::iden(&ctx);
468-
let drop = Arc::<WitnessNode<Core>>::drop_(&iden);
469-
let case = Arc::<WitnessNode<Core>>::case(&iden, &drop).unwrap();
467+
let iden = Arc::<ConstructNode<Core>>::iden(&ctx);
468+
let drop = Arc::<ConstructNode<Core>>::drop_(&iden);
469+
let case = Arc::<ConstructNode<Core>>::case(&iden, &drop).unwrap();
470470

471471
let _ = format!("{:?}", case.arrow().source);
472472
}

0 commit comments

Comments
 (0)
Please sign in to comment.