Skip to content

Commit 93df5e1

Browse files
committed
feat: send state transition transaction
1 parent 7ed99d7 commit 93df5e1

5 files changed

Lines changed: 79 additions & 10 deletions

File tree

examples/L2/crates/l2/src/aligned.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use aligned_sdk::{
44
};
55
use alloy::{
66
eips::BlockNumberOrTag,
7+
hex,
78
primitives::Address,
89
providers::{Provider, ProviderBuilder, WsConnect},
910
rpc::types::Filter,
@@ -40,7 +41,7 @@ pub async fn send_proof_to_be_verified_on_aligned(
4041
.expect("Max fee to be retrieved");
4142

4243
let aligned_verification_data =
43-
aligned_sdk::sdk::submit(network, &verification_data, max_fee, wallet, 0.into())
44+
aligned_sdk::sdk::submit(network, &verification_data, max_fee, wallet, nonce.into())
4445
.await
4546
.expect("Proof to be sent");
4647

@@ -54,8 +55,8 @@ pub async fn wait_until_proof_is_aggregated(
5455
proof: &sp1_sdk::SP1ProofWithPublicValues,
5556
vk: &SP1VerifyingKey,
5657
) -> Option<Vec<[u8; 32]>> {
57-
let rpc_url = "";
58-
let ws = WsConnect::new(rpc_url);
58+
let ws_rpc_url = "wss://ethereum-holesky-rpc.publicnode.com";
59+
let ws = WsConnect::new(ws_rpc_url);
5960
let provider = ProviderBuilder::new().on_ws(ws).await.unwrap();
6061

6162
let aligned_proof_agg_address =
@@ -74,19 +75,23 @@ pub async fn wait_until_proof_is_aggregated(
7475
vk: vk.hash_bytes(),
7576
public_inputs: proof.public_values.to_vec(),
7677
};
77-
78+
7879
let mut merkle_path = None;
7980

8081
while let Some(_) = stream.next().await {
81-
merkle_path = aligned_sdk::sdk::aggregation::get_merkle_path_for_proof(
82+
if let Some(merkle_proof) = aligned_sdk::sdk::aggregation::get_merkle_path_for_proof(
8283
network.clone(),
8384
eth_rpc_url.clone(),
8485
beacon_client_url.clone(),
8586
None,
8687
&verification_data,
8788
)
8889
.await
89-
.unwrap();
90+
.unwrap()
91+
{
92+
merkle_path = Some(merkle_proof);
93+
break;
94+
};
9095
}
9196

9297
merkle_path

examples/L2/crates/l2/src/db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ impl DB {
7575
root
7676
}
7777

78+
/// Db genesis state used if a file is not provided
79+
/// Its commitment is: 0x454691b501bc38536f4156a5b7d86502c49d13710d5e5b52b22c563fff4afee0
7880
fn initial_state() -> Vec<UserState> {
7981
vec![
8082
UserState {

examples/L2/crates/l2/src/eth.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use std::str::FromStr;
2+
3+
use alloy::{
4+
network::EthereumWallet, primitives::Address, providers::ProviderBuilder,
5+
rpc::types::TransactionReceipt, signers::local::PrivateKeySigner, sol,
6+
};
7+
8+
sol!(
9+
#[sol(rpc)]
10+
StateTransition,
11+
"abi/StateTransition.json"
12+
);
13+
14+
pub async fn send_state_transition_to_chain(
15+
public_inputs: Vec<u8>,
16+
merkle_proof: Vec<[u8; 32]>,
17+
eth_rpc_url: String,
18+
state_transition_address: String,
19+
private_key: String,
20+
) -> TransactionReceipt {
21+
let rpc_url = eth_rpc_url.parse().expect("RPC URL should be valid");
22+
let signer = PrivateKeySigner::from_str(&private_key)
23+
.expect("Keystore signer should be `cast wallet` compliant");
24+
let wallet = EthereumWallet::from(signer);
25+
26+
let rpc_provider = ProviderBuilder::new().wallet(wallet).on_http(rpc_url);
27+
let state_transition_contract = StateTransition::new(
28+
Address::from_str(&state_transition_address)
29+
.expect("State transition address should be valid"),
30+
rpc_provider,
31+
);
32+
33+
let merkle_proof = merkle_proof.iter().map(|e| e.into()).collect();
34+
35+
let res = state_transition_contract
36+
.updateState(public_inputs.into(), merkle_proof)
37+
.send()
38+
.await
39+
.expect("State transition tx to not revert");
40+
41+
res.get_receipt().await.expect("To get receipt")
42+
}

examples/L2/crates/l2/src/lib.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
use aligned::{send_proof_to_be_verified_on_aligned, wait_until_proof_is_aggregated};
2+
use alloy::hex::hex;
23
use db::{generate_random_transfers, DB};
4+
use eth::send_state_transition_to_chain;
5+
use lambdaworks_crypto::merkle_tree::merkle::MerkleTree;
36
use primitive_types::U256;
47
use sp1_state_transition_program::ProgramOutput;
58
use zk::{prove_state_transition, PROGRAM_ELF};
69

710
mod aligned;
811
mod db;
12+
mod eth;
913
mod zk;
1014

1115
pub async fn start_l2(
@@ -21,11 +25,13 @@ pub async fn start_l2(
2125
let transfers = generate_random_transfers(&db, 10);
2226

2327
// 2. Call zkvm and pass (MerkleTree, Updates to perform)
28+
println!("Staring prover");
2429
let (mut proof, vk) = prove_state_transition(&db, transfers.clone());
2530
let ProgramOutput {
2631
initial_state_merkle_root,
2732
post_state_merkle_root,
2833
} = proof.public_values.read::<ProgramOutput>();
34+
println!("Prover finish");
2935

3036
// 3. If the proving went alright, update the db and verify that the merkle root matches
3137
assert!(db.commitment() == initial_state_merkle_root);
@@ -56,22 +62,37 @@ pub async fn start_l2(
5662
// Once aligned aggregates the proof we will be notified and we'll send the new state commitment on chain
5763

5864
// 4. Send the proof to aligned and wait for verification
65+
println!("Sending proof to aligned batcher");
5966
let _ =
6067
send_proof_to_be_verified_on_aligned(&proof, PROGRAM_ELF.to_vec(), network.clone(), wallet)
6168
.await;
69+
println!("Proof submitted");
6270

71+
println!("Waiting until is proof is aggregated");
6372
// 5. Wait until proof is aggregated
6473
let merkle_path = wait_until_proof_is_aggregated(
6574
network.clone(),
66-
eth_rpc_url,
75+
eth_rpc_url.clone(),
6776
beacon_client_url,
6877
&proof,
6978
&vk,
7079
)
71-
.await;
80+
.await
81+
.expect("To get merkle path in last aggregated proofs");
82+
83+
println!("Proof has been aggregated on aligned, about to send update to chain.");
7284

7385
// 6. Send updateState transaction to Ethereum
74-
// let receipt = update_state_on_chain();
86+
let receipt = send_state_transition_to_chain(
87+
proof.public_values.to_vec(),
88+
merkle_path,
89+
eth_rpc_url.clone(),
90+
"0xdC62Bf47Da2a2afD8Eb838C7004337613Af5C3b9".into(),
91+
"".into(),
92+
)
93+
.await;
94+
95+
println!("State update in contracts tx receipt {:?}", receipt);
7596

7697
// Finally save the db to a file to be retrieved later
7798
db.save().unwrap();

examples/L2/crates/l2/src/zk.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use sp1_sdk::Prover;
21
use types::Transfer;
32

43
use crate::db::DB;

0 commit comments

Comments
 (0)