From 837cb9c18d6ecb86d5dc5dec2d5d103d4ff6e5bd Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 24 Aug 2025 23:59:13 +0000 Subject: [PATCH 1/7] Define a MSRV of 1.78.0 --- README.md | 2 ++ clippy.toml | 1 + 2 files changed, 3 insertions(+) create mode 100644 clippy.toml diff --git a/README.md b/README.md index dc67bfa..b32dfc6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ SimplicityHL looks and feels like [Rust](https://www.rust-lang.org). Just how Ru [A live demo is running](https://ide.simplicity-lang.org). +This project should build on Rust **1.78.0**. + ## Develop the project ### Using Docker diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..a93e948 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +msrv = "1.78.0" From ab54fedb28705fd60f31ad9b7acb43da021d0613 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 25 Aug 2025 00:10:11 +0000 Subject: [PATCH 2/7] delete merkle.rs and unused supporting code `mod merkle` was removed in 24b11afb3663600851f0d591fca54dc17c7e95df but the file it refers to was left hanging around. This results in an unused code warning. With this change, I can run a clean cargo +nightly clippy --all-targets --workspace --all-features --all -- -D warnings --- src/components/merkle.rs | 94 ---------------------------------------- src/util.rs | 40 ----------------- 2 files changed, 134 deletions(-) delete mode 100644 src/components/merkle.rs diff --git a/src/components/merkle.rs b/src/components/merkle.rs deleted file mode 100644 index ed4acb1..0000000 --- a/src/components/merkle.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::sync::Arc; - -use js_sys::{Array, Object}; -use leptos::*; -use simplicityhl::simplicity; -use simplicity::dag::DagLike; -use simplicity::dag::NoSharing; -use simplicity::node; -use wasm_bindgen::prelude::*; - -use crate::util::{DisplayInner, Expression}; - -#[component] -pub fn MerkleExplorer( - run_result: ReadSignal>>, - graph_toggle: ReadSignal, - set_graph_toggle: WriteSignal, -) -> impl IntoView { - move || match run_result.get() { - Some(Ok(_)) => view! { -
-
-
-

Merkle Explorer

- - - - - -
-
-
-
- -
- - - - - - - - - - - - -
-
-
- }, - _ => view! { -
- }, - } -} - -#[wasm_bindgen(module = "/src/assets/js/merkle_graph_d3.js")] -extern "C" { - fn load_merkle_graph_js(dat: JsValue); - fn manualZoom(mode: &str); -} - -fn marshal_merkle_data(expression: &node::Node) -> JsValue { - let mut output = vec![]; - for data in expression.post_order_iter::() { - let text = JsValue::from(DisplayInner::from(data.node).to_string()); - let children = Array::new(); - if data.left_index.is_some() { - children.push(&output.pop().unwrap()); - } - if data.right_index.is_some() { - children.push(&output.pop().unwrap()); - } - let node_obj = Object::new(); - js_sys::Reflect::set(&node_obj, &JsValue::from_str("text"), &text).unwrap(); - js_sys::Reflect::set(&node_obj, &JsValue::from_str("children"), &children).unwrap(); - - output.push(JsValue::from(node_obj)) - } - debug_assert!(output.len() == 1); - output.pop().unwrap() -} - -pub fn reload_graph(expression: Arc) { - let data = marshal_merkle_data(&expression); - load_merkle_graph_js(data); -} diff --git a/src/util.rs b/src/util.rs index 75cde36..d78ff92 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,11 +1,8 @@ -use std::fmt; - use elements::hashes::{sha256, Hash}; use elements::secp256k1_zkp as secp256k1; use secp256k1::rand::{self, Rng, SeedableRng}; use simplicity::dag::{DagLike, MaxSharing, NoSharing}; use simplicity::jet::Elements; -use simplicity::node::Inner; use simplicity::{node, RedeemNode}; use simplicityhl::num::U256; use simplicityhl::simplicity::Preimage32; @@ -115,43 +112,6 @@ pub fn get_compression_factor(node: &node::Node) -> usize { unshared_len / shared_len } -pub struct DisplayInner<'a, M: node::Marker>(&'a node::Node); - -impl<'a, M: node::Marker> From<&'a node::Node> for DisplayInner<'a, M> { - fn from(node: &'a node::Node) -> Self { - Self(node) - } -} - -impl fmt::Display for DisplayInner<'_, M> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0.inner() { - Inner::Iden => f.write_str("iden"), - Inner::Unit => f.write_str("unit"), - Inner::InjL(_) => f.write_str("injl"), - Inner::InjR(_) => f.write_str("injr"), - Inner::Take(_) => f.write_str("take"), - Inner::Drop(_) => f.write_str("drop"), - Inner::Comp(_, _) => f.write_str("comp"), - Inner::Case(_, _) => f.write_str("case"), - Inner::AssertL(_, _) => f.write_str("assertl"), - Inner::AssertR(_, _) => f.write_str("assertr"), - Inner::Pair(_, _) => f.write_str("pair"), - Inner::Disconnect(_, _) => f.write_str("disconnect"), - Inner::Witness(_) => f.write_str("witness"), - Inner::Fail(_) => f.write_str("fail"), - Inner::Jet(jet) => write!(f, "jet_{jet}"), - Inner::Word(value) => write!(f, "const {value}"), - } - } -} - -impl fmt::Debug for DisplayInner<'_, M> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - fn unspendable_internal_key() -> secp256k1::XOnlyPublicKey { secp256k1::XOnlyPublicKey::from_slice(&[ 0xf5, 0x91, 0x9f, 0xa6, 0x4c, 0xe4, 0x5f, 0x83, 0x06, 0x84, 0x90, 0x72, 0xb2, 0x6c, 0x1b, From 1858e6d3082e0922b968aec70284a95b045d7808 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 25 Aug 2025 00:22:27 +0000 Subject: [PATCH 3/7] clippy: fix a bunch of "trivial" lints These are stylistic things that have no effect and don't require moving whole blocks of code around. --- src/components/analysis.rs | 2 +- src/components/app.rs | 2 +- src/components/footer.rs | 4 ++-- src/components/mod.rs | 2 ++ src/components/navbar.rs | 2 +- src/components/program_window/program_tab.rs | 14 +++++++------- src/components/run_window/execution_tab.rs | 4 ++-- src/components/run_window/key_store_tab.rs | 17 ++++++++--------- src/components/run_window/transaction_tab.rs | 14 +++++++------- src/function.rs | 10 +++++----- src/jet.rs | 6 +++--- src/main.rs | 2 +- src/transaction.rs | 9 ++++----- 13 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/components/analysis.rs b/src/components/analysis.rs index 4b23822..6bace9b 100644 --- a/src/components/analysis.rs +++ b/src/components/analysis.rs @@ -1,4 +1,4 @@ -use leptos::*; +use leptos::{component, view, IntoView, ReadSignal, Signal, SignalGet}; use std::str::FromStr; use std::sync::Arc; diff --git a/src/components/app.rs b/src/components/app.rs index 85accf3..f1a0165 100644 --- a/src/components/app.rs +++ b/src/components/app.rs @@ -28,7 +28,7 @@ pub fn App() -> impl IntoView { provide_context(ActiveRunTab::default()); if program.is_empty() { - select_example(examples::get("✍️️ P2PK").expect("P2PK example should exist")) + select_example(examples::get("✍️️ P2PK").expect("P2PK example should exist")); } view! { diff --git a/src/components/footer.rs b/src/components/footer.rs index 7136476..88e8927 100644 --- a/src/components/footer.rs +++ b/src/components/footer.rs @@ -1,4 +1,4 @@ -use leptos::{component, create_signal, view, IntoView, SignalGet, SignalSet, *}; +use leptos::{component, create_signal, view, wasm_bindgen, IntoView, SignalGet, SignalSet}; use wasm_bindgen::JsCast; #[cfg(target_arch = "wasm32")] @@ -69,7 +69,7 @@ fn NewsletterForm() -> impl IntoView { spawn_local(async move { match subscribe_to_newsletter(email_value).await { - Ok(_) => { + Ok(()) => { set_status.set(FormStatus::Success); set_message .set("Thank you for subscribing! We'll keep you updated.".to_string()); diff --git a/src/components/mod.rs b/src/components/mod.rs index 5175873..6342b61 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_pass_by_value)] // leptos has broken lifetime parsing + mod analysis; mod app; mod copy_to_clipboard; diff --git a/src/components/navbar.rs b/src/components/navbar.rs index 620bf53..07097e0 100644 --- a/src/components/navbar.rs +++ b/src/components/navbar.rs @@ -23,7 +23,7 @@ pub fn Navbar( match child { TabView::Tab { name, children } => { tabs_content.push((name, children)); - button_bar.push(view! {}) + button_bar.push(view! {}); } TabView::Button { children } => button_bar.push(children().into_view()), } diff --git a/src/components/program_window/program_tab.rs b/src/components/program_window/program_tab.rs index 63836cb..b97b437 100644 --- a/src/components/program_window/program_tab.rs +++ b/src/components/program_window/program_tab.rs @@ -32,9 +32,9 @@ impl Program { pub fn new(text: String) -> Self { let program = Self { text: create_rw_signal(text), - cached_text: create_rw_signal("".to_string()), - lazy_cmr: create_rw_signal(Err("".to_string())), - lazy_satisfied: create_rw_signal(Err("".to_string())), + cached_text: create_rw_signal(String::new()), + lazy_cmr: create_rw_signal(Err(String::new())), + lazy_satisfied: create_rw_signal(Err(String::new())), }; program.update_on_read(); program @@ -109,9 +109,9 @@ impl Runtime { Self { program, env, - run_succeeded: Default::default(), - debug_output: Default::default(), - error_output: Default::default(), + run_succeeded: RwSignal::default(), + debug_output: RwSignal::default(), + error_output: RwSignal::default(), } } @@ -140,7 +140,7 @@ impl Runtime { return; } }; - let mut runner = Runner::for_program(satisfied_program); + let mut runner = Runner::for_program(&satisfied_program); let success = self.env.with(|env| match runner.run(env) { Ok(..) => { self.error_output.update(String::clear); diff --git a/src/components/run_window/execution_tab.rs b/src/components/run_window/execution_tab.rs index fe7f3f7..3b6386e 100644 --- a/src/components/run_window/execution_tab.rs +++ b/src/components/run_window/execution_tab.rs @@ -10,12 +10,12 @@ pub fn ExecutionTab() -> impl IntoView { let success_string = move || { runtime.error_output.with(|error| match error.is_empty() { true => format!("{}: Success.", get_local_datetime()), - false => "".to_string(), + false => String::new(), }) }; let failure_string = move || { runtime.error_output.with(|error| match error.is_empty() { - true => "".to_string(), + true => String::new(), false => format!("{}:\n{error}", get_local_datetime()), }) }; diff --git a/src/components/run_window/key_store_tab.rs b/src/components/run_window/key_store_tab.rs index 266c578..cece807 100644 --- a/src/components/run_window/key_store_tab.rs +++ b/src/components/run_window/key_store_tab.rs @@ -296,21 +296,20 @@ fn SelectSignedData() -> impl IntoView { thirty_two_bytes_is_insane.set(true); } }; - let update_hash_preimage_bytes = move |event: ev::Event| match >::from_hex( - event_target_value(&event) - .as_str() - .trim() - .trim_start_matches("0x"), - ) { - Ok(bytes) => { + let update_hash_preimage_bytes = move |event: ev::Event| { + if let Ok(bytes) = >::from_hex( + event_target_value(&event) + .as_str() + .trim() + .trim_start_matches("0x"), + ) { signed_data.hash_preimage_bytes.set(bytes); hash_preimage_bytes_text_ref .get() .expect(" should be mounted") .set_custom_validity(""); hash_preimage_bytes_is_insane.set(false); - } - Err(..) => { + } else { sighash_all_radio_ref .get() .expect(" should be mounted") diff --git a/src/components/run_window/transaction_tab.rs b/src/components/run_window/transaction_tab.rs index 6989d19..6513eaf 100644 --- a/src/components/run_window/transaction_tab.rs +++ b/src/components/run_window/transaction_tab.rs @@ -35,13 +35,13 @@ impl TxEnv { #[component] pub fn TransactionTab() -> impl IntoView { let tx_env = use_context::().expect("transaction environment should exist in context"); - let txid_parse_error = create_rw_signal("".to_string()); - let vout_parse_error = create_rw_signal("".to_string()); - let value_in_parse_error = create_rw_signal("".to_string()); - let recipient_address_parse_error = create_rw_signal("".to_string()); - let fee_parse_error = create_rw_signal("".to_string()); - let lock_time_parse_error = create_rw_signal("".to_string()); - let sequence_parse_error = create_rw_signal("".to_string()); + let txid_parse_error = create_rw_signal(String::new()); + let vout_parse_error = create_rw_signal(String::new()); + let value_in_parse_error = create_rw_signal(String::new()); + let recipient_address_parse_error = create_rw_signal(String::new()); + let fee_parse_error = create_rw_signal(String::new()); + let lock_time_parse_error = create_rw_signal(String::new()); + let sequence_parse_error = create_rw_signal(String::new()); let update_txid = move |e: ev::Event| match elements::Txid::from_str(&event_target_value(&e)) { Ok(txid) => { diff --git a/src/function.rs b/src/function.rs index b2f5a96..3f06828 100644 --- a/src/function.rs +++ b/src/function.rs @@ -39,10 +39,10 @@ impl fmt::Display for ErrorKind { FallibleCallName::Panic => writeln!(f, "Explicit panic")?, FallibleCallName::Jet => writeln!(f, "Jet failed")?, FallibleCallName::UnwrapLeft(val) => { - writeln!(f, "Called `unwrap_left()` on a `Right` value: {val}")? + writeln!(f, "Called `unwrap_left()` on a `Right` value: {val}")?; } FallibleCallName::UnwrapRight(val) => { - writeln!(f, "Called `unwrap_right()` on a `Left` value: {val}")? + writeln!(f, "Called `unwrap_right()` on a `Left` value: {val}")?; } FallibleCallName::Unwrap => writeln!(f, "Called `unwrap()` on a `None` value")?, } @@ -80,7 +80,7 @@ pub struct Runner { } impl Runner { - pub fn for_program(program: SatisfiedProgram) -> Self { + pub fn for_program(program: &SatisfiedProgram) -> Self { Self { tasks: vec![Task::Execute(program.redeem().clone())], input: vec![Value::unit()], @@ -303,7 +303,7 @@ mod tests { println!("{name}"); let example = examples::get(name).unwrap(); let (satisfied, tx_env) = satisfied_and_tx_env(example, &signing_keys, &hashed_data); - let mut runner = Runner::for_program(satisfied); + let mut runner = Runner::for_program(&satisfied); if let Err(error) = runner.run(&tx_env) { println!("sighash all = {}", tx_env.c_tx_env().sighash_all()); for debug_line in runner.debug_output() { @@ -326,7 +326,7 @@ mod tests { let (satisfied, tx_env) = satisfied_and_tx_env(example, &signing_keys, &hashed_data); let rust_simplicity_result = simplicity::BitMachine::for_program(satisfied.redeem()) .exec(satisfied.redeem(), &tx_env); - let webide_result = Runner::for_program(satisfied).run(&tx_env); + let webide_result = Runner::for_program(&satisfied).run(&tx_env); match (rust_simplicity_result, webide_result) { (Ok(..), Err(error)) => { panic!("rust-simplicity accepted but web IDE rejected: {error}") diff --git a/src/jet.rs b/src/jet.rs index 7234e91..0105c7c 100644 --- a/src/jet.rs +++ b/src/jet.rs @@ -84,10 +84,10 @@ pub fn execute_jet_with_env( let c_env = J::c_jet_env(env); let success = jet_fn(&mut output_write_frame, input_read_frame, c_env); - if !success { - Err(JetFailed) - } else { + if success { Ok(value_from_frame(&output_type, &mut output_buffer)) + } else { + Err(JetFailed) } } diff --git a/src/main.rs b/src/main.rs index 3109638..90b1013 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,5 +23,5 @@ fn main() { } - }) + }); } diff --git a/src/transaction.rs b/src/transaction.rs index 4fdc30a..9203118 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -55,11 +55,10 @@ impl TxParams { asset: confidential::Asset::Explicit(util::liquid_testnet_bitcoin_asset()), value: confidential::Value::Explicit(self.value_in.saturating_sub(self.fee)), nonce: confidential::Nonce::Null, - script_pubkey: self - .recipient_address - .as_ref() - .map(elements::Address::script_pubkey) - .unwrap_or_else(util::liquid_testnet_faucet_script_pubkey), + script_pubkey: self.recipient_address.as_ref().map_or_else( + util::liquid_testnet_faucet_script_pubkey, + elements::Address::script_pubkey, + ), witness: elements::TxOutWitness::empty(), }, elements::TxOut::new_fee(self.fee, util::liquid_testnet_bitcoin_asset()), From 12c7daffb1ef9bcb583f0ac3a35b2d463691586b Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 25 Aug 2025 00:12:00 +0000 Subject: [PATCH 4/7] clippy: turn on a bunch of pedantic lints --- Cargo.toml | 126 +++++++++++++++++++++++++++ src/components/program_window/mod.rs | 6 +- 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ea21ad..aafcf11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,129 @@ serde_json = "1.0" [dev-dependencies] wasm-bindgen-test = "0.3.50" + +[lints.clippy] +# Exclude lints we don't think are valuable. +needless_question_mark = "allow" # https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 +manual_range_contains = "allow" # More readable than clippy's format. +needless_raw_string_hashes = "allow" # No reason not to use raw strings +uninlined_format_args = "allow" # This is a subjective style choice. +float_cmp = "allow" # Bitcoin floats are typically limited to 8 decimal places and we want them exact. +manual_let_else = "allow" # unsure about this one on stylistic grounds +map_unwrap_or = "allow" # encourages use of `map_or_else` which takes two closures that the reader can't really distinguish +match_bool = "allow" # Adds extra indentation and LOC. +match_same_arms = "allow" # Collapses things that are conceptually unrelated to each other. +must_use_candidate = "allow" # Useful for audit but many false positives. +similar_names = "allow" # Too many (subjectively) false positives. +single_match_else = "allow" # bad style; creates long lines and extra lines +# Exhaustive list of pedantic clippy lints +assigning_clones = "warn" +bool_to_int_with_if = "warn" +borrow_as_ptr = "warn" +case_sensitive_file_extension_comparisons = "warn" +cast_lossless = "warn" +cast_possible_truncation = "allow" # All casts should include a code comment (except test code). +cast_possible_wrap = "allow" # Same as above re code comment. +cast_precision_loss = "warn" +cast_ptr_alignment = "warn" +cast_sign_loss = "allow" # All casts should include a code comment (except in test code). +checked_conversions = "warn" +cloned_instead_of_copied = "warn" +copy_iterator = "warn" +default_trait_access = "warn" +doc_link_with_quotes = "warn" +doc_markdown = "warn" +empty_enum = "warn" +enum_glob_use = "warn" +expl_impl_clone_on_copy = "warn" +explicit_deref_methods = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +fn_params_excessive_bools = "warn" +from_iter_instead_of_collect = "warn" +if_not_else = "warn" +ignored_unit_patterns = "warn" +implicit_clone = "warn" +implicit_hasher = "warn" +inconsistent_struct_constructor = "warn" +index_refutable_slice = "warn" +inefficient_to_string = "warn" +inline_always = "warn" +into_iter_without_iter = "warn" +invalid_upcast_comparisons = "warn" +items_after_statements = "warn" +iter_filter_is_ok = "warn" +iter_filter_is_some = "warn" +iter_not_returning_iterator = "warn" +iter_without_into_iter = "warn" +large_digit_groups = "warn" +large_futures = "warn" +large_stack_arrays = "warn" +large_types_passed_by_value = "warn" +linkedlist = "warn" +macro_use_imports = "warn" +manual_assert = "warn" +manual_instant_elapsed = "warn" +manual_is_power_of_two = "warn" +manual_is_variant_and = "warn" +manual_ok_or = "warn" +manual_string_new = "warn" +many_single_char_names = "warn" +match_wildcard_for_single_variants = "warn" +maybe_infinite_iter = "warn" +mismatching_type_param_order = "warn" +missing_errors_doc = "allow" # FIXME this triggers 184 times; we should fix most +missing_fields_in_debug = "warn" +missing_panics_doc = "allow" # FIXME this one has 40 triggers +mut_mut = "warn" +naive_bytecount = "warn" +needless_bitwise_bool = "warn" +needless_continue = "warn" +needless_for_each = "warn" +needless_pass_by_value = "warn" +no_effect_underscore_binding = "warn" +no_mangle_with_rust_abi = "warn" +option_as_ref_cloned = "warn" +option_option = "warn" +ptr_as_ptr = "warn" +ptr_cast_constness = "warn" +pub_underscore_fields = "warn" +range_minus_one = "warn" +range_plus_one = "warn" +redundant_closure_for_method_calls = "warn" +redundant_else = "warn" +ref_as_ptr = "warn" +ref_binding_to_reference = "warn" +ref_option = "warn" +ref_option_ref = "warn" +return_self_not_must_use = "warn" +same_functions_in_if_condition = "warn" +semicolon_if_nothing_returned = "warn" +should_panic_without_expect = "warn" +single_char_pattern = "warn" +stable_sort_primitive = "warn" +str_split_at_newline = "warn" +string_add_assign = "warn" +struct_excessive_bools = "warn" +struct_field_names = "warn" +too_many_lines = "allow" # FIXME 14 triggers for this lint; probably most should be fixed +transmute_ptr_to_ptr = "warn" +trivially_copy_pass_by_ref = "warn" +unchecked_duration_subtraction = "warn" +unicode_not_nfc = "warn" +unnecessary_box_returns = "warn" +unnecessary_join = "warn" +unnecessary_literal_bound = "warn" +unnecessary_wraps = "warn" +unnested_or_patterns = "warn" +unreadable_literal = "warn" +unsafe_derive_deserialize = "warn" +unused_async = "warn" +unused_self = "warn" +used_underscore_binding = "warn" +used_underscore_items = "warn" +verbose_bit_mask = "warn" +wildcard_imports = "warn" +zero_sized_map_values = "warn" diff --git a/src/components/program_window/mod.rs b/src/components/program_window/mod.rs index 2d3aa97..c1e7061 100644 --- a/src/components/program_window/mod.rs +++ b/src/components/program_window/mod.rs @@ -43,10 +43,10 @@ pub fn ProgramWindow() -> impl IntoView { class:hamburger-active=mobile_open on:click=move |_| set_mobile_open.set(!mobile_open.get()) > - {move || if !mobile_open.get() { - view! { } - } else { + {move || if mobile_open.get() { view! { } + } else { + view! { } }} From 6715eb172177b8e005106c2c2e9277673db70a8c Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 4 Nov 2025 15:13:51 +0000 Subject: [PATCH 5/7] SimplicityHL: use released version 0.2 This updates a couple APIs. Most notably it breaks our ability to read a value from the output frame of a jet in a reasonable-efficient way; however, it does give us the tools we need to just execute the jet in the bit machine. --- Cargo.lock | 262 ++++++++++++++++--- Cargo.toml | 3 +- src/components/program_window/program_tab.rs | 8 +- src/function.rs | 35 ++- src/jet.rs | 89 +------ 5 files changed, 259 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9ecfd6..4f8b75f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,56 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + [[package]] name = "anyhow" version = "1.0.79" @@ -110,7 +160,7 @@ dependencies = [ "bitcoin-io", "bitcoin-units", "bitcoin_hashes", - "hex-conservative 0.2.1", + "hex-conservative", "hex_lit", "secp256k1", ] @@ -149,7 +199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", - "hex-conservative 0.2.1", + "hex-conservative", ] [[package]] @@ -233,12 +283,45 @@ dependencies = [ "half", ] +[[package]] +name = "clap" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + [[package]] name = "collection_literals" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "config" version = "0.14.0" @@ -569,12 +652,6 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -[[package]] -name = "hex-conservative" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" - [[package]] name = "hex-conservative" version = "0.2.1" @@ -642,6 +719,12 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itertools" version = "0.12.1" @@ -968,6 +1051,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "pad-adapter" version = "0.1.1" @@ -994,7 +1083,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1544,33 +1633,18 @@ dependencies = [ "digest", ] -[[package]] -name = "simfony" -version = "0.1.0" -source = "git+https://github.com/BlockstreamResearch/simplicityhl?rev=d5284014e9f67593e50b272f1f676ea8d09f6ec8#d5284014e9f67593e50b272f1f676ea8d09f6ec8" -dependencies = [ - "base64 0.21.7", - "either", - "getrandom", - "hex-conservative 0.1.2", - "itertools 0.13.0", - "miniscript", - "pest", - "pest_derive", - "simplicity-lang", -] - [[package]] name = "simplicity-lang" -version = "0.3.0" -source = "git+https://github.com/BlockstreamResearch/rust-simplicity?rev=ca0c0ebee295937ab021ad018acc44a5aaa12649#ca0c0ebee295937ab021ad018acc44a5aaa12649" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525879699aba1f7f75c0d97355475072adeb0ed0530df4e18f23235252475e68" dependencies = [ "bitcoin", "bitcoin_hashes", "byteorder", "elements", "getrandom", - "hex-conservative 0.1.2", + "hex-conservative", "miniscript", "santiago", "simplicity-sys", @@ -1578,8 +1652,9 @@ dependencies = [ [[package]] name = "simplicity-sys" -version = "0.3.0" -source = "git+https://github.com/BlockstreamResearch/rust-simplicity?rev=ca0c0ebee295937ab021ad018acc44a5aaa12649#ca0c0ebee295937ab021ad018acc44a5aaa12649" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abf9c7d64c5bf45bb2fb966f3b0637d8c13c8d5cdfbd7587900421cb7584c49" dependencies = [ "bitcoin_hashes", "cc", @@ -1592,19 +1667,36 @@ dependencies = [ "console_error_panic_hook", "gloo-net", "gloo-timers", - "hex-conservative 0.2.1", + "hex-conservative", "itertools 0.13.0", "js-sys", "leptos", "leptos_router", "serde", "serde_json", - "simfony", + "simplicityhl", "wasm-bindgen-futures", "wasm-bindgen-test", "web-sys", ] +[[package]] +name = "simplicityhl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1268a95f9a5fe41e94ba0ff9c81ca5ec2794be38049cc609b9085544ea5bd46c" +dependencies = [ + "base64 0.21.7", + "clap", + "either", + "getrandom", + "itertools 0.13.0", + "miniscript", + "pest", + "pest_derive", + "simplicity-lang", +] + [[package]] name = "slab" version = "0.4.9" @@ -1630,6 +1722,12 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.48" @@ -1835,6 +1933,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.7.0" @@ -2015,19 +2119,51 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -2036,42 +2172,90 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" version = "0.6.18" diff --git a/Cargo.toml b/Cargo.toml index aafcf11..079555e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,7 @@ lib-profile-release = "wasm-release" [dependencies] itertools = "0.13.0" -#simplicityhl = "0.2.0" -simplicityhl = { package = "simfony", git = "https://github.com/BlockstreamResearch/simplicityhl", rev = "d5284014e9f67593e50b272f1f676ea8d09f6ec8" } +simplicityhl = { version = "0.2.0" } leptos = { version = "0.6.14", features = ["csr"] } leptos_router = { version = "0.6.15", features = ["csr"] } console_error_panic_hook = "0.1.7" diff --git a/src/components/program_window/program_tab.rs b/src/components/program_window/program_tab.rs index b97b437..d73bdbe 100644 --- a/src/components/program_window/program_tab.rs +++ b/src/components/program_window/program_tab.rs @@ -66,7 +66,13 @@ impl Program { self.cached_text.set(text.clone()); let compiled = simplicityhl::Arguments::parse_from_str(text) .map_err(|error| error.to_string()) - .and_then(|args| CompiledProgram::new(text.as_str(), args)); + .and_then(|args| { + CompiledProgram::new( + text.as_str(), + args, + false, /* include debug symbols */ + ) + }); let cmr = compiled .as_ref() .map(|x| x.commit().cmr()) diff --git a/src/function.rs b/src/function.rs index 3f06828..b1a0a92 100644 --- a/src/function.rs +++ b/src/function.rs @@ -105,25 +105,25 @@ impl Runner { Inner::Unit => self.output.push(Value::unit()), Inner::InjL(t) => { let ty_r = expression.arrow().target.as_sum().unwrap().1; - self.tasks.push(Task::MakeLeft(Arc::new(ty_r.clone()))); + self.tasks.push(Task::MakeLeft(Arc::clone(ty_r))); self.tasks.push(Task::Execute(Arc::clone(t))); self.input.push(input); } Inner::InjR(t) => { let ty_l = expression.arrow().target.as_sum().unwrap().0; - self.tasks.push(Task::MakeRight(Arc::new(ty_l.clone()))); + self.tasks.push(Task::MakeRight(Arc::clone(ty_l))); self.tasks.push(Task::Execute(Arc::clone(t))); self.input.push(input); } Inner::Take(t) => { let (a, _) = input.as_product().ok_or(ErrorKind::WrongType)?; self.tasks.push(Task::Execute(Arc::clone(t))); - self.input.push(a.shallow_clone()); + self.input.push(a.to_value()); } Inner::Drop(t) => { let (_, b) = input.as_product().ok_or(ErrorKind::WrongType)?; self.tasks.push(Task::Execute(Arc::clone(t))); - self.input.push(b.shallow_clone()); + self.input.push(b.to_value()); } Inner::Comp(s, t) => { self.tasks.push(Task::Execute(Arc::clone(t))); @@ -144,9 +144,7 @@ impl Runner { if let Inner::AssertL(_, cmr) = expression.inner() { if let Some(tracked_call) = self.debug_symbols.get(cmr) { match tracked_call.map_value( - &simplicityhl::value::StructuralValue::from( - c.shallow_clone(), - ), + &simplicityhl::value::StructuralValue::from(c.to_value()), ) { Some(Either::Left(fallible_call)) => { let replaced = self @@ -172,10 +170,7 @@ impl Runner { match expression.inner() { Inner::Case(s, _) | Inner::AssertL(s, _) => { self.tasks.push(Task::Execute(Arc::clone(s))); - self.input.push(Value::product( - a.shallow_clone(), - c.shallow_clone(), - )); + self.input.push(Value::product(a.to_value(), c.to_value())); } Inner::AssertR(_, _) => { return Err(self.error(ErrorKind::AssertionFailed)) @@ -186,10 +181,7 @@ impl Runner { match expression.inner() { Inner::Case(_, t) | Inner::AssertR(_, t) => { self.tasks.push(Task::Execute(Arc::clone(t))); - self.input.push(Value::product( - b.shallow_clone(), - c.shallow_clone(), - )); + self.input.push(Value::product(b.to_value(), c.to_value())); } Inner::AssertL(_, _) => { return Err(self.error(ErrorKind::AssertionFailed)) @@ -224,8 +216,8 @@ impl Runner { Task::MoveLeftDisconnectOutput => { let prod_b_c = self.output.pop().unwrap(); let (b, c) = prod_b_c.as_product().unwrap(); - self.output.push(b.shallow_clone()); - self.input.push(c.shallow_clone()); + self.output.push(b.to_value()); + self.input.push(c.to_value()); } Task::MakeLeft(ty_r) => { let val_l = self.output.pop().unwrap(); @@ -276,8 +268,12 @@ mod tests { hashed_data: &HashedData, ) -> (SatisfiedProgram, ElementsEnv>) { let arguments = example.arguments(&signing_keys.public_keys, &hashed_data.hashes); - let compiled = CompiledProgram::new(example.template_text(), arguments) - .expect("example should compile"); + let compiled = CompiledProgram::new( + example.template_text(), + arguments, + false, /* include debug symbols */ + ) + .expect("example should compile"); let tx_env = example.params().tx_env(compiled.commit().cmr()); let sighash_all = secp256k1::Message::from_digest(tx_env.c_tx_env().sighash_all().to_byte_array()); @@ -325,6 +321,7 @@ mod tests { let example = examples::get(name).unwrap(); let (satisfied, tx_env) = satisfied_and_tx_env(example, &signing_keys, &hashed_data); let rust_simplicity_result = simplicity::BitMachine::for_program(satisfied.redeem()) + .expect("program within limits") .exec(satisfied.redeem(), &tx_env); let webide_result = Runner::for_program(&satisfied).run(&tx_env); match (rust_simplicity_result, webide_result) { diff --git a/src/jet.rs b/src/jet.rs index 0105c7c..ff0f737 100644 --- a/src/jet.rs +++ b/src/jet.rs @@ -1,94 +1,29 @@ -use simplicity::ffi::c_jets::frame_ffi::{c_readBit, c_writeBit}; -use simplicity::ffi::c_jets::uword_width; -use simplicity::ffi::ffi::UWORD; -use simplicity::ffi::CFrameItem; +use std::sync::Arc; + use simplicity::jet::Jet; -use simplicity::types::Final; -use simplicity::Value; +use simplicity::node::JetConstructible as _; +use simplicity::types::Context; +use simplicity::{BitMachine, ConstructNode, Value}; use simplicityhl::simplicity; pub struct JetFailed; -/// Create new C read frame from the given `input` value and `ty`pe. -/// -/// Return C read frame together with underlying buffer. -/// -/// ## Safety -/// -/// The returned frame must outlive its buffer or there is a dangling pointer. -unsafe fn get_input_frame(input: &Value, ty: &Final) -> (CFrameItem, Vec) { - let uword_width = uword_width(ty.bit_width()); - let mut buffer = vec![0; uword_width]; - - // Copy bits from value to input frame - let buffer_end = buffer.as_mut_ptr().add(uword_width); - let mut write_frame = CFrameItem::new_write(ty.bit_width(), buffer_end); - for bit in input.iter_padded() { - c_writeBit(&mut write_frame, bit); - } - - // Convert input frame into read frame - let buffer_ptr = buffer.as_mut_ptr(); - let read_frame = CFrameItem::new_read(ty.bit_width(), buffer_ptr); - - (read_frame, buffer) -} - -/// Create C write frame that is as wide as `bit_width`. -/// -/// Return C write frame together with underlying buffer. -/// -/// ## Safety -/// -/// The returned frame must outlive its buffer or there is a dangling pointer. -unsafe fn get_output_frame(bit_width: usize) -> (CFrameItem, Vec) { - let uword_width = uword_width(bit_width); - let mut buffer = vec![0; uword_width]; - - // Return output frame as write frame - let buffer_end = buffer.as_mut_ptr().add(uword_width); - let write_frame = CFrameItem::new_write(bit_width, buffer_end); - - (write_frame, buffer) -} - -/// Write `bit_width` many bits from `buffer` into active write frame. -/// -/// ## Panics -/// -/// Buffer has fewer than bits than `ty` is wide (converted to UWORDs). -fn value_from_frame(ty: &Final, buffer: &mut [UWORD]) -> Value { - assert!(uword_width(ty.bit_width()) <= buffer.len()); - let buffer_ptr = buffer.as_ptr(); - let mut read_frame = unsafe { CFrameItem::new_read(ty.bit_width(), buffer_ptr) }; - - let mut it = (0..ty.bit_width()).map(|_| unsafe { c_readBit(&mut read_frame) }); - - Value::from_padded_bits(&mut it, ty).expect("Jets return values that fit their output type") -} - /// Execute a jet on an input and inside an environment. Return the output. pub fn execute_jet_with_env( jet: &J, input: &Value, env: &J::Environment, ) -> Result { - let input_type = jet.source_ty().to_final(); - let output_type = jet.target_ty().to_final(); + let prog = Arc::>::jet(&Context::new(), *jet) + .finalize_unpruned() + .expect("a single jet definitely typechecks"); - let (input_read_frame, _input_buffer) = unsafe { get_input_frame(input, &input_type) }; - let (mut output_write_frame, mut output_buffer) = - unsafe { get_output_frame(output_type.bit_width()) }; + let mut mac = BitMachine::for_program(&prog).expect("a single jet is within limits"); - let jet_fn = jet.c_jet_ptr(); - let c_env = J::c_jet_env(env); - let success = jet_fn(&mut output_write_frame, input_read_frame, c_env); + mac.input(input).expect("no problem with input"); - if success { - Ok(value_from_frame(&output_type, &mut output_buffer)) - } else { - Err(JetFailed) - } + // The only execution error possible is a jet failure + mac.exec(&prog, env).map_err(|_| JetFailed) } #[cfg(test)] From 67720ab7ccb5f330d3c54ced6a2394b42120acaf Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 4 Nov 2025 16:05:07 +0000 Subject: [PATCH 6/7] SimplicityHl: use released version 0.3 --- Cargo.lock | 21 +++++++++++++++------ Cargo.toml | 2 +- src/jet.rs | 8 +++++--- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f8b75f..2d888d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -590,6 +590,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghost-cell" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8449d342b1c67f49169e92e71deb7b9b27f30062301a16dbc27a4cc8d2351b7" + [[package]] name = "gloo-net" version = "0.6.0" @@ -1635,15 +1641,16 @@ dependencies = [ [[package]] name = "simplicity-lang" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525879699aba1f7f75c0d97355475072adeb0ed0530df4e18f23235252475e68" +checksum = "7938a6a4106edfe5b559a8718df506a0690ac12cfff8ce91c0f6b7f02a644f8c" dependencies = [ "bitcoin", "bitcoin_hashes", "byteorder", "elements", "getrandom", + "ghost-cell", "hex-conservative", "miniscript", "santiago", @@ -1652,9 +1659,9 @@ dependencies = [ [[package]] name = "simplicity-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3abf9c7d64c5bf45bb2fb966f3b0637d8c13c8d5cdfbd7587900421cb7584c49" +checksum = "875630d128f19818161cefe0a3d910b6aae921d8246711db574a689cb2c11747" dependencies = [ "bitcoin_hashes", "cc", @@ -1682,9 +1689,9 @@ dependencies = [ [[package]] name = "simplicityhl" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1268a95f9a5fe41e94ba0ff9c81ca5ec2794be38049cc609b9085544ea5bd46c" +checksum = "e34851a609baa909fc4af8aa643fe304a393b59b8c39d4e04de4a64d5eb0012a" dependencies = [ "base64 0.21.7", "clap", @@ -1694,6 +1701,8 @@ dependencies = [ "miniscript", "pest", "pest_derive", + "serde", + "serde_json", "simplicity-lang", ] diff --git a/Cargo.toml b/Cargo.toml index 079555e..05963ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ lib-profile-release = "wasm-release" [dependencies] itertools = "0.13.0" -simplicityhl = { version = "0.2.0" } +simplicityhl = { version = "0.3.0" } leptos = { version = "0.6.14", features = ["csr"] } leptos_router = { version = "0.6.15", features = ["csr"] } console_error_panic_hook = "0.1.7" diff --git a/src/jet.rs b/src/jet.rs index ff0f737..51ddfd8 100644 --- a/src/jet.rs +++ b/src/jet.rs @@ -14,9 +14,11 @@ pub fn execute_jet_with_env( input: &Value, env: &J::Environment, ) -> Result { - let prog = Arc::>::jet(&Context::new(), *jet) - .finalize_unpruned() - .expect("a single jet definitely typechecks"); + let prog = Context::with_context(|ctx| { + Arc::>::jet(&ctx, *jet) + .finalize_unpruned() + .expect("a single jet definitely typechecks") + }); let mut mac = BitMachine::for_program(&prog).expect("a single jet is within limits"); From 66e1a6ae28a27e3327ac75f6bc7d5f092106f309 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 4 Nov 2025 16:08:07 +0000 Subject: [PATCH 7/7] remove use of deprecated encoding function --- src/transaction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transaction.rs b/src/transaction.rs index 9203118..7b2304d 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -91,7 +91,7 @@ impl TxParams { pub fn transaction(&self, pruned: &RedeemNode) -> elements::Transaction { let mut tx = self.unsatisfied_transaction(); - let (simplicity_program_bytes, simplicity_witness_bytes) = pruned.encode_to_vec(); + let (simplicity_program_bytes, simplicity_witness_bytes) = pruned.to_vec_with_witness(); let cmr = pruned.cmr(); tx.input[0].witness = elements::TxInWitness { amount_rangeproof: None,