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 31 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
3 changes: 3 additions & 0 deletions Cargo.lock

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

169 changes: 100 additions & 69 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 All @@ -6,10 +7,10 @@ use sha2::Digest;
use sov_db::ledger_db::{LedgerDB, SharedLedgerOps};
use sov_db::rocks_db_config::RocksdbConfig;
use sov_db::schema::types::StoredTransaction;
use sov_mock_da::MockDaSpec;
#[cfg(test)]
use sov_modules_api::DaSpec;
use sov_rollup_interface::stf::SoftConfirmationReceipt;
use sov_modules_api::L2Block;
use sov_rollup_interface::soft_confirmation::{
SignedSoftConfirmationHeader, SoftConfirmationHeader,
};

struct TestExpect {
payload: serde_json::Value,
Expand Down Expand Up @@ -40,26 +41,14 @@ async fn queries_test_runner(test_queries: Vec<TestExpect>, rpc_config: RpcConfi
}
}

fn populate_ledger(
ledger_db: &mut LedgerDB,
state_root: &[u8],
soft_confirmation_receipts: Vec<SoftConfirmationReceipt<MockDaSpec>>,
tx_bodies: Vec<Vec<Vec<u8>>>,
) {
for (soft_confirmation_receipt, tx_bodies) in
soft_confirmation_receipts.into_iter().zip(tx_bodies)
{
ledger_db
.commit_soft_confirmation(state_root, soft_confirmation_receipt, Some(tx_bodies))
.unwrap();
fn populate_ledger(ledger_db: &mut LedgerDB, l2_blocks: Vec<L2Block<'_, [u8; 32]>>) {
for block in l2_blocks {
let tx_hashes = block.txs.to_vec();
ledger_db.commit_l2_block(block, tx_hashes, true).unwrap();
}
}

fn test_helper(
test_queries: Vec<TestExpect>,
soft_confirmation_receipts: Vec<SoftConfirmationReceipt<MockDaSpec>>,
tx_bodies: Vec<Vec<Vec<u8>>>,
) {
fn test_helper(test_queries: Vec<TestExpect>, l2_blocks: Vec<L2Block<'_, [u8; 32]>>) {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_io()
.enable_time()
Expand All @@ -71,12 +60,7 @@ fn test_helper(
let tmpdir = tempfile::tempdir().unwrap();
let mut ledger_db =
LedgerDB::with_config(&RocksdbConfig::new(tmpdir.path(), None, None)).unwrap();
populate_ledger(
&mut ledger_db,
&[1; 32],
soft_confirmation_receipts,
tx_bodies,
);
populate_ledger(&mut ledger_db, l2_blocks);
let server = jsonrpsee::server::ServerBuilder::default()
.build("127.0.0.1:0")
.await
Expand Down Expand Up @@ -114,52 +98,79 @@ fn batch2_tx_receipts() -> (Vec<StoredTransaction>, Vec<Vec<u8>>) {
fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value) {
let tx_bodies_1 = vec![b"tx1 body".to_vec(), b"tx2 body".to_vec()];
let (batch_2_receipts, tx_bodies_2) = batch2_tx_receipts();
let soft_confirmation_receipts = vec![
SoftConfirmationReceipt {
l2_height: 1,
da_slot_height: 0,
da_slot_hash: <MockDaSpec as DaSpec>::SlotHash::from([0u8; 32]),
da_slot_txs_commitment: <MockDaSpec as DaSpec>::SlotHash::from([1u8; 32]),
soft_confirmation_signature: vec![],
hash: ::sha2::Sha256::digest(b"batch_receipt").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt").into(),
tx_hashes: vec![
::sha2::Sha256::digest(b"tx1").into(),
::sha2::Sha256::digest(b"tx2").into(),
],
pub_key: vec![],
deposit_data: vec![
"aaaaab".as_bytes().to_vec(),
"eeeeeeeeee".as_bytes().to_vec(),
],
l1_fee_rate: 0,
timestamp: 0,
},
SoftConfirmationReceipt {
l2_height: 2,
da_slot_height: 1,
da_slot_hash: <MockDaSpec as DaSpec>::SlotHash::from([2; 32]),
da_slot_txs_commitment: <MockDaSpec as DaSpec>::SlotHash::from([3; 32]),
soft_confirmation_signature: vec![],
hash: ::sha2::Sha256::digest(b"batch_receipt2").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt2").into(),
tx_hashes: batch_2_receipts.iter().map(|r| r.hash).collect(),
pub_key: vec![],
deposit_data: vec!["c44444".as_bytes().to_vec()],
l1_fee_rate: 0,
timestamp: 0,
},

let tx_hashes_1 = vec![
::sha2::Sha256::digest(b"tx1").into(),
::sha2::Sha256::digest(b"tx2").into(),
];

let tx_bodies = vec![tx_bodies_1, tx_bodies_2];
let header1 = SoftConfirmationHeader::new(
1,
0,
[0u8; 32],
[1u8; 32],
::sha2::Sha256::digest(b"prev_batch_receipt").into(),
[1; 32],
0,
compute_tx_merkle_root(&tx_hashes_1).unwrap(),
vec![
"aaaaab".as_bytes().to_vec(),
"eeeeeeeeee".as_bytes().to_vec(),
],
0,
);

let header2 = SoftConfirmationHeader::new(
2,
1,
[2; 32],
[3; 32],
::sha2::Sha256::digest(b"prev_batch_receipt2").into(),
[1; 32],
0,
compute_tx_merkle_root(&batch_2_receipts.iter().map(|r| r.hash).collect::<Vec<_>>())
.unwrap(),
vec!["c44444".as_bytes().to_vec()],
0,
);

let signed_header1 = SignedSoftConfirmationHeader::new(
header1,
::sha2::Sha256::digest(b"batch_receipt").into(),
vec![],
vec![],
);

let signed_header2 = SignedSoftConfirmationHeader::new(
header2,
::sha2::Sha256::digest(b"batch_receipt2").into(),
vec![],
vec![],
);

let l2_blocks = vec![
L2Block::<[u8; 32]>::new(
signed_header1,
tx_bodies_1.clone().into(),
tx_hashes_1.into(),
),
L2Block::<[u8; 32]>::new(
signed_header2,
tx_bodies_2.clone().into(),
batch_2_receipts
.iter()
.map(|r| r.hash)
.collect::<Vec<_>>()
.into(),
),
];

test_helper(
vec![TestExpect {
payload,
expected: expected.clone(),
}],
soft_confirmation_receipts,
tx_bodies,
l2_blocks,
)
}

Expand Down Expand Up @@ -196,7 +207,13 @@ 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 tx_hashes = vec![
::sha2::Sha256::digest(b"tx1").into(),
::sha2::Sha256::digest(b"tx2").into(),
];
let empty_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, "txMerkleRoot": empty_tx_merkle_root});
regular_test_helper(payload, &expected);

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

let tx_hashes = batch2_tx_receipts()
.0
.iter()
.map(|r| r.hash)
.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 +257,17 @@ fn test_get_soft_confirmation() {
.into_iter()
.map(|body| body.encode_hex::<String>())
.collect::<Vec<String>>();

let tx_hashes = batch2_tx_receipts()
.0
.iter()
.map(|r| r.hash)
.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
17 changes: 8 additions & 9 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 @@ -313,7 +313,7 @@ pub(crate) async fn get_batch_proof_circuit_input_from_commitments<
) -> Result<CommitmentStateTransitionData<'txs, Witness, Da, Tx>, anyhow::Error> {
let mut state_transition_witnesses: VecDeque<Vec<(Witness, Witness)>> =
VecDeque::with_capacity(sequencer_commitments.len());
let mut soft_confirmations: VecDeque<Vec<SignedSoftConfirmation<Tx>>> =
let mut committed_l2_blocks: VecDeque<Vec<L2Block<Tx>>> =
VecDeque::with_capacity(sequencer_commitments.len());
let mut da_block_headers_of_soft_confirmations: VecDeque<
Vec<<<Da as DaService>::Spec as DaSpec>::BlockHeader>,
Expand All @@ -337,8 +337,7 @@ pub(crate) async fn get_batch_proof_circuit_input_from_commitments<
));
}
};
let mut commitment_soft_confirmations =
Vec::with_capacity(soft_confirmations_in_commitment.len());
let mut l2_blocks = Vec::with_capacity(soft_confirmations_in_commitment.len());
let mut da_block_headers_to_push: Vec<<<Da as DaService>::Spec as DaSpec>::BlockHeader> =
vec![];
for soft_confirmation in soft_confirmations_in_commitment {
Expand All @@ -363,12 +362,12 @@ 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 l2_block: L2Block<Tx> = soft_confirmation
.try_into()
.context("Failed to parse transactions")?;
commitment_soft_confirmations.push(signed_soft_confirmation);
l2_blocks.push(l2_block);
}
soft_confirmations.push_back(commitment_soft_confirmations);
committed_l2_blocks.push_back(l2_blocks);

