Skip to content

Commit e0571aa

Browse files
committed
Implement finalization
1 parent cd14fbc commit e0571aa

File tree

1 file changed

+83
-3
lines changed

1 file changed

+83
-3
lines changed

src/core/commit.rs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@
1313
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
1414
//
1515

16-
use crate::core::Value;
17-
use crate::impl_ref_wrapper;
16+
use crate::core::iter::DagIterable;
17+
use crate::core::node::NodeInner;
18+
use crate::core::{Node, Value};
19+
use crate::decode::WitnessIterator;
1820
use crate::jet::{Application, JetNode};
19-
use crate::merkle::cmr;
2021
use crate::merkle::cmr::Cmr;
22+
use crate::merkle::{cmr, imr};
23+
use crate::{analysis, impl_ref_wrapper, inference, Error};
24+
use std::collections::HashMap;
2125
use std::rc::Rc;
2226

2327
/// Underlying combinator of a [`CommitNode`].
@@ -358,6 +362,82 @@ impl<Witness, App: Application> CommitNode<Witness, App> {
358362
| CommitNodeInner::Disconnect(_, r) => Some(r),
359363
}
360364
}
365+
366+
/// Create a new DAG, enriched with the witness and computed metadata.
367+
pub fn finalize<W: WitnessIterator>(
368+
&self,
369+
mut witness: W,
370+
) -> Result<Rc<Node<Value, App>>, Error> {
371+
let root = RefWrapper(self);
372+
let post_order_it = root.iter_post_order();
373+
let arrows = inference::get_arrows(post_order_it.clone())?;
374+
let mut to_finalized: HashMap<RefWrapper<Witness, App>, Rc<Node<Value, App>>> =
375+
HashMap::new();
376+
377+
for commit in post_order_it {
378+
let left = commit.get_left().map(|x| {
379+
to_finalized
380+
.get(&x)
381+
.expect("Children come before parent in post order")
382+
.clone()
383+
});
384+
let right = commit.get_right().map(|x| {
385+
to_finalized
386+
.get(&x)
387+
.expect("Children come before parent in post order")
388+
.clone()
389+
});
390+
391+
let ty = arrows.finalize(&commit)?;
392+
let value = if let CommitNodeInner::Witness(_) = commit.0.inner {
393+
Some(witness.next(&ty.target)?)
394+
} else {
395+
None
396+
};
397+
let imr = imr::compute_imr(
398+
&commit.0.inner,
399+
left.clone(),
400+
right.clone(),
401+
value.as_ref(),
402+
&ty,
403+
);
404+
let bounds = analysis::compute_bounds(commit.0, left.clone(), right.clone(), &ty);
405+
406+
// Verbose but necessary thanks to Rust
407+
let inner = match commit.0.inner {
408+
CommitNodeInner::Iden => NodeInner::Iden,
409+
CommitNodeInner::Unit => NodeInner::Unit,
410+
CommitNodeInner::InjL(_) => NodeInner::InjL(left.unwrap()),
411+
CommitNodeInner::InjR(_) => NodeInner::InjR(left.unwrap()),
412+
CommitNodeInner::Take(_) => NodeInner::Take(left.unwrap()),
413+
CommitNodeInner::Drop(_) => NodeInner::Drop(left.unwrap()),
414+
CommitNodeInner::Comp(_, _) => NodeInner::Comp(left.unwrap(), right.unwrap()),
415+
CommitNodeInner::Case(_, _) => NodeInner::Case(left.unwrap(), right.unwrap()),
416+
CommitNodeInner::AssertL(_, _) => NodeInner::AssertL(left.unwrap(), right.unwrap()),
417+
CommitNodeInner::AssertR(_, _) => NodeInner::AssertR(left.unwrap(), right.unwrap()),
418+
CommitNodeInner::Pair(_, _) => NodeInner::Pair(left.unwrap(), right.unwrap()),
419+
CommitNodeInner::Disconnect(_, _) => {
420+
NodeInner::Disconnect(left.unwrap(), right.unwrap())
421+
}
422+
CommitNodeInner::Witness(_) => NodeInner::Witness(value.unwrap()),
423+
CommitNodeInner::Fail(hl, hr) => NodeInner::Fail(hl, hr),
424+
CommitNodeInner::Hidden(h) => NodeInner::Hidden(h),
425+
CommitNodeInner::Jet(jet) => NodeInner::Jet(jet),
426+
};
427+
let node = Node {
428+
inner,
429+
cmr: commit.0.cmr,
430+
imr,
431+
ty,
432+
bounds,
433+
};
434+
435+
to_finalized.insert(commit, Rc::new(node));
436+
}
437+
438+
witness.finish()?;
439+
Ok(to_finalized.get(&root).unwrap().clone())
440+
}
361441
}
362442

363443
/// Wrapper of references to [`CommitNode`].

0 commit comments

Comments
 (0)