Skip to main content

Node

Struct Node 

Source
pub struct Node<N: Marker> { /* private fields */ }
Expand description

A node in a Simplicity expression.

There are three node types provided by this library: ConstructNode, CommitNode, and RedeemNode, which represent Simplicty programs during construction, at commitment time, and at redemption time, respectively.

This generic structure is used to define conversions and mapping functions over nodes and DAGs, and allows users to define their own custom node types.

For equality and hashing purposes, nodes are characterized entirely by their CMR and cached data. Users who create custom nodes should define a custom type for Marker::CachedData and think carefully about whether and how to implement the std::hash::Hash or equality traits.

Implementations§

Source§

impl Node<Commit>

Source

pub fn arrow(&self) -> &FinalArrow

Accessor for the node’s arrow

Source

pub fn amr(&self) -> Option<Amr>

Accessor for the node’s AMR, if known

Source

pub fn ihr(&self) -> Option<Ihr>

Accessor for the node’s IHR, if known

Source

pub fn finalize<C: Converter<Commit, Redeem>>( &self, converter: &mut C, ) -> Result<Arc<RedeemNode>, C::Error>

Finalizes a DAG, by iterating through through it without sharing, attaching witnesses, and hiding branches.

This is a thin wrapper around Node::convert which fixes a few types to make it easier to use.

Source

pub fn unfinalize_types<'brand>( &self, inference_context: &Context<'brand>, ) -> Result<Arc<ConstructNode<'brand>>, Error>

Convert a CommitNode back to a ConstructNode by redoing type inference

Source

pub fn decode<I: Iterator<Item = u8>, J: Jet>( bits: BitIter<I>, ) -> Result<Arc<Self>, DecodeError>

Decode a Simplicity program from bits, without witness data.

§Usage

Use this method only if the serialization does not include the witness data. This means, the program simply has no witness during commitment, or the witness is provided by other means.

If the serialization contains the witness data, then use RedeemNode::decode().

Source

pub fn encode(&self, w: &mut BitWriter<&mut dyn Write>) -> Result<usize>

👎Deprecated since 0.5.0:

use Self::encode_without_witness instead

Encode a Simplicity expression to bits without any witness data

Source

pub fn encode_to_vec(&self) -> Vec<u8>

👎Deprecated since 0.5.0:

use Self::to_vec_without_witness instead

Encode a Simplicity program to a vector of bytes, without any witness data.

Source§

impl<'brand> Node<Construct<'brand>>

Source

pub fn arrow(&self) -> &Arrow<'brand>

Accessor for the node’s arrow

Source

pub fn set_arrow_to_program(&self) -> Result<(), Error>

Sets the source and target type of the node to unit

Source

pub fn finalize_types(&self) -> Result<Arc<CommitNode>, Error>

Convert a ConstructNode to a CommitNode by finalizing all of the types.

Also sets the source and target type of this node to unit. This is almost certainly what you want, since the resulting CommitNode cannot be further composed, and needs to be 1->1 to go on-chain. But if you don’t, call Self::finalize_types_non_program instead.

Source

pub fn finalize_types_non_program(&self) -> Result<Arc<CommitNode>, Error>

Convert a ConstructNode to a CommitNode by finalizing all of the types.

Does not sets the source and target type of this node to unit.

Source

pub fn finalize_unpruned(&self) -> Result<Arc<RedeemNode>, FinalizeError>

Finalize the witness program as an unpruned redeem program.

Witness nodes must be populated with sufficient data, to ensure that the resulting redeem program successfully runs on the Bit Machine. Furthermore, all disconnected branches must be populated, even those that are not executed.

The resulting redeem program is not pruned.

§See

RedeemNode::prune

Source

pub fn finalize_pruned<JE: JetEnvironment>( &self, env: &JE, ) -> Result<Arc<RedeemNode>, FinalizeError>

Finalize the witness program as a pruned redeem program.

Witness nodes must be populated with sufficient data, to ensure that the resulting redeem program successfully runs on the Bit Machine. Furthermore, all disconnected branches must be populated, even those that are not executed.

The resulting redeem program is pruned based on the given transaction environment.

§See

RedeemNode::prune

Source

pub fn decode<I: Iterator<Item = u8>, J: Jet>( context: &Context<'brand>, bits: BitIter<I>, ) -> Result<Arc<Self>, Error>

Decode a Simplicity expression from bits, without witness data.

§Usage

Use this method only if the serialization does not include the witness data. This means, the program simply has no witness during commitment, or the witness is provided by other means.

If the serialization contains the witness data, then use crate::RedeemNode::decode().

Source

pub fn encode(&self, w: &mut BitWriter<&mut dyn Write>) -> Result<usize>

👎Deprecated since 0.5.0:

use Self::encode_without_witness instead

Encode a Simplicity expression to bits, with no witness data

Source§

impl Node<Redeem>

Source

pub fn amr(&self) -> Amr

Accessor for the node’s AMR

Source

pub fn ihr(&self) -> Ihr

Accessor for the node’s IHR

Source

pub fn arrow(&self) -> &FinalArrow

Accessor for the node’s type arrow

Source

pub fn bounds(&self) -> NodeBounds

Accessor for the node’s bit machine bounds

Source

pub fn unfinalize(&self) -> Result<Arc<CommitNode>, Error>

Convert a RedeemNode back to a CommitNode by forgetting witnesses and cached data.

Source

pub fn to_construct_node<'brand>( &self, inference_context: &Context<'brand>, ) -> Arc<ConstructNode<'brand>>

