Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Separating fibnacci example #1

Merged
merged 7 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main

permissions:
contents: read

env:
RUSTFLAGS: -D warnings

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: dtolnay/rust-toolchain@7ba5d857b13a2c335579877a00c25c134410d383 # nightly
- uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3
- run: cargo test -- --nocapture
- name: Upload Bitcoin Scripts Performance Report
if: always()
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
with:
name: bitcoin-scripts-performance-report
path: target/bitcoin_scripts_performance_report.csv
- name: Generate coverage report
run: cargo install cargo-tarpaulin && cargo tarpaulin --engine llvm --out Xml
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
with:
token: ${{ secrets.CODECOV_TOKEN }}

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: dtolnay/rust-toolchain@7ba5d857b13a2c335579877a00c25c134410d383 # nightly
- uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3
- run: cargo clippy --all --all-features --all-targets -- -D warnings

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: dtolnay/rust-toolchain@7ba5d857b13a2c335579877a00c25c134410d383 # nightly
with:
components: rustfmt
- uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3
- run: cargo +nightly fmt --all -- --check

typos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: crate-ci/typos@935271f0204ebdf61717cf6caac31d8d115f1c14 # v1.23.6
with:
files: .
33 changes: 33 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "fibonacci-example"
version = "0.1.0"
edition = "2021"

[dependencies]
rust-bitcoin-m31 = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/rust-bitcoin-m31/" }
bitcoin-script = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/rust-bitcoin-script" }
bitcoin = "0.32.0"
bitcoin-scriptexec = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/rust-bitcoin-scriptexec", features = ["debug"] }
sha2 = "0.10.8"
rand = "0.8.5"
rand_chacha = "0.3.1"
stwo-prover = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/stwo" }
num-traits = "0.2.0"
lazy_static = "1.4.0"
ctor = "0.2.8"
itertools = "0.13.0"
hex = "0.4.3"
anyhow = "1.0.86"
covenants-gadgets = { git = "https://github.com/Bitcoin-Wildlife-Sanctuary/covenants-gadgets" }
clap = { version = "4.5.0", features = ["derive"] }
colored = "2.1.0"
bitcoin-circle-stark = {git = "https://github.com/Bitcoin-Wildlife-Sanctuary/bitcoin-circle-stark"}

[profile.dev]
opt-level = 3

[profile.release]
lto = true

[features]
profiler = ["bitcoin-scriptexec/profiler"]
20 changes: 20 additions & 0 deletions demo/script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
./bitcoin-cli --datadir=signet sendtoaddress "tb1qlpxp7md3sn9cfu7z3ygh2cv8vhfgh7p829s4ly" 0.008

./bitcoin-cli --datadir=signet createrawtransaction "[{\"txid\":\"66424b8d982856435307cf5200b825cfcf0a126daf888bb2daa2530106f4cd71\", \"vout\": 0}]" "[{\"tb1p2jczsavv377s46epv9ry6uydy67fqew0ghdhxtz2xp5f56ghj5wqlexrvn\":0.00794341}, {\"tb1qvu62dh2l4d9j09e880musdew6g5ex8n6apx72cx5zafv2mjx6r5qn2hzkf\":0.0000033}]"

./bitcoin-cli --datadir=signet signrawtransactionwithwallet 020000000171cdf4060153a2dab28b88af6d120acfcf25b80052cf0753435628988d4b42660000000000fdffffff02e51e0c000000000022512054b028758c8fbd0aeb2161464d708d26bc9065cf45db732c4a30689a6917951c4a010000000000002200206734a6dd5fab4b2797273bf7c8372ed229931e7ae84de560d41752c56e46d0e800000000

./bitcoin-cli --datadir=signet sendrawtransaction 0200000000010171cdf4060153a2dab28b88af6d120acfcf25b80052cf0753435628988d4b42660000000000fdffffff02e51e0c000000000022512054b028758c8fbd0aeb2161464d708d26bc9065cf45db732c4a30689a6917951c4a010000000000002200206734a6dd5fab4b2797273bf7c8372ed229931e7ae84de560d41752c56e46d0e802473044022035cf2eb36768cf39ac0b158dec8882afe670e868e87dd2259e5930e5eec2f6fe022012252cddc148f0c9c83b3d241c2800982e36fc4c9e6ff57a2b3dbbaf80ebb615012103126f275795cf7beaa0fcea23bec70ba56bfa6120c8c8331d9f8916fe7bee2fba00000000

