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

L2Block #1825

Open
wants to merge 46 commits into
base: nightly
Choose a base branch
from
Open

L2Block #1825

Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
087ceeb
L2Block and header
jfldde Feb 5, 2025
7dfd6f5
Tx merkle root
jfldde Feb 5, 2025
fe1df49
Cleanup end_soft_confirmation
jfldde Feb 6, 2025
635b30b
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 6, 2025
173b189
Merge branch 'nightly' into new-block-format
jfldde Feb 7, 2025
56dcb4c
Single merkle root calc
jfldde Feb 7, 2025
f180cc8
Extract signature validation and lower produce_l2_block complexity
jfldde Feb 7, 2025
57dcf3c
Add state root to header
jfldde Feb 8, 2025
99bb171
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 8, 2025
5ef974e
Lint
jfldde Feb 8, 2025
0fa0a78
Relint
jfldde Feb 8, 2025
caa9dbe
Update soft_confirmation test with additional tx_merkle_root field
jfldde Feb 8, 2025
799f512
Merge branch 'nightly' into new-block-format
jfldde Feb 9, 2025
bc298a6
Restore hashing to_be_bytes
jfldde Feb 10, 2025
e2c01c8
Clearer if let Err pattern
jfldde Feb 10, 2025
b6545cf
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 10, 2025
88bfea8
Make txs and blobs public members
rakanalh Feb 10, 2025
d7ac592
Rename signed_soft_confirmation to l2_block
rakanalh Feb 10, 2025
d3e1be7
Rename commit_soft_confirmation to commit_l2_block
rakanalh Feb 10, 2025
c806fe2
More renaming
rakanalh Feb 10, 2025
ff286a9
MOAR
rakanalh Feb 10, 2025
1ed833f
Merge remote-tracking branch 'origin/nightly' into new-block-format
rakanalh Feb 10, 2025
fcd9a33
Commit l2_block state root as array
jfldde Feb 10, 2025
457c32e
Fix merge
jfldde Feb 10, 2025
8d4875e
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 10, 2025
cd49308
Share MigrateSoftConfirmationTxMerkleRoot
jfldde Feb 10, 2025
f6e8dce
Define and use EMPTY_TX_ROOT
jfldde Feb 10, 2025
24b72e7
Remove SoftConfirmationReceipt
jfldde Feb 10, 2025
3ca91ec
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 10, 2025
1cb41f1
Ugly fix for ci
jfldde Feb 10, 2025
619627e
Cleanup
jfldde Feb 11, 2025
d158ab1
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 11, 2025
26621e7
Remove unused methods
jfldde Feb 11, 2025
e8140e8
Rename
jfldde Feb 11, 2025
50bb893
Consistent naming when obvious
jfldde Feb 11, 2025
504c40e
Merge branch 'nightly' of https://github.com/chainwayxyz/citrea into …
jfldde Feb 12, 2025
5dd57ac
Remove blobs in L2block
jfldde Feb 12, 2025
5411610
Merge branch 'nightly' into new-block-format
jfldde Feb 12, 2025
617dd9b
Lint
jfldde Feb 12, 2025
2ecb779
Restrict compute_blobs visibility
jfldde Feb 12, 2025
54f6e11
Fix test
jfldde Feb 12, 2025
db8f8c0
Rename
jfldde Feb 12, 2025
e18e886
Merge branch 'nightly' into new-block-format
jfldde Feb 12, 2025
01d5357
Verify tx_merkle_root
jfldde Feb 12, 2025
9f5bee6
Use primitives instead
jfldde Feb 12, 2025
d4ca07e
Merge branch 'nightly' into new-block-format
jfldde Feb 12, 2025
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: 2 additions & 0 deletions Cargo.lock

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

