Skip to content
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
116 changes: 58 additions & 58 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions circuits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,10 @@ After calling the [`proceedWithdraw`](https://github.com/GOATNetwork/bitvm2-L2-c
```
export BITCOIN_NETWORK=regtest
export GENESIS_SEQUENCER_COMMIT_TXID=$(cat ./data/commit-chain/commit_info.json.0 | jq -r .genesis_txid)

export LATEST_SEQUENCER_COMMIT_TXID=$(cat ./data/commit-chain/commit_info.json.2 | jq -r .txid)
export OPERATOR_BLOCKHASH_COMMIT_TXID=$(cat ./data/commit-chain/commit_info.json.2 | jq -r .txid)

export HEADER_CHAIN_INPUT_PROOF="data/header-chain/0-116000.bin"
export COMMIT_CHAIN_INPUT_PROOF="data/commit-chain/2-1.bin"
export STATE_CHAIN_INPUT_PROOF="data/state-chain/9511050-10.bin"
Expand Down
19 changes: 9 additions & 10 deletions circuits/operator-proof/guest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,47 @@
zkm_zkvm::entrypoint!(main);
use std::str::FromStr;
use header_chain::{
HeaderChainCircuitInput, SPV, CircuitTransaction,
HeaderChainCircuitInput, SPV,
};
use alloy_primitives::{U256, Address};
use bitcoin_light_client_circuit::EthClientExecutorInput;
use commit_chain::CommitChainCircuitInput;
use state_chain::StateChainCircuitInput;
use bitcoin::{ScriptBuf, TxOut};
use bitcoin::{ScriptBuf, TxOut, Transaction};

pub fn main() {
// calculate operator public input: https://github.com/ProjectZKM/Ziren/blob/main/crates/sdk/src/utils.rs#L42
let included_watchertowers: U256 = zkm_zkvm::io::read::<U256>();
let graph_id: [u8; 16] = zkm_zkvm::io::read::<[u8; 16]>();
let operator_genesis_sequencer_commit_txid: [u8; 32] = zkm_zkvm::io::read();
println!("read operator commit txn");
let operator_latest_sequencer_commit_txn: CircuitTransaction = zkm_zkvm::io::read(); // private inputs
let latest_sequencer_commit_txid = operator_latest_sequencer_commit_txn.0.compute_txid(); // public input
let operator_latest_sequencer_commit_txn: Transaction = zkm_zkvm::io::read(); // private inputs
let latest_sequencer_commit_txid = operator_latest_sequencer_commit_txn.compute_txid(); // public input
// https://github.com/KSlashh/BitVM/blob/v2/goat/src/transactions/watchtower_challenge.rs#L128
let watchtower_challenge_txns: Vec<CircuitTransaction> = zkm_zkvm::io::read();
let watchtower_challenge_txns: Vec<Transaction> = zkm_zkvm::io::read();
let watchtower_challenge_txn_pubkey: Vec<bitcoin::secp256k1::PublicKey> = zkm_zkvm::io::read();
let watchtower_challenge_txn_scripts: Vec<ScriptBuf> = zkm_zkvm::io::read();
let watchtower_challenge_txn_prev_outs: Vec<TxOut> = zkm_zkvm::io::read();
let watchtower_challenge_txn_prev_indices: Vec<usize> = zkm_zkvm::io::read();

let operator_header_chain: HeaderChainCircuitInput = zkm_zkvm::io::read();
let operator_commit_chain: CommitChainCircuitInput = zkm_zkvm::io::read();
let operator_state_chain: StateChainCircuitInput = zkm_zkvm::io::read();
let spv: SPV = zkm_zkvm::io::read();
let spv_ss_commit: SPV = zkm_zkvm::io::read();
let spv_operator_blockhash: SPV = zkm_zkvm::io::read();

let (btc_best_block_hash, constant, included_watchtowers) = bitcoin_light_client_circuit::propose_longest_chain(
included_watchertowers,
graph_id,
operator_genesis_sequencer_commit_txid,
operator_latest_sequencer_commit_txn,
watchtower_challenge_txns,
watchtower_challenge_txn_pubkey,
watchtower_challenge_txn_scripts,
watchtower_challenge_txn_prev_outs,
watchtower_challenge_txn_prev_indices,
operator_header_chain,
operator_commit_chain,
operator_state_chain,
spv,
spv_ss_commit,
spv_operator_blockhash,
);

zkm_zkvm::io::commit(&btc_best_block_hash);
Expand Down
84 changes: 57 additions & 27 deletions circuits/operator-proof/host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ use bitcoin_script::script;
use borsh::BorshDeserialize;
use client::btc_chain::BTCClient;
use commit_chain::{CommitChainCircuitInput, CommitChainPrevProofType};
use header_chain::{
CircuitBlockHeader, CircuitTransaction, HeaderChainCircuitInput, HeaderChainPrevProofType,
};
use header_chain::{CircuitBlockHeader, HeaderChainCircuitInput, HeaderChainPrevProofType};
use proof_builder::{LongRunning, ProofBuilder, ProofRequest};
use state_chain::{StateChainCircuitInput, StateChainPrevProofType};
use std::str::FromStr;
Expand Down Expand Up @@ -44,6 +42,9 @@ pub struct Args {
#[clap(long, env)]
pub latest_sequencer_commit_txid: String,

#[clap(long, env)]
pub operator_blockhash_commit_txid: String,

#[clap(long, env)]
pub genesis_sequencer_commit_txid: String,

Expand Down Expand Up @@ -90,36 +91,46 @@ static ELF_ID: OnceLock<String> = OnceLock::new();
pub async fn fetch_target_block_and_watchtower_tx(
esplora_url: &str,
latest_sequencer_commit_txid: &str,
operator_blockhash_commit_txid: &str,
watchtower_challenge_init_txid: &String,
watchtower_challenge_txids: &str,
watchtower_public_keys: &str,
bitcoin_network: Network,
) -> anyhow::Result<(
u32,
bitcoin::Block,
u32,
bitcoin::Block,
bitcoin::Transaction,
bitcoin::Transaction,
Vec<CircuitTransaction>,
Vec<Transaction>,
Vec<TxOut>,
Vec<usize>,
Vec<bitcoin::secp256k1::PublicKey>,
Vec<ScriptBuf>,
)> {
let watchtower_challenge_txids: Vec<&str> = watchtower_challenge_txids.split(",").collect();
let watchtower_public_keys: Vec<&str> = watchtower_public_keys.split(",").collect();
let btc_client = BTCClient::new(bitcoin_network, Some(&esplora_url));

let latest_sequencer_commit_txid = Txid::from_str(&latest_sequencer_commit_txid).unwrap();
let operator_latest_sequencer_commit_txn =
btc_client.get_tx(&latest_sequencer_commit_txid).await.unwrap().unwrap();

let tx_status = btc_client.get_tx_status(&latest_sequencer_commit_txid).await.unwrap();
let block_pos = tx_status.block_height.unwrap();
tracing::info!("block height: {block_pos}");
let target_block = btc_client.get_block_by_height(block_pos).await.unwrap();
let block_pos_ss_commit = tx_status.block_height.unwrap();
tracing::info!("block height: {block_pos_ss_commit}");
let target_block_ss_commit = btc_client.get_block_by_height(block_pos_ss_commit).await.unwrap();

let operator_blockhash_commit_txid = Txid::from_str(&operator_blockhash_commit_txid).unwrap();
let operator_blockhash_commit_txn =
btc_client.get_tx(&operator_blockhash_commit_txid).await.unwrap().unwrap();
let tx_status = btc_client.get_tx_status(&operator_blockhash_commit_txid).await.unwrap();
let block_pos_operator_blockhash = tx_status.block_height.unwrap();
let target_block_operator_blockhash =
btc_client.get_block_by_height(block_pos_operator_blockhash).await.unwrap();

// --- watchtower_challenge_txns --- //
let mut watchtower_challenge_txns = Vec::new();
let mut watchtower_challenge_txn_prev_outs: Vec<TxOut> = Vec::new();
let mut watchtower_challenge_txn_prev_indices: Vec<usize> = Vec::new();
let mut watchtower_challenge_txn_pubkeys = Vec::new();
let mut watchtower_challenge_txn_scripts: Vec<ScriptBuf> = Vec::new();

Expand All @@ -135,11 +146,10 @@ pub async fn fetch_target_block_and_watchtower_tx(
let index = txn.input[0].previous_output.vout as usize;
watchtower_challenge_txn_prev_outs
.push(watchtower_challlenge_init_txn.output[index].clone());
watchtower_challenge_txn_prev_indices.push(index);

let public_key = PublicKey::from_str(pk).unwrap();
watchtower_challenge_txn_pubkeys.push(public_key.clone());
watchtower_challenge_txns.push(CircuitTransaction(txn));
watchtower_challenge_txns.push(txn);

// https://github.com/GOATNetwork/BitVM/blob/GA/goat/src/transactions/watchtower_challenge.rs#L45
// generate_pay_to_pubkey_taproot_script
Expand All @@ -155,12 +165,14 @@ pub async fn fetch_target_block_and_watchtower_tx(
}

Ok((
block_pos,
target_block,
block_pos_ss_commit,
target_block_ss_commit,
block_pos_operator_blockhash,
target_block_operator_blockhash,
operator_latest_sequencer_commit_txn,
operator_blockhash_commit_txn,
watchtower_challenge_txns,
watchtower_challenge_txn_prev_outs,
watchtower_challenge_txn_prev_indices,
watchtower_challenge_txn_pubkeys,
watchtower_challenge_txn_scripts,
))
Expand Down Expand Up @@ -209,13 +221,17 @@ impl ProofBuilder for OperatorProofBuilder {
commit_chain_input_proof,
state_chain_input_proof,
genesis_sequencer_commit_txid,
target_block,
block_pos,

target_block_ss_commit,
block_pos_ss_commit,
operator_latest_sequencer_commit_txn,

block_pos_operator_blockhash,
target_block_operator_blockhash,
operator_blockhash_commit_txn,

watchtower_challenge_txns,
watchtower_challenge_txn_prev_outs,
watchtower_challenge_txn_prev_indices,
watchtower_challenge_txn_pubkeys,
watchtower_challenge_txn_scripts,
..
Expand Down Expand Up @@ -293,9 +309,9 @@ impl ProofBuilder for OperatorProofBuilder {
.collect::<Vec<CircuitBlockHeader>>()
};

let found = bitcoin_block_headers
.iter()
.position(|h| h.compute_block_hash() == *target_block.block_hash().as_byte_array());
let found = bitcoin_block_headers.iter().position(|h| {
h.compute_block_hash() == *target_block_ss_commit.block_hash().as_byte_array()
});
tracing::info!("block found: {:?}", found);
if found.is_none() {
anyhow::bail!(
Expand All @@ -304,11 +320,25 @@ impl ProofBuilder for OperatorProofBuilder {
}

tracing::info!("block headers: {:?}", bitcoin_block_headers.len());
tracing::info!("construct spv");
let spv = build_spv(
tracing::info!(
"construct spv for ss commit, {}",
operator_latest_sequencer_commit_txn.compute_txid()
);
let spv_ss_commit = build_spv(
&operator_latest_sequencer_commit_txn,
*block_pos,
target_block.clone(),
*block_pos_ss_commit,
target_block_ss_commit.clone(),
&bitcoin_block_headers,
);

tracing::info!(
"construct spv for operator blockhash commit, {}",
operator_blockhash_commit_txn.compute_txid()
);
let spv_operator_blockhash = build_spv(
&operator_blockhash_commit_txn,
*block_pos_operator_blockhash,
target_block_operator_blockhash.clone(),
&bitcoin_block_headers,
);

Expand All @@ -329,12 +359,12 @@ impl ProofBuilder for OperatorProofBuilder {
stdin.write(&watchtower_challenge_txn_pubkeys);
stdin.write(&watchtower_challenge_txn_scripts);
stdin.write(&watchtower_challenge_txn_prev_outs);
stdin.write(&watchtower_challenge_txn_prev_indices);

stdin.write(&header_chain_input);
stdin.write(&commit_chain_input);
stdin.write(&state_chain_input);
stdin.write(&spv);
stdin.write(&spv_ss_commit);
stdin.write(&spv_operator_blockhash);

let elf_id = if ELF_ID.get().is_none() {
ELF_ID
Expand Down
18 changes: 12 additions & 6 deletions circuits/operator-proof/host/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Generate operator proof
use bitcoin::constants::TARGET_BLOCK_SPACING;
use clap::Parser;
use operator_proof::{Args, OperatorProofBuilder, fetch_target_block_and_watchtower_tx};
use proof_builder::{ProofBuilder, ProofRequest};
Expand All @@ -12,17 +13,20 @@ async fn main() {
zkm_sdk::utils::setup_logger();

let (
block_pos,
target_block,
block_pos_ss_commit,
target_block_ss_commit,
block_pos_operator_blockhash,
target_block_operator_blockhash,
operator_latest_sequencer_commit_txn,
operator_blockhash_commit_txn,
watchtower_challenge_txns,
watchtower_challenge_txn_prev_outs,
watchtower_challenge_txn_prev_indices,
watchtower_challenge_txn_pubkeys,
watchtower_challenge_txn_scripts,
) = fetch_target_block_and_watchtower_tx(
&args.esplora_url,
&args.latest_sequencer_commit_txid,
&args.operator_blockhash_commit_txid,
&args.watchtower_challenge_init_txid,
&args.watchtower_challenge_txids,
&args.watchtower_public_keys,
Expand All @@ -45,13 +49,15 @@ async fn main() {

output: args.output.clone(),

block_pos,
target_block,
block_pos_ss_commit,
target_block_ss_commit,
operator_latest_sequencer_commit_txn,
block_pos_operator_blockhash,
target_block_operator_blockhash,
operator_blockhash_commit_txn,

watchtower_challenge_txns,
watchtower_challenge_txn_prev_outs,
watchtower_challenge_txn_prev_indices,
watchtower_challenge_txn_pubkeys,
watchtower_challenge_txn_scripts,
};
Expand Down
16 changes: 11 additions & 5 deletions circuits/proof-builder/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use bitcoin::{Block, ScriptBuf, Transaction, TxOut};
use commit_chain::CircuitCommit;
use header_chain::{CircuitBlockHeader, CircuitTransaction};
use header_chain::CircuitBlockHeader;
use serde::{Deserialize, Serialize};
use state_chain::CircuitStateBlock;
use thiserror::Error;
Expand Down Expand Up @@ -54,12 +54,17 @@ pub enum ProofRequest {
state_chain_input_proof: String,
execution_layer_block_number: u64,
output: String,
target_block: Block,
block_pos: u32,

target_block_ss_commit: Block,
block_pos_ss_commit: u32,
operator_latest_sequencer_commit_txn: Transaction,
watchtower_challenge_txns: Vec<CircuitTransaction>,

target_block_operator_blockhash: Block,
block_pos_operator_blockhash: u32,
operator_blockhash_commit_txn: Transaction,

watchtower_challenge_txns: Vec<Transaction>,
watchtower_challenge_txn_prev_outs: Vec<TxOut>,
watchtower_challenge_txn_prev_indices: Vec<usize>,
watchtower_challenge_txn_pubkeys: Vec<bitcoin::secp256k1::PublicKey>,
watchtower_challenge_txn_scripts: Vec<ScriptBuf>,
},
Expand Down Expand Up @@ -113,4 +118,5 @@ pub struct OnDemandTask {
pub included_watchtowers: Vec<bool>,
pub watchtower_public_keys: Vec<String>,
pub graph_id: Option<String>,
pub operator_blockhash_commit_txid: Option<String>,
}
Loading
Loading