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

Split transition information from BatchInfo to BatchTransition #637

Merged
merged 9 commits into from
Feb 6, 2025
Prev Previous commit
Next Next commit
fixes after rebase
  • Loading branch information
prajwolrg authored and Prajwol Gyawali committed Feb 6, 2025
commit 31b2b3f6b78627932963dfe0fb5c0f372bf07056
4 changes: 2 additions & 2 deletions bin/strata-sequencer-client/src/duty_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ async fn handle_commit_batch_duty<R>(
where
R: StrataSequencerApiClient + Send + Sync,
{
let sig = sign_checkpoint(duty.checkpoint(), &idata.key);
let sig = sign_checkpoint(duty.inner(), &idata.key);

rpc.complete_checkpoint_signature(duty.checkpoint().batch_info().idx(), HexBytes64(sig.0))
rpc.complete_checkpoint_signature(duty.inner().batch_info().epoch(), HexBytes64(sig.0))
.await
.map_err(DutyExecError::CompleteCheckpoint)?;

Expand Down
66 changes: 26 additions & 40 deletions crates/sequencer/src/checkpoint/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use strata_consensus_logic::csm::message::ClientUpdateNotif;
use strata_db::{traits::Database, types::CheckpointEntry};
use strata_primitives::{buf::Buf32, params::Params};
use strata_state::{
batch::{BatchInfo, BootstrapState},
batch::{BatchInfo, BatchTransition, BootstrapState},
client_state::ClientState,
};
use strata_storage::NodeStorage;
Expand Down Expand Up @@ -68,22 +68,23 @@ pub fn checkpoint_worker<D: Database>(
continue;
}

let (batch_info, bootstrap_state) =
let (batch_info, batch_transition, bootstrap_state) =
match get_next_batch(state, storage.as_ref(), rollup_params_commitment) {
Err(error) => {
warn!(?error, "Failed to get next batch");
continue;
}
Ok((b, bs)) => (b, bs),
Ok((b, bt, bs)) => (b, bt, bs),
};

let checkpoint_idx = batch_info.idx();
let checkpoint_idx = batch_info.epoch();
// sanity check
assert!(checkpoint_idx == next_checkpoint_idx);

// else save a pending proof checkpoint entry
debug!("save checkpoint pending proof: {}", checkpoint_idx);
let entry = CheckpointEntry::new_pending_proof(batch_info, bootstrap_state);
let entry =
CheckpointEntry::new_pending_proof(batch_info, batch_transition, bootstrap_state);
if let Err(e) = checkpoint_handle.put_checkpoint_and_notify_blocking(checkpoint_idx, entry)
{
warn!(?e, "Failed to save checkpoint at idx: {}", checkpoint_idx);
Expand All @@ -95,15 +96,15 @@ pub fn checkpoint_worker<D: Database>(
fn get_next_batch_idx(state: &ClientState) -> u64 {
match state.l1_view().last_finalized_checkpoint() {
None => 0,
Some(prev_checkpoint) => prev_checkpoint.batch_info.idx + 1,
Some(prev_checkpoint) => prev_checkpoint.batch_info.epoch + 1,
}
}

fn get_next_batch(
state: &ClientState,
storage: &NodeStorage,
rollup_params_commitment: Buf32,
) -> Result<(BatchInfo, BootstrapState), Error> {
) -> Result<(BatchInfo, BatchTransition, BootstrapState), Error> {
let chsman = storage.chainstate();

if !state.is_chain_active() {
Expand Down Expand Up @@ -166,65 +167,50 @@ fn get_next_batch(
let current_chain_state_root = current_chain_state.compute_state_root();
let l2_transition = (initial_chain_state_root, current_chain_state_root);

let new_batch = BatchInfo::new(
first_checkpoint_idx,
l1_range,
l2_range,
l1_transition,
l2_transition,
tip_id,
(0, current_l1_state.total_accumulated_pow),
rollup_params_commitment,
);
let new_transition =
BatchTransition::new(l1_transition, l2_transition, rollup_params_commitment);

let new_batch = BatchInfo::new(first_checkpoint_idx, l1_range, l2_range, tip_id);

let genesis_bootstrap = new_batch.get_initial_bootstrap_state();
Ok((new_batch, genesis_bootstrap))
let genesis_bootstrap = new_transition.get_initial_bootstrap_state();
Ok((new_batch, new_transition, genesis_bootstrap))
}
Some(prev_checkpoint) => {
let checkpoint = prev_checkpoint.batch_info.clone();
let batch_info = prev_checkpoint.batch_info.clone();
let batch_transition = prev_checkpoint.batch_transition.clone();

let current_l1_state = state
.l1_view()
.tip_verification_state()
.ok_or(Error::ChainInactive)?;
let l1_range = (
checkpoint.l1_range.1 + 1,
batch_info.l1_range.1 + 1,
current_l1_state.last_verified_block_num as u64,
);
let current_l1_state_hash = current_l1_state.compute_hash().unwrap();
let l1_transition = (checkpoint.l1_transition.1, current_l1_state_hash);
let l1_transition = (batch_transition.l1_transition.1, current_l1_state_hash);

// Also, rather than tip heights, we might need to limit the max range a prover will
// be proving
let l2_range = (checkpoint.l2_range.1 + 1, tip_height);
let l2_range = (batch_info.l2_range.1 + 1, tip_height);
let current_chain_state = chsman
.get_toplevel_chainstate_blocking(tip_height)?
.ok_or(Error::MissingIdxChainstate(0))?;
let current_chain_state_root = current_chain_state.compute_state_root();
let l2_transition = (checkpoint.l2_transition.1, current_chain_state_root);

let new_batch = BatchInfo::new(
checkpoint.idx + 1,
l1_range,
l2_range,
l1_transition,
l2_transition,
tip_id,
(
checkpoint.l1_pow_transition.1,
current_l1_state.total_accumulated_pow,
),
rollup_params_commitment,
);
let l2_transition = (batch_transition.l2_transition.1, current_chain_state_root);

let new_batch_info = BatchInfo::new(batch_info.epoch + 1, l1_range, l2_range, tip_id);
let new_transition =
BatchTransition::new(l1_transition, l2_transition, rollup_params_commitment);

// If prev checkpoint was proved, use the bootstrap state of the prev checkpoint
// else create a bootstrap state based on initial info of this batch
let bootstrap_state = if prev_checkpoint.is_proved {
prev_checkpoint.bootstrap_state.clone()
} else {
new_batch.get_initial_bootstrap_state()
new_transition.get_initial_bootstrap_state()
};
Ok((new_batch, bootstrap_state))
Ok((new_batch_info, new_transition, bootstrap_state))
}
}
}
52 changes: 13 additions & 39 deletions crates/sequencer/src/duty/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use std::{collections::HashSet, time};
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};
use strata_primitives::{buf::Buf32, hash::compute_borsh_hash};
use strata_state::{
batch::{BatchInfo, BatchTransition, BootstrapState},
id::L2BlockId,
};
use strata_state::{batch::BatchCheckpoint, id::L2BlockId};

/// Describes when we'll stop working to fulfill a duty.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -44,15 +41,15 @@ impl Duty {
pub fn expiry(&self) -> Expiry {
match self {
Self::SignBlock(_) => Expiry::NextBlock,
Self::CommitBatch(duty) => Expiry::CheckpointIdxFinalized(duty.idx()),
Self::CommitBatch(duty) => Expiry::CheckpointIdxFinalized(duty.0.batch_info().epoch()),
}
}

/// Returns a unique identifier for the duty.
pub fn id(&self) -> Buf32 {
match self {
// We want Batch commitment duty to be unique by the checkpoint idx
Self::CommitBatch(duty) => compute_borsh_hash(&duty.idx()),
Self::CommitBatch(duty) => compute_borsh_hash(&duty.0.batch_info().epoch()),
_ => compute_borsh_hash(self),
}
}
Expand Down Expand Up @@ -99,45 +96,22 @@ impl BlockSigningDuty {
/// When this duty is created, in order to execute the duty, the sequencer looks for corresponding
/// batch proof in the proof db.
#[derive(Clone, Debug, BorshSerialize, Serialize, Deserialize)]
pub struct BatchCheckpointDuty {
/// Checkpoint/batch info
batch_info: BatchInfo,

/// Checkpoint/batch transition which needs to be proven
batch_transition: BatchTransition,

/// Bootstrapping state based on which the `batch_transition` will be verified
bootstrap_state: BootstrapState,
}
pub struct BatchCheckpointDuty(BatchCheckpoint);

impl BatchCheckpointDuty {
pub fn new(
batch_info: BatchInfo,
batch_transition: BatchTransition,
bootstrap_state: BootstrapState,
) -> Self {
Self {
batch_info,
batch_transition,
bootstrap_state,
}
}

/// Gen checkpoint index.
pub fn idx(&self) -> u64 {
self.batch_info.epoch()
}

pub fn batch_info(&self) -> &BatchInfo {
&self.batch_info
/// Creates a new `BatchCheckpointDuty` from a `BatchCheckpoint`.
pub fn new(batch_checkpoint: BatchCheckpoint) -> Self {
Self(batch_checkpoint)
}

pub fn batch_transition(&self) -> &BatchTransition {
&self.batch_transition
/// Consumes `self`, returning the inner `BatchCheckpoint`.
pub fn into_inner(self) -> BatchCheckpoint {
self.0
}

pub fn bootstrap_state(&self) -> &BootstrapState {
&self.bootstrap_state
/// Returns a reference to the inner `BatchCheckpoint`.
pub fn inner(&self) -> &BatchCheckpoint {
&self.0
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/sequencer/src/duty/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn update_tracker(
let latest_finalized_batch = state
.l1_view()
.last_finalized_checkpoint()
.map(|x| x.batch_info.idx());
.map(|x| x.batch_info.epoch());

let tracker_update = StateUpdate::new(
block_idx,
Expand Down