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

Commit

Permalink
Separating fibnacci example (#1)
Browse files Browse the repository at this point in the history
* fix dependencies

* remove cargo-husky

* move demo impl here

* add the demo txs

* redirection

* add github ci

---------

Co-authored-by: weikengchen <[email protected]>
  • Loading branch information
PayneJoe and weikengchen authored Aug 15, 2024
1 parent b6d1577 commit 2b27af0
Show file tree
Hide file tree
Showing 27 changed files with 3,510 additions and 0 deletions.
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

0 comments on commit 2b27af0

Please sign in to comment.