da_block_headers_of_soft_confirmations.push_back(da_block_headers_to_push);
for l2_height in
Expand All @@ -387,7 +386,7 @@ pub(crate) async fn get_batch_proof_circuit_input_from_commitments<
}
Ok((
state_transition_witnesses,
soft_confirmations,
committed_l2_blocks,
da_block_headers_of_soft_confirmations,
))
}
Expand Down
4 changes: 3 additions & 1 deletion crates/batch-prover/src/db_migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::sync::OnceLock;

use citrea_common::db_migrations::{
MigrateBatchAndSlotByNumber, MigrateVerifiedProofsBySlotNumber, RemoveUnusedTables,
MigrateBatchAndSlotByNumber, MigrateSoftConfirmationTxMerkleRoot,
MigrateVerifiedProofsBySlotNumber, RemoveUnusedTables,
};
use sov_db::ledger_db::migrations::LedgerMigration;
use sov_db::schema::tables::BATCH_PROVER_LEDGER_TABLES;
Expand All @@ -16,6 +17,7 @@ pub fn migrations() -> &'static Vec<Box<dyn LedgerMigration + Send + Sync + 'sta
Box::new(RemoveUnusedTables {
tables: BATCH_PROVER_LEDGER_TABLES,
}),
Box::new(MigrateSoftConfirmationTxMerkleRoot),
]
})
}
5 changes: 1 addition & 4 deletions crates/batch-prover/src/proving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,7 @@ pub(crate) fn save_commitments<DB>(
let l2_end_height = sequencer_commitment.l2_end_block_number;
for i in l2_start_height..=l2_end_height {
ledger_db
.put_soft_confirmation_status(
SoftConfirmationNumber(i),
SoftConfirmationStatus::Proven,
)
.put_l2_block_status(SoftConfirmationNumber(i), SoftConfirmationStatus::Proven)
.unwrap_or_else(|_| {
panic!(
"Failed to put soft confirmation status in the ledger db {}",
Expand Down
Loading
Loading