diff --git a/bitcoind-tests/tests/common/daemon.rs b/bitcoind-tests/tests/common/daemon.rs index 7eb3c9a5..6d04c7ab 100644 --- a/bitcoind-tests/tests/common/daemon.rs +++ b/bitcoind-tests/tests/common/daemon.rs @@ -51,7 +51,7 @@ pub trait Call { fn get_new_address(&self) -> elements::Address; fn send_to_address(&self, addr: &elements::Address, amt: &str) -> elements::Txid; fn get_transaction(&self, txid: &elements::Txid) -> elements::Transaction; - fn send_raw_transaction(&self, hex: &elements::Transaction) -> elements::Txid; + fn send_raw_transaction(&self, hex: &elements::Transaction) -> Result; fn generate(&self, blocks: u32); } @@ -89,14 +89,16 @@ impl Call for ElementsD { elements::Txid::from_str(&tx_id).unwrap() } - fn send_raw_transaction(&self, tx: &elements::Transaction) -> elements::Txid { + // Returns the node's rejection reason instead of panicking, so that one rejected + // spend does not stop the remaining test cases. + fn send_raw_transaction(&self, tx: &elements::Transaction) -> Result { let tx_id = self - .call("sendrawtransaction", &[serialize_hex(tx).into()]) - .as_str() - .unwrap() - .to_string(); + .client() + .call::("sendrawtransaction", &[serialize_hex(tx).into()]) + .map_err(|error| error.to_string())?; + let tx_id = tx_id.as_str().unwrap(); - elements::Txid::from_str(&tx_id).unwrap() + Ok(elements::Txid::from_str(tx_id).unwrap()) } fn generate(&self, blocks: u32) { diff --git a/bitcoind-tests/tests/common/test.rs b/bitcoind-tests/tests/common/test.rs index 28bd9f6d..56fd5817 100644 --- a/bitcoind-tests/tests/common/test.rs +++ b/bitcoind-tests/tests/common/test.rs @@ -1,12 +1,15 @@ +use std::path::{Path, PathBuf}; use std::str::FromStr; +use std::sync::Arc; use elements::pset::PartiallySignedTransaction as Psbt; use elements::{confidential, secp256k1_zkp as secp256k1}; +use elementsd::bitcoincore_rpc::jsonrpc::serde_json; use elementsd::ElementsD; use secp256k1::XOnlyPublicKey; use simplicity::jet::elements::{ElementsEnv, ElementsUtxo}; use simplicityhl::ast::ElementsJetHinter; -use simplicityhl::{elements, simplicity}; +use simplicityhl::{elements, simplicity, UnresolvedValues, UnstableFeatures}; use crate::common::daemon::Call; @@ -17,6 +20,8 @@ pub struct TestCase<'a> { template: Option, compiled: Option, witness: FnWitness, + witness_file: Option, + pruned: bool, lock_time: elements::LockTime, sequence: elements::Sequence, daemon: &'a ElementsD, @@ -37,6 +42,8 @@ impl<'a> TestCase<'a> { template: None, compiled: None, witness: empty_witness, + witness_file: None, + pruned: false, lock_time: elements::LockTime::ZERO, sequence: elements::Sequence::ZERO, daemon, @@ -50,10 +57,8 @@ impl<'a> TestCase<'a> { self } - pub fn program_path>(mut self, path: P) -> Self { - let text = - std::fs::read_to_string(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(path)) - .expect("path should be readable"); + pub fn program_path>(mut self, path: P) -> Self { + let text = read_file(path); let compiled = simplicityhl::CompiledProgram::new( text.as_str(), simplicityhl::Arguments::default(), @@ -65,17 +70,38 @@ impl<'a> TestCase<'a> { self } - pub fn template_path>(mut self, path: P) -> Self { - let text = - std::fs::read_to_string(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(path)) - .expect("path should be readable"); - let template = - simplicityhl::TemplateAst::new(text.as_str(), Box::new(ElementsJetHinter::new())) - .expect("program should compile"); + pub fn template_path>(self, path: P) -> Self { + self.template_path_with_unstable(path, &UnstableFeatures::none()) + } + + pub fn template_path_with_unstable>( + mut self, + path: P, + unstable_features: &UnstableFeatures, + ) -> Self { + let text = read_file(path); + let template = simplicityhl::TemplateAst::new_with_unstable( + text.as_str(), + unstable_features, + Box::new(ElementsJetHinter::new()), + ) + .expect("program should compile"); self.template = Some(template); self } + pub fn arguments_file>(self, path: P) -> Self { + let parameters = self + .template + .as_ref() + .expect("template should exist") + .parameters(); + let arguments = read_values(path) + .resolve(parameters) + .expect("arguments should be consistent with the program"); + self.arguments(arguments) + } + pub fn arguments(mut self, arguments: simplicityhl::Arguments) -> Self { let compiled = self .template @@ -92,6 +118,18 @@ impl<'a> TestCase<'a> { self } + /// Read the witness from a file. Use this for witnesses that do not sign the transaction. + pub fn witness_file>(mut self, path: P) -> Self { + self.witness_file = Some(path.as_ref().to_path_buf()); + self + } + + /// Prune the program against the spending transaction before it is broadcast. + pub fn pruned(mut self) -> Self { + self.pruned = true; + self + } + pub fn lock_time(mut self, lock_time: elements::LockTime) -> Self { self.lock_time = lock_time; self @@ -162,7 +200,9 @@ impl<'a> TestCase<'a> { self.funding = Some(Funding { address, txid }); } - pub fn spend_utxo(&self) { + /// Spend the funding output, returning the reason if the program cannot be satisfied + /// or the node rejects the spend. + pub fn spend_utxo(&self) -> Result<(), String> { let compiled = self.compiled.as_ref().expect("test program is missing"); let (outpoint, utxo) = self.get_vout(); let mut psbt = Psbt::from_tx(elements::Transaction { @@ -192,28 +232,32 @@ impl<'a> TestCase<'a> { let control_block = info .control_block(&script_ver) .expect("control block should exist"); - let sighash_all = { + let env = { let tx = psbt .extract_tx() .expect("transaction should be extractable"); let utxos = vec![ElementsUtxo::from(utxo)]; let index = 0; let annex = None; - let env = ElementsEnv::new( - &tx, + ElementsEnv::new( + Arc::new(tx), utxos, index, compiled.commit().cmr(), control_block.clone(), annex, self.genesis_hash, - ); - env.c_tx_env().sighash_all() + ) + }; + let witness_values = match &self.witness_file { + Some(path) => read_values(path) + .resolve(compiled.witness_types()) + .expect("witness should be consistent with the program"), + None => (self.witness)(env.c_tx_env().sighash_all().to_byte_array()), }; - let witness_values = (self.witness)(sighash_all.to_byte_array()); let satisfied_program = compiled - .satisfy(witness_values) - .expect("program should be satisfiable"); + .satisfy_with_env(witness_values, self.pruned.then_some(&env)) + .map_err(|error| format!("program is not satisfiable: {error}"))?; let (program_bytes, witness_bytes) = satisfied_program.redeem().to_vec_with_witness(); psbt.inputs_mut()[0].final_script_witness = Some(elements::Witness::from(vec![ witness_bytes, @@ -225,10 +269,19 @@ impl<'a> TestCase<'a> { .extract_tx() .expect("transaction should be extractable"); - let _txid = self.daemon.send_raw_transaction(&tx); + self.daemon.send_raw_transaction(&tx).map(|_txid| ()) } } fn empty_witness(_sighash_all: [u8; 32]) -> simplicityhl::WitnessValues { simplicityhl::WitnessValues::default() } + +fn read_file>(path: P) -> String { + std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join(path)) + .expect("path should be readable") +} + +fn read_values>(path: P) -> UnresolvedValues { + serde_json::from_str(&read_file(path)).expect("values file should be valid JSON") +} diff --git a/bitcoind-tests/tests/spend_utxo.rs b/bitcoind-tests/tests/spend_utxo.rs index d0b6c797..22a23076 100644 --- a/bitcoind-tests/tests/spend_utxo.rs +++ b/bitcoind-tests/tests/spend_utxo.rs @@ -4,7 +4,9 @@ use elements::secp256k1_zkp as secp256k1; use secp256k1::hashes::{sha256, Hash, HashEngine}; use simplicityhl::types::TypeConstructible; use simplicityhl::value::ValueConstructible; -use simplicityhl::{elements, ResolvedType, TemplateProgramWitness, Value, WitnessNameToValueMap}; +use simplicityhl::{ + elements, ResolvedType, TemplateProgramWitness, UnstableFeatures, Value, WitnessNameToValueMap, +}; mod common; use common::daemon::{self, Call}; @@ -37,14 +39,70 @@ fn spend_utxo() { .name("Pay to multisig") .program_path("../examples/p2ms.simf") .witness(p2ms), + // Pruned spends: the node rejects programs with unexecuted branches or unread + // witness data, so these check what pruning produces against the real node. + TestCase::new(&daemon, genesis_hash) + .name("OP_CAT (pruned)") + .program_path("../examples/cat.simf") + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("HODL vault (pruned)") + .program_path("../examples/hodl_vault.simf") + .witness(hodl_vault) + .lock_time(elements::LockTime::from_consensus(1000)) + .sequence(elements::Sequence::ENABLE_LOCKTIME_NO_RBF) + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Pay to public key (pruned)") + .template_path("../examples/p2pk.simf") + .arguments(p2pk_args()) + .witness(p2pk) + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Pay to public key hash (pruned)") + .program_path("../examples/p2pkh.simf") + .witness(p2pkh) + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Pay to multisig (pruned)") + .program_path("../examples/p2ms.simf") + .witness(p2ms) + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Kitchen sink (pruned)") + .template_path_with_unstable("../examples/kitchen_sink.simf", &UnstableFeatures::all()) + .arguments_file("../examples/kitchen_sink.args") + .witness_file("../examples/kitchen_sink.wit") + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Witness read only by a hidden branch (pruned)") + .program_path("../fixtures/pruning_hidden_witness.simf") + .witness_file("../fixtures/pruning_hidden_witness.none.wit") + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Witness read by the taken branch (pruned)") + .program_path("../fixtures/pruning_hidden_witness.simf") + .witness_file("../fixtures/pruning_hidden_witness.eq.wit") + .pruned(), + TestCase::new(&daemon, genesis_hash) + .name("Identical case nodes taking different branches (pruned)") + .program_path("../fixtures/pruning_twin_cases.simf") + .pruned(), ]; tests.iter_mut().for_each(TestCase::create_utxo); daemon.generate(1000); // satisfies lock time of all test cases + let mut rejected = vec![]; for test in tests { println!("⏳ {}", test.name); - test.spend_utxo(); - println!("✅ {}", test.name); + match test.spend_utxo() { + Ok(()) => println!("✅ {}", test.name), + Err(error) => { + println!("❌ {}: {error}", test.name); + rejected.push(test.name); + } + } } + assert!(rejected.is_empty(), "rejected spends: {rejected:?}"); } fn hodl_vault(sighash_all: [u8; 32]) -> simplicityhl::WitnessValues { diff --git a/fixtures/pruning_hidden_witness.eq.wit b/fixtures/pruning_hidden_witness.eq.wit new file mode 100644 index 00000000..c744f2f9 --- /dev/null +++ b/fixtures/pruning_hidden_witness.eq.wit @@ -0,0 +1,14 @@ +{ + "FIRST": { + "value": "Some(0x0000000000000000000000000000000000000000000000000000000000000000)", + "type": "Option" + }, + "SECOND": { + "value": "Some(0x0000000000000000000000000000000000000000000000000000000000000000)", + "type": "Option" + }, + "CHECK_NONE": { + "value": "false", + "type": "bool" + } +} diff --git a/fixtures/pruning_hidden_witness.none.wit b/fixtures/pruning_hidden_witness.none.wit new file mode 100644 index 00000000..c7c2a81e --- /dev/null +++ b/fixtures/pruning_hidden_witness.none.wit @@ -0,0 +1,14 @@ +{ + "FIRST": { + "value": "None", + "type": "Option" + }, + "SECOND": { + "value": "Some(0x0000000000000000000000000000000000000000000000000000000000000000)", + "type": "Option" + }, + "CHECK_NONE": { + "value": "true", + "type": "bool" + } +} diff --git a/fixtures/pruning_hidden_witness.simf b/fixtures/pruning_hidden_witness.simf new file mode 100644 index 00000000..c0a32395 --- /dev/null +++ b/fixtures/pruning_hidden_witness.simf @@ -0,0 +1,32 @@ +/* + * PRUNING: WITNESS READ ONLY BY A HIDDEN BRANCH + * + * Pruning fixture, not a meaningful contract. `SECOND` is bound outside the + * `match` and read only by the `false` branch. When `CHECK_NONE` is true, + * pruning hides that branch and must shrink `SECOND` to the bits the rest of + * the program reads; otherwise the node finds unread witness data and + * rejects the spend. + * + * Regression test for https://github.com/BlockstreamResearch/rust-simplicity/pull/379 + */ +fn assert_eq_256(a: u256, b: u256) { + assert!(jet::eq_256(a, b)); +} + +fn assert_none_256(value: Option) { + assert!(is_none::(value)); +} + +fn assert_none_or_eq_256(check_none: bool, first: Option, second: Option) { + match check_none { + true => assert_none_256(first), + false => assert_eq_256(unwrap(first), unwrap(second)), + }; +} + +fn main() { + let first: Option = witness::FIRST; + let second: Option = witness::SECOND; + let check_none: bool = witness::CHECK_NONE; + assert_none_or_eq_256(check_none, first, second); +} diff --git a/fixtures/pruning_twin_cases.simf b/fixtures/pruning_twin_cases.simf new file mode 100644 index 00000000..e3da79eb --- /dev/null +++ b/fixtures/pruning_twin_cases.simf @@ -0,0 +1,40 @@ +/* + * PRUNING: IDENTICAL CASE NODES THAT TAKE DIFFERENT BRANCHES + * + * Pruning fixture, not a meaningful contract. `step` is called twice, so the + * compiled program holds identical copies of its `match` nodes, and the two + * calls take different branches. The encoding merges identical nodes, so + * pruning must leave each merged node with only the branches some copy + * takes; otherwise the node rejects the spend with an anti-DoS error. + * + * Regression test for https://github.com/BlockstreamResearch/SimplicityHL/issues/391 + */ +fn nested(a: bool, b: bool) -> bool { + match a { + false => match b { + false => false, + true => true, + }, + true => false, + } +} + +fn step(cur: Option) -> (bool, Option) { + match cur { + None => (false, None), + Some(x: bool) => match nested(x, true) { + false => (false, Some(true)), + true => (true, None), + }, + } +} + +fn main() { + let (f0, n0): (bool, Option) = step(Some(false)); + let (f1, _n1): (bool, Option) = step(n0); + let hit: bool = match f0 { + true => f0, + false => f1, + }; + assert!(hit); +} diff --git a/src/lib.rs b/src/lib.rs index 7bc750db..8c8a091b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -569,7 +569,6 @@ pub(crate) mod tests { use crate::test_utils::TempWorkspace; use base64::display::Base64Display; use base64::engine::general_purpose::STANDARD; - use simplicity::BitMachine; use std::borrow::Cow; use std::path::{Path, PathBuf}; @@ -855,21 +854,43 @@ pub(crate) mod tests { self } - fn run(self) -> Result<(), simplicity::bit_machine::ExecutionError> { + /// Prune the program and panic unless an Elements node would accept the result. + fn run(self) -> Result, simplicity::bit_machine::ExecutionError> { let env = dummy_env::dummy_with(self.lock_time, self.sequence, self.include_fee_output); let pruned = self.program.redeem().prune(&env)?; - let mut mac = BitMachine::for_program(&pruned) - .expect("program should be within reasonable bounds"); - mac.exec(&pruned, &env).map(|_| ()) + let violations = crate::test_utils::consensus_violations(&pruned, &env); + assert!( + violations.is_empty(), + "pruned program would be rejected by an Elements node:\n- {}", + violations.join("\n- ") + ); + Ok(pruned) } pub fn assert_run_success(self) { match self.run() { - Ok(()) => {} + Ok(_) => {} Err(error) => panic!("Unexpected error: {error}"), } } + /// Like [`Self::assert_run_success`], and compare the pruned encoding with + /// `test-data/pruned/.json` (only with the `serde` feature). + /// + /// Set `SIMPLICITYHL_BLESS=1` to rewrite the fixture instead. The fixture is only + /// rewritten once the pruned program passes the consensus checks of [`Self::run`], + /// so blessing cannot record an encoding that a node would reject. + pub fn assert_run_success_with_pruned_fixture(self, name: &str) { + let pruned = match self.run() { + Ok(pruned) => pruned, + Err(error) => panic!("Unexpected error: {error}"), + }; + #[cfg(feature = "serde")] + assert_pruned_fixture(name, &pruned); + #[cfg(not(feature = "serde"))] + let _ = (name, pruned); + } + #[cfg(feature = "serde")] pub fn get_encoding_with_witness(self) -> (String, String) { let (program_bytes, witness_bytes) = self.program.redeem().to_vec_with_witness(); @@ -880,6 +901,44 @@ pub(crate) mod tests { } } + #[cfg(feature = "serde")] + fn assert_pruned_fixture(name: &str, pruned: &RedeemNode) { + use base64::Engine; + + #[derive(::serde::Serialize, ::serde::Deserialize, PartialEq, Eq)] + struct Encoding { + program: String, + witness: String, + } + + let (program_bytes, witness_bytes) = pruned.to_vec_with_witness(); + let actual = Encoding { + program: STANDARD.encode(&program_bytes), + witness: STANDARD.encode(&witness_bytes), + }; + + let path = format!("./test-data/pruned/{name}.json"); + if std::env::var_os("SIMPLICITYHL_BLESS").is_some() { + let json = serde_json::to_string_pretty(&actual).unwrap(); + std::fs::create_dir_all("./test-data/pruned").unwrap(); + std::fs::write(&path, json + "\n").unwrap(); + return; + } + let expected = std::fs::read_to_string(&path) + .unwrap_or_else(|error| panic!("{path}: {error}; bless with SIMPLICITYHL_BLESS=1")); + let expected = serde_json::from_str::(&expected).unwrap(); + let len = |b64: &str| STANDARD.decode(b64).unwrap().len(); + assert!( + expected == actual, + "pruned encoding differs from {path}: program {} -> {} bytes, witness {} -> {} bytes; \ + if this is intended, bless with SIMPLICITYHL_BLESS=1", + len(&expected.program), + program_bytes.len(), + len(&expected.witness), + witness_bytes.len(), + ); + } + /// THE DEFAULT HELPER /// Automatically sets up the standard `lib` self-referencing dependency. pub(crate) fn run_dependency_test(root_path: &str, lib_alias: &str) { @@ -1103,42 +1162,42 @@ pub(crate) mod tests { fn cat() { TestCase::program_file("./examples/cat.simf") .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("cat"); } #[test] fn modules() { TestCase::program_file_with_unstable("./examples/modules.simf", UnstableFeatures::all()) .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("modules"); } #[test] fn ctv() { TestCase::program_file("./examples/ctv.simf") .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("ctv"); } #[test] fn raw_hash() { TestCase::program_file_with_unstable("./examples/raw_hash.simf", UnstableFeatures::all()) .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("raw_hash"); } #[test] fn regression_153() { TestCase::program_file("./examples/array_fold_2n.simf") .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("array_fold_2n"); } #[test] fn pattern_matching() { TestCase::program_file("./examples/pattern_matching.simf") .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("pattern_matching"); } #[test] @@ -1149,7 +1208,7 @@ pub(crate) mod tests { t.sequence = elements::Sequence::ENABLE_LOCKTIME_NO_RBF; t.lock_time = elements::LockTime::from_time(1734967235 + 600).unwrap(); t.include_fee_output = true; - t.assert_run_success(); + t.assert_run_success_with_pruned_fixture("non_interactive_fee_bump"); } #[test] @@ -1159,14 +1218,14 @@ pub(crate) mod tests { .with_sequence(1000) .print_sighash_all() .with_witness_file("./examples/escrow_with_delay.timeout.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("escrow_with_delay.timeout"); } #[test] fn hash_loop() { TestCase::program_file("./examples/hash_loop.simf") .with_witness_values(WitnessValues::default()) - .assert_run_success(); + .assert_run_success_with_pruned_fixture("hash_loop"); } #[test] @@ -1176,7 +1235,7 @@ pub(crate) mod tests { .with_lock_time(1000) .print_sighash_all() .with_witness_file("./examples/hodl_vault.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("hodl_vault"); } #[test] @@ -1185,7 +1244,7 @@ pub(crate) mod tests { TestCase::program_file("./examples/htlc.simf") .print_sighash_all() .with_witness_file("./examples/htlc.complete.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("htlc.complete"); } #[test] @@ -1197,7 +1256,7 @@ pub(crate) mod tests { ) .with_argument_file("./examples/kitchen_sink.args") .with_witness_file("./examples/kitchen_sink.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("kitchen_sink"); } #[test] @@ -1207,7 +1266,7 @@ pub(crate) mod tests { .with_sequence(25920) .print_sighash_all() .with_witness_file("./examples/last_will.inherit.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("last_will.inherit"); } #[test] @@ -1319,13 +1378,36 @@ pub(crate) mod tests { ); } + #[test] + #[cfg(feature = "serde")] + fn pruning_hidden_witness_none() { + TestCase::program_file("./fixtures/pruning_hidden_witness.simf") + .with_witness_file("./fixtures/pruning_hidden_witness.none.wit") + .assert_run_success_with_pruned_fixture("pruning_hidden_witness.none"); + } + + #[test] + #[cfg(feature = "serde")] + fn pruning_hidden_witness_eq() { + TestCase::program_file("./fixtures/pruning_hidden_witness.simf") + .with_witness_file("./fixtures/pruning_hidden_witness.eq.wit") + .assert_run_success_with_pruned_fixture("pruning_hidden_witness.eq"); + } + + #[test] + fn pruning_twin_cases() { + TestCase::program_file("./fixtures/pruning_twin_cases.simf") + .with_witness_values(WitnessValues::default()) + .assert_run_success_with_pruned_fixture("pruning_twin_cases"); + } + #[test] #[cfg(feature = "serde")] fn p2ms() { TestCase::program_file("./examples/p2ms.simf") .print_sighash_all() .with_witness_file("./examples/p2ms.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("p2ms"); } #[test] @@ -1335,7 +1417,7 @@ pub(crate) mod tests { .with_argument_file("./examples/p2pk.args") .print_sighash_all() .with_witness_file("./examples/p2pk.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("p2pk"); } #[test] @@ -1344,7 +1426,7 @@ pub(crate) mod tests { TestCase::program_file("./examples/p2pkh.simf") .print_sighash_all() .with_witness_file("./examples/p2pkh.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("p2pkh"); } #[test] @@ -1354,7 +1436,7 @@ pub(crate) mod tests { .with_sequence(1000) .print_sighash_all() .with_witness_file("./examples/presigned_vault.complete.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("presigned_vault.complete"); } #[test] @@ -1362,7 +1444,7 @@ pub(crate) mod tests { fn sighash_all_anyonecanpay() { TestCase::program_file("./examples/sighash_all_anyonecanpay.simf") .with_witness_file("./examples/sighash_all_anyonecanpay.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("sighash_all_anyonecanpay"); } #[test] @@ -1370,7 +1452,7 @@ pub(crate) mod tests { fn sighash_all_anyprevout() { TestCase::program_file("./examples/sighash_all_anyprevout.simf") .with_witness_file("./examples/sighash_all_anyprevout.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("sighash_all_anyprevout"); } #[test] @@ -1378,7 +1460,7 @@ pub(crate) mod tests { fn sighash_all_anyprevoutanyscript() { TestCase::program_file("./examples/sighash_all_anyprevoutanyscript.simf") .with_witness_file("./examples/sighash_all_anyprevoutanyscript.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("sighash_all_anyprevoutanyscript"); } #[test] @@ -1386,7 +1468,7 @@ pub(crate) mod tests { fn sighash_none() { TestCase::program_file("./examples/sighash_none.simf") .with_witness_file("./examples/sighash_none.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("sighash_none"); } #[test] @@ -1394,7 +1476,7 @@ pub(crate) mod tests { fn sighash_single() { TestCase::program_file("./examples/sighash_single.simf") .with_witness_file("./examples/sighash_single.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("sighash_single"); } #[test] @@ -1403,7 +1485,7 @@ pub(crate) mod tests { TestCase::program_file("./examples/transfer_with_timeout.simf") .print_sighash_all() .with_witness_file("./examples/transfer_with_timeout.transfer.wit") - .assert_run_success(); + .assert_run_success_with_pruned_fixture("transfer_with_timeout.transfer"); } #[test] diff --git a/src/test_utils.rs b/src/test_utils.rs index 5683a62e..eccaaba9 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -1,11 +1,104 @@ use std::fs; use std::path::PathBuf; +use std::sync::Arc; use std::time; use std::sync::atomic::{AtomicUsize, Ordering}; +use simplicity::bit_machine::{PruneTracker, SetTracker}; +use simplicity::dag::{DagLike, InternalSharing}; +use simplicity::jet::elements::ElementsEnv; +use simplicity::jet::Elements; +use simplicity::node::Inner; +use simplicity::{BitIter, BitMachine, RedeemNode}; + use crate::ast::ElementsJetHinter; -use crate::{TemplateAst, UnstableFeatures}; +use crate::{elements, TemplateAst, UnstableFeatures}; + +/// Check that a pruned program would pass the checks an Elements node runs on a spend. +/// +/// The node only sees bytes, so the program is encoded and decoded again first. Decoding +/// rejects witness data that the program does not read, and programs that are not maximally +/// shared. The decoded program must keep its CMR, run, and take every case branch that is not +/// hidden; otherwise the node rejects it with an anti-DoS error. Pruning must also be +/// idempotent, or the first pass left work undone. +/// +/// Return a description of each violation. +pub fn consensus_violations( + pruned: &Arc, + env: &ElementsEnv>, +) -> Vec { + let mut violations = Vec::new(); + let (program_bytes, witness_bytes) = pruned.to_vec_with_witness(); + + match pruned.prune(env) { + Ok(twice) + if twice.to_vec_with_witness() != (program_bytes.clone(), witness_bytes.clone()) => + { + let (twice_program, twice_witness) = twice.to_vec_with_witness(); + violations.push(format!( + "pruning is not idempotent: pruning again changes the encoding from {} + {} bytes to {} + {} bytes (program + witness)", + program_bytes.len(), + witness_bytes.len(), + twice_program.len(), + twice_witness.len(), + )); + } + Ok(_) => {} + Err(error) => violations.push(format!("pruning again failed: {error}")), + } + + let decoded = match RedeemNode::decode::<_, _, Elements>( + BitIter::from(program_bytes.as_slice()), + BitIter::from(witness_bytes.as_slice()), + ) { + Ok(decoded) => decoded, + Err(error) => { + violations.push(format!("encoding does not decode: {error}")); + return violations; + } + }; + if decoded.cmr() != pruned.cmr() { + violations.push(format!( + "decoding changes the CMR from {} to {}", + pruned.cmr(), + decoded.cmr() + )); + } + + let mut tracker = SetTracker::default(); + let executed = BitMachine::for_program(&decoded) + .map_err(|error| error.to_string()) + .and_then(|mut mac| { + mac.exec_with_tracker(&decoded, env, &mut tracker) + .map_err(|error| error.to_string()) + }); + if let Err(error) = executed { + violations.push(format!("decoded program fails to run: {error}")); + return violations; + } + + // Decoding guarantees maximal sharing, so each IHR names exactly one node and the + // IHR-keyed tracker says exactly which branches of that node ran. + for data in decoded.as_ref().post_order_iter::() { + let ihr = data.node.ihr(); + let (left, right) = (tracker.contains_left(ihr), tracker.contains_right(ihr)); + let unexecuted = match data.node.inner() { + Inner::Case(..) => !left || !right, + Inner::AssertL(..) => !left, + Inner::AssertR(..) => !right, + _ => false, + }; + if unexecuted { + violations.push(format!( + "anti-DoS: case node {} has a branch that is neither executed nor hidden (left executed: {left}, right executed: {right})", + data.node.cmr() + )); + } + } + + violations +} /// Compile `src` up to and including analysis, with all unstable features enabled. /// Return the message of every reported error, in the order they are presented to the user. diff --git a/test-data/pruned/array_fold_2n.json b/test-data/pruned/array_fold_2n.json new file mode 100644 index 00000000..51129400 --- /dev/null +++ b/test-data/pruned/array_fold_2n.json @@ -0,0 +1,4 @@ +{ + "program": "5JpsgAAAAEECBAhAoQYmyAAAAAAQLAg4w1MQcKkHGGph9AoPqMNsMPuFCSBZaBRpcTmcVRCRXQmYAIq4WDF4UsJ7AwqF1hL9cVIyFlhwCtu/AEMAxCcGPwowFA3BcDAUHBwuGAKDiELicBQcWEChJBuK7IAAAAIBgFQsWbcTmBd77UKPutD6OLpAkNFbS8SYUsZldxGEoA3o23T+XYAMMAxC1sHNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiE4EfkSCAcGA5Fg", + "witness": "" +} diff --git a/test-data/pruned/cat.json b/test-data/pruned/cat.json new file mode 100644 index 00000000..e1ff9ac3 --- /dev/null +++ b/test-data/pruned/cat.json @@ -0,0 +1,4 @@ +{ + "program": "5DJsBAEWACDAKkChNiIAIIQKEkIMONRQLJm3A5rruXg9CdT0ZA4zl/jbkryjKfPZUy2qtPZa7RiiPFRiHDAMQtjBzOKohIroTMAEVcLBi8KWE9gYVC6wl+uKkZCyw4BW3fgCGAYq2Dgiug4MFSBQmwvQQgUJIQYcaigWTNtOYIi/1AcaRNMBhc3vyX09ErCRo/sv5CAbaGAJlp1bvfigwDELYYF3vtQo+60Po4ukCQ0VtLxJhSxmV3EYSgDejbdP5dgAw8PAoTgJ+OAQDgoHCwuIwGIOOAOPgA==", + "witness": "" +} diff --git a/test-data/pruned/ctv.json b/test-data/pruned/ctv.json new file mode 100644 index 00000000..abb6ab1a --- /dev/null +++ b/test-data/pruned/ctv.json @@ -0,0 +1,4 @@ +{ + "program": "5wEkCTVkcziqISK6EzABFXCwYvClhPYGFQusJfripGQssOAVt34AhgGJAoSQgwVw+HGBzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYhZhamq05rruXg9CdT0ZA4zl/jbkryjKfPZUy2qtPZa7RiiPFRiHDAMSBQkg3AxS/DI5n4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDAMQswtJgiL/UBxpE0wGFze/JfT0SsJGj+y/kIBtoYAmWnVu9+KDwICkChJBuIxS9wI5u8lZwLSPPkvMpefT82f85Cc97MlOKr7Djoj7EAHmx0TDAMQswtLVcjm8ToYSOAZ74jeLno8FWHRgos74PKQ3vn+6/VNqUJJRywMAxIFCSDcail+GBzfQgn7m8T+SlBrmrOch86kHUDO438Z7mfcnzyKpQtkIOGAYhZhaTaCHQWKequSoQRbKj9ZMNUNP9TZslL2ACY8pcCYeALJMHjQCkChJBuQope4Ac0vqVxn0dNTcJGVHIKgZVnO4Ri5KL+OnrThZFmsP0velhgGIWYWk20qztTpHBhF8ugDjaMMsLl9/jQllEBh7MsI4rcUNpyvh4iApAoSQbkqKX4YnNKg3OgxzUB7/tnnkIYePSA4b9lUGNvmRsOpjaQAmHTtYYBiFmFpMDLqyIAl/t8mPC4rRGEfM1lVH7CAxNfptKDrOKJGwAHAeSgFIFCSDcpRS9gcxgts54X+MRHKrfq2DJAzmcXWPmk3AyFTFgxcx5QC1WKBgGIWYWkwYulQXr0Fu/BAWgC5j7LWeBAl+pI9pt9ZFn0rcXaN1Fh5BAUgUJINy1FL8KcxsXX6Q/gR6bfNv+QIkq2TSNzaS+85toDfqr3uY18KY5BgGIWYWk2R+ra7Pj7bD7ngvTZ8puEzNaYgGZeeHhbJwsZpxe6Uuh5aAUgUJINzCijVicxaVg5c7bCv5v4Efeky6pdqN8+a2UbNm+82P8XJkfgUkBgGJAoTaa49AZswUpxgRNKz1+4uDuXbUafwXtXbjwic1dRV8fxdBCBQkhBhxqKBZM26Dmf7mfDw7DxJRotWTkSgnKVskuvR6itvdUy8omlW0PLqAMAxC2MHNuPwXvzv9stXb3QFgqI0+EkTeqbTD8hwv1sedPf8PVoQYBiE4GfmrBAODgcNA4pA46A5FgcnAOVoHL4DmRA5ogObYA==", + "witness": "" +} diff --git a/test-data/pruned/escrow_with_delay.timeout.json b/test-data/pruned/escrow_with_delay.timeout.json new file mode 100644 index 00000000..46209410 --- /dev/null +++ b/test-data/pruned/escrow_with_delay.timeout.json @@ -0,0 +1,4 @@ +{ + "program": "5AOgUNR2V1G0LgaaCRbvaHlCcHKcyI4gqieQ6H03x2NG8g/AiDE2l5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmAQJigw+gUJIEnDmuu5eD0J1PRkDjOX+NuSvKMp89lTLaq09lrtGKI8VGIcMAxIFCSD7zcBFB+AigWTYw5gXe+1Cj7rQ+ji6QJDRW0vEmFLGZXcRhKAN6Nt0/l2ADDAMQm0/EoIBwEDhixA+gHDQnBkkIMFXlObQQ6CxT1VyVCCLZUfrJhqhp/qbNkpewATHlLgTDwBZJgwDEJqA4EDaFwEBwUHGYHHAPHYHHo", + "witness": "9ttDKEoTB8KsOUEZ1XAL7oS00Vfy+EYUFw1bLN+SMTQmTNMlFSuSMaxQaxkzi7xoC3NvucCUnurdz4TM6cMgagA=" +} diff --git a/test-data/pruned/hash_loop.json b/test-data/pruned/hash_loop.json new file mode 100644 index 00000000..7043faf7 --- /dev/null +++ b/test-data/pruned/hash_loop.json @@ -0,0 +1,4 @@ +{ + "program": "6DhJAk1ZHN3krOBaR58l5lLz6fmz/nITnvZkpxVfYcdEfYgA82OiYYBiQKEGJFB8iUUCyG0IOSQKhZDbzcCMOQcYcfA4VC0BbBuGIOSQKhZDcRoOSQKhZDcVG3GHH4WYcfhxwqFmFrG42NxyYcg4w4+BwqFoC2Dcg0HJIFQshuRSDkkCoWQ3JE24w4/IIw4/IU4VCzC1jcnUHJIFQshuUiDkkCoWQ3Ks24w4/Jww4/J84VCzC1jctzcaGHH5AmHH5CHCoWYWsbmDNzDGHIOMOPgcKhaAthJBuZJBxwsAsmqjmcVRCRXQmYAIq4WDF4UsJ7AwqF1hL9cVIyFlhwCtu/AEMAxIFCSD7BRmynNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiQKDc1RxSSBMNWJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYiA6gNwHCgOKgOOAOQoHJIJyXYvxe6s0Gh2xp3ZFlh3qHuPHSu4IG8t/0ywQErz6pmrOy8mBcmguToDMOIGYHKIJynLynFypC5WAMg7QMgOWIHL4JzBl5gxcwoXMQAyDwYDIDmNCcyReZIXMoFzLgMg8OAyA5nAOaoDm3Cc3hebwXN8FzggMg8UAZAc4wTnLLzli5zQudABkHjADIDnVA54wnPQXnoFz1Bc9oDIPHIGQHPkE59i8/IufgLn8AZB5AgZAc/xAoTaUCv8unS2JIuR6/UZI5pZ0lxWHhfvR2ocOcRAma/lEiABCBQkhBiDDhZEixG0M6IZzkLPP/t8aZ/NfTm5pw5IQ0J/duRiaFMIlp35sJi4YBgObaVZ2p0jgwi+XQBxtGGWFy+/xoSyiAw9mWEcVuKG05XwwDUFvC4EzboOb6EE/c3ifyUoNc1ZzkPnUg6gZ3G/jPcz7k+eRVKFshBwwDELhDBzaCHQWKequSoQRbKj9ZMNUNP9TZslL2ACY8pcCYeALJMGAYhOHn6CsEA4jA4pA6C4", + "witness": "" +} diff --git a/test-data/pruned/hodl_vault.json b/test-data/pruned/hodl_vault.json new file mode 100644 index 00000000..32c42e81 --- /dev/null +++ b/test-data/pruned/hodl_vault.json @@ -0,0 +1,4 @@ +{ + "program": "53k2QAAAfQCECh0ChJCDDjUUCyacAxOb6EE/c3ifyUoNc1ZzkPnUg6gZ3G/jPcz7k+eRVKFshBwwDELYwc2gh0FinqrkqEEWyo/WTDVDT/U2bJS9gAmPKXAmHgCyTBgGIXAt3g5tpVnanSODCL5dAHG0YZYXL7/GhLKIDD2ZYRxW4obTlfDAMVkAAMNQA4UQKHQKEkG4gONxEKBYmBl1ZEAS/2+THhcVojCPmayqj9hAYmv02lB1nFEjYADgPDwKFpNL6lcZ9HTU3CRlRyCoGVZzuEYuSi/jp604WRZrD9L3pYeGgVaXm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYBvIFDoFCDDj8ZnHHH4QcKkGCoWsgw5AoSQJNWRzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYkChJCDDclDDhYBZtVpzBEX+oDjSJpgMLm9+S+nolYSNH9l/IQDbQwBMtOrd78UGAYkChJBuAH5RmHHCxCzM/BVazZBMsdgY/lS0WYcYfsNRJVmhtHQmf/PVrNEOe4weAAUgUJINw4UasTm8ToYSOAZ74jeLno8FWHRgos74PKQ3vn+6/VNqUJJRywMAxIFCSDciDjjjjjcjhQfkMccccccLQFwFsYc3eSs4FpHnyXmUvPp+bP+chOe9mSnFV9hx0R9iADzY6JhgGIThB+ZkEA4YBxQBxuByIA5JgcmSbTjAj/KIPa+tpgioDdK4D5sLjvHJcZ3nlPV1gTcrjhPcoIQKHQKDcrzjcpxQkgScOZxVEJFdCZgAirhYMXhSwnsDCoXWEv1xUjIWWHAK278AQwDEgUJINy/ONzAig/Lk4VC0Guu5eD0J1PRkDjOX+NuSvKMp89lTLaq09lrtGKI8VGIcPFwFCbQOLAcAA4WSKAOMQcRgcThcWgONQcywHM0FzPgOOQc14HNmFzcAOPRc4ADj8HOqBzsg==", + "witness": "AAAD6AABhqCQIxuN6WoflA3c9Ab+g4lBfKj7CwMVFgji+UsxtEOn4NJqEuQ332kCjwkCfDfV9nQqEMHohkBh0Rm4u86WLSbT8jQfVx8Gkhbt/HKCL2CUuOwznC9y3GSuoO7R49YKv0Vy/dBGGOW1vGcszXHPrxJbbBsQGuyjp7k4/oOTKrOHQw==" +} diff --git a/test-data/pruned/htlc.complete.json b/test-data/pruned/htlc.complete.json new file mode 100644 index 00000000..0d9ea671 --- /dev/null +++ b/test-data/pruned/htlc.complete.json @@ -0,0 +1,4 @@ +{ + "program": "5dOgUIMQKEGGIOMFgSQJNWRzOKohIroTMAEVcLBi8KWE9gYVC6wl+uKkZCyw4BW3fgCGAYhN6SEGH4IKBYtVyOa67l4PQnU9GQOM5f425K8oynz2VMtqrT2Wu0YojxUYhwwDEgUJINuFGrE5gXe+1Cj7rQ+ji6QJDRW0vEmFLGZXcRhKAN6Nt0/l2ADDAMQNQHCQOKAnFybSzND1W/DFeu7ZH4MXHT8cQBEuKQrdxGdnIFSyOhq+UkoIQKEkG4yONxoKBYs26Dm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxC1sHN4nQwkcAz3xG8XPR4KsOjBRZ3weUhvfP91+qbUoSSjlgYBitLzfMz987l3WKtAxSudDhYOBTf5tlucUbKz5QK2LfAvMA4GQKDchj8gzjhYEkCThzBEX+oDjSJpgMLm9+S+nolYSNH9l/IQDbQwBMtOrd78UGAYhOS5OKT8lBOJBOACwbGHM/BVazZBMsdgY/lS0WYcYfsNRJVmhtHQmf/PVrNEOe4wYBiE4zPylBANwHCCRQBkDiELiYBpBx0ByAA5SkigDeDlgZjdreD9I7T+vYBwnuy5itrph/V3aqjvaYkbL53quWGAgwDlu", + "witness": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7pZ5SujI/wsqxJYlJklfRecWsxU4OPn4vhFTgG3YtZp4H3c9p7XLlEdBTLRpa62Zm610SRMLrAg+9kJMVi9e3gA==" +} diff --git a/test-data/pruned/kitchen_sink.json b/test-data/pruned/kitchen_sink.json new file mode 100644 index 00000000..d1cc70fd --- /dev/null +++ b/test-data/pruned/kitchen_sink.json @@ -0,0 +1,4 @@ +{ + "program": "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", + "witness": "AAAABegAEAAcAAAPoA==" +} diff --git a/test-data/pruned/last_will.inherit.json b/test-data/pruned/last_will.inherit.json new file mode 100644 index 00000000..71c124b4 --- /dev/null +++ b/test-data/pruned/last_will.inherit.json @@ -0,0 +1,4 @@ +{ + "program": "5lHQKEGJsWVABAmKDEkWQAAAAEChXD4cYHNkfq2uz4+2w+54L02fKbhMzWmIBmXnh4WycLGacXulLoYBiFmFqacAxOYwW2c8L/GIjlVv1bBkgZzOLrHzSbgZCpiwYuY8oBarFAwDELgDBzBi6VBevQW78EBaALmPstZ4ECX6kj2m31kWfStxdo3UWGAYvhwU5tx+C9+d/tlq7e6AsFRGnwkib1TaYfkOF+tjzp7/h6tCDAODhcLbOHMWlYOXO2wr+b+BH3pMuqXajfPmtlGzZvvNj/FyZH4FJAYBiFxCQkUM6IZzkLPP/t8aZ/NfTm5pw5IQ0J/duRiaFMIlp35sJi6DA0DEcxsXX6Q/gR6bfNv+QIkq2TSNzaS+85toDfqr3uY18KY5BgGwJxikg2sUJFuG44C4CCjmf7mfDw7DxJRotWTkSgnKVskuvR6itvdUy8omlW0PLqAMA0kChJB+QZxuQooFi04Bgc0VlElpdPDwml7bGal4pXvr8rC0lyUiv2L8mg85kQcfUhgGIWszfYPpNJx18ed8hVMKXhtpd+GDaips7t68r4pp01WZw1h46AoTgB+TQIBwQDiQLj4BiDkuTaXm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYBCBQgw/KY4VJIEnDmcVRCRXQmYAIq4WDF4UsJ7AwqF1hL9cVIyFlhwCtu/AEMAxIFCSDcBONwMUH5cnCoWhsYc113LwehOp6MgcZy/xtyV5RlPnsqZbVWnstdoxRHioxDhgGITeBxWDgQHDSRQBxgDiYLiwBxmDmHA5jDSaKZZD7WoV+gt7B9F7HlNDTzipFOhX9KvIoss0cLMieGAcyIA=", + "witness": "OqkA3bFYVFxox+iX4BSo9RzMXSFf4zMm1XxQaRTGVqHm4QmsY+QXm7KhOu4X9UZCxW30vdZJQUWkxS0RuAJtt4A=" +} diff --git a/test-data/pruned/modules.json b/test-data/pruned/modules.json new file mode 100644 index 00000000..24aaaffd --- /dev/null +++ b/test-data/pruned/modules.json @@ -0,0 +1,4 @@ +{ + "program": "5CpsgAAAA8EIFCbIAAAAFBCBQgw41FCSDZpIFq1CjS4nM4qiEiuhMwARVwsGLwpYT2BhULrCX64qRkLLDgFbd+AIYBiE4CfgRgKBuH4MKBcCNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4doFIFBtgIBwwgUJINxLZAAAAEYMAqFizbicwRF/qA40iaYDC5vfkvp6JWEjR/ZfyEA20MATLTq3e/FBgGIWtg5gXe+1Cj7rQ+ji6QJDRW0vEmFLGZXcRhKAN6Nt0/l2ADDAMQnAj8eggHBgOOgOQAA==", + "witness": "" +} diff --git a/test-data/pruned/non_interactive_fee_bump.json b/test-data/pruned/non_interactive_fee_bump.json new file mode 100644 index 00000000..454686ef --- /dev/null +++ b/test-data/pruned/non_interactive_fee_bump.json @@ -0,0 +1,4 @@ +{ + "program": "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", + "witness": "5mCM62b2KJbKB2YZZN0qsIZ9+Uyq6wiawJCJ0Twjz2TuOg1C+PhML2J9QjDJ81eRnEiidBF+OMnD0yoOh1cLRQ==" +} diff --git a/test-data/pruned/p2ms.json b/test-data/pruned/p2ms.json new file mode 100644 index 00000000..8087902c --- /dev/null +++ b/test-data/pruned/p2ms.json @@ -0,0 +1,4 @@ +{ + "program": "5uk2l5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmARacYEf5RB7X1tMEVAbpXAfNhcd45LjO88p6usCblccJ7lBgtPyYRQDJLGGIJJonwvxOqRTamOQiwbfM2EMA+InecBt8gyCoWRAoQY4oNggUIOOQKE2AACEGGHIMMFgFpHxOQKEGHG4AccgwVJIEnDmuu5eD0J1PRkDjOX+NuSvKMp89lTLaq09lrtGKI8VGIcMAxCcWpIPxAbiIUH4CcKhZtjDmBd77UKPutD6OLpAkNFbS8SYUsZldxGEoA3o23T+XYAMMAxCbj8fggHAgOGEkH4mFGmNOYIi/1AcaRNMBhc3vyX09ErCRo/sv5CAbaGAJlp1bvfigwDEgUJIQYYkgTHMBzOKohIroTMAEVcLBi8KWE9gYVC6wl+uKkZCyw4BW3fgCGAYgaQtrBzPwVWs2QTLHYGP5UtFmHGH7DUSVZobR0Jn/z1azRDnuMGAYj8hDBUfkOCAcKC4mAYB5FAcjgOSZAoNyRNyfOMOONygOMOFiFrAcAQKDcoD8rjjDjjj8sDjDjhZBbQHEKBQmwAgQgUJINy4ONy6FAsWbac3eSs4FpHnyXmUvPp+bP+chOe9mSnFV9hx0R9iADzY6JhgGIWs3idDCRwDPfEbxc9Hgqw6MFFnfB5SG98/3X6ptShJKOWB5CAUJwADlMDgYHCQOKwOOwOZ0DmjA5pyRQBywBzXg=", + "witness": "+6WeUroyP8LKsSWJSZJX0XnFrMVODj5+L4RU4Bt2LWaeB93Pae1y5RHQUy0aWutmZutdEkTC6wIPvZCTFYvXt6U7fVasUVyOV5x8EOUdWjMv3vE6nglrfHOYEWbFuEU+qn+mp/FBWf+/e7qOOitBu0dmDQhILf5I14DoxcrM/XEg" +} diff --git a/test-data/pruned/p2pk.json b/test-data/pruned/p2pk.json new file mode 100644 index 00000000..6b10091f --- /dev/null +++ b/test-data/pruned/p2pk.json @@ -0,0 +1,4 @@ +{ + "program": "4Gki0vN8zP3zuXdYq0DFK50OFg4FN/m2W5xRsrPlArYt8C8wChXDhzXXcvB6E6noyBxnL/G3JXlGU+eypltVaey12jFEeKjEOGAYhZnFAtjYw5nFUQkV0JmACKuFgxeFLCewMKhdYS/XFSMhZYcArbvwBDAMQA==", + "witness": "90s8pXRkf4WVYksSkySvovOLWYqcHHz8XwipwDbsWs08D7ue09rlyiOgplo0tdbMzda6JImF1gQfeyEmKxevbw==" +} diff --git a/test-data/pruned/p2pkh.json b/test-data/pruned/p2pkh.json new file mode 100644 index 00000000..1a8911e9 --- /dev/null +++ b/test-data/pruned/p2pkh.json @@ -0,0 +1,4 @@ +{ + "program": "5PugUJtImXnNTGGN1W7dMpL66h+UqiOQS/0Kky+iiYX+24co73ghAoQYckgSasjmcVRCRXQmYAIq4WDF4UsJ7AwqF1hL9cVIyFlhwCtu/AEMAxCa0kIMPwAUCxarkc113LwehOp6MgcZy/xtyV5RlPnsqZbVWnstdoxRHioxDhgGJAoSQbcKNWJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYgagOEgcRkChJBuKjcVnCoWLNug5n4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDAMQtbBzBEX+oDjSJpgMLm9+S+nolYSNH9l/IQDbQwBMtOrd78UGAYhcB4Fw5vE6GEjgGe+I3i56PBVh0YKLO+DykN75/uv1TalCSUcsDAMSBQkg/II43IYUOKBZtjDm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxA3hcIH5MggHFoHJYDk4A==", + "witness": "eb5mfvncu6xVoGKVzocLBwKb/NstzijZWfKBWxb4F5j3SzyldGR/hZViSxKTJK+i84tZipwcfPxfCKnANuxazTwPu57T2uXKI6CmWjS11szN1rokiYXWBB97ISYrF69v" +} diff --git a/test-data/pruned/pattern_matching.json b/test-data/pruned/pattern_matching.json new file mode 100644 index 00000000..5c29a022 --- /dev/null +++ b/test-data/pruned/pattern_matching.json @@ -0,0 +1,4 @@ +{ + "program": "5SpsgAAACAEWQAAAAGDBAMkg0BULILSIQKEGIFCSEGHGAy4MKBZs24nNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiFtYOZxVEJFdCZgAirhYMXhSwnsDCoXWEv1xUjIWWHAK278AQwDEgw44wHCeJxQLhTNo5giL/UBxpE0wGFze/JfT0SsJGj+y/kIBtoYAmWnVu9+KDAMQuIDAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGHgYFH4CccYDinjUUC4qN4nQwkcAz3xG8XPR4KsOjBRZ3weUhvfP91+qbUoSSjlgeAAULi4z8FVrNkEyx2Bj+VLRZhxh+w1ElWaG0dCZ/89Ws0Q57jB4hAo3GJgqPxoCBcEAUXE4DFp1yjz3XDlSWG6KD6uwQMHpCSP8mFE6iCuwXftljUgrzDAOPwnIFJBuQALyVFAsDaCHQWKequSoQRbKj9ZMNUNP9TZslL2ACY8pcCYeALJMHj0ChaDd5KzgWkefJeZS8+n5s/5yE572ZKcVX2HHRH2IAPNjomHjsChNp+SgIBwEDksA==", + "witness": "" +} diff --git a/test-data/pruned/presigned_vault.complete.json b/test-data/pruned/presigned_vault.complete.json new file mode 100644 index 00000000..adfe52d7 --- /dev/null +++ b/test-data/pruned/presigned_vault.complete.json @@ -0,0 +1,4 @@ +{ + "program": "5CugUIMTYgfQCBMUkIMFXlOYF3vtQo+60Po4ukCQ0VtLxJhSxmV3EYSgDejbdP5dgAwwDFaXm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYBrIFCDD8GOFSSBJw5nFUQkV0JmACKuFgxeFLCewMKhdYS/XFSMhZYcArbvwBDAMSBQkg3ATjcDFB+KThULQ2MOa67l4PQnU9GQOM5f425K8oynz2VMtqrT2Wu0YojxUYhwwDEJvPxqCAcDA4cSKAMgcThcWANIOOAOPTbL6zGGLCITbVHSVazVRLRqau7zb51gwLR25PEkyhhBEGAcggA=", + "witness": "dttDKEoTB8KsOUEZ1XAL7oS00Vfy+EYUFw1bLN+SMTQmTNMlFSuSMaxQaxkzi7xoC3NvucCUnurdz4TM6cMgagA=" +} diff --git a/test-data/pruned/pruning_hidden_witness.eq.json b/test-data/pruned/pruning_hidden_witness.eq.json new file mode 100644 index 00000000..3068a73b --- /dev/null +++ b/test-data/pruned/pruning_hidden_witness.eq.json @@ -0,0 +1,4 @@ +{ + "program": "5IugUOgUOgUIMQYccbA4VC0DakChJBtpxwsCRcCM6IZzkLPP/t8aZ/NfTm5pw5IQ0J/duRiaFMIlp35sJi6DA0DEcwRF/qA40iaYDC5vfkvp6JWEjR/ZfyEA20MATLTq3e/FBgGsfhhxwuBmfgqtZsgmWOwMfypaLMOMP2GokqzQ2joTP/nq1miHPcYOkChaCSDcCPwMUCwZt0HNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiFqYOZxVEJFdCZgAirhYMXhSwnsDCoXWEv1xUjIWWHAK278AQwDEJwE/IAEA4KYUaqHRicitq7V3sIxBilw1vd5ElXBZX1gpPIkl4xTQKwwDjEkUAaAccEigDYDkMByKA5HAA==", + "witness": "gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" +} diff --git a/test-data/pruned/pruning_hidden_witness.none.json b/test-data/pruned/pruning_hidden_witness.none.json new file mode 100644 index 00000000..8dcdb609 --- /dev/null +++ b/test-data/pruned/pruning_hidden_witness.none.json @@ -0,0 +1,4 @@ +{ + "program": "44dAodAodAoQYaHHGxOFQsxtKBQyOELySDG9yJbXMEC4MNfmRLt6wc8OnVDdzyENc7YsHTG2nHJIFwKJKaIga/1FgzAyfjs6ti0AfqX7vX8YHUumNJHVhpNps6WXgwDEDhAWhg5gXe+1Cj7rQ+ji6QJDRW0vEmFLGZXcRhKAN6Nt0/l2ADDAMQm8/FAIBwMHg4HCSRQBmDiAkUAawcWgcYgcag==", + "witness": "YA==" +} diff --git a/test-data/pruned/pruning_twin_cases.json b/test-data/pruned/pruning_twin_cases.json new file mode 100644 index 00000000..8cb22aa9 --- /dev/null +++ b/test-data/pruned/pruning_twin_cases.json @@ -0,0 +1,4 @@ +{ + "program": "5FJgEFIEJAyJBQgxMggWA2SBQfScgUNApwZkcHhyZ2RA/xSMegr7pPXLzt42VuKTMpj72RM7XiQNgaBiCxBrA3kChofNibtVheaSihbG1b6Vpm7Qe6EU7pFmTv53H7wpeqaISBwYkFAcQMweHgcSAcTkCg/FJgGSBQbic5AoYArAykGtqcTTpHkeWz4WLNwlN0jccLfdAmkBSWKhXTOj4BgGATJJBuMxRg5nFUQkV0JmACKuFgxeFLCewMKhdYS/XFSMhZYcArbvwBDAMQmk/CgQDaBwcDho", + "witness": "" +} diff --git a/test-data/pruned/raw_hash.json b/test-data/pruned/raw_hash.json new file mode 100644 index 00000000..ea90c844 --- /dev/null +++ b/test-data/pruned/raw_hash.json @@ -0,0 +1,4 @@ +{ + "program": "6CRNgVAixEjQGAVWW9W33eDNZgIEBggKDA4QDSFVoEBESExQVFhcYGRobHB0eHwbFpICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8G4KhZBbCdWQIQKEGIMOFgNkgw4WDVQIQccLBqsBANxBxwsBuEIMOFgNw1BhwsGq0EIOOFg1XAEA3EHHCwG4vQYcLBquIIQccLBquQIBuA4mA4/asQQDkOQKEkCQ/ItnFUQkV0JmACKuFgxeFLCewMKhdYS/XFSMhZYcArbvwBDAMCBQkg3I8F5TCgWA/IhrruXg9CdT0ZA4zl/jbkryjKfPZUy2qtPZa7RiiPFRiHDAMCBQkg3JsF5YCgWA/I5gXe+1Cj7rQ+ji6QJDRW0vEmFLGZXcRhKAN6Nt0/l2ADDAMCBQkg3KcF5cigWA/IlgiL/UBxpE0wGFze/JfT0SsJGj+y/kIBtoYAmWnVu9+KDAMCBQkg3LMF5gxQLAfkez8FVrNkEyx2Bj+VLRZhxh+w1ElWaG0dCZ/89Ws0Q57jBgGBAoSQbl+C8xgoFgPyPbxOhhI4BnviN4uejwVYdGCizvg8pDe+f7r9U2pQklHLAwDAgUJINzFgvMsKBYD8lW7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAwIFCSDcoTjjjjjjjcz4tQ/KJtpVnanSODCL5dAHG0YZYXL7/GhLKIDD2ZYRxW4obTlfDAMAswuAM26Dm+hBP3N4n8lKDXNWc5D51IOoGdxv4z3M+5PnkVShbIQcMAxC4Mwc2gh0FinqrkqEEWyo/WTDVDT/U2bJS9gAmPKXAmHgCyTBgGK0p4KqsVJAEYa3Wmrcc7Q0aRQ6r9DwEuyYdGTDMkoVfkGDhwXBguHmBl1ZEAS/2+THhcVojCPmayqj9hAYmv02lB1nFEjYADgO8ChcRml9SuM+jpqbhIyo5BUDKs53CMXJRfx09acLIs1h+l70sO0CrEAAQcUrEAAgcVrEAAwcWhVYgAIDjBYgAKDjIKhZBbCQOdBAoNznm5wzhUBzhH5sDhUbnXNzdHCo3O2bnPOFQHOcfnTOFQHOkDUPzjnCoDEHAwOGAOawHERAoSQbm7tNSpK78/2dF5JhSZsVpLzDtoqaHlzfb4dMz/S1qafXv3gwCoWJgxdKgvXoLd+CAtAFzH2Ws8CBL9SR7Tb6yLPpW4u0bqLDyPAoWk0qDc6DHNQHv+2eeQhh49IDhv2VQY2+ZGw6mNpACYdO1h5GgUJuPzeAgHAguQoDAXJIBkDliBy+A5iwOZgDmlA5sgOb8DnJAA==", + "witness": "" +} diff --git a/test-data/pruned/sighash_all_anyonecanpay.json b/test-data/pruned/sighash_all_anyonecanpay.json new file mode 100644 index 00000000..2706e601 --- /dev/null +++ b/test-data/pruned/sighash_all_anyonecanpay.json @@ -0,0 +1,4 @@ +{ + "program": "5+0kCTVkcziqISK6EzABFXCwYvClhPYGFQusJfripGQssOAVt34AhgGJAoSQgwVw+HGJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYhZhamq5HNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiQKEkG4GKVn4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDwIChYhZmCIv9QHGkTTAYXN78l9PRKwkaP7L+QgG2hgCZadW734oPAAKQKEkG4hFL8OMDm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxCzC0tVpzeJ0MJHAM98RvFz0eCrDowUWd8HlIb3z/dfqm1KEko5YGAYkChJBuMxS/DI5voQT9zeJ/JSg1zVnOQ+dSDqBncb+M9zPuT55FUoWyEHDAMQswtJtBDoLFPVXJUIItlR+smGqGn+ps2Sl7ABMeUuBMPAFkmDwICkChJBuQYpepzS+pXGfR01NwkZUcgqBlWc7hGLkov46etOFkWaw/S96WGAYhZhaTbSrO1OkcGEXy6AONowywuX3+NCWUQGHsywjitxQ2nK+HkEBSBQkg3JMUvwpzGC2znhf4xEcqt+rYMkDOZxdY+aTcDIVMWDFzHlALVYoGAYhaHbjmDF0qC9egt34IC0AXMfZazwIEv1JHtNvrIs+lbi7RuosMAxC3EJFDOiGc5Czz/7fGmfzX05uacOSENCf3bkYmhTCJad+bCYugwNAxHNKg3OgxzUB7/tnnkIYePSA4b9lUGNvmRsOpjaQAmHTtYYBsC4UFwwwMurIgCX+3yY8LitEYR8zWVUfsIDE1+m0oOs4okbAAcB5SgUgUJINy2FK24/Be/O/2y1dvdAWCojT4SRN6ptMPyHC/Wx509/w9WhB4jAoWTuEHMWlYOXO2wr+b+BH3pMuqXajfPmtlGzZvvNj/FyZH4FJAYBiFsMbF1+kP4Eem3zb/kCJKtk0jc2kvvObaA36q97mNfCmOQeFAULeFwE2R+ra7Pj7bD7ngvTZ8puEzNaYgGZeeHhbJwsZpxe6Uuh5egUgUJINzHCl7A5m+wfSaTjr4875CqYUvDbS78MG1FTZ3b15XxTTpqszhrDAMQswtJn+5nw8Ow8SUaLVk5EoJylbJLr0eorb3VMvKJpVtDy6gDzGgUgUJINzPCl7I5gX7NPShZI6jBuY7JMfQIWoaaJQFUm4GMAxE5ZKse04FDAMQswtJorKJLS6eHhNL22M1LxSvfX5WFpLkpFfsX5NB5zIg4+pDzOgUgUJINzXCl7ac1SqL2gfiSh3UdqrVGooOvbSHkpdxyGNvf2//leGoXqVBgGIWYWkzpuNGyGt2LbP1o1ZH5v0Xb6PdSGHTtdnqp+uC61eoHKh5rQKQKEkG5vhRqxObTVSARaOVXZtiPy8V51Mw8A278YhdbXfWB4ZhQlC0BpAwDELQPyhazWhQGQJi9ZOygNEZeHZwMdbOgjZlK9kkMcYvu1jaFtgwDAgUJtLzfMz987l3WKtAxSudDhYOBTf5tlucUbKz5QK2LfAvMAhAoSQblcblecKnFAs2xhzWiS8gcM7spGaQ0DmR/iq9/+fs9efBzaYArnstYIShOuGAYhNx+eQEA4EBwgDikDjoDkWBycA5agczIHNUBzdgc5wHO6Bz4g", + "witness": "6uDgKrlIWLWlcSUQB09YGfwpnWKmQSpjc8v5LrQqYnT7cIJ6DW2oTPVJ2ZsURU8VA9+CoU1RQZ+k+wje5jdFMQ==" +} diff --git a/test-data/pruned/sighash_all_anyprevout.json b/test-data/pruned/sighash_all_anyprevout.json new file mode 100644 index 00000000..ee00f6aa --- /dev/null +++ b/test-data/pruned/sighash_all_anyprevout.json @@ -0,0 +1,4 @@ +{ + "program": "6AZJAk1ZHM4qiEiuhMwARVwsGLwpYT2BhULrCX64qRkLLDgFbd+AIYBiQKEkIMFcPhxicwLvfahR91ofRxdIEhoraXiTCljMruIwlAG9G26fy7ABhgGIWYWpquRzXXcvB6E6noyBxnL/G3JXlGU+eypltVaey12jFEeKjEOGAYkChJBuBilZ+Cq1myCZY7Ax/Klosw4w/YaiSrNDaOhM/+erWaIc9xg8CAoWIWZgiL/UBxpE0wGFze/JfT0SsJGj+y/kIBtoYAmWnVu9+KDwACkChJBuIRS/DjA5u8lZwLSPPkvMpefT82f85Cc97MlOKr7Djoj7EAHmx0TDAMQswtLVac3idDCRwDPfEbxc9Hgqw6MFFnfB5SG98/3X6ptShJKOWBgGJAoSQbjMUvwyOb6EE/c3ifyUoNc1ZzkPnUg6gZ3G/jPcz7k+eRVKFshBwwDELMLSbQQ6CxT1VyVCCLZUfrJhqhp/qbNkpewATHlLgTDwBZJg8CApAoSQbkGKXqc0vqVxn0dNTcJGVHIKgZVnO4Ri5KL+OnrThZFmsP0velhgGIWYWk20qztTpHBhF8ugDjaMMsLl9/jQllEBh7MsI4rcUNpyvh5BAUgUJINyTFL8OCnNKg3OgxzUB7/tnnkIYePSA4b9lUGNvmRsOpjaQAmHTtYYBiFmFpMDLqyIAl/t8mPC4rRGEfM1lVH7CAxNfptKDrOKJGwAHAeMgKQKEkG5Ril+HBjmMFtnPC/xiI5Vb9WwZIGczi6x80m4GQqYsGLmPKAWqxQMAxCzC0u4gOYMXSoL16C3fggLQBcx9lrPAgS/Uke02+siz6VuLtG6iwwDEgUJINy1FL8Kc24/Be/O/2y1dvdAWCojT4SRN6ptMPyHC/Wx509/w9WhBgGIWh3CDmLSsHLnbYV/N/Aj70mXVLtRvnzWyjZs33mx/i5Mj8CkgMAxC3EJFDOiGc5Czz/7fGmfzX05uacOSENCf3bkYmhTCJad+bCYugwNAxHMbF1+kP4Eem3zb/kCJKtk0jc2kvvObaA36q97mNfCmOQYBsC4UFww2R+ra7Pj7bD7ngvTZ8puEzNaYgGZeeHhbJwsZpxe6Uuh5hwKQKEkG5mBS9gczfYPpNJx18ed8hVMKXhtpd+GDaips7t68r4pp01WZw1hgGIWYWkz/cz4eHYeJKNFqyciUE5Stkl16PUVt7qmXlE0q2h5dQB5lwKQKEkG5qBS9kcwL9mnpQskdRg3MdkmPoELUNNEoCqTcDGAYicslWPacChgGIWYWk0VlElpdPDwml7bGal4pXvr8rC0lyUiv2L8mg85kQcfUh5pwKQKEkG5uBS9tOapVF7QPxJQ7qO1VqjUUHXtpDyUu45DG3v7f/yvDUL1KgwDELMLSZ03GjZDW7Ftn60asj836Lt9HupDDp2uz1U/XBdavUDlQ824FIFCSDc5Ao1YnNpqpAItHKrs2xH5eK86mYeAbd+MQutrvrA8MwoShaA0gYBiFoH5EtZrQoDIExesnZQGiMvDs4GOtnQRsyleySGOMX3axtC2wYBgQKE2l5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmAQgUJINyWNyXOFTigWbYw5rRJeQOGd2UjNIaBzI/xVe//P2evPg5tMAVz2WsEJQnXDAMQm4/PcCAcCA4QBxSBx0ByLA5OAcwAHMmBzSAc2oHOMBzsgc9AHP4A", + "witness": "l0dMPuxHNzcWAEoplAWtCm3m0LGK6y2Wbk6Ib0XeL41TBH/Ba4v/y0WxbddZqTl8jGofXViD4ty7bYm5Cuxd/Q==" +} diff --git a/test-data/pruned/sighash_all_anyprevoutanyscript.json b/test-data/pruned/sighash_all_anyprevoutanyscript.json new file mode 100644 index 00000000..d8e6e2a6 --- /dev/null +++ b/test-data/pruned/sighash_all_anyprevoutanyscript.json @@ -0,0 +1,4 @@ +{ + "program": "540kCTVkcziqISK6EzABFXCwYvClhPYGFQusJfripGQssOAVt34AhgGJAoSQgwVw+HGJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYhZhamq5HNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiQKEkG4GKVn4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDwIChYhZmCIv9QHGkTTAYXN78l9PRKwkaP7L+QgG2hgCZadW734oPAAKQKEkG4hFL8OMDm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxCzC0tVpzeJ0MJHAM98RvFz0eCrDowUWd8HlIb3z/dfqm1KEko5YGAYkChJBuMxS/DI5voQT9zeJ/JSg1zVnOQ+dSDqBncb+M9zPuT55FUoWyEHDAMQswtJtBDoLFPVXJUIItlR+smGqGn+ps2Sl7ABMeUuBMPAFkmDwICkChJBuQYpepzS+pXGfR01NwkZUcgqBlWc7hGLkov46etOFkWaw/S96WGAYhZhaTbSrO1OkcGEXy6AONowywuX3+NCWUQGHsywjitxQ2nK+HkEBSBQkg3JMUvw4Kc0qDc6DHNQHv+2eeQhh49IDhv2VQY2+ZGw6mNpACYdO1hgGIWYWkwMurIgCX+3yY8LitEYR8zWVUfsIDE1+m0oOs4okbAAcB4yApAoSQblGKX4cGOYwW2c8L/GIjlVv1bBkgZzOLrHzSbgZCpiwYuY8oBarFAwDELMLS7iA5gxdKgvXoLd+CAtAFzH2Ws8CBL9SR7Tb6yLPpW4u0bqLDAMSBQkg3LUUvYHMbF1+kP4Eem3zb/kCJKtk0jc2kvvObaA36q97mNfCmOQYBiFmFpNkfq2uz4+2w+54L02fKbhMzWmIBmXnh4WycLGacXulLoeWgFIFCSDcwopeyObcfgvfnf7Zau3ugLBURp8JIm9U2mH5DhfrY86e/4erQgwDELMLSYtKwcudthX838CPvSZdUu1G+fNbKNmzfebH+LkyPwKSA8wgFIFCSDcyope2nM32D6TScdfHnfIVTCl4baXfhg2oqbO7evK+KadNVmcNYYBiFmFpM/3M+Hh2HiSjRasnIlBOUrZJdej1Fbe6pl5RNKtoeXUAeZQCkChJBuaUUasTmisoktLp4eE0vbYzUvFK99flYWkuSkV+xfk0HnMiDj6kMAxC0EHMC/Zp6ULJHUYNzHZJj6BC1DTRKAqk3AxgGInLJVj2nAoYBiQKE2l5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmAQgUJINuNvOFTigWbYw5nTcaNkNbsW2frRqyPzfou30e6kMOna7PVT9cF1q9QOVDAMQm4/OYCAcCA4QBxUBx2ByMA5OgcsAOYEDmSA5owObYDnFA52QA==", + "witness": "goe1wgj38QRpwLi+Ez8zRk3CCCrfE76Ayc7OoVy+958RLhIlM7wemd5lEFkafXwyCT46Mb9g1qaE+H9orEKTyg==" +} diff --git a/test-data/pruned/sighash_none.json b/test-data/pruned/sighash_none.json new file mode 100644 index 00000000..23ca93a4 --- /dev/null +++ b/test-data/pruned/sighash_none.json @@ -0,0 +1,4 @@ +{ + "program": "5v0kCTVkcziqISK6EzABFXCwYvClhPYGFQusJfripGQssOAVt34AhgGJAoSQgwVw+HGJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYhZhamq5HNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiQKEkG4GKVn4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDwIChYhZmCIv9QHGkTTAYXN78l9PRKwkaP7L+QgG2hgCZadW734oPAAKQKEkG4hFL8OMDm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxCzC0tVpzeJ0MJHAM98RvFz0eCrDowUWd8HlIb3z/dfqm1KEko5YGAYkChJBuMxS/DI5voQT9zeJ/JSg1zVnOQ+dSDqBncb+M9zPuT55FUoWyEHDAMQswtJtBDoLFPVXJUIItlR+smGqGn+ps2Sl7ABMeUuBMPAFkmDwICkChJBuQYpepzS+pXGfR01NwkZUcgqBlWc7hGLkov46etOFkWaw/S96WGAYhZhaTbSrO1OkcGEXy6AONowywuX3+NCWUQGHsywjitxQ2nK+HkEBSBQkg3JMUvYnNKg3OgxzUB7/tnnkIYePSA4b9lUGNvmRsOpjaQAmHTtYYBiFmFpMDLqyIAl/t8mPC4rRGEfM1lVH7CAxNfptKDrOKJGwAHAeSQFIFCSDcoxS9mcxgts54X+MRHKrfq2DJAzmcXWPmk3AyFTFgxcx5QC1WKBgGIWYWkwYulQXr0Fu/BAWgC5j7LWeBAl+pI9pt9ZFn0rcXaN1Fh5RAUgUJINyzFL8KcxsXX6Q/gR6bfNv+QIkq2TSNzaS+85toDfqr3uY18KY5BgGIWYWk2R+ra7Pj7bD7ngvTZ8puEzNaYgGZeeHhbJwsZpxe6Uuh5JAUgUJINzBijVicxaVg5c7bCv5v4Efeky6pdqN8+a2UbNm+82P8XJkfgUkBgGIWgg5tx+C9+d/tlq7e6AsFRGnwkib1TaYfkOF+tjzp7/h6tCDAMSBQm0vN8zP3zuXdYq0DFK50OFg4FN/m2W5xRsrPlArYt8C8wCEChJBtxt5wqcUCzbGHM/3M+Hh2HiSjRasnIlBOUrZJdej1Fbe6pl5RNKtoeXUAYBiE3H5qgQDgQHCAOKgOOwORgHJ0DlcBy/A5kgOaEDm1A=", + "witness": "daDW/7G3k77Wd5aIA/Fch5teU8DWAHEmSw+YMK1NSTeVY31OKTXGLjlBJSpD0FqypkrpPf6PdiLfEAHHGaePkQ==" +} diff --git a/test-data/pruned/sighash_single.json b/test-data/pruned/sighash_single.json new file mode 100644 index 00000000..7917d712 --- /dev/null +++ b/test-data/pruned/sighash_single.json @@ -0,0 +1,4 @@ +{ + "program": "54EkCTVkcziqISK6EzABFXCwYvClhPYGFQusJfripGQssOAVt34AhgGJAoSQgwVw+HGJzAu99qFH3Wh9HF0gSGitpeJMKWMyu4jCUAb0bbp/LsAGGAYhZhamq5HNddy8HoTqejIHGcv8bcleUZT57KmW1Vp7LXaMUR4qMQ4YBiQKEkG4GKVn4KrWbIJljsDH8qWizDjD9hqJKs0No6Ez/56tZohz3GDwIChYhZmCIv9QHGkTTAYXN78l9PRKwkaP7L+QgG2hgCZadW734oPAAKQKEkG4hFL8OMDm7yVnAtI8+S8yl59PzZ/zkJz3syU4qvsOOiPsQAebHRMMAxCzC0tVpzeJ0MJHAM98RvFz0eCrDowUWd8HlIb3z/dfqm1KEko5YGAYkChJBuMxS/DI5voQT9zeJ/JSg1zVnOQ+dSDqBncb+M9zPuT55FUoWyEHDAMQswtJtBDoLFPVXJUIItlR+smGqGn+ps2Sl7ABMeUuBMPAFkmDwICkChJBuQYpepzS+pXGfR01NwkZUcgqBlWc7hGLkov46etOFkWaw/S96WGAYhZhaTbSrO1OkcGEXy6AONowywuX3+NCWUQGHsywjitxQ2nK+HkEBSBQkg3JMUvYnNKg3OgxzUB7/tnnkIYePSA4b9lUGNvmRsOpjaQAmHTtYYBiFmFpMDLqyIAl/t8mPC4rRGEfM1lVH7CAxNfptKDrOKJGwAHAeSQFIFCSDcoxS9mcxgts54X+MRHKrfq2DJAzmcXWPmk3AyFTFgxcx5QC1WKBgGIWYWkwYulQXr0Fu/BAWgC5j7LWeBAl+pI9pt9ZFn0rcXaN1Fh5RAUgUJINyzFL8Kc24/Be/O/2y1dvdAWCojT4SRN6ptMPyHC/Wx509/w9WhBgGIWh2g5i0rBy522FfzfwI+9Jl1S7Ub581so2bN95sf4uTI/ApIDAMQtxCRQzohnOQs8/+3xpn819ObmnDkhDQn925GJoUwiWnfmwmLoMDQMRzGxdfpD+BHpt82/5AiSrZNI3NpL7zm2gN+qve5jXwpjkGAbAuFBcMNkfq2uz4+2w+54L02fKbhMzWmIBmXnh4WycLGacXulLoeYUCkChJBuZYUrN9g+k0nHXx53yFUwpeG2l34YNqKmzu3ryvimnTVZnDWHiMChYhZmf7mfDw7DxJRotWTkSgnKVskuvR6itvdUy8omlW0PLqAPLMCkChJBuaQUasTmisoktLp4eE0vbYzUvFK99flYWkuSkV+xfk0HnMiDj6kMAxC0D8TsC/Zp6ULJHUYNzHZJj6BC1DTRKAqk3AxgGInLJVj2nAoYBgQKE2l5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmAQgUJINxobjU4VOKBZtjDmdNxo2Q1uxbZ+tGrI/N+i7fR7qQw6drs9VP1wXWr1A5UMAxCbj85QIBwIDhAHFIHHAHJwDlaBy+A5jwOaADmzA5wgOdYA==", + "witness": "iq5tGhmZAujxnHi4VlEY4etEjfom0kOWFvaJJ+oy3TOpZMgstdMAETEH1YtSUC9qfba8NQ395QRLSbAamO6OjQ==" +} diff --git a/test-data/pruned/transfer_with_timeout.transfer.json b/test-data/pruned/transfer_with_timeout.transfer.json new file mode 100644 index 00000000..e3dc77a7 --- /dev/null +++ b/test-data/pruned/transfer_with_timeout.transfer.json @@ -0,0 +1,4 @@ +{ + "program": "5FOgUOgUM6fR/zzMbUjCwWh8OC/RVo63YLVGQm0HCgVa499nCVkyDDjUUJtLzfMz987l3WKtAxSudDhYOBTf5tlucUbKz5QK2LfAvMAhAoQYbYcKkkCThzOKohIroTMAEVcLBi8KWE9gYVC6wl+uKkZCyw4BW3fgCGAYkChJBuAnG4GKD8POFQtDYw5rruXg9CdT0ZA4zl/jbkryjKfPZUy2qtPZa7RiiPFRiHDAMQm8/F4IBwMDhxNpxgR/lEHtfW0wRUBulcB82Fx3jkuM7zynq6wJuVxwnuUEIFBuKD8ZnHCwAbEigDgINQXAAHBAcagcdg8gQOQYHIcA", + "witness": "90s8pXRkf4WVYksSkySvovOLWYqcHHz8XwipwDbsWs08D7ue09rlyiOgplo0tdbMzda6JImF1gQfeyEmKxevb/yKZEUPdEWlvcdasB3Br9Q8nDV7yxRVShqRN7Je6qGJvKWMcYIbkYxL7VnDDskhvwd/AdJdi/MHIbToyVhjD2eA" +}