simplicity/
lib.rs

1// SPDX-License-Identifier: CC0-1.0
2
3#![cfg_attr(bench, feature(test))]
4#![allow(
5    // we use `bool` to represent bits and frequentely assert_eq against them
6    clippy::bool_assert_comparison,
7    // we use () as the environment for Core (FIXME we should probabl use a newtype)
8    clippy::let_unit_value,
9    // We write map(Arc::clone) to signify that a cheap Arc is being cloned
10    clippy::map_clone
11)]
12
13#[cfg(feature = "bitcoin")]
14pub extern crate bitcoin;
15#[cfg(feature = "elements")]
16pub extern crate elements;
17#[cfg(feature = "serde")]
18pub extern crate serde;
19
20/// Re-export of byteorder crate
21pub extern crate byteorder;
22/// Re-export of hashes crate
23pub extern crate hashes;
24/// Re-export of hex crate
25pub extern crate hex;
26
27#[cfg(bench)]
28extern crate test;
29
30#[macro_use]
31mod macros;
32
33mod analysis;
34mod bit_encoding;
35pub mod bit_machine;
36pub mod dag;
37pub mod human_encoding;
38pub mod jet;
39mod merkle;
40pub mod node;
41#[cfg(feature = "elements")]
42pub mod policy;
43pub mod types;
44mod value;
45
46pub use bit_encoding::decode;
47pub use bit_encoding::encode;
48pub use bit_encoding::{
49    u2, BitCollector, BitIter, CloseError as BitIterCloseError, EarlyEndOfStreamError,
50};
51pub use bit_encoding::{write_to_vec, BitWriter};
52
53#[cfg(feature = "elements")]
54pub use crate::policy::{
55    sighash, Policy, Preimage32, Satisfier, SimplicityKey, ToXOnlyPubkey, Translator,
56};
57
58pub use crate::analysis::{Cost, NodeBounds};
59pub use crate::bit_machine::BitMachine;
60pub use crate::encode::{encode_natural, encode_value, encode_witness};
61pub use crate::merkle::{
62    amr::Amr,
63    cmr::Cmr,
64    ihr::{Ihr, Imr},
65    tmr::Tmr,
66    FailEntropy, HasCmr,
67};
68pub use crate::node::{CommitNode, ConstructNode, Hiding, RedeemNode};
69pub use crate::value::{Value, ValueRef, Word};
70pub use simplicity_sys as ffi;
71use std::fmt;
72
73/// Return the version of Simplicity leaves inside a tap tree.
74#[cfg(feature = "elements")]
75pub fn leaf_version() -> elements::taproot::LeafVersion {
76    elements::taproot::LeafVersion::from_u8(0xbe).expect("constant leaf version")
77}
78
79/// Error type for simplicity
80#[non_exhaustive]
81#[derive(Debug)]
82pub enum Error {
83    /// Decoder error
84    Decode(decode::Error),
85    /// A disconnect node was *not* populated at redeem time
86    DisconnectRedeemTime,
87    /// Type-checking error
88    Type(types::Error),
89    // Execution error
90    Execution(bit_machine::ExecutionError),
91    /// Tried to parse a jet but the name wasn't recognized
92    InvalidJetName(String),
93    /// Policy error
94    #[cfg(feature = "elements")]
95    Policy(policy::Error),
96}
97
98impl fmt::Display for Error {
99    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100        match self {
101            Error::Decode(ref e) => fmt::Display::fmt(e, f),
102            Error::DisconnectRedeemTime => {
103                f.write_str("disconnect node had one child (redeem time); must have two")
104            }
105            Error::Type(ref e) => fmt::Display::fmt(e, f),
106            Error::Execution(ref e) => fmt::Display::fmt(e, f),
107            Error::InvalidJetName(s) => write!(f, "unknown jet `{}`", s),
108            #[cfg(feature = "elements")]
109            Error::Policy(ref e) => fmt::Display::fmt(e, f),
110        }
111    }
112}
113
114impl std::error::Error for Error {
115    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
116        match *self {
117            Error::Decode(ref e) => Some(e),
118            Error::DisconnectRedeemTime => None,
119            Error::Type(ref e) => Some(e),
120            Error::Execution(ref e) => Some(e),
121            Error::InvalidJetName(..) => None,
122            #[cfg(feature = "elements")]
123            Error::Policy(ref e) => Some(e),
124        }
125    }
126}
127
128impl From<crate::decode::Error> for Error {
129    fn from(e: crate::decode::Error) -> Error {
130        Error::Decode(e)
131    }
132}
133
134impl From<EarlyEndOfStreamError> for Error {
135    fn from(e: EarlyEndOfStreamError) -> Error {
136        Error::Decode(e.into())
137    }
138}
139
140impl From<crate::types::Error> for Error {
141    fn from(e: crate::types::Error) -> Error {
142        Error::Type(e)
143    }
144}
145
146#[cfg(feature = "elements")]
147impl From<policy::Error> for Error {
148    fn from(e: policy::Error) -> Error {
149        Error::Policy(e)
150    }
151}