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
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ GOAT Network's BitVM bridge implementation. See [GOAT BitVM Whitepaper](https://
- `localnet/`: clone-and-run mock testnet (five `mock-gc` nodes on regtest + anvil + graph-node) and the on-demand e2e suite, see [localnet/README.md](localnet/README.md); `make localnet-reset`, `make e2e-smoke`


## Transaction graph

[![BitVM Bitcoin transaction graph with per-input sighash labels](transaction-graph.svg)](transaction-graph.svg)

Open the [full-size transaction graph](transaction-graph.svg) to inspect the
connectors, competing spends, CSV paths, and per-input signature types. Blue
paths show operator and claim transactions; red paths show challenges and
timeouts. Dots mark connected branches; crossings without dots are not connected.

The graph includes peg-in funding and refunds, the Take-1 and Take-2 claim
paths, Watchtower and Verifier branches, and PreKickoff slots. See the
[node transaction guide](node/README.md#bitcoin-transaction-graph) for the
connector and signature notation.

## Transaction graph checks

The checks cover critical connector relationships, default network timing, and
Expand All @@ -27,7 +41,7 @@ core dispute safety for Bitcoin, Testnet4, Signet and Regtest:
committed pubin. It models the current Commit-Timeout and verifier gates,
including an operator withholding evidence and a possibly offline watchtower.
An honest verifier's enabled defences have an explicit bounded response time.
- `tests/tla_shipped_values.rs` checks that the TLA values match Rust. A timing
- `crates/bitvm-gc/tests/tla_shipped_values.rs` checks that the TLA values match Rust. A timing
change requires regenerating the values and rerunning the checks.
- Every other `audit/tla/<Model>.tla` with a `<Model>.cfg` is checked as well;
its header states what it models and which code it follows.
Expand Down
102 changes: 47 additions & 55 deletions circuits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## Overview

Trust Setup: choose a snapshot of GOAT Pre Alpha Mainnet, which consists of (Seqeuncer Set, EVM Block Hash)
The initial trust anchor is a GOAT snapshot containing the sequencer set and EVM block hash.
For Bitcoin transaction wiring and signature types, see the [transaction graph](../transaction-graph.svg).

Main components:

Expand All @@ -29,13 +30,13 @@ Circuits:
>> * The latest_sequencer_commit_txid is included in the header chain proof
>> * The latest_sequencer_commit_txid is the latest commit txn in the commit chain
>> * The state chain's latest block(EVM block) is signed by the sequencer set in the latest block of commit chain
>> * For each watchtower proof,
>> * For each included Watchtower proof,

>>> * The watchtower challenge transaction is valid
>>> * The proof is valid
>>> * The graph is as same as the operator's graph id
>>> * The operator's total work >= Watchtowers' largest total work
>>> * The operator's block height that includes the latest sequencer commit transaction is larger than the watchtower's
>>> * For claims from the same genesis, the operator's total work is at least the Watchtower's
>>> * The operator's commitment inclusion height is at least the watchtower's for a claim from the same genesis

>> * Verify that the withdrawal state change in the Gateway contract is correct

Expand Down Expand Up @@ -65,17 +66,17 @@ under 2.0, so the header, commit and state chain proofs restart from genesis at
BABE garbled-circuit verifier treats `vkey_hash` and `vk_root` as static inputs and `committed_values_digest`
as the dynamic one.

## Guest workspace
## Build inputs

All guest programs (`*/guest`) form one workspace rooted at `circuits/Cargo.toml`, with a single
`Cargo.lock` and `[patch.crates-io]`. The guest-side shared crates live in `circuits/crates/`, inside
that root, because cargo hashes a path dependency outside the workspace root by its absolute path,
which would make each guest ELF, and so its vk, depend on where the repository is checked out. Keep any
new guest-side path dependency under `circuits/`. The ELF also depends on `ZKM_IMM_WRAP_VK` and
`BITCOIN_NETWORK` at build time.
Build all five guest programs with the same `BITCOIN_NETWORK` and
`ZKM_IMM_WRAP_VK` settings used by the nodes and Proof Builder. Program or proof
system changes require matching verification keys and proof artifacts.

## Preparation

Run the proof examples from `circuits/`. The host binaries load `.env` there;
export the same configuration before running the helper scripts.

```bash
mkdir -p data/header-chain
mkdir -p data/commit-chain
Expand All @@ -89,19 +90,18 @@ if `Network Prover` is used, see [this](https://docs.zkm.io/dev/prover.html#netw
Launch the Regtest.

```bash
cd scripts
docker compose up -d
(cd ../scripts && docker compose up -d)
```

## Bitcoin Header Chain

```
# regtest
# export BITCOIN_NETWOKR=regtest
# export BITCOIN_NETWORK=regtest

# testnet
# export BITCOIN_NETWOKR=testnet4
# export ESPLORA_URL=https://mempool.space/testnet/api
# export BITCOIN_NETWORK=testnet4
# export ESPLORA_URL=https://mempool.space/testnet4/api


bash cron-header-chain-proof.sh $start $batch
Expand All @@ -114,14 +114,15 @@ bash cron-header-chain-proof.sh $start $batch
Example:

```bash
cd node
cd ../node
GOAT_BLOCK_NUMBER=9511050 bash -x ssp-ci.sh
cd ../circuits
```

All the initial publishers are hardcoded. In the `ssp-ci.sh`, we simutate 2-round publisher rotations.
This publication script is a Regtest fixture with hardcoded publishers. In the `ssp-ci.sh`, we simulate 2-round publisher rotations.
`GOAT_BLOCK_NUMBER` is the GOAT's current block number, which is used as the key to fetch sequencer set commitment.

Note that we should deploy [SequencerSetPublisher Contract](https://github.com/GOATNetwork/bitvm2-L2-contracts/tree/main/script#deploy) before publishing the sequencer set.
Deploy the SequencerSetPublisher contract before publishing the sequencer set.

Then setup the correct contract address in your `.env`.

Expand Down Expand Up @@ -168,7 +169,7 @@ RUST_LOG=info cargo run --package commit-chain-proof --bin commit-chain-proof -r

## State Chain

State Chain represents the L2's state transition, which checks the EVM's execution, withdrawal transaction inclusion and sequencers' aggrement.
State Chain represents the L2's state transition, which checks the EVM's execution, withdrawal transaction inclusion and sequencers' agreement.

We generate `state-chain-proof` periodically, like by 5 GOAT EVM blocks. Optionally, the block may contain a `proceedWithdraw` transaction.

Expand All @@ -177,7 +178,7 @@ We generate `state-chain-proof` periodically, like by 5 GOAT EVM blocks. Optiona

```
export BATCH_SIZE=10
export L2_CONTRACT_ADDRESS=0x21f619040AC2eAcacEF8Fe17Ae8bDF53ec69C66f
export L2_CONTRACT_ADDRESSES="$GOAT_GATEWAY_CONTRACT_ADDRESS"

export EL_START_BLOCK_NUMBER=10346748
export start=$EL_START_BLOCK_NUMBER
Expand All @@ -186,7 +187,8 @@ bash cron-state-chain-proof.sh $start $BATCH_SIZE

## Watchtower proof

If a challenge is happened, each watchtower should broadcast a `watchtower-challenge-tx` to submit its longest chain.
When a challenge occurs, each Watchtower can publish a `watchtower-challenge-tx`
containing its proof commitment.

* Generate proofs

Expand All @@ -196,7 +198,6 @@ export GENESIS_SEQUENCER_COMMIT_TXID=$(cat ./data/commit-chain/commit_info.json.
export LATEST_SEQUENCER_COMMIT_TXID=$(cat ./data/commit-chain/commit_info.json.0 | jq -r .txid)
export HEADER_CHAIN_INPUT_PROOF="data/header-chain/0-116000.bin"
export COMMIT_CHAIN_INPUT_PROOF="data/commit-chain/0-1.bin"
export LATEST_STATE_BLOCK_HASH="0x7908184bce067fa5a4508d309cbaf22dd1e0b586ad2dd42c0e51a5308a7bd815"
export STATE_CHAIN_INPUT_PROOF="data/state-chain/9511050-10.bin"

RUST_LOG=info cargo run --package watchtower-proof --bin watchtower-proof -r -- --output "data/watchtower/output.bin"
Expand All @@ -216,46 +217,37 @@ RUST_LOG=info cargo run --package watchtower-proof --bin watchtower-proof -r --

## Operator proof

* Simutate a withdraw challenge
* Simulate a withdraw challenge

```bash
cd crates/bitvm-gc
cargo test -r test_take2
```

Make sure the operator has enough balance, if not, run this command to fund the operator.

```
bitcoin-cli -regtest -rpcuser=$... -rpcpassword=$... sendtoaddress bcrt1qhnmlpxyxdntekge4u24m4a7yk6elc3zs4v89e7fqja8vagfnrs8sq28cwd 50
(cd .. && cargo test -r -p bitvm-gc --test regtest regtest_take2_flow -- --ignored)
```

Get the withdraw-challenge-init-txid , graph-id, watchtower's challenge transaction id and compressed public key.
Fund the Operator on Regtest and obtain the graph ID, Watchtower-Challenge-Init
transaction ID, and indexed Watchtower transactions and public keys from that run.

* Generate proofs

After calling the [`proceedWithdraw`](https://github.com/GOATNetwork/bitvm2-L2-contracts/blob/main/src/Gateway.sol#L588), we generate the operator proof with corresponding `graph_id` and transaction id.
After `proceedWithdraw`, generate the Operator proof for the corresponding graph
and withdrawal block. Use values from the same graph and proof-chain history.

```
```bash
export BITCOIN_NETWORK=regtest
export DIR="/home/ubuntu/data/proof-builder-rpc/circuits"
export GENESIS_SEQUENCER_COMMIT_TXID=$(cat ${DIR}/data/commit-chain/commit_info.json.0 | jq -r .genesis_txid)

export LATEST_SEQUENCER_COMMIT_TXID=$(cat ${DIR}/data/commit-chain/commit_info.json.11 | jq -r .txid)
export OPERATOR_COMMITTED_BLOCKHASH =$(cat ${DIR}/data/commit-chain/commit_info.json.11 | jq -r .txid)

export HEADER_CHAIN_INPUT_PROOF="$DIR/data/header-chain/1024-1.bin"
export COMMIT_CHAIN_INPUT_PROOF="$DIR/data/commit-chain/11-1.bin"
export STATE_CHAIN_INPUT_PROOF="$DIR/data/state-chain/10558271-40.bin"

export GRAPH_ID="3C2917B82FE14EF7B8CC8BEF3ECD700F"
export EXECUTION_LAYER_BLOCK_NUMBER=10558309

export INCLUDED_WATCHTOWERS=0
export WATCHTOWER_PUBLIC_KEYS="02e7a08db9093c279535bd0078582469b82bf9f12c6dcb7588e187d2b9cc724279,02f6dce5d37a801064bdf42759dba98afccc80440c32cdc3a8d85c0ed9ae2e749b"
export WATCHTOWER_CHALLENGE_TXIDS="6247824c7c96c4701ef52163316d938412b15cf15962622b3c63f3cf41193f96,fe96c90162c369f45ae4f08140c6197a15c5f3cfe23f04be60f18802e97f4f91"
export WATCHTOWER_CHALLENGE_INIT_TXID="e7723e03ac97172cf033e40d4b9d9c0e22efa7a41eb855a1576f467684a0f6b3"

RUST_LOG=info cargo run --package operator-proof --bin operator-proof -r -- --output "data/operator-proof/output.bin"
export HEADER_CHAIN_INPUT_PROOF="data/header-chain/header.bin"
export COMMIT_CHAIN_INPUT_PROOF="data/commit-chain/commit.bin"
export STATE_CHAIN_INPUT_PROOF="data/state-chain/state.bin"

export GENESIS_SEQUENCER_COMMIT_TXID="${GENESIS_SEQUENCER_COMMIT_TXID:?Set the genesis commitment transaction ID}"
export LATEST_SEQUENCER_COMMIT_TXID="${LATEST_SEQUENCER_COMMIT_TXID:?Set the latest commitment transaction ID}"
export OPERATOR_COMMITTED_BLOCKHASH="${OPERATOR_COMMITTED_BLOCKHASH:?Set the committed Bitcoin block hash}"
export GRAPH_ID="${GRAPH_ID:?Set the graph ID as 32 hexadecimal characters}"
export EXECUTION_LAYER_BLOCK_NUMBER="${EXECUTION_LAYER_BLOCK_NUMBER:?Set the withdrawal block height}"
export INCLUDED_WATCHTOWERS="${INCLUDED_WATCHTOWERS:?Set the Watchtower inclusion bitmask}"
export WATCHTOWER_PUBLIC_KEYS="${WATCHTOWER_PUBLIC_KEYS:?Set the indexed public-key list}"
export WATCHTOWER_CHALLENGE_TXIDS="${WATCHTOWER_CHALLENGE_TXIDS:?Set the indexed transaction-ID list}"
export WATCHTOWER_CHALLENGE_INIT_TXID="${WATCHTOWER_CHALLENGE_INIT_TXID:?Set the challenge-init transaction ID}"

RUST_LOG=info cargo run --package operator-proof --bin operator-proof -r -- --output "data/operator/output.bin"
```

The operator proof is consumed directly by the Assert flow. BABE setup binds its static public
Expand All @@ -266,5 +258,5 @@ input, while the dynamic public input is committed after the watchtower challeng
* commit-chain-input-proof: the commit chain's proof, input and vk.
* included-watchtower: a 256-bit bitmask; each bit flags a valid watchtower inside operator proof.
* execution-layer-block-number: the block number that including `proceedWithdraw`(Peg-out) transaction of GOAT Network's execution layer(Geth).
* watchtower-challenge-info: list of watchtower's challenge transaction id and compressed public key, i.e: [wachtower_info.json](./data/watchtower/watchtower_info.json).
* watchtower-challenge-txids and watchtower-public-keys: comma-separated lists in graph slot order. The inclusion bitmask uses the same indices.
* watchtower-challenge-init-txid: the watchtower challenge init transaction id in GOAT's BitVM graph.
Loading
Loading