-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🧪 Add Test Scripts for testing Splitter Functionality (#3)
# Objective In order to further verify that the splitting logic works fine, we first load some basic operations (such as big integer addition/multiplication) and verify whether these operations are properly split. ## Added - Struct `IOPair` and trait `SplitableScript` to represent logic that must be handled by the splitting mechanism. - Test Scripts - Big integer (`U254`) addition; - Big integer (`U254`) multiplication.
- Loading branch information
Showing
12 changed files
with
841 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,31 @@ | ||
[package] | ||
name = "splitter" | ||
name = "bitvm2-splitter" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
|
||
# Bitcoin Libraries | ||
bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm", 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"] } | ||
|
||
# Other Libraries | ||
strum = "0.26" | ||
strum_macros = "0.26" | ||
hex = "0.4.3" | ||
serde = { version = "1.0.197", features = ["derive"] } | ||
num-bigint = "0.4.4" | ||
# Crypto libraries | ||
hex = "0.4.3" | ||
num-bigint = { version = "0.4.4", features = ["rand"] } | ||
num-traits = "0.2.18" | ||
tokio = { version = "1.37.0", features = ["full"] } | ||
serde_json = "1.0.116" | ||
lazy_static = "1.4.0" | ||
prettytable-rs = "0.10.0" | ||
paste = "1.0" | ||
seq-macro = "0.3.5" | ||
|
||
[dev-dependencies] | ||
# Random libraries | ||
rand_chacha = "0.3.1" | ||
rand = "0.8.5" | ||
num-bigint = { version = "0.4.4", features = ["rand"] } | ||
ark-std = "0.4.0" | ||
konst = "0.3.9" | ||
rand = "0.8.5" | ||
ark-std = "0.4.0" | ||
konst = "0.3.9" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//! 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<Script> { | ||
let instructions: Vec<Instruction> = script | ||
.instructions() | ||
.map(|instruction| instruction.expect("script is most likely corrupted")) | ||
.collect(); | ||
|
||
instructions | ||
.chunks(chunk_size) | ||
.map(|chunk| { | ||
let mut shard = Script::new(); | ||
for instruction in chunk { | ||
shard.push_instruction(*instruction); | ||
} | ||
|
||
shard | ||
}) | ||
.collect() | ||
} | ||
|
||
pub(super) fn naive_split(input: Script, script: Script) -> SplitResult { | ||
// First, we split the script into smaller parts | ||
let shards = split_into_shards(&script, MAX_SCRIPT_SIZE); | ||
let mut intermediate_states: Vec<IntermediateState> = vec![]; | ||
|
||
// Then, we do the following steps: | ||
// 1. We execute the first script with the input | ||
// 2. We take the stack and write it to the intermediate results | ||
// 3. We execute the second script with the saved intermediate results | ||
// 4. Take the stask, save to the intermediate results | ||
// 5. Repeat until the last script | ||
|
||
intermediate_states.push(IntermediateState::from_input_script(&input, &shards[0])); | ||
|
||
for shard in shards.clone().into_iter().skip(1) { | ||
// Executing a piece of the script with the current input. | ||
// NOTE #1: unwrap is safe to use here since intermediate_states is of length 1. | ||
// NOTE #2: we need to feed in both the stack and the altstack | ||
|
||
intermediate_states.push(IntermediateState::from_intermediate_result( | ||
intermediate_states.last().unwrap(), | ||
&shard, | ||
)); | ||
} | ||
|
||
assert_eq!( | ||
intermediate_states.len(), | ||
shards.len(), | ||
"Intermediate results should be the same as the number of scripts" | ||
); | ||
|
||
SplitResult { | ||
shards, | ||
intermediate_states, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
//! 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::*, utils::stack_to_script}; | ||
use bitcoin_scriptexec::Stack; | ||
|
||
pub struct IntermediateState { | ||
pub stack: Stack, | ||
pub altstack: Stack, | ||
} | ||
|
||
impl IntermediateState { | ||
/// Executes the script with the given input and returns the intermediate result, | ||
/// that is, the stack and altstack after the execution | ||
pub fn from_input_script(input: &Script, script: &Script) -> Self { | ||
let script = script! { | ||
{ input.clone() } | ||
{ script.clone() } | ||
}; | ||
|
||
let result = execute_script(script); | ||
|
||
Self { | ||
stack: result.main_stack.clone(), | ||
altstack: result.alt_stack.clone(), | ||
} | ||
} | ||
|
||
/// Based on the previous intermediate result, executes the script with the stacks | ||
/// and altstacks of the previous result and returns the new intermediate result | ||
pub fn from_intermediate_result(result: &Self, script: &Script) -> Self { | ||
let Self { stack, altstack } = result; | ||
|
||
let insert_result_script = script! { | ||
// Checks for length of the stack and altstack | ||
// 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_to_script(stack) } | ||
} | ||
|
||
if !altstack.is_empty() { | ||
{ stack_to_script(altstack) } | ||
|
||
for i in (0..altstack.len()).rev() { | ||
{ i } OP_ROLL | ||
OP_TOALTSTACK | ||
} | ||
} | ||
}; | ||
|
||
Self::from_input_script(&insert_result_script, script) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
//! Module that contains the implementation of the splitter | ||
//! together with all auxiliary functions and data structures. | ||
|
||
pub mod core; | ||
pub mod intermediate_state; | ||
pub mod script; | ||
|
||
#[cfg(test)] | ||
pub mod tests; |
Oops, something went wrong.