Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Unreleased

* Fix `RedeemNode::prune` producing programs that consensus rejects, and add `ExecutionError::PruningFailed` [#391](https://github.com/BlockstreamResearch/rust-simplicity/issues/391).
* Add `Cost::get_padding_size`, returning the chain-agnostic length of the padding witness
stack item needed to bring a cost within the witness budget, and `Cost::get_padding_bytes`,
returning the chain-specific bytes that fill it (an all-zero item on Bitcoin, an annex on
Elements). Deprecate `Cost::get_padding` in favour of these.
* `Cost::get_budget` and `Cost::is_budget_valid` now take `&[Vec<u8>]` instead of `&Vec<Vec<u8>>`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLMs tend to add random information to the CHANGELOG. This is a private method so I'd vote to remove it. Fine to do in follow up.

and compute the serialized witness length directly rather than via the Elements consensus
encoder, making them available under the `bitcoin` feature (which `elements` implies) as
well as `elements`.
Comment on lines +4 to +11

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Claude Opus 5.5 responding on behalf of @KyrylR

In c0bfd57

Minor: this entry is incomplete.

It omits the main change: Bitcoin::cmr() and Bitcoin::cost() no longer panic. It also omits the libsimplicity bump, and it lists the private get_budget as changed API.

Agreed by: Opus 5.5, Mythos, Fable


# 0.9.0 - 2026-09-16

Expand Down
2 changes: 1 addition & 1 deletion simplicity-sys/depend/simplicity-HEAD-revision.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# This file has been automatically generated.
3f0bb69c4547bcf3483ca5ccbd06699464166650
4e0beb5947b7e75ee7974d82a1447e89a0b4b5d6
61 changes: 61 additions & 0 deletions simplicity-sys/src/c_jets/c_env/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use hashes::sha256;

use crate::c_jets::frame_ffi::CFrameItem;
use crate::ffi::sha256::CSha256Midstate;
use crate::ffi::{c_size_t, c_uchar, c_uint, c_uint_fast32_t};

Expand Down Expand Up @@ -108,6 +109,39 @@ extern "C" {
pub fn simplicity_mallocTapEnv(rawEnv: *const CRawTapEnv) -> *mut CTapEnv;
#[link_name = "rustsimplicity_0_8_bitcoin_mallocTransaction"]
pub fn simplicity_mallocTransaction(rawTx: *const CRawTransaction) -> *mut CTransaction;

// Bitcoin jets whose C implementations read the transaction environment.
// Each has signature `bool f(frameItem* dst, frameItem src, const txEnv* env)`
// (note `src` is passed *by value*, matching the C definitions in bitcoinJets.c).
#[link_name = "rustsimplicity_0_8_bitcoin_sig_all_hash"]
pub fn bitcoin_sig_all_hash(dst: *mut CFrameItem, src: CFrameItem, env: *const CTxEnv) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_check_lock_height"]
pub fn bitcoin_check_lock_height(
dst: *mut CFrameItem,
src: CFrameItem,
env: *const CTxEnv,
) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_check_lock_distance"]
pub fn bitcoin_check_lock_distance(
dst: *mut CFrameItem,
src: CFrameItem,
env: *const CTxEnv,
) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_check_lock_duration"]
pub fn bitcoin_check_lock_duration(
dst: *mut CFrameItem,
src: CFrameItem,
env: *const CTxEnv,
) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_current_index"]
pub fn bitcoin_current_index(dst: *mut CFrameItem, src: CFrameItem, env: *const CTxEnv)
-> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_num_inputs"]
pub fn bitcoin_num_inputs(dst: *mut CFrameItem, src: CFrameItem, env: *const CTxEnv) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_tx_hash"]
pub fn bitcoin_tx_hash(dst: *mut CFrameItem, src: CFrameItem, env: *const CTxEnv) -> bool;
#[link_name = "rustsimplicity_0_8_bitcoin_tap_env_hash"]
pub fn bitcoin_tap_env_hash(dst: *mut CFrameItem, src: CFrameItem, env: *const CTxEnv) -> bool;
Comment on lines +113 to +144

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Claude Opus 5.5 responding on behalf of @KyrylR

In b4cc29f

Major: these 8 declarations, and the wrappers at L173-L198, are unused and conflict with the WASM ABI.

  • Unused. c_jet_ptr already sends every Bitcoin jet through the generated jets_wrapper::bitcoin_*. Nothing references these, and the new jet::bitcoin tests still pass with this file reverted to base.
  • WASM ABI. They pass frameItem src by value, which is what WRAP_ exists to avoid ("Only the latter is permissible in WASM"). cargo +1.88.0 build --target wasm32-unknown-unknown -p simplicity-sys gives 8 wasm_c_abi warnings here and 0 on base. They also skip the WRAP_ postcondition assert on dst->offset.
  • Crash from safe code. They are 8 more safe pub fns that can be crashed without unsafe: passing CFrameItem { edge: null(), len: 0 } to current_index segfaults. The generated wrappers have the same signature; this adds more of them.
  • Commit message mismatch. The message names annex_hash and the tapbranch/tapleaf/taptweak builders, but only 8 functions are declared.

Suggest deleting the block. That also resolves the code-generation question in the PR description.

Agreed by: all ten (WASM ABI: Mythos, Fable; segfault: Astra ×3, Sol ×1)

}

impl CTxEnv {
Expand Down Expand Up @@ -136,6 +170,33 @@ impl CRawBuffer {
}
}

// Safe wrappers around the bitcoin environment jets above. These expose a
// Rust-safe signature (`&mut CFrameItem`, `&CTxEnv`) that can be used directly
// as a `JetEnvironment::c_jet_ptr` function pointer, mirroring how the
// elements backend exposes its jets via the `jets_wrapper` module. We cannot
// hand out the raw `extern "C"` functions as fn pointers because `c_jet_ptr`
// returns a safe (non-extern) function pointer.
macro_rules! bitcoin_env_jet_wrapper {
($name:ident, $ffi:ident) => {
pub fn $name(dst: &mut CFrameItem, src: CFrameItem, env: &CTxEnv) -> bool {
// SAFETY: we pass valid references through as pointers to a C
// function that treats them as borrowed (`frameItem* dst`,
// `const txEnv* env`) and `src` is forwarded by value exactly as
// the C `frameItem src` parameter expects.
unsafe { $ffi(dst, src, env) }
}
};
}

bitcoin_env_jet_wrapper!(sig_all_hash, bitcoin_sig_all_hash);
bitcoin_env_jet_wrapper!(check_lock_height, bitcoin_check_lock_height);
bitcoin_env_jet_wrapper!(check_lock_distance, bitcoin_check_lock_distance);
bitcoin_env_jet_wrapper!(check_lock_duration, bitcoin_check_lock_duration);
bitcoin_env_jet_wrapper!(current_index, bitcoin_current_index);
bitcoin_env_jet_wrapper!(num_inputs, bitcoin_num_inputs);
bitcoin_env_jet_wrapper!(tx_hash, bitcoin_tx_hash);
bitcoin_env_jet_wrapper!(tap_env_hash, bitcoin_tap_env_hash);

// Will uncomment in a later commit; need to update libsimplicity first.
#[cfg(test)]
mod tests {
Expand Down
Loading
Loading