Convert a RedeemNode back into a ConstructNode by loosening the finalized types, witness data and disconnected branches.

Source

pub fn prune<JE: JetEnvironment>( &self, env: &JE, ) -> Result<Arc<RedeemNode>, ExecutionError>

Prune the redeem program for the given transaction environment.

Pruning works as follows:

  1. Run the redeem program on the Bit Machine.
  2. Mark all (un)used case branches using the IHR of the case node.
  3. Rebuild the program and omit unused branches.

The pruning result depends on the witness data (which is already part of the redeem program) and on the transaction environment. These two inputs determine which case branches are used and which are not. Pruning must be done for each transaction environment separately, starting from the same original, unpruned program. Pruning is a lossy process, so pruning an already pruned program is not sound.

Pruning fails if the original, unpruned program fails to run on the Bit Machine (step 1). In this case, the witness data needs to be revised. The other pruning steps (2 & 3) never fail.

Source

pub fn prune_with_tracker<JE: JetEnvironment, T: PruneTracker>( &self, env: &JE, tracker: &mut T, ) -> Result<Arc<RedeemNode>, ExecutionError>

Prune the redeem program, as in Self::prune, but with a custom tracker which can introspect or control pruning.

See crate::bit_machine::StderrTracker as an example which outputs the IHR of each case combinator that we prune a child of.

Source

pub fn decode<I1, I2, J: Jet>( program: BitIter<I1>, witness: BitIter<I2>, ) -> Result<Arc<Self>, DecodeError>
where I1: Iterator<Item = u8>, I2: Iterator<Item = u8>,

Decode a Simplicity program from bits, including the witness data.

Source

pub fn encode( &self, prog: &mut BitWriter<&mut dyn Write>, witness: &mut BitWriter<&mut dyn Write>, ) -> Result<usize>

👎Deprecated since 0.5.0:

use Self::encode_with_witness instead

Encode the program to bits.

Includes witness data. Returns the number of written bits.

Source

pub fn encode_to_vec(&self) -> (Vec<u8>, Vec<u8>)

👎Deprecated since 0.5.0:

use Self::to_vec_with_witness instead

Encode the program and witness data to byte vectors.

Source§

impl<N: Marker> Node<N>

Source

pub fn inner(&self) -> &Inner<Arc<Node<N>>, N::Disconnect, N::Witness>

Accessor for the node’s “inner value”, i.e. its combinator

Source

pub fn cmr(&self) -> Cmr

Accessor for the node’s CMR

Source

pub fn sharing_id(&self) -> Option<N::SharingId>

Accessor for the node’s cached data

Source

pub fn cached_data(&self) -> &N::CachedData

Accessor for the node’s cached data

Source

pub fn from_parts( inner: Inner<Arc<Self>, N::Disconnect, N::Witness>, data: N::CachedData, ) -> Self

Contruct a node from its constituent parts.

This method can be used to directly costruct a node. It will compute the CMR automatically based on the value of inner but requires that cached_data be provided.

If available, Constructible and its dependent traits will be easier to use.

Source

pub fn convert<S, M, C>( &self, converter: &mut C, ) -> Result<Arc<Node<M>>, C::Error>
where S: for<'a> SharingTracker<&'a Self> + Default, M: Marker, C: Converter<N, M>,

Generic conversion function from one type of node to another, with the ability to prune during the conversion.

Parameterized over what kind of sharing to use when iterating over the DAG, and what conversion logic to use.

See the documentation for Converter for details.

Source

pub fn display(&self) -> Display<'_, N>

Source

pub fn display_expr(&self) -> DisplayExpr<'_, N>

Display the Simplicity expression as a linear string.

The linear string has no sharing and may be exponentially larger than the originally shared expression!

Source

pub fn display_as_graph( &self, format: GraphFormat, sharing_level: SharingLevel, ) -> DisplayAsGraph<'_, N>

Display the Simplicity expression as a graph in the given format and sharing level.

This is the general form of display_as_dot and display_as_mermaid. Use those convenience methods for the common case of DOT or Mermaid output with no sharing.

The format field of the returned DisplayAsGraph can be changed after construction, and the fmt::Display impl will use whatever format and sharing are set at that point. See also DisplayAsGraph::to_dot_string and DisplayAsGraph::to_mermaid_string to render to a specific format regardless of the stored format field.

Source

pub fn display_as_dot(&self) -> DisplayAsGraph<'_, N>

Display the Simplicity expression as a Graphviz DOT graph.

The DOT output can be rendered with dot -Tsvg or similar tools. Shared nodes appear once in the graph with multiple incoming edges.

Source

pub fn display_as_mermaid(&self) -> DisplayAsGraph<'_, N>

Display the Simplicity expression as a Mermaid diagram.

