diff --git a/crates/astria-conductor/tests/blackbox/firm_only.rs b/crates/astria-conductor/tests/blackbox/firm_only.rs index 48478ef6c6..2c7f70a12a 100644 --- a/crates/astria-conductor/tests/blackbox/firm_only.rs +++ b/crates/astria-conductor/tests/blackbox/firm_only.rs @@ -5,7 +5,13 @@ use astria_conductor::{ Conductor, Config, }; -use astria_core::generated::astria::execution::v2::CreateExecutionSessionRequest; +use astria_core::generated::{ + astria::execution::v2::CreateExecutionSessionRequest, + execution::v2::{ + CommitmentState, + ExecutionSession, + }, +}; use futures::future::{ join, join4, @@ -23,29 +29,31 @@ use wiremock::{ }; use crate::{ + block_metadata, celestia_network_head, - execution_session, + execution_session_parameters, helpers::{ make_config, spawn_conductor, MockGrpc, CELESTIA_BEARER_TOKEN, CELESTIA_CHAIN_ID, + EXECUTION_SESSION_ID, SEQUENCER_CHAIN_ID, }, mount_celestia_blobs, mount_celestia_header_network_head, mount_create_execution_session, mount_execute_block, + mount_firm_update_commitment_state, mount_sequencer_commit, mount_sequencer_genesis, mount_sequencer_validator_set, - mount_update_commitment_state, }; #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn simple() { - let test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; mount_create_execution_session!( test_conductor, @@ -56,16 +64,8 @@ async fn simple() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -93,22 +93,11 @@ async fn simple() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -128,7 +117,7 @@ async fn simple() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn submits_two_heights_in_succession() { - let test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; mount_create_execution_session!( test_conductor, @@ -139,16 +128,8 @@ async fn submits_two_heights_in_succession() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), ); @@ -183,44 +164,22 @@ async fn submits_two_heights_in_succession() { let execute_block_number_2 = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state_number_2 = mount_update_commitment_state!( + let update_commitment_state_number_2 = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); let execute_block_number_3 = mount_execute_block!( test_conductor, number: 3, - hash: "3", - parent: "2", ); - let update_commitment_state_number_3 = mount_update_commitment_state!( + let update_commitment_state_number_3 = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 3, - hash: "3", - parent: "2", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, ); @@ -242,7 +201,7 @@ async fn submits_two_heights_in_succession() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn skips_already_executed_heights() { - let test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; mount_create_execution_session!( test_conductor, @@ -253,16 +212,8 @@ async fn skips_already_executed_heights() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 5, - hash: "1", - parent: "0", - ), - soft: ( - number: 5, - hash: "1", - parent: "0", - ), + firm_number: 5, + soft_number: 5, lowest_celestia_search_height: 1, ), ); @@ -294,22 +245,11 @@ async fn skips_already_executed_heights() { let execute_block = mount_execute_block!( test_conductor, number: 6, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 6, - hash: "2", - parent: "1", - ), - soft: ( - number: 6, - hash: "2", - parent: "1", - ), + number: 6, lowest_celestia_search_height: 1, ); @@ -329,7 +269,7 @@ async fn skips_already_executed_heights() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn fetch_from_later_celestia_height() { - let test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; mount_create_execution_session!( test_conductor, @@ -340,16 +280,8 @@ async fn fetch_from_later_celestia_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 4, ), ); @@ -377,22 +309,11 @@ async fn fetch_from_later_celestia_height() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 4, ); @@ -450,27 +371,28 @@ async fn exits_on_celestia_chain_id_mismatch() { "create_execution_session", matcher::message_type::(), ) - .respond_with(GrpcResponse::constant_response(execution_session!( - execution_session_parameters: ( + .respond_with(GrpcResponse::constant_response(ExecutionSession { + session_id: EXECUTION_SESSION_ID.to_string(), + execution_session_parameters: Some(execution_session_parameters!( rollup_start_block_number: 2, rollup_end_block_number: 9, sequencer_start_block_height: 3, celestia_max_look_ahead: 10, - ), - commitment_state: ( - firm: ( + )), + commitment_state: Some(CommitmentState { + firm_executed_block_metadata: Some(block_metadata!( number: 1, hash: "1", parent: "0", - ), - soft: ( + )), + soft_executed_block_metadata: Some(block_metadata!( number: 1, hash: "1", parent: "0", - ), + )), lowest_celestia_search_height: 1, - ) - ))) + }), + })) .expect(0..) .mount(&mock_grpc.mock_server) .await; @@ -531,10 +453,9 @@ async fn exits_on_celestia_chain_id_mismatch() { /// block has already been executed. /// 7. Mount `execute_block` and `update_commitment_state` for firm block 4, awaiting their /// satisfaction. -#[expect(clippy::too_many_lines, reason = "All lines reasonably necessary")] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn restarts_after_reaching_stop_block_height() { - let test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::FirmOnly).await; mount_create_execution_session!( test_conductor, @@ -545,16 +466,8 @@ async fn restarts_after_reaching_stop_block_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), up_to_n_times: 1, // Only respond once, since a new execution session is needed after restart. @@ -586,24 +499,13 @@ async fn restarts_after_reaching_stop_block_height() { test_conductor, mock_name: "execute_block_1", number: 2, - hash: "2", - parent: "1", expected_calls: 1, // should not be called again upon restart ); - let update_commitment_state_1 = mount_update_commitment_state!( + let update_commitment_state_1 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_1", - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 1, // should not be called again upon restart ); @@ -631,16 +533,8 @@ async fn restarts_after_reaching_stop_block_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + firm_number: 2, + soft_number: 2, lowest_celestia_search_height: 1, ), ); @@ -649,24 +543,13 @@ async fn restarts_after_reaching_stop_block_height() { test_conductor, mock_name: "execute_block_2", number: 3, - hash: "3", - parent: "2", expected_calls: 1, ); - let update_commitment_state_2 = mount_update_commitment_state!( + let update_commitment_state_2 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_2", - firm: ( - number: 3, - hash: "3", - parent: "2", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 1, ); diff --git a/crates/astria-conductor/tests/blackbox/helpers/macros.rs b/crates/astria-conductor/tests/blackbox/helpers/macros.rs index 2802f617a2..be031bfcc4 100644 --- a/crates/astria-conductor/tests/blackbox/helpers/macros.rs +++ b/crates/astria-conductor/tests/blackbox/helpers/macros.rs @@ -67,46 +67,22 @@ macro_rules! filtered_sequencer_block { // 1. applying #[rustfmt::skip] on the macro or on the containing module triggers issue 52234. // 2. applying #![rustfmt::skip] triggers issue 64266. #[macro_export] -macro_rules! execution_session { +macro_rules! execution_session_parameters { ( - execution_session_parameters: ( - rollup_start_block_number: $rollup_start_block_number:expr, - rollup_end_block_number: $rollup_end_block_number:expr, - sequencer_start_block_height: $start_height:expr, - celestia_max_look_ahead: $celestia_max_look_ahead:expr$(,)? - ), - commitment_state: ( - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), - lowest_celestia_search_height: $lowest_celestia_search_height:expr$(,)? - )$(,)? + rollup_start_block_number: + $rollup_start_block_number:expr,rollup_end_block_number: + $rollup_end_block_number:expr,sequencer_start_block_height: + $start_height:expr,celestia_max_look_ahead: + $celestia_max_look_ahead:expr $(,)? ) => { - ::astria_core::generated::astria::execution::v2::ExecutionSession { - session_id: $crate::helpers::EXECUTION_SESSION_ID.to_string(), - execution_session_parameters: Some( - ::astria_core::generated::astria::execution::v2::ExecutionSessionParameters { - rollup_id: Some($crate::ROLLUP_ID.to_raw()), - rollup_start_block_number: $rollup_start_block_number, - rollup_end_block_number: $rollup_end_block_number, - sequencer_start_block_height: $start_height, - sequencer_chain_id: $crate::SEQUENCER_CHAIN_ID.to_string(), - celestia_chain_id: $crate::helpers::CELESTIA_CHAIN_ID.to_string(), - celestia_search_height_max_look_ahead: $celestia_max_look_ahead, - } - ), - commitment_state: Some(::astria_core::generated::astria::execution::v2::CommitmentState { - firm_executed_block_metadata: Some($crate::block_metadata!( - number: $firm_number, - hash: $firm_hash, - parent: $firm_parent, - )), - soft_executed_block_metadata: Some($crate::block_metadata!( - number: $soft_number, - hash: $soft_hash, - parent: $soft_parent, - )), - lowest_celestia_search_height: $lowest_celestia_search_height, - }), + ::astria_core::generated::astria::execution::v2::ExecutionSessionParameters { + rollup_id: Some($crate::ROLLUP_ID.to_raw()), + rollup_start_block_number: $rollup_start_block_number, + rollup_end_block_number: $rollup_end_block_number, + sequencer_start_block_height: $start_height, + sequencer_chain_id: $crate::SEQUENCER_CHAIN_ID.to_string(), + celestia_chain_id: $crate::helpers::CELESTIA_CHAIN_ID.to_string(), + celestia_search_height_max_look_ahead: $celestia_max_look_ahead, } }; } @@ -173,19 +149,17 @@ macro_rules! mount_celestia_header_network_head { } #[macro_export] -macro_rules! mount_update_commitment_state { +macro_rules! mount_soft_update_commitment_state { ( $test_env:ident, - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + number: $number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr $(,)? ) => { - mount_update_commitment_state!( + mount_soft_update_commitment_state!( $test_env, mock_name: None, - firm: ( number: $firm_number, hash: $firm_hash, parent: $firm_parent, ), - soft: ( number: $soft_number, hash: $soft_hash, parent: $soft_parent, ), + number: $number, lowest_celestia_search_height: $lowest_celestia_search_height, expected_calls: 1, ) @@ -193,16 +167,14 @@ macro_rules! mount_update_commitment_state { ( $test_env:ident, mock_name: $mock_name:expr, - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + number: $number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr $(,)? ) => { - mount_update_commitment_state!( + mount_soft_update_commitment_state!( $test_env, mock_name: $mock_name, - firm: ( number: $firm_number, hash: $firm_hash, parent: $firm_parent, ), - soft: ( number: $soft_number, hash: $soft_hash, parent: $soft_parent, ), + number: $number, lowest_celestia_search_height: $lowest_celestia_search_height, expected_calls: 1, ) @@ -210,8 +182,7 @@ macro_rules! mount_update_commitment_state { ( $test_env:ident, mock_name: $mock_name:expr, - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + number: $number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr, expected_calls: $expected_calls:expr $(,)? @@ -219,19 +190,45 @@ macro_rules! mount_update_commitment_state { $test_env .mount_update_commitment_state( $mock_name.into(), - ::astria_core::generated::astria::execution::v2::CommitmentState { - firm_executed_block_metadata: Some($crate::block_metadata!( - number: $firm_number, - hash: $firm_hash, - parent: $firm_parent, - )), - soft_executed_block_metadata: Some($crate::block_metadata!( - number: $soft_number, - hash: $soft_hash, - parent: $soft_parent, - )), - lowest_celestia_search_height: $lowest_celestia_search_height, - }, + $number, + false, + $lowest_celestia_search_height, + $expected_calls, + ) + .await + }; +} + +#[macro_export] +macro_rules! mount_firm_update_commitment_state { + ( + $test_env:ident, + number: $number:expr, + lowest_celestia_search_height: $lowest_celestia_search_height:expr + $(,)? + ) => { + mount_firm_update_commitment_state!( + $test_env, + mock_name: None, + number: $number, + lowest_celestia_search_height: $lowest_celestia_search_height, + expected_calls: 1, + ) + }; + ( + $test_env:ident, + mock_name: $mock_name:expr, + number: $number:expr, + lowest_celestia_search_height: $lowest_celestia_search_height:expr, + expected_calls: $expected_calls:expr + $(,)? + ) => { + $test_env + .mount_update_commitment_state( + $mock_name.into(), + $number, + true, + $lowest_celestia_search_height, $expected_calls, ) .await @@ -251,26 +248,11 @@ macro_rules! mount_execute_block { $test_env:ident, mock_name: $mock_name:expr, number: $number:expr, - hash: $hash:expr, - parent: $parent:expr, expected_calls: $expected_calls:expr $(,)? ) => {{ - use ::base64::prelude::*; $test_env.mount_execute_block( $mock_name.into(), - ::serde_json::json!({ - "sessionId": $crate::helpers::EXECUTION_SESSION_ID, - "parentHash": $parent, - "transactions": [ - {"priceFeedData": {}}, - {"sequencedData": BASE64_STANDARD.encode($crate::helpers::data())} - ], - }), - $crate::block_metadata!( - number: $number, - hash: $hash, - parent: $parent, - ), + $number, $expected_calls, ) .await @@ -279,30 +261,22 @@ macro_rules! mount_execute_block { $test_env:ident, mock_name: $mock_name:expr, number: $number:expr, - hash: $hash:expr, - parent: $parent:expr, ) => { mount_execute_block!( $test_env, mock_name: None, number: $number, - hash: $hash, - parent: $parent, expected_calls: 1, ) }; ( $test_env:ident, number: $number:expr, - hash: $hash:expr, - parent: $parent:expr $(,)? ) => { mount_execute_block!( $test_env, mock_name: None, number: $number, - hash: $hash, - parent: $parent, ) }; } @@ -341,8 +315,8 @@ macro_rules! mount_create_execution_session { celestia_max_look_ahead: $celestia_max_look_ahead:expr $(,)? ), commitment_state: ( - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + firm_number: $firm_number:expr, + soft_number: $soft_number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr$(,)? ) $(,)? @@ -356,8 +330,8 @@ macro_rules! mount_create_execution_session { celestia_max_look_ahead: $celestia_max_look_ahead, ), commitment_state: ( - firm: ( number: $firm_number, hash: $firm_hash, parent: $firm_parent, ), - soft: ( number: $soft_number, hash: $soft_hash, parent: $soft_parent, ), + firm_number: $firm_number, + soft_number: $soft_number, lowest_celestia_search_height: $lowest_celestia_search_height, ), expected_calls: 1, @@ -373,8 +347,8 @@ macro_rules! mount_create_execution_session { celestia_max_look_ahead: $celestia_max_look_ahead:expr $(,)? ), commitment_state: ( - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + firm_number: $firm_number:expr, + soft_number: $soft_number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr$(,)? ), up_to_n_times: $up_to_n_times:expr @@ -389,8 +363,8 @@ macro_rules! mount_create_execution_session { celestia_max_look_ahead: $celestia_max_look_ahead, ), commitment_state: ( - firm: ( number: $firm_number, hash: $firm_hash, parent: $firm_parent, ), - soft: ( number: $soft_number, hash: $soft_hash, parent: $soft_parent, ), + firm_number: $firm_number, + soft_number: $soft_number, lowest_celestia_search_height: $lowest_celestia_search_height, ), expected_calls: 1, @@ -406,27 +380,23 @@ macro_rules! mount_create_execution_session { celestia_max_look_ahead: $celestia_max_look_ahead:expr $(,)? ), commitment_state: ( - firm: ( number: $firm_number:expr, hash: $firm_hash:expr, parent: $firm_parent:expr$(,)? ), - soft: ( number: $soft_number:expr, hash: $soft_hash:expr, parent: $soft_parent:expr$(,)? ), + firm_number: $firm_number:expr, + soft_number: $soft_number:expr, lowest_celestia_search_height: $lowest_celestia_search_height:expr$(,)? ), expected_calls: $expected_calls:expr, up_to_n_times: $up_to_n_times:expr $(,)? ) => { $test_env.mount_create_execution_session( - $crate::execution_session!( - execution_session_parameters: ( - rollup_start_block_number: $rollup_start_block_number, - rollup_end_block_number: $rollup_end_block_number, - sequencer_start_block_height: $start_height, - celestia_max_look_ahead: $celestia_max_look_ahead, - ), - commitment_state: ( - firm: ( number: $firm_number, hash: $firm_hash, parent: $firm_parent), - soft: ( number: $soft_number, hash: $soft_hash, parent: $soft_parent), - lowest_celestia_search_height: $lowest_celestia_search_height, - ), + $crate::execution_session_parameters!( + rollup_start_block_number: $rollup_start_block_number, + rollup_end_block_number: $rollup_end_block_number, + sequencer_start_block_height: $start_height, + celestia_max_look_ahead: $celestia_max_look_ahead, ), + $firm_number, + $soft_number, + $lowest_celestia_search_height, $up_to_n_times, $expected_calls, ).await; @@ -460,28 +430,8 @@ macro_rules! mount_sequencer_genesis { #[macro_export] macro_rules! mount_get_executed_block_metadata { - ( - $test_env:ident, - number: $number:expr, - hash: $hash:expr, - parent: $parent:expr $(,)? - ) => {{ - let block = $crate::block_metadata!( - number: $number, - hash: $hash, - parent: $parent, - ); - let identifier = ::astria_core::generated::astria::execution::v2::ExecutedBlockIdentifier { - identifier: Some( - ::astria_core::generated::astria::execution::v2::executed_block_identifier::Identifier::Number(block.number) - )}; - $test_env.mount_get_executed_block_metadata( - ::astria_core::generated::astria::execution::v2::GetExecutedBlockMetadataRequest { - identifier: Some(identifier), - }, - block, - ) - .await + ($test_env:ident,number: $number:expr,) => {{ + $test_env.mount_get_executed_block_metadata($number).await }}; } diff --git a/crates/astria-conductor/tests/blackbox/helpers/mod.rs b/crates/astria-conductor/tests/blackbox/helpers/mod.rs index a1c67aa830..63adcbacb5 100644 --- a/crates/astria-conductor/tests/blackbox/helpers/mod.rs +++ b/crates/astria-conductor/tests/blackbox/helpers/mod.rs @@ -1,4 +1,5 @@ use std::{ + cmp::max, sync::LazyLock, time::Duration, }; @@ -12,18 +13,33 @@ use astria_conductor::{ }; use astria_core::{ brotli::compress_bytes, - generated::astria::{ + generated::{ + astria::{ + execution::v2::{ + CommitmentState, + ExecutionSession, + }, + sequencerblock::v1::FilteredSequencerBlock, + }, execution::v2::{ - CommitmentState, - ExecutedBlockMetadata, - ExecutionSession, + executed_block_identifier::Identifier, + ExecuteBlockResponse, + ExecutedBlockIdentifier, + ExecutionSessionParameters, + GetExecutedBlockMetadataRequest, }, - sequencerblock::v1::FilteredSequencerBlock, }, primitive::v1::RollupId, sequencerblock::v1::block, }; -use astria_grpc_mock::response::error_response; +use astria_grpc_mock::{ + response::error_response, + Times, +}; +use base64::{ + prelude::BASE64_STANDARD, + Engine as _, +}; use bytes::Bytes; use celestia_types::{ nmt::Namespace, @@ -111,19 +127,33 @@ pub async fn spawn_conductor(execution_commit_level: CommitLevel) -> TestConduct conductor.spawn() }; + let state = TestRollupState { + soft_hash: 1, + firm_hash: 1, + firm_number: 0, + }; + TestConductor { conductor, mock_grpc, mock_http, metrics_handle, + state, } } +struct TestRollupState { + soft_hash: u8, + firm_hash: u8, + firm_number: u64, +} + pub struct TestConductor { pub conductor: conductor::Handle, pub mock_grpc: MockGrpc, pub mock_http: wiremock::MockServer, pub metrics_handle: metrics::Handle, + state: TestRollupState, } impl Drop for TestConductor { @@ -150,6 +180,11 @@ impl Drop for TestConductor { } impl TestConductor { + pub fn put_rollup_state_hashes(&mut self, firm: u8, soft: u8) { + self.state.firm_hash = firm; + self.state.soft_hash = soft; + } + pub async fn mount_abci_info(&self, latest_block_height: u32) { use wiremock::{ matchers::body_partial_json, @@ -176,21 +211,37 @@ impl TestConductor { .await; } - pub async fn mount_get_executed_block_metadata( - &self, - expected_pbjson: S, - block: ExecutedBlockMetadata, - ) { + pub async fn mount_get_executed_block_metadata(&self, number: u64) { use astria_grpc_mock::{ matcher::message_partial_pbjson, response::constant_response, Mock, }; + + let expected_pbjson = GetExecutedBlockMetadataRequest { + identifier: Some(ExecutedBlockIdentifier { + identifier: Some(Identifier::Number(number)), + }), + }; + + // Calculate difference between firm block number and firm hash, applying to given + // number to obtain its hash. This accomodates potential use cases where the + // hash does not match the block number. + let delta = i64::try_from(self.state.firm_number) + .unwrap() + .saturating_sub(i64::from(self.state.firm_hash)); + let hash = u8::try_from(i64::try_from(number).unwrap().saturating_sub(delta)) + .expect("should be able to derive `u8` hash from `number + (firm_number - firm_hash)`"); + Mock::for_rpc_given( "get_executed_block_metadata", message_partial_pbjson(&expected_pbjson), ) - .respond_with(constant_response(block)) + .respond_with(constant_response(block_metadata!( + number: number, + hash: hash, + parent: hash.saturating_sub(1), + ))) .expect(1..) .mount(&self.mock_grpc.mock_server) .await; @@ -309,12 +360,33 @@ impl TestConductor { } pub async fn mount_create_execution_session( - &self, - execution_session: ExecutionSession, + &mut self, + execution_session_parameters: ExecutionSessionParameters, + firm_number: u64, + soft_number: u64, + lowest_celestia_search_height: u64, up_to_n_times: u64, expected_calls: u64, ) { use astria_core::generated::astria::execution::v2::CreateExecutionSessionRequest; + self.state.firm_number = firm_number; + let execution_session = ExecutionSession { + session_id: EXECUTION_SESSION_ID.to_string(), + execution_session_parameters: Some(execution_session_parameters), + commitment_state: Some(CommitmentState { + soft_executed_block_metadata: Some(block_metadata!( + number: soft_number, + hash: self.state.soft_hash, + parent: self.state.soft_hash.saturating_sub(1), + )), + firm_executed_block_metadata: Some(block_metadata!( + number: firm_number, + hash: self.state.firm_hash, + parent: self.state.firm_hash.saturating_sub(1), + )), + lowest_celestia_search_height, + }), + }; astria_grpc_mock::Mock::for_rpc_given( "create_execution_session", astria_grpc_mock::matcher::message_type::(), @@ -328,24 +400,36 @@ impl TestConductor { .await; } - pub async fn mount_execute_block( + pub async fn mount_execute_block( &self, mock_name: Option<&str>, - expected_pbjson: S, - block_metadata: ExecutedBlockMetadata, + number: u64, expected_calls: u64, ) -> astria_grpc_mock::MockGuard { - use astria_core::generated::astria::execution::v2::ExecuteBlockResponse; use astria_grpc_mock::{ matcher::message_partial_pbjson, response::constant_response, Mock, }; - let mut mock = - Mock::for_rpc_given("execute_block", message_partial_pbjson(&expected_pbjson)) - .respond_with(constant_response(ExecuteBlockResponse { - executed_block_metadata: Some(block_metadata.clone()), - })); + + let parent_initializer = max(self.state.soft_hash, self.state.firm_hash); + let response = ExecuteBlockResponse { + executed_block_metadata: Some(block_metadata!( + number: number, + hash: parent_initializer.saturating_add(1), + parent: parent_initializer, + )), + }; + + let mut mock = Mock::for_rpc_given( + "execute_block", + message_partial_pbjson(&json!({ + "sessionId": EXECUTION_SESSION_ID.to_string(), + "parentHash": parent_initializer.to_string(), + "transactions": [{"priceFeedData": {}}, {"sequencedData": BASE64_STANDARD.encode(data())}], + })), + ) + .respond_with(constant_response(response)); if let Some(name) = mock_name { mock = mock.with_name(name); } @@ -376,10 +460,12 @@ impl TestConductor { } pub async fn mount_update_commitment_state( - &self, + &mut self, mock_name: Option<&str>, - commitment_state: CommitmentState, - expected_calls: impl Into, + number: u64, + is_with_firm: bool, + lowest_celestia_search_height: u64, + expected_calls: impl Into, ) -> astria_grpc_mock::MockGuard { use astria_core::generated::astria::execution::v2::UpdateCommitmentStateRequest; use astria_grpc_mock::{ @@ -387,6 +473,32 @@ impl TestConductor { response::constant_response, Mock, }; + + // If this is a firm commitment update, we want to match the soft info to firm. If not, + // we leave the firm info as is. + let (firm_number, soft_hash) = if is_with_firm { + self.state.firm_number = number; + self.state.firm_hash = self.state.firm_hash.saturating_add(1); + (number, self.state.firm_hash) // Set soft initializer to firm initializer + } else { + self.state.soft_hash = self.state.soft_hash.saturating_add(1); + (self.state.firm_number, self.state.soft_hash) + }; + + let commitment_state = CommitmentState { + firm_executed_block_metadata: Some(block_metadata!( + number: firm_number, + hash: self.state.firm_hash, + parent: self.state.firm_hash.saturating_sub(1), + )), + soft_executed_block_metadata: Some(block_metadata!( + number: number, + hash: soft_hash, + parent: soft_hash.saturating_sub(1), + )), + lowest_celestia_search_height, + }; + let mut mock = Mock::for_rpc_given( "update_commitment_state", message_partial_pbjson(&UpdateCommitmentStateRequest { diff --git a/crates/astria-conductor/tests/blackbox/soft_and_firm.rs b/crates/astria-conductor/tests/blackbox/soft_and_firm.rs index 00d0a75ea9..883e45cb2e 100644 --- a/crates/astria-conductor/tests/blackbox/soft_and_firm.rs +++ b/crates/astria-conductor/tests/blackbox/soft_and_firm.rs @@ -15,12 +15,13 @@ use crate::{ mount_create_execution_session, mount_execute_block, mount_execute_block_tonic_code, + mount_firm_update_commitment_state, mount_get_executed_block_metadata, mount_get_filtered_sequencer_block, mount_sequencer_commit, mount_sequencer_genesis, mount_sequencer_validator_set, - mount_update_commitment_state, + mount_soft_update_commitment_state, SEQUENCER_CHAIN_ID, }; @@ -35,7 +36,7 @@ use crate::{ /// 5. the rollup's firm commitment state is updated (but without executing the block) #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn executes_soft_first_then_updates_firm() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; mount_create_execution_session!( test_conductor, @@ -46,16 +47,8 @@ async fn executes_soft_first_then_updates_firm() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -80,22 +73,11 @@ async fn executes_soft_first_then_updates_firm() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state_soft = mount_update_commitment_state!( + let update_commitment_state_soft = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -126,18 +108,9 @@ async fn executes_soft_first_then_updates_firm() { mount_sequencer_validator_set!(test_conductor, height: 2u32); - let update_commitment_state_firm = mount_update_commitment_state!( + let update_commitment_state_firm = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -165,13 +138,9 @@ async fn executes_soft_first_then_updates_firm() { /// before the conductor receives the next block. /// 5. 2000ms is allotted for the conductor to execute the next block and update the soft commitment /// state at the next height. -#[expect( - clippy::too_many_lines, - reason = "all mounts and test logic are necessary" -)] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn executes_firm_then_soft_at_next_height() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; mount_create_execution_session!( test_conductor, @@ -182,16 +151,8 @@ async fn executes_firm_then_soft_at_next_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -224,8 +185,6 @@ async fn executes_firm_then_soft_at_next_height() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); // Mount soft block at current height with a slight delay @@ -242,18 +201,9 @@ async fn executes_firm_then_soft_at_next_height() { delay: Duration::from_millis(1000), ); - let update_commitment_state_firm = mount_update_commitment_state!( + let update_commitment_state_firm = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -263,19 +213,10 @@ async fn executes_firm_then_soft_at_next_height() { // will succeed immediately and future erroneous calls will not be checked. It would be most // ideal to mount this logic directly to the server, but this workaround functions with the // current setup of the blackbox test helpers. - let _stale_update_soft_commitment_state = mount_update_commitment_state!( + let _stale_update_soft_commitment_state = mount_soft_update_commitment_state!( test_conductor, mock_name: "should_be_ignored_update_commitment_state_soft", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 0, ); @@ -296,22 +237,11 @@ async fn executes_firm_then_soft_at_next_height() { let execute_block = mount_execute_block!( test_conductor, number: 3, - hash: "3", - parent: "2", ); - let update_commitment_state_soft = mount_update_commitment_state!( + let update_commitment_state_soft = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, ); @@ -329,11 +259,11 @@ async fn executes_firm_then_soft_at_next_height() { ); } -#[expect(clippy::too_many_lines, reason = "it's a test, it's fine")] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn missing_block_is_fetched_for_updating_firm_commitment() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + test_conductor.put_rollup_state_hashes(1, 2); mount_create_execution_session!( test_conductor, execution_session_parameters: ( @@ -343,16 +273,8 @@ async fn missing_block_is_fetched_for_updating_firm_commitment() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + firm_number: 1, + soft_number: 2, lowest_celestia_search_height: 1, ) ); @@ -367,8 +289,6 @@ async fn missing_block_is_fetched_for_updating_firm_commitment() { mount_get_executed_block_metadata!( test_conductor, number: 2, - hash: "2", - parent: "1", ); mount_celestia_header_network_head!( @@ -389,18 +309,9 @@ async fn missing_block_is_fetched_for_updating_firm_commitment() { mount_sequencer_validator_set!(test_conductor, height: 2u32); - let update_commitment_state_firm = mount_update_commitment_state!( + let update_commitment_state_firm = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -419,22 +330,11 @@ async fn missing_block_is_fetched_for_updating_firm_commitment() { let execute_block_soft = mount_execute_block!( test_conductor, number: 3, - hash: "3", - parent: "2", ); - let update_commitment_state_soft = mount_update_commitment_state!( + let update_commitment_state_soft = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, ); @@ -457,13 +357,9 @@ async fn missing_block_is_fetched_for_updating_firm_commitment() { /// Astria Geth will return a `PermissionDenied` error if the `execute_block` RPC is called /// before `get_genesis_info` and `get_commitment_state` are called, which would happen in the /// case of a restart. This response is mounted to cause the conductor to restart. -#[expect( - clippy::too_many_lines, - reason = "all lines fairly necessary, and I don't think a test warrants a refactor" -)] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn restarts_on_permission_denied() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; mount_create_execution_session!( test_conductor, @@ -474,16 +370,8 @@ async fn restarts_on_permission_denied() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), expected_calls: 2, @@ -539,37 +427,17 @@ async fn restarts_on_permission_denied() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state_soft = mount_update_commitment_state!( + let update_commitment_state_soft = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); - let update_commitment_state_firm = mount_update_commitment_state!( + let update_commitment_state_firm = mount_firm_update_commitment_state!( test_conductor, - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -612,7 +480,7 @@ async fn restarts_on_permission_denied() { )] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn restarts_after_reaching_soft_stop_height_first() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; mount_create_execution_session!( test_conductor, @@ -623,16 +491,8 @@ async fn restarts_after_reaching_soft_stop_height_first() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), up_to_n_times: 1, // We only respond once since a new execution session is needed after restart @@ -680,41 +540,21 @@ async fn restarts_after_reaching_soft_stop_height_first() { test_conductor, mock_name: "execute_block_1", number: 2, - hash: "2", - parent: "1", expected_calls: 1, // This should not be called again after restart ); - let update_commitment_state_soft_1 = mount_update_commitment_state!( + let update_commitment_state_soft_1 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_soft_1", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 1, ); - let update_commitment_state_firm_1 = mount_update_commitment_state!( + let update_commitment_state_firm_1 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_firm_1", - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 1, // Should not be called again after restart ); @@ -728,7 +568,7 @@ async fn restarts_after_reaching_soft_stop_height_first() { ), ) .await - .expect("conductor should have updated the firm commitment state within 1000ms"); + .expect("conductor should have updated the commitment state within 1000ms"); mount_create_execution_session!( test_conductor, @@ -739,16 +579,8 @@ async fn restarts_after_reaching_soft_stop_height_first() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + firm_number: 2, + soft_number: 2, lowest_celestia_search_height: 1, ), ); @@ -757,42 +589,22 @@ async fn restarts_after_reaching_soft_stop_height_first() { test_conductor, mock_name: "execute_block_2", number: 3, - hash: "3", - parent: "2", expected_calls: 1, ); // This condition should be satisfied, since there is a delay on the firm block response - let update_commitment_state_soft_2 = mount_update_commitment_state!( + let update_commitment_state_soft_2 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_soft_2", - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 1, ); - let update_commitment_state_firm_2 = mount_update_commitment_state!( + let update_commitment_state_firm_2 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_firm_2", - firm: ( - number: 3, - hash: "3", - parent: "2", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 1, ); @@ -836,7 +648,7 @@ async fn restarts_after_reaching_soft_stop_height_first() { )] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn restarts_after_reaching_firm_stop_height_first() { - let test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftAndFirm).await; mount_create_execution_session!( test_conductor, @@ -847,16 +659,8 @@ async fn restarts_after_reaching_firm_stop_height_first() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), up_to_n_times: 1, // We only respond once since a new execution session is needed after restart @@ -904,42 +708,22 @@ async fn restarts_after_reaching_firm_stop_height_first() { test_conductor, mock_name: "execute_block_1", number: 2, - hash: "2", - parent: "1", expected_calls: 1, // This should not be called again after restart ); // Should not be called since the firm block will be received first - let _update_commitment_state_soft_1 = mount_update_commitment_state!( + let _update_commitment_state_soft_1 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_soft_1", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 0, ); - let update_commitment_state_firm_1 = mount_update_commitment_state!( + let update_commitment_state_firm_1 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_firm_1", - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 1, // Should not be called again after restart ); @@ -963,16 +747,8 @@ async fn restarts_after_reaching_firm_stop_height_first() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + firm_number: 2, + soft_number: 2, lowest_celestia_search_height: 1, ), ); @@ -981,42 +757,22 @@ async fn restarts_after_reaching_firm_stop_height_first() { test_conductor, mock_name: "execute_block_2", number: 3, - hash: "3", - parent: "2", expected_calls: 1, ); // This condition does not need to be satisfied, since firm block may fire first after restart - let _update_commitment_state_soft_2 = mount_update_commitment_state!( + let _update_commitment_state_soft_2 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_soft_2", - firm: ( - number: 2, - hash: "2", - parent: "1", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 0..=1, ); - let update_commitment_state_firm_2 = mount_update_commitment_state!( + let update_commitment_state_firm_2 = mount_firm_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_firm_2", - firm: ( - number: 3, - hash: "3", - parent: "2", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 1, ); diff --git a/crates/astria-conductor/tests/blackbox/soft_only.rs b/crates/astria-conductor/tests/blackbox/soft_only.rs index 0bf44c11f7..051463f24f 100644 --- a/crates/astria-conductor/tests/blackbox/soft_only.rs +++ b/crates/astria-conductor/tests/blackbox/soft_only.rs @@ -5,7 +5,13 @@ use astria_conductor::{ Conductor, Config, }; -use astria_core::generated::astria::execution::v2::CreateExecutionSessionRequest; +use astria_core::generated::{ + astria::execution::v2::CreateExecutionSessionRequest, + execution::v2::{ + CommitmentState, + ExecutionSession, + }, +}; use futures::future::{ join, join4, @@ -14,25 +20,27 @@ use telemetry::metrics; use tokio::time::timeout; use crate::{ - execution_session, + block_metadata, + execution_session_parameters, helpers::{ make_config, mount_genesis, spawn_conductor, MockGrpc, + EXECUTION_SESSION_ID, }, mount_abci_info, mount_create_execution_session, mount_execute_block, mount_get_filtered_sequencer_block, mount_sequencer_genesis, - mount_update_commitment_state, + mount_soft_update_commitment_state, SEQUENCER_CHAIN_ID, }; #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn simple() { - let test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; mount_create_execution_session!( test_conductor, @@ -43,16 +51,8 @@ async fn simple() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -72,22 +72,11 @@ async fn simple() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -107,7 +96,7 @@ async fn simple() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn submits_two_heights_in_succession() { - let test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; mount_create_execution_session!( test_conductor, @@ -118,16 +107,8 @@ async fn submits_two_heights_in_succession() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -153,23 +134,12 @@ async fn submits_two_heights_in_succession() { test_conductor, mock_name: "first_execute", number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state_number_2 = mount_update_commitment_state!( + let update_commitment_state_number_2 = mount_soft_update_commitment_state!( test_conductor, mock_name: "first_update", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, ); @@ -177,23 +147,12 @@ async fn submits_two_heights_in_succession() { test_conductor, mock_name: "second_execute", number: 3, - hash: "3", - parent: "2", ); - let update_commitment_state_number_3 = mount_update_commitment_state!( + let update_commitment_state_number_3 = mount_soft_update_commitment_state!( test_conductor, mock_name: "second_update", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, ); @@ -215,7 +174,7 @@ async fn submits_two_heights_in_succession() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn skips_already_executed_heights() { - let test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; mount_create_execution_session!( test_conductor, @@ -226,16 +185,8 @@ async fn skips_already_executed_heights() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 5, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 5, lowest_celestia_search_height: 1, ) ); @@ -255,22 +206,11 @@ async fn skips_already_executed_heights() { let execute_block = mount_execute_block!( test_conductor, number: 6, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 6, - hash: "2", - parent: "1", - ), + number: 6, lowest_celestia_search_height: 1, ); @@ -290,7 +230,7 @@ async fn skips_already_executed_heights() { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn requests_from_later_genesis_height() { - let test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; mount_create_execution_session!( test_conductor, @@ -301,16 +241,8 @@ async fn requests_from_later_genesis_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ) ); @@ -330,22 +262,11 @@ async fn requests_from_later_genesis_height() { let execute_block = mount_execute_block!( test_conductor, number: 2, - hash: "2", - parent: "1", ); - let update_commitment_state = mount_update_commitment_state!( + let update_commitment_state = mount_soft_update_commitment_state!( test_conductor, - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1 ); @@ -403,27 +324,28 @@ async fn exits_on_sequencer_chain_id_mismatch() { "create_execution_session", matcher::message_type::(), ) - .respond_with(GrpcResponse::constant_response(execution_session!( - execution_session_parameters: ( + .respond_with(GrpcResponse::constant_response(ExecutionSession { + session_id: EXECUTION_SESSION_ID.to_string(), + execution_session_parameters: Some(execution_session_parameters!( rollup_start_block_number: 2, rollup_end_block_number: 9, sequencer_start_block_height: 3, celestia_max_look_ahead: 10, - ), - commitment_state: ( - firm: ( + )), + commitment_state: Some(CommitmentState { + firm_executed_block_metadata: Some(block_metadata!( number: 1, hash: "1", parent: "0", - ), - soft: ( + )), + soft_executed_block_metadata: Some(block_metadata!( number: 1, hash: "1", parent: "0", - ), + )), lowest_celestia_search_height: 1, - ), - ))) + }), + })) .expect(0..) .mount(&mock_grpc.mock_server) .await; @@ -468,13 +390,9 @@ async fn exits_on_sequencer_chain_id_mismatch() { /// start block number of 2, reflecting that the first block has already been executed. /// 5. Mount `execute_block` and `update_commitment_state` mocks for the soft block at height 4, /// awaiting their satisfaction. -#[expect( - clippy::too_many_lines, - reason = "All lines reasonably necessary for the thoroughness of this test" -)] #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn restarts_after_reaching_stop_block_height() { - let test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; + let mut test_conductor = spawn_conductor(CommitLevel::SoftOnly).await; mount_create_execution_session!( test_conductor, @@ -485,16 +403,8 @@ async fn restarts_after_reaching_stop_block_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 1, - hash: "1", - parent: "0", - ), + firm_number: 1, + soft_number: 1, lowest_celestia_search_height: 1, ), up_to_n_times: 1, // We need a new execution session after restart @@ -521,24 +431,13 @@ async fn restarts_after_reaching_stop_block_height() { test_conductor, mock_name: "execute_block_1", number: 2, - hash: "2", - parent: "1", expected_calls: 1, ); - let update_commitment_state_1 = mount_update_commitment_state!( + let update_commitment_state_1 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_1", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + number: 2, lowest_celestia_search_height: 1, expected_calls: 1, ); @@ -565,16 +464,8 @@ async fn restarts_after_reaching_stop_block_height() { celestia_max_look_ahead: 10, ), commitment_state: ( - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 2, - hash: "2", - parent: "1", - ), + firm_number: 1, + soft_number: 2, lowest_celestia_search_height: 1, ), ); @@ -583,24 +474,13 @@ async fn restarts_after_reaching_stop_block_height() { test_conductor, mock_name: "execute_block_2", number: 3, - hash: "3", - parent: "2", expected_calls: 1, ); - let update_commitment_state_2 = mount_update_commitment_state!( + let update_commitment_state_2 = mount_soft_update_commitment_state!( test_conductor, mock_name: "update_commitment_state_2", - firm: ( - number: 1, - hash: "1", - parent: "0", - ), - soft: ( - number: 3, - hash: "3", - parent: "2", - ), + number: 3, lowest_celestia_search_height: 1, expected_calls: 1, );