32 changes: 27 additions & 5 deletions bin/citrea/src/test_rpc.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use citrea_common::utils::compute_tx_merkle_root;
#[cfg(test)]
use citrea_common::RpcConfig;
use hex::ToHex;
Expand Down Expand Up @@ -50,7 +51,12 @@ fn populate_ledger(
soft_confirmation_receipts.into_iter().zip(tx_bodies)
{
ledger_db
.commit_soft_confirmation(state_root, soft_confirmation_receipt, Some(tx_bodies))
.commit_soft_confirmation(
rakanalh marked this conversation as resolved.
Show resolved Hide resolved
state_root,
soft_confirmation_receipt,
Some(tx_bodies),
[0u8; 32],
)
.unwrap();
}
}
Expand Down Expand Up @@ -196,7 +202,9 @@ macro_rules! jsonrpc_result {
fn test_get_soft_confirmation() {
// Get the first soft confirmation by number
let payload = jsonrpc_req!("ledger_getSoftConfirmationByNumber", [1]);
let expected = jsonrpc_result!({"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1, "txs":["74783120626f6479", "74783220626f6479"],"prevHash":"0209d4aa08c40ed0fcb2bb6eb276481f2ad045914c3065e13e4f1657e97638b1","stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"", "l1FeeRate":0, "timestamp": 0});

let empty_tx_merkle_root = compute_tx_merkle_root(&[]).unwrap();
let expected = jsonrpc_result!({"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1, "txs":["74783120626f6479", "74783220626f6479"],"prevHash":"0209d4aa08c40ed0fcb2bb6eb276481f2ad045914c3065e13e4f1657e97638b1","stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"", "l1FeeRate":0, "timestamp": 0, "txMerkleRoot": empty_tx_merkle_root});
regular_test_helper(payload, &expected);

// Get the first soft confirmation by hash
Expand All @@ -213,8 +221,15 @@ fn test_get_soft_confirmation() {
.into_iter()
.map(|body| body.encode_hex::<String>())
.collect::<Vec<String>>();

let tx_hashes = batch2_tx_receipts()
.1
.into_iter()
.flat_map(|tx| tx.try_into().ok())
.collect::<Vec<_>>();
let tx_merkle_root = compute_tx_merkle_root(&tx_hashes).unwrap();
let expected = jsonrpc_result!(
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2, "txs": txs, "prevHash":"11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d","stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0}
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2, "txs": txs, "prevHash":"11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d","stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0, "txMerkleRoot": tx_merkle_root}
);
regular_test_helper(payload, &expected);

Expand All @@ -233,10 +248,17 @@ fn test_get_soft_confirmation() {
.into_iter()
.map(|body| body.encode_hex::<String>())
.collect::<Vec<String>>();

let tx_hashes = batch2_tx_receipts()
.1
.into_iter()
.flat_map(|tx| tx.try_into().ok())
.collect::<Vec<_>>();
let tx_merkle_root = compute_tx_merkle_root(&tx_hashes).unwrap();
let expected = jsonrpc_result!(
[
{"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1,"txs":["74783120626f6479", "74783220626f6479"],"prevHash":"0209d4aa08c40ed0fcb2bb6eb276481f2ad045914c3065e13e4f1657e97638b1", "stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0},
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2,"txs": txs, "prevHash": "11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d", "stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0}
{"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1,"txs":["74783120626f6479", "74783220626f6479"],"prevHash":"0209d4aa08c40ed0fcb2bb6eb276481f2ad045914c3065e13e4f1657e97638b1", "stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0, "txMerkleRoot": empty_tx_merkle_root},
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2,"txs": txs, "prevHash": "11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d", "stateRoot":"0101010101010101010101010101010101010101010101010101010101010101","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0, "txMerkleRoot": tx_merkle_root}
]
);
regular_test_helper(payload, &expected);
Expand Down
8 changes: 4 additions & 4 deletions crates/batch-prover/src/da_block_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use sov_db::schema::types::{SlotNumber, SoftConfirmationNumber};
use sov_modules_api::{DaSpec, StateDiff, Zkvm};
use sov_rollup_interface::da::{BlockHeaderTrait, SequencerCommitment};
use sov_rollup_interface::services::da::{DaService, SlotData};
use sov_rollup_interface::soft_confirmation::SignedSoftConfirmation;
use sov_rollup_interface::soft_confirmation::L2Block;
use sov_rollup_interface::spec::SpecId;
use sov_rollup_interface::zk::ZkvmHost;
use tokio::select;
Expand All @@ -36,7 +36,7 @@ use crate::proving::{data_to_prove, extract_and_store_proof, prove_l1, GroupComm

type CommitmentStateTransitionData<'txs, Witness, Da, Tx> = (
VecDeque<Vec<(Witness, Witness)>>,
VecDeque<Vec<SignedSoftConfirmation<'txs, Tx>>>,
VecDeque<Vec<L2Block<'txs, Tx>>>,
VecDeque<Vec<<<Da as DaService>::Spec as DaSpec>::BlockHeader>>,
);

Expand Down Expand Up @@ -312,7 +312,7 @@ pub(crate) async fn get_batch_proof_circuit_input_from_commitments<
l1_block_cache: &Arc<Mutex<L1BlockCache<Da>>>,
) -> Result<CommitmentStateTransitionData<'txs, Witness, Da, Tx>, anyhow::Error> {
let mut state_transition_witnesses: VecDeque<Vec<(Witness, Witness)>> = VecDeque::new();
let mut soft_confirmations: VecDeque<Vec<SignedSoftConfirmation<Tx>>> = VecDeque::new();
let mut soft_confirmations: VecDeque<Vec<L2Block<'txs, Tx>>> = VecDeque::new();
let mut da_block_headers_of_soft_confirmations: VecDeque<
Vec<<<Da as DaService>::Spec as DaSpec>::BlockHeader>,
> = VecDeque::new();
Expand Down Expand Up @@ -357,7 +357,7 @@ pub(crate) async fn get_batch_proof_circuit_input_from_commitments<
};
da_block_headers_to_push.push(filtered_block.header().clone());
}
let signed_soft_confirmation: SignedSoftConfirmation<Tx> = soft_confirmation
let signed_soft_confirmation: L2Block<Tx> = soft_confirmation
.try_into()
.context("Failed to parse transactions")?;
commitment_soft_confirmations.push(signed_soft_confirmation);
Expand Down
25 changes: 14 additions & 11 deletions crates/batch-prover/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use backoff::exponential::ExponentialBackoffBuilder;
use backoff::future::retry as retry_backoff;
use citrea_common::cache::L1BlockCache;
use citrea_common::da::get_da_block_at_height;
use citrea_common::utils::soft_confirmation_to_receipt;
use citrea_common::utils::{compute_tx_hashes, soft_confirmation_to_receipt};
use citrea_common::{InitParams, RollupPublicKeys, RunnerConfig};
use citrea_primitives::types::SoftConfirmationHash;
use jsonrpsee::core::client::Error as JsonrpseeError;
use jsonrpsee::http_client::{HttpClient, HttpClientBuilder};
use sov_db::ledger_db::BatchProverLedgerOps;
use sov_db::schema::types::{SlotNumber, SoftConfirmationNumber};
use sov_ledger_rpc::LedgerRpcClient;
use sov_modules_api::{Context, SignedSoftConfirmation, SlotData, Spec};
use sov_modules_api::{Context, L2Block, SlotData, Spec};
use sov_modules_stf_blueprint::{Runtime, StfBlueprint};
use sov_prover_storage_manager::{ProverStorage, ProverStorageManager, SnapshotManager};
use sov_rollup_interface::da::BlockHeaderTrait;
Expand Down Expand Up @@ -208,11 +208,10 @@ where
.storage_manager
.create_storage_on_l2_height(l2_height)?;

let mut signed_soft_confirmation: SignedSoftConfirmation<StfTransaction<C, Da::Spec, RT>> =
soft_confirmation
.clone()
.try_into()
.context("Failed to parse transactions")?;
let mut l2_block: L2Block<StfTransaction<C, Da::Spec, RT>> = soft_confirmation
.clone()
.try_into()
.context("Failed to parse transactions")?;
// Register this new block with the fork manager to active
// the new fork on the next block
self.fork_manager.register_block(l2_height)?;
Expand All @@ -226,9 +225,9 @@ where
Default::default(),
Default::default(),
current_l1_block.header(),
&mut signed_soft_confirmation,
&mut l2_block,
)?;
let txs_bodies = signed_soft_confirmation.blobs().to_owned();
let txs_bodies = l2_block.blobs().to_owned();

