Skip to content

Commit

Permalink
🐛 getting closer
Browse files Browse the repository at this point in the history
  • Loading branch information
ZamDimon committed Sep 17, 2024
1 parent e1470f0 commit 793036e
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 9 deletions.
5 changes: 4 additions & 1 deletion splitter/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ impl fmt::Display for ExecuteInfo {
pub fn execute_script(script: ScriptBuf) -> ExecuteInfo {
let mut exec = Exec::new(
ExecCtx::Tapscript,
Options::default(),
Options {
require_minimal: false,
..Default::default()
},
TxTemplate {
tx: Transaction {
version: bitcoin::transaction::Version::TWO,
Expand Down
4 changes: 3 additions & 1 deletion splitter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ pub mod treepp {
pub use bitcoin::ScriptBuf as Script;
}

pub(crate) mod debug;
pub mod split;

pub(crate) mod debug;
pub(crate) mod test_scripts;
pub(crate) mod utils;

#[cfg(test)]
mod tests {
Expand Down
6 changes: 3 additions & 3 deletions splitter/src/split/intermediate_state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module contains the [`IntermediateState`] struct, which is used to store the intermediate
//! state of the stack and altstack during the execution of a script split into the shards (subprograms).
use crate::treepp::*;
use crate::{treepp::*, utils::stack_to_script};
use bitcoin_scriptexec::Stack;

pub struct IntermediateState {
Expand Down Expand Up @@ -36,11 +36,11 @@ impl IntermediateState {
// are used to avoid panic when referencing the first element
// of the stack or altstack (by using get(0) method)
if !stack.is_empty() {
{ stack.get(0) }
{ stack_to_script(stack) }
}

if !altstack.is_empty() {
{ altstack.get(0) }
{ stack_to_script(altstack) }

for _ in 0..altstack.len() {
OP_TOALTSTACK
Expand Down
3 changes: 3 additions & 0 deletions splitter/src/split/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub struct SplitResult {

/// Trait that any script that can be split should implement
pub trait SplitableScript<const INPUT_SIZE: usize, const OUTPUT_SIZE: usize> {
const INPUT_SIZE: usize = INPUT_SIZE;
const OUTPUT_SIZE: usize = OUTPUT_SIZE;

/// Returns the main logic (f) of the script
fn script() -> Script;

Expand Down
184 changes: 180 additions & 4 deletions splitter/src/split/tests.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use crate::treepp::*;
use crate::{
split::script::{IOPair, SplitableScript},
test_scripts::int_mul::U254MulScript,
treepp::*,
utils::stack_to_script,
};

use super::core::split_into_shards;
use super::{
core::split_into_shards,
intermediate_state::{self, IntermediateState},
};

/// Tests whether splitting the script into subprograms (shards)
/// works properly
/// works properly for the most basic script
#[test]
fn test_split() {
fn test_split_basic() {
const CHUNK_SIZE: usize = 3;

// Adding a toy script to test the splitting
Expand Down Expand Up @@ -53,4 +61,172 @@ fn test_split() {
!shard_3_result.success,
"Shard 3 for somer reason succeeded"
);

// Now, we are going to concatenate all the shards and verify that the script is also correct
let verification_script = script! {
for shard in shards {
{ shard }
}
};
let result = execute_script(verification_script);
assert!(result.success, "Verification has failed");
}

/// Tests whether splitting the script into subprograms (shards)
/// works properly for the most advanced script (two big integers multipication)
#[test]
fn test_split_mul() {
const CHUNK_SIZE: usize = 100;

// Generating a random valid input for the script and the script itself
let test_script = U254MulScript::script();
let IOPair { input, output } = U254MulScript::generate_valid_io_pair();
assert!(
U254MulScript::verify(input.clone(), output.clone()),
"input/output is not correct"
);

// Splitting the script into shards
let shards = split_into_shards(&test_script, CHUNK_SIZE);

// Now, we are going to concatenate all the shards and verify that the script is also correct
let verification_script = script! {
{ input }
for shard in shards {
{ shard }
}
{ output }

// Now, we need to verify that the output is correct.
for i in (0..U254MulScript::OUTPUT_SIZE).rev() {
// { <a_1> <a_2> ... <a_n> <b_1> <b_2> ... <b_n> } <- we need to push element <a_n> to the top of the stack
{ i+1 } OP_ROLL
OP_EQUALVERIFY
}

OP_TRUE
};

let result = execute_script(verification_script);
assert!(result.success, "Verification has failed");
}

#[test]
fn test_from_input_script_mainstack_only() {
// Adding input and verification scripts
let input_script = script! {
{ 13123 } { 1235 }
};
let main_script = script! {
OP_ADD 1 OP_ADD 3 OP_ADD
};

// Creating an intermediate state
let IntermediateState { stack, altstack } =
IntermediateState::from_input_script(&input_script, &main_script);

// Asserting that the altstack is empty
assert!(altstack.is_empty(), "Altstack is not empty");

// Now, checking that our stack is simply a number 14362
let verify_script = script! {
{ stack_to_script(&stack) }
{ 14362 }
OP_EQUAL
};
let result = execute_script(verify_script);
assert!(result.success, "Verification failed");
}

#[test]
fn test_state_from_input_script_mainstack_and_altstack() {
// Adding input and verification scripts
let input_script = script! {
{13123} {1235}
};
let main_script = script! {
OP_ADD 1 OP_ADD 3 OP_ADD 5 OP_TOALTSTACK
};

// Creating an intermediate state
let IntermediateState { stack, altstack } =
IntermediateState::from_input_script(&input_script, &main_script);

// Now, checking that our stack is simply a number 14362
let verify_mainstack_script = script! {
{ stack_to_script(&stack) }
{14362}
OP_EQUAL
};
let result = execute_script(verify_mainstack_script);
assert!(result.success, "mainstack verification failed");

// Asserting that the altstack is correct
let verify_altstack_script = script! {
{ stack_to_script(&altstack) }
{ 5 }
OP_EQUAL
};
let result = execute_script(verify_altstack_script);
assert!(result.success, "altstack verification failed");
}

#[test]
fn test_state_from_state() {
const CHUNK_SIZE: usize = 3;

// Adding input and verification scripts
let input_script = script! {
{ 10 } { 20 }
};
let main_script = script! {
OP_1 OP_TOALTSTACK OP_1 OP_TOALTSTACK OP_0 OP_TOALTSTACK
OP_FROMALTSTACK OP_FROMALTSTACK OP_FROMALTSTACK
OP_ADD OP_ADD OP_ADD
};

// Now, splitting the main_script:
let shards = split_into_shards(&main_script, CHUNK_SIZE);

// Creating the first intermediate state
let z1 = IntermediateState::from_input_script(&input_script, &shards[0]);

// Asserting that both the stack and altstack are correct
let verify_main_stack_script = script! {
{ stack_to_script(&z1.stack) }
OP_1 OP_EQUALVERIFY
{ 20 } OP_EQUALVERIFY
{ 10 } OP_EQUAL
};

let result = execute_script(verify_main_stack_script);
assert!(result.success, "Mainstack verification failed");

let verify_alt_stack_script = script! {
{ stack_to_script(&z1.altstack) }
OP_1 OP_EQUAL
};
let result = execute_script(verify_alt_stack_script);
assert!(result.success, "Altstack verification failed");

// Now, getting the second state
let z2 = IntermediateState::from_intermediate_result(&z1, &shards[1]);

// Asserting that both the stack and altstack are correct
let verify_main_stack_script = script! {
{ stack_to_script(&z2.stack) }
{ 20 } OP_EQUALVERIFY
{ 10 } OP_EQUAL
};
let result = execute_script(verify_main_stack_script);
assert!(result.success, "Mainstack verification failed");

let verify_alt_stack_script = script! {
{ stack_to_script(&z2.altstack) }
OP_0 OP_EQUALVERIFY
OP_1 OP_EQUALVERIFY
OP_1 OP_EQUAL
};
let result = execute_script(verify_alt_stack_script);
assert!(result.success, "Altstack verification failed");
}
11 changes: 11 additions & 0 deletions splitter/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use bitcoin_scriptexec::Stack;

use crate::treepp::*;

pub(crate) fn stack_to_script(stack: &Stack) -> Script {
script! {
for element in stack.iter_str() {
{ element.to_vec() }
}
}
}

0 comments on commit 793036e

Please sign in to comment.