Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retries for proofs and starknet #14

Merged
merged 6 commits into from
Jan 8, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/cairo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
submodules: true
- uses: software-mansion/setup-scarb@v1
with:
scarb-version: "2.8.5"
scarb-version: "2.9.1"
- run: cd contracts/starknet && scarb fmt --check
- run: cd contracts/starknet && scarb build
# - run: snforge test
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,68 @@ Required toolchain components:
./scripts/deploy.sh
```

#### Terminal 4: MMR Builder Options

The MMR builder supports several options for controlling how the MMR is built:

```bash
# Build MMR with default settings (from latest finalized block)
cargo run --bin build_mmr --release

# Build from a specific start block
cargo run --bin build_mmr --release -- --start-block <BLOCK_NUMBER>

# Build from the latest onchain MMR block
cargo run --bin build_mmr --release -- --from-latest

# Control batch size
cargo run --bin build_mmr --release -- --batch-size <SIZE>

# Process specific number of batches
cargo run --bin build_mmr --release -- --num-batches <COUNT>

# Skip proof verification
cargo run --bin build_mmr --release -- --skip-proof

# Combine options (examples)
cargo run --bin build_mmr --release -- --from-latest --num-batches 10
cargo run --bin build_mmr --release -- --start-block 1000 --batch-size 512
```

Available options:
- `--start-block, -s`: Start building from this block number
- `--from-latest, -l`: Start building from the latest onchain MMR block
- `--batch-size`: Number of blocks per batch (default: 1024)
- `--num-batches, -n`: Number of batches to process
- `--skip-proof, -p`: Skip proof verification
- `--env-file, -e`: Path to environment file (default: .env)

Note: `--from-latest` and `--start-block` cannot be used together.

#### Terminal 4: Light Client Process

Execute client binary:
```bash
cargo run --bin client --release
```

The client supports the following options:

```bash
# Run with default settings (5 second polling interval)
cargo run --bin client --release

# Run with custom polling interval (in seconds)
cargo run --bin client --release -- --polling-interval 10