let next_state_root = soft_confirmation_result.state_root_transition.final_root;
// Check if post state root is the same as the one in the soft confirmation
Expand All @@ -254,13 +253,17 @@ where

self.storage_manager.finalize_l2(l2_height)?;

let receipt =
soft_confirmation_to_receipt::<C, _, Da::Spec>(signed_soft_confirmation, current_spec);
let tx_hashes =
compute_tx_hashes::<C, _, Da::Spec>(l2_block.txs(), l2_block.blobs(), current_spec);

let merkle_root = l2_block.tx_merkle_root();
let receipt = soft_confirmation_to_receipt::<C, _, Da::Spec>(l2_block, tx_hashes);

self.ledger_db.commit_soft_confirmation(
next_state_root.as_ref(),
receipt,
Some(txs_bodies),
merkle_root,
)?;

self.ledger_db.extend_l2_range_of_l1_slot(
Expand Down
1 change: 1 addition & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ hyper = { workspace = true }
jsonrpsee = { workspace = true, features = ["http-client", "server"] }
lru = { workspace = true }
metrics = { workspace = true }
rs_merkle = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
Expand Down
38 changes: 27 additions & 11 deletions crates/common/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::collections::{HashMap, HashSet};

use anyhow::Context as _;
use rs_merkle::algorithms::Sha256;
use rs_merkle::MerkleTree;
use sov_db::ledger_db::SharedLedgerOps;
use sov_db::schema::types::SoftConfirmationNumber;
use sov_modules_api::{Context, Spec};
use sov_rollup_interface::da::{DaSpec, SequencerCommitment};
use sov_rollup_interface::digest::Digest;
use sov_rollup_interface::rpc::SoftConfirmationStatus;
use sov_rollup_interface::soft_confirmation::SignedSoftConfirmation;
use sov_rollup_interface::soft_confirmation::L2Block;
use sov_rollup_interface::spec::SpecId;
use sov_rollup_interface::stf::{SoftConfirmationReceipt, StateDiff, TransactionDigest};

Expand Down Expand Up @@ -84,24 +87,27 @@ pub fn check_l2_range_exists<DB: SharedLedgerOps>(
false
}

pub fn soft_confirmation_to_receipt<C: Context, Tx: TransactionDigest + Clone, DS: DaSpec>(
soft_confirmation: SignedSoftConfirmation<'_, Tx>,
pub fn compute_tx_hashes<C: Context, Tx: TransactionDigest + Clone, DS: DaSpec>(
txs: &[Tx],
blobs: &[Vec<u8>],
current_spec: SpecId,
) -> SoftConfirmationReceipt<DS> {
let tx_hashes = if current_spec >= SpecId::Kumquat {
soft_confirmation
.txs()
.iter()
) -> Vec<[u8; 32]> {
if current_spec >= SpecId::Kumquat {
txs.iter()
.map(|tx| tx.compute_digest::<<C as Spec>::Hasher>().into())
.collect()
} else {
soft_confirmation
.blobs()
blobs
.iter()
.map(|raw_tx| <C as Spec>::Hasher::digest(raw_tx).into())
.collect()
};
}
}

pub fn soft_confirmation_to_receipt<C: Context, Tx: TransactionDigest + Clone, DS: DaSpec>(
soft_confirmation: L2Block<Tx>,
tx_hashes: Vec<[u8; 32]>,
) -> SoftConfirmationReceipt<DS> {
SoftConfirmationReceipt {
l2_height: soft_confirmation.l2_height(),
hash: soft_confirmation.hash(),
Expand All @@ -117,3 +123,13 @@ pub fn soft_confirmation_to_receipt<C: Context, Tx: TransactionDigest + Clone, D
pub_key: soft_confirmation.pub_key().to_vec(),
}
}

pub fn compute_tx_merkle_root(tx_hashes: &[[u8; 32]]) -> anyhow::Result<[u8; 32]> {
if tx_hashes.is_empty() {
return Ok([0u8; 32]);
}
jfldde marked this conversation as resolved.
Show resolved Hide resolved

MerkleTree::<Sha256>::from_leaves(tx_hashes)
.root()
.context("Couldn't compute merkle root")
}
1 change: 1 addition & 0 deletions crates/fullnode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jsonrpsee = { workspace = true }
metrics = { workspace = true }
metrics-derive = { workspace = true }
once_cell = { workspace = true, default-features = true }
rocksdb = { workspace = true }
rs_merkle = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
Expand Down
3 changes: 3 additions & 0 deletions crates/fullnode/src/db_migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::OnceLock;

use soft_confirmation_tx_merkle_root::MigrateSoftConfirmationTxMerkleRoot;
use sov_db::ledger_db::migrations::LedgerMigration;

use crate::db_migrations::batch_and_slot_by_number::MigrateBatchAndSlotByNumber;
Expand All @@ -9,6 +10,7 @@ use crate::db_migrations::verified_proofs::MigrateVerifiedProofsBySlotNumber;

mod batch_and_slot_by_number;
mod remove_unused_common_tables;
mod soft_confirmation_tx_merkle_root;
mod verified_batch_proof_encoding;
mod verified_proofs;

Expand All @@ -21,6 +23,7 @@ pub fn migrations() -> &'static Vec<Box<dyn LedgerMigration + Send + Sync + 'sta
Box::new(MigrateBatchAndSlotByNumber {}),
Box::new(RemoveUnusedTables {}),
Box::new(FixVerifiedBatchProofsEncoding {}),
Box::new(MigrateSoftConfirmationTxMerkleRoot),
]
})
}
Loading