|
1 | | -use aligned::{send_proof_to_be_verified_on_aligned, wait_until_proof_is_aggregated}; |
2 | | -use db::{generate_random_transfers, DB}; |
3 | | -use eth::send_state_transition_to_chain; |
4 | | -use primitive_types::U256; |
5 | | -use prover::{prove_state_transition, PROGRAM_ELF}; |
6 | | -use sp1_state_transition_program::ProgramOutput; |
7 | | -use tracing::info; |
8 | | - |
9 | 1 | mod aligned; |
| 2 | +pub mod config; |
10 | 3 | mod db; |
11 | 4 | mod eth; |
| 5 | +pub mod l2; |
12 | 6 | mod prover; |
13 | | - |
14 | | -pub struct Config { |
15 | | - pub network: aligned_sdk::common::types::Network, |
16 | | - pub eth_rpc_url: String, |
17 | | - pub ws_eth_rpc_url: String, |
18 | | - pub beacon_client_url: String, |
19 | | - pub private_key_store_path: String, |
20 | | - pub private_key_store_password: String, |
21 | | - pub state_transition_contract_address: String, |
22 | | -} |
23 | | - |
24 | | -pub async fn start_l2(config: Config) { |
25 | | - // 0. Load merkle tree file, if not created, create initial state |
26 | | - let mut db = DB::new("./db".to_string()); |
27 | | - |
28 | | - loop { |
29 | | - // 1. Create random transfers |
30 | | - let transfers = generate_random_transfers(&db, 10); |
31 | | - |
32 | | - // 2. Call zkvm and transfer to perform and verify |
33 | | - info!("Starting prover..."); |
34 | | - let (mut proof, vk) = prove_state_transition(&db, transfers.clone()); |
35 | | - let ProgramOutput { |
36 | | - initial_state_merkle_root, |
37 | | - post_state_merkle_root, |
38 | | - } = proof.public_values.read::<ProgramOutput>(); |
39 | | - info!("Prover finish"); |
40 | | - |
41 | | - // 3. If the proving went alright, update the db and verify that the merkle root matches |
42 | | - assert!(db.commitment() == initial_state_merkle_root); |
43 | | - // Note: we don't have to verify that the user has enough balance, as the prover already validates it |
44 | | - for transfer in transfers { |
45 | | - let mut user_from = db |
46 | | - .user_states |
47 | | - .get(&transfer.from) |
48 | | - .expect("User must exist in state") |
49 | | - .clone(); |
50 | | - |
51 | | - let mut user_to = db |
52 | | - .user_states |
53 | | - .get(&transfer.to) |
54 | | - .expect("User must exist in state") |
55 | | - .clone(); |
56 | | - |
57 | | - user_from.balance -= transfer.amount; |
58 | | - user_from.nonce += U256::one(); |
59 | | - user_to.balance += transfer.amount; |
60 | | - |
61 | | - db.user_states.insert(transfer.from, user_from); |
62 | | - db.user_states.insert(transfer.to, user_to); |
63 | | - } |
64 | | - assert!(db.commitment() == post_state_merkle_root); |
65 | | - |
66 | | - // Fow now, in order for a proof to be aggregated, we first need to submit it via the fast mode or verification layer |
67 | | - // Let's suppose that our L2 would run the prover once every 24hs and submit it on aligned |
68 | | - // Once aligned aggregates the proof we will be notified and we'll send the new state commitment on chain |
69 | | - |
70 | | - // 4. Send the proof to aligned and wait for verification |
71 | | - info!("Sending proof to aligned batcher..."); |
72 | | - let _ = send_proof_to_be_verified_on_aligned(&config, &proof, PROGRAM_ELF.to_vec()).await; |
73 | | - info!("Proof submitted"); |
74 | | - |
75 | | - // 5. Wait until proof is aggregated |
76 | | - info!("Waiting until proof is aggregated..."); |
77 | | - let merkle_path = wait_until_proof_is_aggregated(&config, &proof, &vk).await; |
78 | | - info!("Proof has been aggregated on aligned, about to send update to chain..."); |
79 | | - |
80 | | - // 6. Send updateState transaction to Ethereum |
81 | | - let receipt = |
82 | | - send_state_transition_to_chain(&config, proof.public_values.to_vec(), merkle_path) |
83 | | - .await; |
84 | | - |
85 | | - info!( |
86 | | - "State update in contracts tx hash: {:?}", |
87 | | - receipt.transaction_hash |
88 | | - ); |
89 | | - |
90 | | - // 7. Finally save the db to a file to be retrieved later |
91 | | - db.save().unwrap(); |
92 | | - } |
93 | | -} |
0 commit comments