# Use a specific environment file
cargo run --bin client --release -- --env-file .env.local
```

Available options:
- `--polling-interval`: Time between polls in seconds (default: 5)
- `--env-file, -e`: Path to environment file (default: .env)

#### Terminal 5: Block Hash Relayer Process

Execute relayer process:
Expand Down
31 changes: 31 additions & 0 deletions config/.env.docker.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ETH_RPC_URL=http://anvil:8545
FORK_URL=http://209.127.228.66:8545

BONSAI_API_KEY=XXX
BONSAI_API_URL=https://api.bonsai.xyz/

DATABASE_URL=XXX

ETH_ACCOUNT_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
ACCOUNT_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

SN_MESSAGING=0x0c77a52c35601106993B684E6b20D68FF0a89493
L1_MESSAGE_SENDER=0x77F83238fa5FFD7E031C2D1195AC5d0a8D1B3df5

export FOUNDRY_EVM_VERSION=cancun

ANVIL_CONFIG=config/anvil.messaging.json
STARKNET_RPC_URL=http://katana:5050
STARKNET_PRIVATE_KEY=0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912
STARKNET_ACCOUNT_ADDRESS=0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec

L2_MSG_PROXY=0x01c0692f888adfb3dea3d4b4446afbfcd3a2456a64b113084af3549e8d6915e8
FOSSIL_STORE=0x02d4eac88f8e9bbb0fd4ff2c35d385710bf3f8a6e4061266ac4de628dac11dd5

STARKNET_VERIFIER=0x03848e3432559e5804d48e1a60faa59c9ab00f515bcf122e3865193277eb118a
FOSSIL_VERIFIER=0x029d9eba080e8e7a6eed79f432b8d0cbe1e7ffe4187eda3cf2819cde8d700ff2

STARKNET_ACCOUNT=katana-0

DEPLOYMENT_VERSION=local
CHAIN_ID=11155111
27 changes: 0 additions & 27 deletions config/.env.example

This file was deleted.

6 changes: 3 additions & 3 deletions config/anvil.messaging.docker.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"chain": "ethereum",
"rpc_url": "http://localhost:8545",
"contract_address": "0xE37675Bb1cc1c90dB0Deed8033CAb650770e79cE",
"rpc_url": "http://anvil:8545",
"contract_address": "0xe9FfA5399C14206e16D801dA5BD94cbF67bE82a7",
"sender_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"private_key": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
"interval": 2,
"from_block": 7422233
"from_block": 7442506
}
35 changes: 30 additions & 5 deletions contracts/starknet/store/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#[starknet::interface]
pub trait IFossilStore<TContractState> {
fn initialize(ref self: TContractState, verifier_address: starknet::ContractAddress, min_update_interval: u64);
fn initialize(
ref self: TContractState,
verifier_address: starknet::ContractAddress,
min_update_interval: u64,
);
fn store_latest_blockhash_from_l1(ref self: TContractState, block_number: u64, blockhash: u256);
fn update_mmr_state(ref self: TContractState, journal: verifier::Journal);
fn get_latest_blockhash_from_l1(self: @TContractState) -> (u64, u256);
fn get_mmr_state(self: @TContractState, batch_index: u64) -> Store::MMRSnapshot;
fn get_latest_mmr_block(self: @TContractState) -> u64;
fn get_min_mmr_block(self: @TContractState) -> u64;
}

#[starknet::contract]
Expand Down Expand Up @@ -38,6 +43,7 @@ mod Store {
latest_blockhash_from_l1: (u64, u256),
latest_mmr_block: u64,
mmr_batches: Map<u64, MMRBatch>,
min_mmr_block: u64,
min_update_interval: u64,
}

Expand Down Expand Up @@ -65,7 +71,11 @@ mod Store {

#[abi(embed_v0)]
impl FossilStoreImpl of super::IFossilStore<ContractState> {
fn initialize(ref self: ContractState, verifier_address: starknet::ContractAddress, min_update_interval: u64) {
fn initialize(
ref self: ContractState,
verifier_address: starknet::ContractAddress,
min_update_interval: u64,
) {
assert!(!self.initialized.read(), "Contract already initialized");
self.initialized.write(true);
self.verifier_address.write(verifier_address);
Expand Down Expand Up @@ -98,14 +108,25 @@ mod Store {
actual_update_interval >= min_update_interval,
"Update interval: {} must be greater than or equal to the minimum update interval: {}",
actual_update_interval,
min_update_interval
min_update_interval,
);
self.latest_mmr_block.write(journal.latest_mmr_block);
}

let mut curr_state = self.mmr_batches.entry(journal.batch_index);

curr_state.latest_mmr_block.write(journal.latest_mmr_block);

let min_mmr_block = self.min_mmr_block.read();
let lowest_batch_block = journal.latest_mmr_block - journal.leaves_count + 1;
if min_mmr_block != 0 {
if lowest_batch_block < min_mmr_block {
self.min_mmr_block.write(lowest_batch_block);
}
} else {
self.min_mmr_block.write(lowest_batch_block);
}

curr_state.latest_mmr_block_hash.write(journal.latest_mmr_block_hash);
curr_state.leaves_count.write(journal.leaves_count);
curr_state.root_hash.write(journal.root_hash);
Expand All @@ -117,8 +138,8 @@ mod Store {
latest_mmr_block: journal.latest_mmr_block,
latest_mmr_block_hash: journal.latest_mmr_block_hash,
leaves_count: journal.leaves_count,
root_hash: journal.root_hash
}
root_hash: journal.root_hash,
},
);
}

Expand All @@ -136,5 +157,9 @@ mod Store {
fn get_latest_mmr_block(self: @ContractState) -> u64 {
self.latest_mmr_block.read()
}

fn get_min_mmr_block(self: @ContractState) -> u64 {
self.min_mmr_block.read()
}
}
}
8 changes: 6 additions & 2 deletions contracts/starknet/verifier/src/fossil_verifier.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ mod FossilVerifier {

#[external(v0)]
fn verify_mmr_proof(ref self: ContractState, proof: Span<felt252>) -> bool {
let journal = self.bn254_verifier.read().verify_groth16_proof_bn254(proof).expect('Failed to verify proof');
let journal = self
.bn254_verifier
.read()
.verify_groth16_proof_bn254(proof)
.expect('Failed to verify proof');

let journal = decode_journal(journal);

Expand All @@ -59,7 +63,7 @@ mod FossilVerifier {
batch_index: journal.batch_index,
latest_mmr_block: journal.latest_mmr_block,
new_leaves_count: journal.leaves_count,
new_mmr_root: journal.root_hash
new_mmr_root: journal.root_hash,
},
);

Expand Down
8 changes: 4 additions & 4 deletions contracts/starknet/verifier/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub(crate) fn decode_journal(journal_bytes: Span<u8>) -> Journal {
m += 1;
};

Journal { batch_index, latest_mmr_block, latest_mmr_block_hash, root_hash, leaves_count, }
Journal { batch_index, latest_mmr_block, latest_mmr_block_hash, root_hash, leaves_count }
}

trait BitShift<T> {
Expand Down Expand Up @@ -163,7 +163,7 @@ mod tests {
assert_eq!(journal.latest_mmr_block, 7253851);
assert_eq!(
journal.latest_mmr_block_hash,
0x858768dd79b8c6190fb224ff398345ffe4fcb9c4899c55e0fc0994b7d35177af
0x858768dd79b8c6190fb224ff398345ffe4fcb9c4899c55e0fc0994b7d35177af,
);
assert_eq!(
journal.root_hash, 0x72aa9525dc9b7953631c0699d041fd4f23aa9f98c4a73aab27fbf2f0b9b451f8,
Expand Down Expand Up @@ -340,8 +340,8 @@ mod tests {
0,
0,
0,
0
0,
]
.span()
}
}
}
36 changes: 27 additions & 9 deletions crates/publisher/bin/build_mmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ struct Args {
num_batches: Option<u64>,

/// Skip proof verification
#[arg(short, long, default_value_t = false)]
#[arg(short = 'p', long, default_value_t = false)]
skip_proof: bool,

/// Path to environment file (optional)
#[arg(short = 'e', long, default_value = ".env")]
env_file: String,

/// Start building from this block number. If not specified, starts from the latest finalized block.
#[arg(short = 's', long)]
start_block: Option<u64>,

/// Start building from the latest MMR block
#[arg(short = 'l', long, default_value_t = false)]
from_latest: bool,
}

#[tokio::main]
Expand All @@ -40,14 +48,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let private_key = get_env_var("STARKNET_PRIVATE_KEY")?;
let account_address = get_env_var("STARKNET_ACCOUNT_ADDRESS")?;

// Parse CLI arguments
let args = Args::parse();

let starknet_provider = StarknetProvider::new(&rpc_url)?;
let starknet_account =
StarknetAccount::new(starknet_provider.provider(), &private_key, &account_address)?;

let mut builder = AccumulatorBuilder::new(
&rpc_url,
chain_id,
&verifier_address,
&store_address,
Expand All @@ -61,11 +67,23 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
e
})?;

// Build MMR from finalized block to block #0 or up to the specified number of batches
if let Some(num_batches) = args.num_batches {
builder.build_with_num_batches(num_batches).await?;
} else {
builder.build_from_finalized().await?;
// Build MMR from specified start block or finalized block
match (args.from_latest, args.start_block, args.num_batches) {
(true, Some(_), _) => {
return Err("Cannot specify both --from-latest and --start-block".into());
}
(true, None, Some(num_batches)) => {
builder.build_from_latest_with_batches(num_batches).await?
}
(true, None, None) => builder.build_from_latest().await?,
(false, Some(start_block), Some(num_batches)) => {
builder
.build_from_block_with_batches(start_block, num_batches)
.await?
}
(false, Some(start_block), None) => builder.build_from_block(start_block).await?,
(false, None, Some(num_batches)) => builder.build_with_num_batches(num_batches).await?,
(false, None, None) => builder.build_from_finalized().await?,
}

info!("Host finished");
Expand Down
1 change: 1 addition & 0 deletions crates/publisher/src/api/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub async fn prove_mmr_update(
)?;

let mut builder = AccumulatorBuilder::new(
rpc_url,
chain_id,
verifier_address,
store_address,
Expand Down
Loading
Loading