From 42470b3db8ff9b3bc8ae91bfcb17ce33c2c1bfa4 Mon Sep 17 00:00:00 2001 From: Velnbur Date: Tue, 1 Oct 2024 12:55:47 +0300 Subject: [PATCH 01/28] WIP --- Cargo.toml | 7 +- core/Cargo.toml | 8 + core/src/assert/disprove_script.rs | 42 +++++ core/src/assert/mod.rs | 20 +++ core/src/lib.rs | 2 + core/src/winternitz.rs | 270 +++++++++++++++++++++++++++++ splitter/Cargo.toml | 2 +- splitter/src/debug.rs | 11 ++ splitter/src/lib.rs | 2 +- 9 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 core/Cargo.toml create mode 100644 core/src/assert/disprove_script.rs create mode 100644 core/src/assert/mod.rs create mode 100644 core/src/lib.rs create mode 100644 core/src/winternitz.rs diff --git a/Cargo.toml b/Cargo.toml index aec6998..f2dd00a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,10 @@ [workspace] -members = ["splitter"] +members = ["core", "splitter"] resolver = "2" +[workspace.dependencies] +bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm" } + [profile.dev] opt-level = 3 @@ -30,4 +33,4 @@ branch = "bitvm" [patch.crates-io.bitcoin-units] git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" \ No newline at end of file +branch = "bitvm" diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 index 0000000..e2bc10b --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "bitvm2-core" +version = "0.1.0" +edition = "2021" + +[dependencies] +bitvm2-splitter.path = "../splitter" +bitcoin.workspace = true \ No newline at end of file diff --git a/core/src/assert/disprove_script.rs b/core/src/assert/disprove_script.rs new file mode 100644 index 0000000..9a9043d --- /dev/null +++ b/core/src/assert/disprove_script.rs @@ -0,0 +1,42 @@ +use bitvm2_splitter::treepp::*; + +use crate::winternitz::{self, PublicKey}; + +/// Script which let's challengers spent the **Assert** transaction +/// output if operator computated substates incorrectly. +/// +/// This a typed version of [`Script`] can be easily converted into it. +/// +/// The script structure in general is simple: +/// +/// ```no_run +/// // push public key's of intermidiate states +/// { pk_z[i-1] } +/// { pk_z[i] } +/// // Check Winternitz signatures expecting public +/// // keys and signatures from top of the stack +/// { winternitz::checksig_verify } +/// // compute result of the subrpogram +/// { f[i] } +/// OP_EQUAL +/// OP_VERIFY +/// ``` +/// +/// # TODO: +/// +/// - [ ] Inlcude covenants +pub struct DisproveScript { + intermidiate_state_pubkeys: [PublicKey; 2], + subprogram: Script, +} + +impl From for Script { + fn from(disprove: DisproveScript) -> Self { + let [ pk1, pk2 ] = disprove.intermidiate_state_pubkeys; + script! { + { pk1 } + // { winternitz::checksig_verify } + { pk2 } + } + } +} diff --git a/core/src/assert/mod.rs b/core/src/assert/mod.rs new file mode 100644 index 0000000..cb5fe1b --- /dev/null +++ b/core/src/assert/mod.rs @@ -0,0 +1,20 @@ +use bitcoin::TxIn; +use bitvm2_splitter::{split::intermediate_state::IntermediateState, treepp::Script}; + +use crate::winternitz::PublicKey; + +pub mod disprove_script; + +pub struct AssertTransaction { + // Inputs which are used in the transaction. + inputs: Vec, + // Subprograms $f_{i}$ that will be verified in the transaction. + subprograms: [Script; N], + // Intermidiate states $z_i$. + states: [IntermediateState; N], + // Winternitz public keys that are used for verification of + // related to intermidiate states' signatures. + // + // In paper specified as $\mathsf{pk}_{z_i}$. + states_pubkeys: [PublicKey; N], +} diff --git a/core/src/lib.rs b/core/src/lib.rs new file mode 100644 index 0000000..5be46ed --- /dev/null +++ b/core/src/lib.rs @@ -0,0 +1,2 @@ +pub mod assert; +pub mod winternitz; diff --git a/core/src/winternitz.rs b/core/src/winternitz.rs new file mode 100644 index 0000000..600f976 --- /dev/null +++ b/core/src/winternitz.rs @@ -0,0 +1,270 @@ +//! Winternitz One-time Signatures +//! +//! +//! Winternitz signatures are an improved version of Lamport signatures. +//! A detailed introduction to Winternitz signatures can be found +//! in "A Graduate Course in Applied Cryptography" in chapter 14.3 +//! https://toc.cryptobook.us/book.pdf +//! +//! We are trying to closely follow the authors' notation here. + +// +// BEAT OUR IMPLEMENTATION AND WIN A CODE GOLF BOUNTY! +// + +use bitvm2_splitter::treepp::*; +use bitcoin::hashes::{hash160, Hash}; + +/// Bits per digit +const LOG_D: u32 = 4; +/// Digits are base d+1 +pub const D: u32 = (1 << LOG_D) - 1; +/// Number of digits of the message +const N0: u32 = 40; +/// Number of digits of the checksum. N1 = ⌈log_{D+1}(D*N0)⌉ + 1 +const N1: usize = 4; +/// Total number of digits to be signed +const N: u32 = N0 + N1 as u32; +/// The public key type +pub type PublicKey = [[u8; 20]; N as usize]; + +pub type SecretKey = Vec; + +// +// Helper functions +// + +/// Generate a public key for the i-th digit of the message +pub fn public_key_for_digit(mut secret_key: Vec, digit_index: u32) -> [u8; 20] { + secret_key.push(digit_index as u8); + + let mut hash = hash160::Hash::hash(&secret_key); + + for _ in 0..D { + hash = hash160::Hash::hash(&hash[..]); + } + + *hash.as_byte_array() +} + +/// Generate a public key from a secret key +pub fn generate_public_key(secret_key: Vec) -> PublicKey { + let mut public_key_array = [[0u8; 20]; N as usize]; + for i in 0..N { + public_key_array[i as usize] = public_key_for_digit(secret_key.clone(), i); + } + public_key_array +} + +/// Compute the signature for the i-th digit of the message +pub fn digit_signature(mut secret_key: SecretKey, digit_index: u32, message_digit: u8) -> Script { + secret_key.push(digit_index as u8); + + let mut hash = hash160::Hash::hash(&secret_key); + + for _ in 0..message_digit { + hash = hash160::Hash::hash(&hash[..]); + } + + let hash_bytes = hash.as_byte_array().to_vec(); + + script! { + { hash_bytes } + { message_digit } + } +} + +/// Compute the checksum of the message's digits. +/// Further infos in chapter "A domination free function for Winternitz signatures" +pub fn checksum(digits: [u8; N0 as usize]) -> u32 { + let mut sum = 0; + for digit in digits { + sum += digit as u32; + } + D * N0 - sum +} + +/// Convert a number to digits +pub fn to_digits(mut number: u32) -> [u8; DIGIT_COUNT] { + let mut digits: [u8; DIGIT_COUNT] = [0; DIGIT_COUNT]; + for i in 0..DIGIT_COUNT { + let digit = number % (D + 1); + number = (number - digit) / (D + 1); + digits[i] = digit as u8; + } + digits +} + + + +/// Compute the signature for a given message +pub fn sign_digits(secret_key: SecretKey, message_digits: [u8; N0 as usize]) -> Script { + // const message_digits = to_digits(message, n0) + let mut checksum_digits = to_digits::(checksum(message_digits)).to_vec(); + checksum_digits.append(&mut message_digits.to_vec()); + + script! { + for i in 0..N { + { digit_signature(secret_key.clone(), i, checksum_digits[ (N-1-i) as usize]) } + } + } +} + +pub fn sign(secret_key: SecretKey, message_bytes: &[u8]) -> Script { + // Convert message to digits + let mut message_digits = [0u8; 20 * 2 as usize]; + for (digits, byte) in message_digits.chunks_mut(2).zip(message_bytes) { + digits[0] = byte & 0b00001111; + digits[1] = byte >> 4; + } + + sign_digits(secret_key, message_digits) +} + +pub fn checksig_verify(public_key: &PublicKey) -> Script { + script! { + // + // Verify the hash chain for each digit + // + + // Repeat this for every of the n many digits + for digit_index in 0..N { + // Verify that the digit is in the range [0, d] + // See https://github.com/BitVM/BitVM/issues/35 + { D } + OP_MIN + + // Push two copies of the digit onto the altstack + OP_DUP + OP_TOALTSTACK + OP_TOALTSTACK + + // Hash the input hash d times and put every result on the stack + for _ in 0..D { + OP_DUP OP_HASH160 + } + + // Verify the signature for this digit + OP_FROMALTSTACK + OP_PICK + { public_key[N as usize - 1 - digit_index as usize].to_vec() } + OP_EQUALVERIFY + + // Drop the d+1 stack items + for _ in 0..(D+1)/2 { + OP_2DROP + } + } + + // + // Verify the Checksum + // + + // 1. Compute the checksum of the message's digits + OP_FROMALTSTACK OP_DUP OP_NEGATE + for _ in 1..N0 { + OP_FROMALTSTACK OP_TUCK OP_SUB + } + { D * N0 } + OP_ADD + + + // 2. Sum up the signed checksum's digits + OP_FROMALTSTACK + for _ in 0..N1 - 1 { + for _ in 0..LOG_D { + OP_DUP OP_ADD + } + OP_FROMALTSTACK + OP_ADD + } + + // 3. Ensure both checksums are equal + OP_EQUALVERIFY + + + // Convert the message's digits to bytes + for i in 0..N0 / 2 { + OP_SWAP + for _ in 0..LOG_D { + OP_DUP OP_ADD + } + OP_ADD + // Push all bytes to the altstack, except for the last byte + if i != (N0/2) - 1 { + OP_TOALTSTACK + } + } + // Read the bytes from the altstack + for _ in 0..N0 / 2 - 1{ + OP_FROMALTSTACK + } + + } +} + + +#[cfg(test)] +mod test { + use bitcoin::hex::FromHex as _; + + use super::*; + + // The secret key + const MY_SECKEY: &str = "b138982ce17ac813d505b5b40b665d404e9528e7"; + + + #[test] + fn test_winternitz() { + // The message to sign + #[rustfmt::skip] + const MESSAGE: [u8; N0 as usize] = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 7, 7, 7, 7, 7, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 7, 7, 7, 7, 7, + ]; + + let secret_key = Vec::::from_hex(MY_SECKEY).unwrap(); + let public_key = generate_public_key(secret_key.clone()); + + let script = script! { + { sign_digits(secret_key.clone(), MESSAGE) } + { checksig_verify(&public_key) } + }; + + println!( + "Winternitz signature size:\n \t{:?} bytes / {:?} bits \n\t{:?} bytes / bit", + script.len(), + N0 * 4, + script.len() as f64 / (N0 * 4) as f64 + ); + + run(script! { + { sign_digits(secret_key, MESSAGE) } + { checksig_verify(&public_key) } + + 0x21 OP_EQUALVERIFY + 0x43 OP_EQUALVERIFY + 0x65 OP_EQUALVERIFY + 0x87 OP_EQUALVERIFY + 0xA9 OP_EQUALVERIFY + 0xCB OP_EQUALVERIFY + 0xED OP_EQUALVERIFY + 0x7F OP_EQUALVERIFY + 0x77 OP_EQUALVERIFY + 0x77 OP_EQUALVERIFY + + 0x21 OP_EQUALVERIFY + 0x43 OP_EQUALVERIFY + 0x65 OP_EQUALVERIFY + 0x87 OP_EQUALVERIFY + 0xA9 OP_EQUALVERIFY + 0xCB OP_EQUALVERIFY + 0xED OP_EQUALVERIFY + 0x7F OP_EQUALVERIFY + 0x77 OP_EQUALVERIFY + 0x77 OP_EQUAL + }); + } + + // TODO: test the error cases: negative digits, digits > D, ... +} diff --git a/splitter/Cargo.toml b/splitter/Cargo.toml index 383809d..36f1925 100644 --- a/splitter/Cargo.toml +++ b/splitter/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # Bitcoin Libraries -bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm", features = ["rand-std"]} +bitcoin = { workspace = true, features = ["rand-std"]} bitcoin-script = { git = "https://github.com/BitVM/rust-bitcoin-script" } bitcoin-scriptexec = { git = "https://github.com/BitVM/rust-bitcoin-scriptexec/"} bitcoin-script-stack = { git = "https://github.com/FairgateLabs/rust-bitcoin-script-stack"} diff --git a/splitter/src/debug.rs b/splitter/src/debug.rs index 62ac034..1418ad0 100644 --- a/splitter/src/debug.rs +++ b/splitter/src/debug.rs @@ -75,6 +75,17 @@ pub fn execute_script(script: ScriptBuf) -> ExecuteInfo { } } +pub fn run(script: bitcoin::ScriptBuf) { + let exec_result = execute_script(script); + if !exec_result.success { + println!( + "ERROR: {:?} <--- \n STACK: {:#?} \n ALTSTACK {:#?}", + exec_result.error, exec_result.main_stack, exec_result.alt_stack + ); + } + assert!(exec_result.success); +} + /// Execute a script on stack without `MAX_STACK_SIZE` limit. /// This function is only used for script test, not for production. /// diff --git a/splitter/src/lib.rs b/splitter/src/lib.rs index 734bae2..101b91f 100644 --- a/splitter/src/lib.rs +++ b/splitter/src/lib.rs @@ -1,7 +1,7 @@ #[allow(dead_code)] // Re-export what is needed to write treepp scripts pub mod treepp { - pub use crate::debug::execute_script; + pub use crate::debug::{execute_script, run}; pub use bitcoin_script::{define_pushable, script}; define_pushable!(); From 700a4a78a6fc48bdaa91ec40f5045acb4aa0c301 Mon Sep 17 00:00:00 2001 From: ZamDimon Date: Fri, 4 Oct 2024 11:18:33 +0300 Subject: [PATCH 02/28] :interrobang: preparing for merge --- Cargo.toml | 36 --- splitter/Cargo.toml | 31 --- splitter/README.md | 25 -- splitter/src/debug.rs | 172 -------------- splitter/src/lib.rs | 33 --- splitter/src/split/core.rs | 67 ------ splitter/src/split/intermediate_state.rs | 54 ----- splitter/src/split/mod.rs | 9 - splitter/src/split/script.rs | 92 -------- splitter/src/split/tests.rs | 286 ----------------------- splitter/src/test_scripts/int_add.rs | 129 ---------- splitter/src/test_scripts/int_mul.rs | 122 ---------- splitter/src/test_scripts/mod.rs | 9 - splitter/src/utils.rs | 11 - 14 files changed, 1076 deletions(-) delete mode 100644 Cargo.toml delete mode 100644 splitter/Cargo.toml delete mode 100644 splitter/README.md delete mode 100644 splitter/src/debug.rs delete mode 100644 splitter/src/lib.rs delete mode 100644 splitter/src/split/core.rs delete mode 100644 splitter/src/split/intermediate_state.rs delete mode 100644 splitter/src/split/mod.rs delete mode 100644 splitter/src/split/script.rs delete mode 100644 splitter/src/split/tests.rs delete mode 100644 splitter/src/test_scripts/int_add.rs delete mode 100644 splitter/src/test_scripts/int_mul.rs delete mode 100644 splitter/src/test_scripts/mod.rs delete mode 100644 splitter/src/utils.rs diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index f2dd00a..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[workspace] -members = ["core", "splitter"] -resolver = "2" - -[workspace.dependencies] -bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm" } - -[profile.dev] -opt-level = 3 - -[profile.release] -lto = true - -[patch.crates-io.base58check] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" - -[patch.crates-io.bitcoin] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" - -[patch.crates-io.bitcoin_hashes] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" - -[patch.crates-io.bitcoin-internals] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" - -[patch.crates-io.bitcoin-io] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" - -[patch.crates-io.bitcoin-units] -git = "https://github.com/rust-bitcoin/rust-bitcoin" -branch = "bitvm" diff --git a/splitter/Cargo.toml b/splitter/Cargo.toml deleted file mode 100644 index 36f1925..0000000 --- a/splitter/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "bitvm2-splitter" -version = "0.1.0" -edition = "2021" - -[dependencies] -# Bitcoin Libraries -bitcoin = { workspace = true, features = ["rand-std"]} -bitcoin-script = { git = "https://github.com/BitVM/rust-bitcoin-script" } -bitcoin-scriptexec = { git = "https://github.com/BitVM/rust-bitcoin-scriptexec/"} -bitcoin-script-stack = { git = "https://github.com/FairgateLabs/rust-bitcoin-script-stack"} -# Some test script to test the splitter -bitcoin-window-mul = { git = "https://github.com/distributed-lab/bitcoin-window-mul.git" } - -# General-purpose libraries -strum = "0.26" -strum_macros = "0.26" -serde = { version = "1.0.197", features = ["derive"] } -serde_json = "1.0.116" -tokio = { version = "1.37.0", features = ["full"] } - -# Crypto libraries -hex = "0.4.3" -num-bigint = { version = "0.4.4", features = ["rand"] } -num-traits = "0.2.18" - -# Random libraries -rand_chacha = "0.3.1" -rand = "0.8.5" -ark-std = "0.4.0" -konst = "0.3.9" diff --git a/splitter/README.md b/splitter/README.md deleted file mode 100644 index 7ca15dd..0000000 --- a/splitter/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# :jigsaw: Bitcoin Splitter - -This is a crate for splitting the Bitcoin script into multiple parts as suggested by the recent [_BitVM2 paper_](https://bitvm.org/bitvm_bridge.pdf). - -## :raising_hand: But What is Bitcoin Splitter? - -Suppose we have the input $x$ and the function $f$ and the prover wants to convince the skeptical verifier that $y=f(x)$. Of course, one way to do that is to publish the following Bitcoin script: - -```bash - OP_EQUAL -``` - -However, the main issue is that besides basic usages such as hash function computation (in that case, $f=H$ for native _SHA-256_ hash function), typically $f$ is very large. The BitVM2 paper suggests splitting the function $f$ into multiple parts and publishing them separately. Formally, suppose - -$$ -f = f_n \circ f_{n-1} \circ \cdots \circ f_1 -$$ - -Then, instead of proving $y=f(x)$, the prover can prove the following statements: - -$$ -z_1 = f_1(z_0), \quad z_2 = f_2(z_1), \quad \ldots, \quad z_n = f_n(z_{n-1}) -$$ - -for $z_1:=x,z_n:=y$. Then, the prover publishes $z_1,\dots,z_n$ together with $f_1,\dots,f_n$. Then, the verifier can ensure that all $z_1,\dots,z_n$ were obtained correctly. In case something was computed wrong, the verifier can challenge the prover and claim the bounty. For more details, see _BitVM2 paper_. diff --git a/splitter/src/debug.rs b/splitter/src/debug.rs deleted file mode 100644 index 1418ad0..0000000 --- a/splitter/src/debug.rs +++ /dev/null @@ -1,172 +0,0 @@ -use bitcoin::{hashes::Hash, ScriptBuf, TapLeafHash, Transaction}; -use bitcoin_scriptexec::{Exec, ExecCtx, ExecError, ExecStats, Options, Stack, TxTemplate}; -use core::fmt; - -/// Information about the status of the script execution. -#[derive(Debug)] -pub struct ExecuteInfo { - pub success: bool, - pub error: Option, - pub main_stack: Stack, - pub alt_stack: Stack, - pub stats: ExecStats, -} - -impl fmt::Display for ExecuteInfo { - /// Formats the `ExecuteInfo` struct for display. - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.success { - writeln!(f, "Script execution successful.")?; - } else { - writeln!(f, "Script execution failed!")?; - } - - if let Some(ref error) = self.error { - writeln!(f, "Error: {:?}", error)?; - } - - writeln!(f, "Stats: {:?}", self.stats)?; - Ok(()) - } -} - -/// Executes the given script and returns the result of the execution -/// (success, error, stack, etc.) -pub fn execute_script(script: ScriptBuf) -> ExecuteInfo { - let mut exec = Exec::new( - ExecCtx::Tapscript, - Options { - // TODO: Figure our how to optimize stack_to_script function to avoid disabling require_minimal - require_minimal: false, - ..Default::default() - }, - TxTemplate { - tx: Transaction { - version: bitcoin::transaction::Version::TWO, - lock_time: bitcoin::locktime::absolute::LockTime::ZERO, - input: vec![], - output: vec![], - }, - prevouts: vec![], - input_idx: 0, - taproot_annex_scriptleaf: Some((TapLeafHash::all_zeros(), None)), - }, - script, - vec![], - ) - .expect("error when creating the execution body"); - - // Execute all the opcodes while possible - loop { - if exec.exec_next().is_err() { - break; - } - } - - // Obtaining the result of the execution - let result = exec.result().unwrap(); - - ExecuteInfo { - success: result.success, - error: result.error.clone(), - main_stack: exec.stack().clone(), - alt_stack: exec.altstack().clone(), - stats: exec.stats().clone(), - } -} - -pub fn run(script: bitcoin::ScriptBuf) { - let exec_result = execute_script(script); - if !exec_result.success { - println!( - "ERROR: {:?} <--- \n STACK: {:#?} \n ALTSTACK {:#?}", - exec_result.error, exec_result.main_stack, exec_result.alt_stack - ); - } - assert!(exec_result.success); -} - -/// Execute a script on stack without `MAX_STACK_SIZE` limit. -/// This function is only used for script test, not for production. -/// -/// NOTE: Only for test purposes. -#[allow(dead_code)] -pub fn execute_script_no_stack_limit(script: bitcoin::ScriptBuf) -> ExecuteInfo { - // Get the default options for the script exec. - // NOTE: Do not enforce the stack limit. - let opts = Options { - enforce_stack_limit: false, - ..Default::default() - }; - - let mut exec = Exec::new( - ExecCtx::Tapscript, - opts, - TxTemplate { - tx: Transaction { - version: bitcoin::transaction::Version::TWO, - lock_time: bitcoin::locktime::absolute::LockTime::ZERO, - input: vec![], - output: vec![], - }, - prevouts: vec![], - input_idx: 0, - taproot_annex_scriptleaf: Some((TapLeafHash::all_zeros(), None)), - }, - script, - vec![], - ) - .expect("error while creating the execution body"); - - // Execute all the opcodes while possible - loop { - if exec.exec_next().is_err() { - break; - } - } - - // Get the result of the execution - let result = exec.result().unwrap(); - - ExecuteInfo { - success: result.success, - error: result.error.clone(), - main_stack: exec.stack().clone(), - alt_stack: exec.altstack().clone(), - stats: exec.stats().clone(), - } -} - -#[cfg(test)] -mod test { - use super::execute_script_no_stack_limit; - use crate::treepp::*; - - #[test] - fn test_script_debug() { - let script = script! { - OP_TRUE - DEBUG - OP_TRUE - OP_VERIFY - }; - let exec_result = execute_script(script); - assert!(!exec_result.success); - } - - #[test] - fn test_script_execute_no_stack_limit() { - let script = script! { - for _ in 0..1001 { - OP_1 - } - for _ in 0..1001 { - OP_DROP - } - OP_1 - }; - - let exec_result = execute_script_no_stack_limit(script); - assert!(exec_result.success); - } -} diff --git a/splitter/src/lib.rs b/splitter/src/lib.rs deleted file mode 100644 index 101b91f..0000000 --- a/splitter/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -#[allow(dead_code)] -// Re-export what is needed to write treepp scripts -pub mod treepp { - pub use crate::debug::{execute_script, run}; - pub use bitcoin_script::{define_pushable, script}; - - define_pushable!(); - pub use bitcoin::ScriptBuf as Script; -} - -pub mod split; - -pub(crate) mod debug; -pub(crate) mod test_scripts; -pub(crate) mod utils; - -#[cfg(test)] -mod tests { - use super::treepp::*; - - /// Tests that checks that environment was set up correctly by running a 2+3=5 script. - #[test] - fn test_healthy_check() { - let script = script! { - 2 3 OP_ADD 5 OP_EQUAL - }; - - let exec_result = execute_script(script); - assert!(exec_result.success); - - println!("Environment is set up correctly!"); - } -} diff --git a/splitter/src/split/core.rs b/splitter/src/split/core.rs deleted file mode 100644 index 686ee82..0000000 --- a/splitter/src/split/core.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! Module containing the logic of splitting the script into smaller parts - -use bitcoin::script::Instruction; - -use super::script::SplitResult; -use crate::{split::intermediate_state::IntermediateState, treepp::*}; - -/// Maximum size of the script in bytes -pub(super) const MAX_SCRIPT_SIZE: usize = 30000; - -// TODO: Currently, the chunk size splits the script into the parts of the same size IN TERMS OF INSTRUCTIONS, not bytes. -/// Splits the given script into smaller parts -pub(super) fn split_into_shards(script: &Script, chunk_size: usize) -> Vec