The Mermaid output can be rendered in Markdown or the Mermaid live editor. Shared nodes appear once in the diagram with multiple incoming edges.

Source

pub fn encode_without_witness(&self, prog: &mut dyn Write) -> Result<usize>

Encode a Simplicity expression to bits without any witness data.

Source

pub fn to_vec_without_witness(&self) -> Vec<u8>

Encode a Simplicity expression to a vector of bytes, without any witness data.

Source§

impl<N: Marker<Witness = Value>> Node<N>

Source

pub fn encode_with_witness( &self, prog: &mut dyn Write, witness: &mut dyn Write, ) -> Result<(usize, usize)>

Encode the program and witness data to bits.

Returns the number of written bits for the program and witness, respectively.

Source

pub fn to_vec_with_witness(&self) -> (Vec<u8>, Vec<u8>)

Encode the program and witness data to byte vectors.

Trait Implementations§

Source§

impl<N: Marker> DagLike for &Node<N>

Source§

type Node = Node<N>

The type of the DAG node, with no references or wrappers
Source§

fn data(&self) -> &Node<N>

A pointer to the underlying data
Source§

fn as_dag_node(&self) -> Dag<Self>

Interpret the node as a DAG node
Source§

fn left_child(&self) -> Option<Self>

Accessor for the left child of the node, if one exists
Source§

fn right_child(&self) -> Option<Self>

Accessor for the right child of the node, if one exists
Source§

fn n_children(&self) -> usize

Number of children that the node has. Read more
Source§

fn rtl_post_order_iter<S: SharingTracker<SwapChildren<Self>> + Default>( self, ) -> RtlPostOrderIter<Self, S>

Obtains an iterator of all the nodes rooted at the DAG, in right-to-left post order. Read more
Source§

fn pre_order_iter<S: SharingTracker<Self> + Default>( self, ) -> PreOrderIter<Self, S>

Obtains an iterator of all the nodes rooted at the DAG, in pre-order.
Source§

fn verbose_pre_order_iter<S: SharingTracker<Self> + Default>( self, max_depth: Option<usize>, ) -> VerbosePreOrderIter<Self, S>
where Self: Clone,

Obtains a verbose iterator of all the nodes rooted at the DAG, in pre-order. Read more
Source§

fn post_order_iter<S: SharingTracker<Self> + Default>( self, ) -> PostOrderIter<Self, S>

Obtains an iterator of all the nodes rooted at the DAG, in post order. Read more
Source§

fn is_shared_as<S: SharingTracker<Self> + Default>(self) -> bool
where Self: Clone,

Checks whether a DAG’s internal sharing (as expressed by shared pointers) matches the given target sharing.
Source§

fn post_order_iter_with_tracker<S: SharingTracker<Self>>( self, tracker: S, ) -> PostOrderIter<Self, S>

Obtains an post-order iterator of all the nodes rooted at DAG, using the given tracker. Read more
Source§

impl<N: Marker> Debug for Node<N>
where for<'a> &'a Node<N>: DagLike,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'n, M: Marker> From<&'n Node<M>> for Display<'n, M>

Source§

fn from(node: &'n Node<M>) -> Self

Converts to this type from the input type.
Source§

impl<'a, M: Marker> From<&'a Node<M>> for DisplayExpr<'a, M>

Source§

fn from(node: &'a Node<M>) -> Self

Converts to this type from the input type.
Source§

impl<N: Marker> HasCmr for Node<N>

Source§

fn cmr(&self) -> Cmr

Access the Commitment Merkle Root.
Source§

impl<N: Marker> Hash for Node<N>
where N::CachedData: Hash,

Source§

fn hash<H: Hasher>(&self, h: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<N: Marker> PartialEq for Node<N>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<N: Marker> SharingTracker<&Node<N>> for MaxSharing<N>

Source§

fn record(&mut self, d: &&Node<N>, index: usize) -> Option<usize>

Marks an object as having been seen, and record the index when it was seen. Read more
Source§

fn seen_before(&self, d: &&Node<N>) -> Option<usize>

Check whether an object has been seen before; if so, return the index it was recorded at.
Source§

impl<N: Marker> Eq for Node<N>
where N::CachedData: Eq,

Auto Trait Implementations§

§

impl<N> Freeze for Node<N>
where <N as Marker>::CachedData: Freeze, <N as Marker>::Disconnect: Freeze, <N as Marker>::Witness: Freeze,

§

impl<N> !RefUnwindSafe for Node<N>

§

impl<N> Send for Node<N>
where <N as Marker>::CachedData: Send + Sync, <N as Marker>::Disconnect: Send + Sync, <N as Marker>::Witness: Send + Sync,

§

impl<N> Sync for Node<N>
where <N as Marker>::CachedData: Sync + Send, <N as Marker>::Disconnect: Sync + Send, <N as Marker>::Witness: Sync + Send,

§

impl<N> Unpin for Node<N>
where <N as Marker>::CachedData: Unpin, <N as Marker>::Disconnect: Unpin, <N as Marker>::Witness: Unpin,

§

impl<N> UnsafeUnpin for Node<N>

§

impl<N> !UnwindSafe for Node<N>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,