Skip to content

Commit

Permalink
Add prev_hash to soft confirmations (#873)
Browse files Browse the repository at this point in the history
* Add prev_hash to types

* Initialize prev_hash

* Add batch hash type

* Initialize prev_hash in nodes

* Remove pre_state_root

* Completely initialize batch_hash

* Remove pre_state_root

* Handle removal of pre_state_root

* Verify prev_hash

* Remove missed pre_state_root

* Remove redundant clone

* Fix previous_batch asserts

* Add get_soft_batch_by_number

* Only assert prior hash when not genesis

* Pass pre_state around for hooks

* Resolve RPC test

* Pass prev_hash in receipt

* Check prev_hash before applying soft confirmation

* Add prev hash to zk output

* Add type for soft confirmation hash

* Cleanup primitives to prevent cyclic deps

* Remove worker_thread counts

* Fix proving
  • Loading branch information
rakanalh authored Jul 14, 2024
1 parent f634146 commit d4e597b
Show file tree
Hide file tree
Showing 38 changed files with 324 additions and 246 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion bin/citrea/provers/risc0/guest-bitcoin/Cargo.lock

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

51 changes: 27 additions & 24 deletions bin/citrea/src/rollup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {
let mut storage_manager = self.create_storage_manager(&rollup_config)?;
let prover_storage = storage_manager.create_finalized_storage()?;

let prev_root = ledger_db
.get_head_soft_batch()?
.map(|(number, _)| prover_storage.get_root_hash(number.0 + 1))
.transpose()?;

// TODO(https://github.com/Sovereign-Labs/sovereign-sdk/issues/1218)
let rpc_methods =
self.create_rpc_methods(&prover_storage, &ledger_db, &da_service, None)?;
Expand All @@ -56,10 +51,16 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {

let genesis_root = prover_storage.get_root_hash(1);

let init_variant = match prev_root {
Some(root_hash) => InitVariant::Initialized(root_hash),
let prev_data = match ledger_db.get_head_soft_batch()? {
Some((number, soft_batch)) => {
Some((prover_storage.get_root_hash(number.0 + 1)?, soft_batch.hash))
}
None => None,
};
let init_variant = match prev_data {
Some((root_hash, batch_hash)) => InitVariant::Initialized((root_hash, batch_hash)),
None => match genesis_root {
Ok(root_hash) => InitVariant::Initialized(root_hash),
Ok(root_hash) => InitVariant::Initialized((root_hash, [0; 32])),
_ => InitVariant::Genesis(genesis_config),
},
};
Expand Down Expand Up @@ -108,11 +109,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {
let mut storage_manager = self.create_storage_manager(&rollup_config)?;
let prover_storage = storage_manager.create_finalized_storage()?;

let prev_root = ledger_db
.get_head_soft_batch()?
.map(|(number, _)| prover_storage.get_root_hash(number.0 + 1))
.transpose()?;

let runner_config = rollup_config.runner.expect("Runner config is missing");
// TODO(https://github.com/Sovereign-Labs/sovereign-sdk/issues/1218)
let rpc_methods = self.create_rpc_methods(
Expand All @@ -126,10 +122,16 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {

let genesis_root = prover_storage.get_root_hash(1);

let init_variant = match prev_root {
Some(root_hash) => InitVariant::Initialized(root_hash),
let prev_data = match ledger_db.get_head_soft_batch()? {
Some((number, soft_batch)) => {
Some((prover_storage.get_root_hash(number.0 + 1)?, soft_batch.hash))
}
None => None,
};
let init_variant = match prev_data {
Some((root_hash, batch_hash)) => InitVariant::Initialized((root_hash, batch_hash)),
None => match genesis_root {
Ok(root_hash) => InitVariant::Initialized(root_hash),
Ok(root_hash) => InitVariant::Initialized((root_hash, [0; 32])),
_ => InitVariant::Genesis(genesis_config),
},
};
Expand Down Expand Up @@ -185,11 +187,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {
let mut storage_manager = self.create_storage_manager(&rollup_config)?;
let prover_storage = storage_manager.create_finalized_storage()?;

let prev_root = ledger_db
.get_head_soft_batch()?
.map(|(number, _)| prover_storage.get_root_hash(number.0 + 1))
.transpose()?;

let runner_config = rollup_config.runner.expect("Runner config is missing");
// TODO(https://github.com/Sovereign-Labs/sovereign-sdk/issues/1218)
let rpc_methods = self.create_rpc_methods(
Expand All @@ -203,10 +200,16 @@ pub trait CitreaRollupBlueprint: RollupBlueprint {

let genesis_root = prover_storage.get_root_hash(1);

let init_variant = match prev_root {
Some(root_hash) => InitVariant::Initialized(root_hash),
let prev_data = match ledger_db.get_head_soft_batch()? {
Some((number, soft_batch)) => {
Some((prover_storage.get_root_hash(number.0 + 1)?, soft_batch.hash))
}
None => None,
};
let init_variant = match prev_data {
Some((root_hash, batch_hash)) => InitVariant::Initialized((root_hash, batch_hash)),
None => match genesis_root {
Ok(root_hash) => InitVariant::Initialized(root_hash),
Ok(root_hash) => InitVariant::Initialized((root_hash, [0; 32])),
_ => InitVariant::Genesis(genesis_config),
},
};
Expand Down
28 changes: 15 additions & 13 deletions bin/citrea/src/test_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value)
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]),
pre_state_root: vec![],
post_state_root: vec![],
state_root: vec![],
soft_confirmation_signature: vec![],
batch_hash: ::sha2::Sha256::digest(b"batch_receipt").into(),
hash: ::sha2::Sha256::digest(b"batch_receipt").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt").into(),
tx_receipts: vec![
TransactionReceipt::<u32> {
tx_hash: ::sha2::Sha256::digest(b"tx1").into(),
Expand Down Expand Up @@ -168,10 +168,10 @@ fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value)
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]),
pre_state_root: vec![],
post_state_root: vec![],
state_root: vec![],
soft_confirmation_signature: vec![],
batch_hash: ::sha2::Sha256::digest(b"batch_receipt2").into(),
hash: ::sha2::Sha256::digest(b"batch_receipt2").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt2").into(),
tx_receipts: batch2_tx_receipts(),
phantom_data: PhantomData,
pub_key: vec![],
Expand All @@ -183,7 +183,8 @@ fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value)

let batches = vec![
BatchReceipt {
batch_hash: ::sha2::Sha256::digest(b"batch_receipt").into(),
hash: ::sha2::Sha256::digest(b"batch_receipt").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt").into(),
tx_receipts: vec![
TransactionReceipt::<u32> {
tx_hash: ::sha2::Sha256::digest(b"tx1").into(),
Expand All @@ -204,7 +205,8 @@ fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value)
phantom_data: PhantomData,
},
BatchReceipt {
batch_hash: ::sha2::Sha256::digest(b"batch_receipt2").into(),
hash: ::sha2::Sha256::digest(b"batch_receipt2").into(),
prev_hash: ::sha2::Sha256::digest(b"prev_batch_receipt2").into(),
tx_receipts: batch2_tx_receipts(),
phantom_data: PhantomData,
},
Expand Down Expand Up @@ -327,7 +329,7 @@ fn test_get_batches() {
fn test_get_soft_batch() {
// Get the first soft batch by number
let payload = jsonrpc_req!("ledger_getSoftBatchByNumber", [1]);
let expected = jsonrpc_result!({"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1, "txs":["74783120626f6479", "74783220626f6479"],"preStateRoot":"","postStateRoot":"","softConfirmationSignature":"","pubKey":"", "l1FeeRate":0, "timestamp": 0});
let expected = jsonrpc_result!({"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1, "txs":["74783120626f6479", "74783220626f6479"],"prevHash":"0209d4aa08c40ed0fcb2bb6eb276481f2ad045914c3065e13e4f1657e97638b1","stateRoot":"","softConfirmationSignature":"","pubKey":"", "l1FeeRate":0, "timestamp": 0});
regular_test_helper(payload, &expected);

// Get the first soft batch by hash
Expand All @@ -344,7 +346,7 @@ fn test_get_soft_batch() {
.map(|tx_receipt| tx_receipt.body_to_save.unwrap().encode_hex::<String>())
.collect::<Vec<String>>();
let expected = jsonrpc_result!(
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2, "txs": txs, "preStateRoot":"","postStateRoot":"","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0}
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2, "txs": txs, "prevHash":"11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d","stateRoot":"","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0}
);
regular_test_helper(payload, &expected);

Expand All @@ -364,8 +366,8 @@ fn test_get_soft_batch() {
.collect::<Vec<String>>();
let expected = jsonrpc_result!(
[
{"daSlotHeight":0,"daSlotHash":"0000000000000000000000000000000000000000000000000000000000000000","daSlotTxsCommitment":"0101010101010101010101010101010101010101010101010101010101010101","depositData": ["616161616162", "65656565656565656565"],"hash":"b5515a80204963f7db40e98af11aedb49a394b1c7e3d8b5b7a33346b8627444f","l2Height":1,"txs":["74783120626f6479", "74783220626f6479"],"preStateRoot":"","postStateRoot":"","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0},
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2,"txs": txs, "preStateRoot":"","postStateRoot":"","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":"","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0},
{"daSlotHeight":1,"daSlotHash":"0202020202020202020202020202020202020202020202020202020202020202","daSlotTxsCommitment":"0303030303030303030303030303030303030303030303030303030303030303","depositData": ["633434343434"],"hash":"f85fe0cb36fdaeca571c896ed476b49bb3c8eff00d935293a8967e1e9a62071e","l2Height":2,"txs": txs, "prevHash": "11ec8b9896aa1f400cc1dbd1b0ab3dcc97f2025b3d309b70ec249f687a807d1d", "stateRoot":"","softConfirmationSignature":"","pubKey":"","l1FeeRate":0, "timestamp": 0}
]
);
regular_test_helper(payload, &expected);
Expand Down Expand Up @@ -553,7 +555,7 @@ proptest!(
let first_tx_num = curr_tx_num;
let curr_batch = curr_slot_batches.get(batch_index).unwrap();
let last_tx_num = first_tx_num + curr_batch.tx_receipts.len();
let batch_hash = hex::encode(curr_batch.batch_hash);
let batch_hash = hex::encode(curr_batch.hash);
let _batch_receipt= 0;
let tx_hashes: Vec<String> = curr_batch.tx_receipts.iter().map(|tx| {
hex::encode(tx.tx_hash)
Expand Down
6 changes: 3 additions & 3 deletions bin/citrea/tests/e2e/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2355,7 +2355,7 @@ async fn sequencer_crash_restore_mempool() -> Result<(), anyhow::Error> {
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[tokio::test(flavor = "multi_thread")]
async fn test_db_get_proof() {
// citrea::initialize_logging(tracing::Level::INFO);

Expand Down Expand Up @@ -2479,7 +2479,7 @@ async fn test_db_get_proof() {
prover_node_task.abort();
}

#[tokio::test(flavor = "multi_thread", worker_threads = 3)]
#[tokio::test(flavor = "multi_thread")]
async fn full_node_verify_proof_and_store() {
// citrea::initialize_logging(tracing::Level::INFO);

Expand Down Expand Up @@ -3173,7 +3173,7 @@ async fn test_ledger_get_head_soft_batch() {
.unwrap();
assert_eq!(latest_block.header.number.unwrap(), 2);
assert_eq!(
head_soft_batch.post_state_root.as_slice(),
head_soft_batch.state_root.as_slice(),
latest_block.header.state_root.as_slice()
);
assert_eq!(head_soft_batch.l2_height, 2);
Expand Down
14 changes: 2 additions & 12 deletions crates/citrea-stf/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,14 @@ where
data.completeness_proof,
)?;

assert_eq!(
data.initial_state_root.as_ref(),
data.soft_confirmations
.front()
.expect("At least one set of soft confirmations")
.first()
.expect("At least one soft confirmation")
.pre_state_root()
.as_slice(),
"Invalid initial state root"
);

println!("going into apply_soft_confirmations_from_sequencer_commitments");
let (final_state_root, state_diff) = self
.app
.apply_soft_confirmations_from_sequencer_commitments(
data.sequencer_public_key.as_ref(),
data.sequencer_da_public_key.as_ref(),
&data.initial_state_root,
data.initial_batch_hash,
pre_state,
data.da_data,
data.state_transition_witnesses,
Expand All @@ -83,6 +72,7 @@ where
let out: StateTransition<Da::Spec, _> = StateTransition {
initial_state_root: data.initial_state_root,
final_state_root,
initial_batch_hash: data.initial_batch_hash,
validity_condition, // TODO: not sure about what to do with this yet
state_diff,
da_slot_hash: data.da_block_header_of_commitments.hash(),
Expand Down
Loading

0 comments on commit d4e597b

Please sign in to comment.