Skip to content

Commit

Permalink
implement v2 execution api
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanoroshiba committed Feb 27, 2025
1 parent 063c832 commit 959e08f
Show file tree
Hide file tree
Showing 27 changed files with 1,717 additions and 4,505 deletions.
12 changes: 7 additions & 5 deletions crates/astria-auctioneer/src/block/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Proposed {
#[derive(Debug, Clone)]
pub(crate) struct Executed {
/// The rollup block metadata that resulted from executing a proposed Sequencer block.
block: execution::v1::Block,
block_metadata: execution::v2::ExecutedBlockMetadata,
/// The hash of the sequencer block that was executed optimistically.
sequencer_block_hash: block::Hash,
}
Expand All @@ -106,8 +106,9 @@ impl Executed {
pub(crate) fn try_from_raw(
raw: optimistic_execution::ExecuteOptimisticBlockStreamResponse,
) -> eyre::Result<Self> {
let block = if let Some(raw_block) = raw.block {
execution::v1::Block::try_from_raw(raw_block).wrap_err("invalid rollup block")?
let block_metadata = if let Some(raw_block_metadata) = raw.block {
execution::v2::ExecutedBlockMetadata::try_from_raw(raw_block_metadata)
.wrap_err("invalid rollup block")?
} else {
return Err(eyre!("missing block"));
};
Expand All @@ -119,7 +120,7 @@ impl Executed {
.wrap_err("invalid block hash")?;

Ok(Self {
block,
block_metadata,
sequencer_block_hash,
})
}
Expand All @@ -129,6 +130,7 @@ impl Executed {
}

pub(crate) fn rollup_block_hash(&self) -> RollupBlockHash {
RollupBlockHash::new(self.block.hash().clone())
let bytes = self.block_metadata.hash().to_string().into_bytes().into();
RollupBlockHash::new(bytes)
}
}
45 changes: 21 additions & 24 deletions crates/astria-conductor/src/celestia/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,18 +275,18 @@ struct RunningReader {
/// The next Celestia height that will be fetched.
celestia_next_height: u64,

/// The reference Celestia height. `celestia_reference_height` + `celestia_variance` = C is the
/// maximum Celestia height up to which Celestia's blobs will be fetched.
/// `celestia_reference_height` is initialized to the base Celestia height stored in the
/// rollup genesis. It is later advanced to that Celestia height from which the next block
/// is derived that will be executed against the rollup (only if greater than the current
/// value; it will never go down).
/// The reference Celestia height. `celestia_reference_height` +
/// `celestia_search_height_max_look_ahead` = C is the maximum Celestia height up to which
/// Celestia's blobs will be fetched. `celestia_reference_height` is initialized to the
/// base Celestia height stored in the rollup state. It is later advanced to that Celestia
/// height from which the next block is derived that will be executed against the rollup
/// (only if greater than the current value; it will never go down).
celestia_reference_height: u64,

/// `celestia_variance` + `celestia_reference_height` define the maximum Celestia height from
/// Celestia blobs can be fetched. Set once during initialization to the value stored in
/// the rollup genesis.
celestia_variance: u64,
/// `celestia_search_height_max_look_ahead` + `celestia_reference_height` define the maximum
/// Celestia height from Celestia blobs that can be fetched. Set once during initialization
/// to the value stored in the rollup state.
celestia_search_height_max_look_ahead: u64,

/// The rollup ID of the rollup that conductor is driving. Set once during initialization to
/// the value stored in the
Expand Down Expand Up @@ -332,9 +332,10 @@ impl RunningReader {
let sequencer_namespace =
astria_core::celestia::namespace_v0_from_sha256_of_bytes(sequencer_chain_id.as_bytes());

let celestia_next_height = rollup_state.celestia_base_block_height();
let celestia_reference_height = rollup_state.celestia_base_block_height();
let celestia_variance = rollup_state.celestia_block_variance();
let celestia_next_height = rollup_state.lowest_celestia_search_height();
let celestia_reference_height = rollup_state.lowest_celestia_search_height();
let celestia_search_height_max_look_ahead =
rollup_state.celestia_search_height_max_look_ahead();

Ok(Self {
block_cache,
Expand All @@ -353,7 +354,7 @@ impl RunningReader {
celestia_head_height: None,
celestia_next_height,
celestia_reference_height,
celestia_variance,
celestia_search_height_max_look_ahead,

rollup_id,
rollup_namespace,
Expand All @@ -368,7 +369,7 @@ impl RunningReader {
info!(
initial_celestia_height = self.celestia_next_height,
initial_max_celestia_height = self.max_permitted_celestia_height(),
celestia_variance = self.celestia_variance,
celestia_search_height_max_look_ahead = self.celestia_search_height_max_look_ahead,
rollup_namespace = %base64(&self.rollup_namespace.as_bytes()),
rollup_id = %self.rollup_id,
sequencer_chain_id = %self.sequencer_chain_id,
Expand Down Expand Up @@ -544,14 +545,14 @@ impl RunningReader {

/// Returns the maximum permitted Celestia height given the current state.
///
/// The maximum permitted Celestia height is calculated as `ref_height + 6 * variance`, with:
/// The maximum permitted Celestia height is calculated as `ref_height +
/// celestia_search_height_max_look_ahead`, with:
///
/// - `ref_height` the height from which the last expected sequencer block was derived,
/// - `variance` the `celestia_block_variance` received from the connected rollup genesis info,
/// - and the factor 6 based on the assumption that there are up to 6 sequencer heights stored
/// per Celestia height.
/// - `celestia_search_height_max_look_ahead` received from the current rollup state,
fn max_permitted_celestia_height(&self) -> u64 {
max_permitted_celestia_height(self.celestia_reference_height, self.celestia_variance)
self.celestia_reference_height
.saturating_add(self.celestia_search_height_max_look_ahead)
}

fn record_latest_celestia_height(&mut self, height: u64) {
Expand Down Expand Up @@ -706,10 +707,6 @@ async fn get_sequencer_chain_id(client: SequencerClient) -> eyre::Result<tenderm
Ok(genesis.chain_id)
}

fn max_permitted_celestia_height(reference: u64, variance: u64) -> u64 {
reference.saturating_add(variance.saturating_mul(6))
}

#[instrument(skip_all)]
fn report_exit(exit_reason: eyre::Result<&str>, message: &str) -> eyre::Result<()> {
match exit_reason {
Expand Down
153 changes: 43 additions & 110 deletions crates/astria-conductor/src/conductor/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Inner {
self.restart_or_shutdown(exit_status).await
}

/// Shuts down all tasks.
/// Shuts down all tasks and returns a token indicating whether to restart or not.
///
/// Waits 25 seconds for all tasks to shut down before aborting them. 25 seconds
/// because kubernetes issues SIGKILL 30 seconds after SIGTERM, giving 5 seconds
Expand Down Expand Up @@ -164,7 +164,10 @@ fn should_restart_despite_error(err: &eyre::Report) -> bool {
let mut current = Some(err.as_ref() as &dyn std::error::Error);
while let Some(err) = current {
if let Some(status) = err.downcast_ref::<tonic::Status>() {
if status.code() == tonic::Code::PermissionDenied {
if status.code() == tonic::Code::PermissionDenied
// Fallback in case execute block is called outside of execution session bounds
|| status.code() == tonic::Code::OutOfRange
{
return true;
}
}
Expand All @@ -177,7 +180,7 @@ fn should_restart_or_shutdown(
config: &Config,
status: &crate::executor::State,
) -> eyre::Result<RestartOrShutdown> {
let Some(rollup_stop_block_number) = status.rollup_stop_block_number() else {
let Some(rollup_stop_block_number) = status.rollup_end_block_number() else {
return Err(eyre!(
"executor exited with a success value even though it was not configured to run with a \
stop height and even though it received no shutdown signal; this should not happen"
Expand All @@ -187,12 +190,7 @@ fn should_restart_or_shutdown(
match config.execution_commit_level {
crate::config::CommitLevel::FirmOnly | crate::config::CommitLevel::SoftAndFirm => {
if status.has_firm_number_reached_stop_height() {
let restart_or_shutdown = if status.halt_at_rollup_stop_number() {
RestartOrShutdown::Shutdown
} else {
RestartOrShutdown::Restart
};
Ok(restart_or_shutdown)
Ok(RestartOrShutdown::Restart)
} else {
Err(eyre!(
"executor exited with a success value, but the stop height was not reached
Expand All @@ -203,19 +201,14 @@ fn should_restart_or_shutdown(
status.firm_number(),
status.firm_block_number_as_sequencer_height(),
status.rollup_start_block_number(),
status.sequencer_start_height(),
status.sequencer_start_block_height(),
rollup_stop_block_number,
))
}
}
crate::config::CommitLevel::SoftOnly => {
if status.has_soft_number_reached_stop_height() {
let restart_or_shutdown = if status.halt_at_rollup_stop_number() {
RestartOrShutdown::Shutdown
} else {
RestartOrShutdown::Restart
};
Ok(restart_or_shutdown)
Ok(RestartOrShutdown::Restart)
} else {
Err(eyre!(
"executor exited with a success value, but the stop height was not reached
Expand All @@ -226,7 +219,7 @@ fn should_restart_or_shutdown(
status.soft_number(),
status.soft_block_number_as_sequencer_height(),
status.rollup_start_block_number(),
status.sequencer_start_height(),
status.sequencer_start_block_height(),
rollup_stop_block_number,
))
}
Expand All @@ -237,9 +230,9 @@ fn should_restart_or_shutdown(
#[cfg(test)]
mod tests {
use astria_core::generated::astria::execution::v2::{
Block,
CommitmentState,
GenesisInfo,
ExecutedBlockMetadata,
ExecutionSessionParameters,
};
use astria_eyre::eyre::WrapErr as _;
use pbjson_types::Timestamp;
Expand All @@ -252,7 +245,7 @@ mod tests {
config::CommitLevel,
test_utils::{
make_commitment_state,
make_genesis_info,
make_execution_session_parameters,
make_rollup_state,
},
Config,
Expand All @@ -279,15 +272,19 @@ mod tests {
}
}

#[test]
fn should_restart_despite_error() {
let tonic_error: Result<&str, tonic::Status> =
Err(tonic::Status::new(tonic::Code::PermissionDenied, "error"));
#[track_caller]
fn should_restart_despite_error_test(code: tonic::Code) {
let tonic_error: Result<&str, tonic::Status> = Err(tonic::Status::new(code, "error"));
let err = tonic_error.wrap_err("wrapper_1");
let err = err.wrap_err("wrapper_2");
let err = err.wrap_err("wrapper_3");
assert!(super::should_restart_despite_error(&err.unwrap_err()));
}
#[test]
fn should_restart_despite_error() {
should_restart_despite_error_test(tonic::Code::PermissionDenied);
should_restart_despite_error_test(tonic::Code::OutOfRange);
}

#[track_caller]
fn assert_restart_or_shutdown(
Expand All @@ -309,63 +306,31 @@ mod tests {
..make_config()
},
&make_rollup_state(
GenesisInfo {
sequencer_start_height: 10,
"test_execution_session".to_string(),
ExecutionSessionParameters {
sequencer_start_block_height: 10,
rollup_start_block_number: 10,
rollup_stop_block_number: 99,
halt_at_rollup_stop_number: false,
..make_genesis_info()
rollup_end_block_number: 99,
..make_execution_session_parameters()
},
CommitmentState {
firm: Some(Block {
firm_executed_block_metadata: Some(ExecutedBlockMetadata {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
hash: hex::encode([0u8; 32]).to_string(),
parent_hash: String::new(),
timestamp: Some(Timestamp::default()),
}),
soft: Some(Block {
soft_executed_block_metadata: Some(ExecutedBlockMetadata {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
hash: hex::encode([0u8; 32]).to_string(),
parent_hash: String::new(),
timestamp: Some(Timestamp::default()),
}),
..make_commitment_state()
},
),
&RestartOrShutdown::Restart,
);

assert_restart_or_shutdown(
&Config {
execution_commit_level: CommitLevel::SoftAndFirm,
..make_config()
},
&make_rollup_state(
GenesisInfo {
sequencer_start_height: 10,
rollup_start_block_number: 10,
rollup_stop_block_number: 99,
halt_at_rollup_stop_number: true,
..make_genesis_info()
},
CommitmentState {
firm: Some(Block {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
timestamp: Some(Timestamp::default()),
}),
soft: Some(Block {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
timestamp: Some(Timestamp::default()),
}),
..make_commitment_state()
},
),
&RestartOrShutdown::Shutdown,
);
}

#[test]
Expand All @@ -376,62 +341,30 @@ mod tests {
..make_config()
},
&make_rollup_state(
GenesisInfo {
sequencer_start_height: 10,
"test_execution_session".to_string(),
ExecutionSessionParameters {
sequencer_start_block_height: 10,
rollup_start_block_number: 10,
rollup_stop_block_number: 99,
halt_at_rollup_stop_number: false,
..make_genesis_info()
rollup_end_block_number: 99,
..make_execution_session_parameters()
},
CommitmentState {
firm: Some(Block {
firm_executed_block_metadata: Some(ExecutedBlockMetadata {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
hash: hex::encode([0u8; 32]).to_string(),
parent_hash: String::new(),
timestamp: Some(Timestamp::default()),
}),
soft: Some(Block {
soft_executed_block_metadata: Some(ExecutedBlockMetadata {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
hash: hex::encode([0u8; 32]).to_string(),
parent_hash: String::new(),
timestamp: Some(Timestamp::default()),
}),
..make_commitment_state()
},
),
&RestartOrShutdown::Restart,
);

assert_restart_or_shutdown(
&Config {
execution_commit_level: CommitLevel::SoftOnly,
..make_config()
},
&make_rollup_state(
GenesisInfo {
sequencer_start_height: 10,
rollup_start_block_number: 10,
rollup_stop_block_number: 99,
halt_at_rollup_stop_number: true,
..make_genesis_info()
},
CommitmentState {
firm: Some(Block {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
timestamp: Some(Timestamp::default()),
}),
soft: Some(Block {
number: 99,
hash: vec![0u8; 32].into(),
parent_block_hash: vec![].into(),
timestamp: Some(Timestamp::default()),
}),
..make_commitment_state()
},
),
&RestartOrShutdown::Shutdown,
);
}
}
Loading

0 comments on commit 959e08f

Please sign in to comment.