From 352b58b67a9b1c4af5abfebff312d7d066232798 Mon Sep 17 00:00:00 2001 From: topologoanatom Date: Tue, 20 Jan 2026 12:00:03 +0200 Subject: [PATCH 1/3] reproduce incorrect arithmetic jet trace --- src/tracker.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/tracker.rs b/src/tracker.rs index 15177e06..672a4ad5 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -524,4 +524,52 @@ mod tests { Some("Some((Right(0x6d521c38ec1ea15734ae22b7c46064412829c0d0579f0a713d1c04ede979026f), Right(1000)))") ); } + const TEST_ARITHMETIC_JETS: &str = r#" + fn main() { + + let x: u32 = 5; + let y: u32 = 4; + + let sum: (bool, u32) = jet::add_32(x, y); + let prod: u64 = jet::multiply_32(x, y); + + assert!(jet::eq_64(prod, 20)); + } + "#; + + #[test] + fn test_arith_jet_trace_regression() { + let env = create_test_env(); + + let program = TemplateProgram::new(TEST_ARITHMETIC_JETS).unwrap(); + let program = program.instantiate(Arguments::default(), true).unwrap(); + let satisfied = program.satisfy(WitnessValues::default()).unwrap(); + + let (mut tracker, _, jet_store) = create_test_tracker(&satisfied.debug_symbols); + + let _ = satisfied.redeem().prune_with_tracker(&env, &mut tracker); + + let jets = jet_store.borrow(); + + assert_eq!( + jets.get("add_32").unwrap().0, + Some(vec!["5".to_string(), "4".to_string()]) + ); + assert_eq!( + jets.get("add_32").unwrap().1, + Some("(false, 9)".to_string()) + ); + + assert_eq!( + jets.get("multiply_32").unwrap().0, + Some(vec!["5".to_string(), "4".to_string()]) + ); + assert_eq!(jets.get("multiply_32").unwrap().1, Some("20".to_string())); + + assert_eq!( + jets.get("eq_64").unwrap().0, + Some(vec!["20".to_string(), "20".to_string()]) + ); + assert_eq!(jets.get("eq_64").unwrap().1, Some("true".to_string())); + } } From 5030d7e2ddca5e16094913268e9c0a45213aba96 Mon Sep 17 00:00:00 2001 From: topologoanatom Date: Tue, 20 Jan 2026 12:05:20 +0200 Subject: [PATCH 2/3] fix branch condition for output frame bit skip --- src/tracker.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tracker.rs b/src/tracker.rs index 672a4ad5..4a6f693a 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -220,19 +220,19 @@ impl<'a> DefaultTracker<'a> { match output.clone() { NodeOutput::Success(mut output_frame) => { let target_ty = &node.arrow().target; + let jet_target_ty = resolve_jet_type(&target_type(jet)); // Skip the leading bit when the frame has extra padding. - // This occurs because jets are wrapped in AssertL (a Case combinator), - // which adds structure to the output frame for some jets. - if output_frame.len() > target_ty.bit_width() { + // This occurs because some jets (like eq_64 etc.) are wrapped in AssertL (a Case combinator), + // see compile::with_debug_symbol + if target_ty.as_sum().is_some() { let _ = output_frame.next(); } let output_value = SimValue::from_padded_bits(&mut output_frame, target_ty) .expect("output from bit machine is always well-formed"); - let target_ty = resolve_jet_type(&target_type(jet)); - Value::reconstruct(&StructuralValue::from(output_value), &target_ty) + Value::reconstruct(&StructuralValue::from(output_value), &jet_target_ty) } _ => None, } From 11a03babb1af01934d0b3cb7e762d3833a798b02 Mon Sep 17 00:00:00 2001 From: topologoanatom Date: Thu, 22 Jan 2026 10:28:19 +0200 Subject: [PATCH 3/3] Bump version to 0.4.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 528b3e17..986aa395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -676,7 +676,7 @@ dependencies = [ [[package]] name = "simplicityhl" -version = "0.4.0" +version = "0.4.1" dependencies = [ "arbitrary", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index ab736714..20372f73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simplicityhl" -version = "0.4.0" +version = "0.4.1" authors = ["sanket1729 "] license = "CC0-1.0" homepage = "https://github.com/BlockstreamResearch/SimplicityHL"