cargo run -- -f 66424b8d982856435307cf5200b825cfcf0a126daf888bb2daa2530106f4cd71 -i 973957fcc55b7a39f3d3d738fd6946ccc9d58d3edb4c4a55928ef0e5bada61b7

./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-1.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-2.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-3.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-4.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-5.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-6.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-7.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-8.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-9.txt)
./bitcoin-cli --datadir=signet sendrawtransaction $(< ~/RustroverProjects/bitcoin-cfri/demo/tx-10.txt)
1 change: 1 addition & 0 deletions demo/tx-1.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-10.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-2.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-3.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-4.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-5.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-6.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-7.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-8.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/tx-9.txt

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly-2024-01-04"
236 changes: 236 additions & 0 deletions src/bin/demo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
use bitcoin::consensus::Encodable;
use bitcoin::hashes::{sha256d, Hash};
use bitcoin::opcodes::all::{OP_PUSHBYTES_36, OP_RETURN};
use bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid, WScriptHash};
use clap::Parser;
use colored::Colorize;
use covenants_gadgets::test::SimulationInstruction;
use covenants_gadgets::{get_script_pub_key, get_tx, CovenantInput, CovenantProgram, DUST_AMOUNT};
use fibonacci_example::fiat_shamir::compute_fiat_shamir_hints;
use fibonacci_example::fold::compute_fold_hints;
use fibonacci_example::prepare::compute_prepare_hints;
use fibonacci_example::quotients::compute_quotients_hints;
use fibonacci_example::split::{FibonacciSplitInput, FibonacciSplitProgram, FibonacciSplitState};
use fibonacci_example::FIB_LOG_SIZE;
use std::io::Write;
use stwo_prover::core::channel::{BWSSha256Channel, Channel};
use stwo_prover::core::fields::m31::{BaseField, M31};
use stwo_prover::core::fields::IntoSlice;
use stwo_prover::core::vcs::bws_sha256_hash::BWSSha256Hasher;
use stwo_prover::examples::fibonacci::Fibonacci;
use stwo_prover::trace_generation::commit_and_prove;

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// Funding Txid
#[arg(short, long)]
funding_txid: Option<String>,

/// Txid
#[arg(short, long)]
initial_program_txid: Option<String>,
}

fn main() {
let args = Args::parse();

let amount = (2800u64 + 473977 + 325136 + 591311 * 8 + 10000) / 7 + 330 * 10;
let rest = amount - 330 - 400;

if args.funding_txid.is_none() || args.initial_program_txid.is_none() {
let script_pub_key = get_script_pub_key::<FibonacciSplitProgram>();

let program_address =
Address::from_script(script_pub_key.as_script(), Network::Signet).unwrap();

let init_state = FibonacciSplitProgram::new();
let hash = FibonacciSplitProgram::get_hash(&init_state);

let mut bytes = vec![OP_RETURN.to_u8(), OP_PUSHBYTES_36.to_u8()];
bytes.extend_from_slice(&hash);
bytes.extend_from_slice(&12u32.to_le_bytes());

let caboose_address = Address::from_script(
ScriptBuf::new_p2wsh(&WScriptHash::hash(&bytes)).as_script(),
Network::Signet,
)
.unwrap();

let amount_display =
(((amount as f64) / 1000.0 / 1000.0 / 100.0) * 10000.0).ceil() / 10000.0;
let rest_display = (rest as f64) / 1000.0 / 1000.0 / 100.0;

println!("================= INSTRUCTIONS =================");
println!("To start with, prepare {} BTC into a UTXO transaction which would be used to fund the transaction fee for the entire demo.",
amount_display
);
println!(
"> ./bitcoin-cli --datadir=signet sendtoaddress {} {}",
"\"[an address in the local wallet]\""
.on_bright_green()
.black(),
amount_display
);
println!();
println!("According to that transaction, send BTC from that UTXO to the program and the state caboose with the initial state");
println!("> ./bitcoin-cli --datadir=signet createrawtransaction \"[{{\\\"txid\\\":\\\"{}\\\", \\\"vout\\\": {}}}]\" \"[{{\\\"{}\\\":{:.8}}}, {{\\\"{}\\\":0.0000033}}]\"",
"[txid]".on_bright_green().black(),
"[vout]".on_bright_green().black(), program_address, rest_display,
caboose_address
);
println!();
println!("Then, sign the transaction");
println!(
"> ./bitcoin-cli --datadir=signet signrawtransactionwithwallet {}",
"[tx hex]".on_bright_green().black()
);
println!();
println!("Send the signed transaction");
println!(
"> ./bitcoin-cli --datadir=signet sendrawtransaction {}",
"[signed tx hex]".on_bright_green().black()
);
println!();
println!("Call this tool again with the funding txid and initial program id");
println!("> cargo run -f ");
println!("================================================");
} else {
let fib = Fibonacci::new(FIB_LOG_SIZE, M31::reduce(443693538));

let trace = fib.get_trace();
let channel =
&mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib
.air
.component
.claim])));
let proof = commit_and_prove(&fib.air, channel, vec![trace]).unwrap();

