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

STR-804 Rework L1 access from OL STF #469

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0038b07
chaintsn: started refactoring for epoch-level bookkeeping
delbonis Nov 13, 2024
a6f232b
chaintsn, state: changed exec update handling to use withdrawals queu…
delbonis Nov 14, 2024
1d76049
chaintsn: fixed test
delbonis Nov 14, 2024
e5c14e0
chaintsn, state: split out some state types to epoch-level state
delbonis Nov 14, 2024
c949be3
state: reworked `WriteBatch` related types
delbonis Nov 14, 2024
4b09eae
misc: reworked epoch state relationships some more
delbonis Nov 14, 2024
feb53e3
state: reworked `StateCache` more to remove state ops from system
delbonis Nov 15, 2024
2b62f07
misc: fixed a bunch of compilation issues
delbonis Nov 20, 2024
39265c7
state: fixed overwriting epoch state, fixed broken tests
delbonis Nov 23, 2024
9f745cf
chaintsn: renamed `process_l1_view_update`
delbonis Nov 23, 2024
3e026a3
proof-impl/cl-stf: fix something
delbonis Nov 29, 2024
dfb9e9a
chaintsn: fix broken test
delbonis Nov 29, 2024
2f4e640
misc: fixed a bunch more unit tests
delbonis Nov 29, 2024
be96a5c
state: removing unnecessary `StateOp`s
delbonis Nov 29, 2024
4ed9165
chaintsn, consensus-logic: rework `L1Segment` rules to only be presen…
delbonis Nov 29, 2024
44c5d53
state: fix accessors on block types
delbonis Dec 2, 2024
59edcba
state: fix ZST issue
delbonis Dec 2, 2024
dc54aff
fntest: shortened epoch length, added new `wait_until_checkpoint` uti…
delbonis Dec 3, 2024
ef18a90
misc: cleanups to improve testing
delbonis Dec 9, 2024
e58f189
misc: rework a LOT of types
delbonis Dec 9, 2024
cd6df53
misc: heavy refactoring on status types and finalization code paths
delbonis Dec 10, 2024
71f124d
misc: integrated epoch transition into slot transition, refactored so…
delbonis Dec 11, 2024
62b4e39
status: fixed hot spinning when waiting for new client state
delbonis Dec 12, 2024
14d6c29
status: fixed it a little more
delbonis Dec 12, 2024
9fb5e5c
chaintsn, consensus-logic: fixed slot not advancing past end of secon…
delbonis Dec 13, 2024
ff4adb3
misc: changed a few things to try to address broken things
delbonis Dec 19, 2024
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: 1 addition & 1 deletion bin/prover-client/src/rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl StrataProverClientApiServer for ProverClientRpc {
l2_range: (u64, u64),
) -> RpcResult<Uuid> {
let checkpoint_info = RpcCheckpointInfo {
idx: checkpoint_idx,
epoch: checkpoint_idx,
l1_range,
l2_range,
l2_blockid: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion bin/strata-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ fn do_startup_checks(

// Check that we can connect to bitcoin client and block we believe to be matured in L1 is
// actually present
let safe_l1blockid = last_chain_state.l1_view().safe_block().blkid();
let safe_l1blockid = last_chain_state.epoch_state().safe_l1_blkid();
let block_hash = BlockHash::from_slice(safe_l1blockid.as_ref())?;

match runtime.block_on(bitcoin_client.get_block(&block_hash)) {
Expand Down
75 changes: 45 additions & 30 deletions bin/strata-client/src/rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use bitcoin::{
secp256k1::{PublicKey, XOnlyPublicKey},
Transaction as BTransaction, Txid,
};
use borsh::BorshSerialize;
use futures::TryFutureExt;
use jsonrpsee::core::RpcResult;
use strata_bridge_relay::relayer::RelayerHandle;
Expand Down Expand Up @@ -114,7 +115,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
}

async fn get_l1_status(&self) -> RpcResult<RpcL1Status> {
let l1s = self.status_channel.l1_status();
let l1s = self.status_channel.get_l1_reader_status();
Ok(RpcL1Status::from_l1_status(
l1s,
self.sync_manager.params().rollup().network,
Expand All @@ -141,8 +142,8 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
}

async fn get_client_status(&self) -> RpcResult<RpcClientStatus> {
let sync_state = self.status_channel.sync_state();
let l1_view = self.status_channel.l1_view();
let sync_state = self.status_channel.get_sync_state();
let l1_view = self.status_channel.get_l1_view();

let last_l1 = l1_view.tip_blkid().cloned().unwrap_or_else(|| {
// TODO figure out a better way to do this
Expand All @@ -151,35 +152,43 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
});

// Copy these out of the sync state, if they're there.
let (chain_tip, finalized_blkid) = sync_state
.map(|ss| (*ss.chain_tip_blkid(), *ss.finalized_blkid()))
let (chain_tip, finalized_blkid, finalized_epoch) = sync_state
.map(|ss| {
(
*ss.chain_tip_blkid(),
*ss.finalized_blkid(),
ss.finalized_epoch(),
)
})
.unwrap_or_default();

// FIXME make this load from cache, and put the data we actually want
// here in the client state
// FIXME error handling
let db = self.database.clone();
let slot: u64 = wait_blocking("load_cur_block", move || {
let l2_db = db.l2_db();
l2_db
.get_block_data(chain_tip)
.map(|b| b.map(|b| b.header().blockidx()).unwrap_or(u64::MAX))
.map_err(Error::from)
})
.await?;
let Some(block) = self
.l2_block_manager
.get_block_async(&chain_tip)
.map_err(Error::from)
.await?
else {
// We should never encounter this.
return Err(Error::MissingL2Block(chain_tip).into());
};

let slot: u64 = block.block().header().blockidx();
let epoch = self.status_channel.get_cur_l2_epoch().unwrap_or(0);

Ok(RpcClientStatus {
chain_tip: *chain_tip.as_ref(),
chain_tip_slot: slot,
cur_epoch: epoch,
finalized_blkid: *finalized_blkid.as_ref(),
finalized_epoch,
last_l1_block: *last_l1.as_ref(),
buried_l1_height: l1_view.buried_l1_height(),
})
}

async fn get_recent_block_headers(&self, count: u64) -> RpcResult<Vec<RpcBlockHeader>> {
// FIXME: sync state should have a block number
let sync_state = self.status_channel.sync_state();
let sync_state = self.status_channel.get_sync_state();
let tip_blkid = *sync_state.ok_or(Error::ClientNotStarted)?.chain_tip_blkid();
let db = self.database.clone();

Expand Down Expand Up @@ -210,7 +219,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
}

async fn get_headers_at_idx(&self, idx: u64) -> RpcResult<Option<Vec<RpcBlockHeader>>> {
let sync_state = self.status_channel.sync_state();
let sync_state = self.status_channel.get_sync_state();
let tip_blkid = *sync_state.ok_or(Error::ClientNotStarted)?.chain_tip_blkid();
let db = self.database.clone();

Expand Down Expand Up @@ -343,7 +352,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
async fn get_current_deposits(&self) -> RpcResult<Vec<u32>> {
let deps = self
.status_channel
.deposits_table()
.get_cur_deposits_table()
.ok_or(Error::BeforeGenesis)?;

Ok(deps.get_all_deposits_idxs_iters_iter().collect())
Expand All @@ -352,7 +361,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
async fn get_current_deposit_by_id(&self, deposit_id: u32) -> RpcResult<RpcDepositEntry> {
let deps = self
.status_channel
.deposits_table()
.get_cur_deposits_table()
.ok_or(Error::BeforeGenesis)?;
Ok(deps
.get_deposit(deposit_id)
Expand All @@ -361,12 +370,18 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
}

async fn sync_status(&self) -> RpcResult<RpcSyncStatus> {
let sync_state = self.status_channel.sync_state();
let sync_state = self.status_channel.get_sync_state();
let cur_epoch = self.status_channel.get_cur_l2_epoch().unwrap_or_else(|| {
warn!("cur_epoch unset, using default 0");
0
});
Ok(sync_state
.map(|sync| RpcSyncStatus {
tip_height: sync.chain_tip_height(),
tip_height: sync.tip_height(),
tip_epoch: cur_epoch,
tip_block_id: *sync.chain_tip_blkid(),
finalized_block_id: *sync.finalized_blkid(),
finalized_epoch: sync.finalized_epoch(),
})
.ok_or(Error::ClientNotStarted)?)
}
Expand Down Expand Up @@ -467,7 +482,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {

let deps_table = self
.status_channel
.deposits_table()
.get_cur_deposits_table()
.ok_or(Error::BeforeGenesis)?;

let withdrawal_duties = extract_withdrawal_infos(&deps_table).map(BridgeDuty::from);
Expand All @@ -487,7 +502,7 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
async fn get_active_operator_chain_pubkey_set(&self) -> RpcResult<PublickeyTable> {
let operator_table = self
.status_channel
.operator_table()
.get_cur_operator_table()
.ok_or(Error::BeforeGenesis)?;
let operator_map: BTreeMap<OperatorIdx, PublicKey> = operator_table
.operators()
Expand Down Expand Up @@ -527,20 +542,20 @@ impl<D: Database + Send + Sync + 'static> StrataApiServer for StrataRpcImpl<D> {
}

async fn get_l2_block_status(&self, block_height: u64) -> RpcResult<L2BlockStatus> {
let sync_state = self.status_channel.sync_state();
let l1_view = self.status_channel.l1_view();
let sync_state = self.status_channel.get_sync_state();
let l1_view = self.status_channel.get_l1_view();
if let Some(last_checkpoint) = l1_view.last_finalized_checkpoint() {
if last_checkpoint.batch_info.includes_l2_block(block_height) {
return Ok(L2BlockStatus::Finalized(last_checkpoint.height));
}
}
if let Some(l1_height) = l1_view.get_verified_l1_height(block_height) {
return Ok(L2BlockStatus::Verified(l1_height));
return Ok(L2BlockStatus::Committed(l1_height));
}

if let Some(sync_status) = sync_state {
if block_height < sync_status.chain_tip_height() {
return Ok(L2BlockStatus::Confirmed);
if block_height < sync_status.tip_height() {
return Ok(L2BlockStatus::Accepted);
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/bridge-relay/src/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl RelayerState {
// Otherwise it's better for network health to relay them
// unconditionally.
// TODO make it configurable if we relay or not without chainstate?
if let Some(op_table) = self.status_channel.operator_table() {
if let Some(op_table) = self.status_channel.get_cur_operator_table() {
let sig_res =
strata_primitives::relay::util::verify_bridge_msg_sig(&message, &op_table);

Expand Down
5 changes: 4 additions & 1 deletion crates/btcio/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ pub enum L1StatusUpdate {
IncrementInscriptionCount,
}

#[deprecated(note = "TODO: refactor this to just directly update the fields")]
pub async fn apply_status_updates(st_updates: &[L1StatusUpdate], st_chan: &StatusChannel) {
let mut l1_status = st_chan.l1_status();
// FIXME this should be maintaining the authoritative state internally, updating it, and writing
// it, *not* just reading what we previously wrote from the channel and modifying that
let mut l1_status = st_chan.get_l1_reader_status();
for event in st_updates {
match event {
L1StatusUpdate::CurHeight(height) => l1_status.cur_height = *height,
Expand Down
26 changes: 26 additions & 0 deletions crates/chaintsn/src/clock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Utils for reasoning about chain slots.

use strata_primitives::params::RollupParams;

pub fn get_slot_expected_epoch(slot: u64, params: &RollupParams) -> u64 {
slot / params.target_l2_batch_size as u64
}

pub fn get_epoch_initial_slot(epoch: u64, params: &RollupParams) -> u64 {
epoch * params.target_l2_batch_size
}

pub fn get_epoch_final_slot(epoch: u64, params: &RollupParams) -> u64 {
let epoch_init_slot = get_epoch_initial_slot(epoch, params);
epoch_init_slot + (params.target_l2_batch_size - 1)
Comment on lines +14 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is simpler?

Suggested change
let epoch_init_slot = get_epoch_initial_slot(epoch, params);
epoch_init_slot + (params.target_l2_batch_size - 1)
get_epoch_initial_slot(epoch + 1, params) - 1

}

pub fn is_epoch_init_slot(slot: u64, params: &RollupParams) -> bool {
let epoch = get_slot_expected_epoch(slot, params);
slot == get_epoch_initial_slot(epoch, params)
}

pub fn is_epoch_final_slot(slot: u64, params: &RollupParams) -> bool {
let epoch = get_slot_expected_epoch(slot, params);
slot == get_epoch_final_slot(epoch, params)
}
Loading
Loading