let channel =
&mut BWSSha256Channel::new(BWSSha256Hasher::hash(BaseField::into_slice(&[fib
.air
.component
.claim])));
let (fiat_shamir_output, fiat_shamir_hints) =
compute_fiat_shamir_hints(proof.clone(), channel, &fib.air).unwrap();

let (prepare_output, prepare_hints) =
compute_prepare_hints(&fiat_shamir_output, &proof).unwrap();

let (quotients_output, per_query_quotients_hints) =
compute_quotients_hints(&fiat_shamir_output, &prepare_output);

let per_query_fold_hints = compute_fold_hints(
&proof.commitment_scheme_proof.fri_proof,
&fiat_shamir_output,
&prepare_output,
&quotients_output,
);

let mut initial_program_txid = [0u8; 32];
initial_program_txid
.copy_from_slice(&hex::decode(args.initial_program_txid.unwrap()).unwrap());
initial_program_txid.reverse();

let mut funding_txid = [0u8; 32];
funding_txid.copy_from_slice(&hex::decode(args.funding_txid.unwrap()).unwrap());
funding_txid.reverse();

let mut old_state = FibonacciSplitProgram::new();
let mut old_randomizer = 12u32;
let mut old_balance = rest;
let mut old_txid =
Txid::from_raw_hash(*sha256d::Hash::from_bytes_ref(&initial_program_txid));

let mut old_tx_outpoint1 = OutPoint {
txid: Txid::from_raw_hash(*sha256d::Hash::from_bytes_ref(&funding_txid)),
vout: 0,
};

let get_instruction = |old_state: &FibonacciSplitState| {
if old_state.pc == 0 {
Some(SimulationInstruction::<FibonacciSplitProgram> {
program_index: 0,
fee: 67711,
program_input: FibonacciSplitInput::FiatShamir(Box::new(
fiat_shamir_hints.clone(),
)),
})
} else if old_state.pc == 1 {
Some(SimulationInstruction::<FibonacciSplitProgram> {
program_index: 1,
fee: 46448,
program_input: FibonacciSplitInput::Prepare(
old_state.stack.clone(),
prepare_hints.clone(),
),
})
} else if old_state.pc >= 2 && old_state.pc <= 9 {
let i = old_state.pc - 2;
Some(SimulationInstruction {
program_index: old_state.pc,
fee: 84473,
program_input: FibonacciSplitInput::PerQuery(
old_state.stack.clone(),
per_query_quotients_hints[i].clone(),
per_query_fold_hints[i].clone(),
),
})
} else {
unimplemented!()
}
};

let mut txs = Vec::new();

for _ in 0..10 {
let next = get_instruction(&old_state).unwrap();

let mut new_balance = old_balance;
new_balance -= next.fee as u64; // as for transaction fee
new_balance -= DUST_AMOUNT;

let info = CovenantInput {
old_randomizer,
old_balance,
old_txid,
input_outpoint1: old_tx_outpoint1,
input_outpoint2: None,
optional_deposit_input: None,
new_balance,
};

let new_state =
FibonacciSplitProgram::run(next.program_index, &old_state, &next.program_input)
.unwrap();

let (tx_template, randomizer) = get_tx::<FibonacciSplitProgram>(
&info,
next.program_index,
&old_state,
&new_state,
&next.program_input,
);

txs.push(tx_template.tx.clone());

old_state = new_state;
old_randomizer = randomizer;
old_balance = new_balance;
old_txid = tx_template.tx.compute_txid();

old_tx_outpoint1 = tx_template.tx.input[0].previous_output;
}

for (i, tx) in txs.iter().enumerate() {
let mut bytes = vec![];
tx.consensus_encode(&mut bytes).unwrap();

let mut fs = std::fs::File::create(format!("./tx-{}.txt", i + 1)).unwrap();
fs.write_all(hex::encode(bytes).as_bytes()).unwrap();
}

println!("================= INSTRUCTIONS =================");
println!("All 10 transactions have been generated and stored in the current directory.");
}
}
Loading
Loading