Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions crates/apollo_l1_provider/src/bootstrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ impl Bootstrapper {
self.catch_up_height
}

pub fn sync_started(&self) -> bool {
matches!(self.sync_task_handle, SyncTaskHandle::Started(_))
}

fn sync_task_health_check(&self, is_caught_up: bool) {
let SyncTaskHandle::Started(sync_task) = &self.sync_task_handle else {
return;
Expand Down
18 changes: 13 additions & 5 deletions crates/apollo_l1_provider/src/l1_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ impl L1Provider {
start_height: None,
}
}
pub fn reset_bootstrapper(&mut self) {
self.bootstrapper = Bootstrapper::new(
self.bootstrapper.l1_provider_client.clone(),
self.bootstrapper.sync_client.clone(),
self.config.startup_sync_sleep_retry_interval_seconds,
);
}
// Functions Called by the scraper.

// Start the provider, get first-scrape events, start L2 sync.
Expand Down Expand Up @@ -107,7 +114,7 @@ impl L1Provider {
/// Accept new events from the scraper.
#[instrument(skip_all, err)]
pub fn add_events(&mut self, events: Vec<Event>) -> L1ProviderResult<()> {
if self.state.is_bootstrapping() && !self.bootstrapper.sync_started() {
if self.state.is_uninitialized() {
return Err(L1ProviderError::Uninitialized);
}

Expand Down Expand Up @@ -183,7 +190,7 @@ impl L1Provider {
height: BlockNumber,
state: SessionState,
) -> L1ProviderResult<()> {
if self.state.is_bootstrapping() && !self.bootstrapper.sync_started() {
if self.state.is_uninitialized() {
return Err(L1ProviderError::Uninitialized);
}

Expand All @@ -202,7 +209,7 @@ impl L1Provider {
n_txs: usize,
height: BlockNumber,
) -> L1ProviderResult<Vec<L1HandlerTransaction>> {
if self.state.is_bootstrapping() && !self.bootstrapper.sync_started() {
if self.state.is_uninitialized() {
return Err(L1ProviderError::Uninitialized);
}

Expand Down Expand Up @@ -238,7 +245,7 @@ impl L1Provider {
tx_hash: TransactionHash,
height: BlockNumber,
) -> L1ProviderResult<ValidationStatus> {
if self.state.is_bootstrapping() && !self.bootstrapper.sync_started() {
if self.state.is_uninitialized() {
return Err(L1ProviderError::Uninitialized);
}

Expand Down Expand Up @@ -266,7 +273,7 @@ impl L1Provider {
height: BlockNumber,
) -> L1ProviderResult<()> {
info!("Committing block to L1 provider at height {}.", height);
if self.state.is_bootstrapping() && !self.bootstrapper.sync_started() {
if self.state.is_uninitialized() {
return Err(L1ProviderError::Uninitialized);
}

Expand Down Expand Up @@ -323,6 +330,7 @@ impl L1Provider {

/// Go from current state to Bootstrap state and start the L2 sync.
pub fn start_bootstrapping(&mut self, target_height: BlockNumber) {
self.reset_bootstrapper();
self.state = ProviderState::Bootstrap;
self.bootstrapper.start_l2_sync(self.current_height, target_height);
}
Expand Down
37 changes: 33 additions & 4 deletions crates/apollo_l1_provider/src/l1_provider_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,12 @@ async fn commit_block_backlog() {
let mut l1_provider = L1ProviderContentBuilder::new()
.with_bootstrapper(bootstrapper.clone())
.with_txs([l1_handler(1), l1_handler(2), l1_handler(4)])
.with_state(ProviderState::Uninitialized)
.build_into_l1_provider();

l1_provider.initialize(STARTUP_HEIGHT, vec![]).await.expect("l1 provider initialize failed");
commit_block_expect_error_just_to_start_bootstrapping(&mut l1_provider, TARGET_HEIGHT);
l1_provider.state = ProviderState::Bootstrap;
l1_provider.bootstrapper.start_l2_sync(STARTUP_HEIGHT, TARGET_HEIGHT);

// Test.
// Commit height is below target height. Doesn't trigger backlog.
Expand Down Expand Up @@ -431,6 +433,7 @@ async fn bootstrap_commit_block_received_twice_no_error() {
let mut l1_provider = L1ProviderContentBuilder::new()
.with_bootstrapper(bootstrapper)
.with_txs([l1_handler(1), l1_handler(2)])
.with_state(ProviderState::Uninitialized)
.build_into_l1_provider();

l1_provider.initialize(BlockNumber(0), vec![]).await.expect("l1 provider initialize failed");
Expand All @@ -452,6 +455,7 @@ async fn bootstrap_commit_block_received_twice_error_if_new_uncommitted_txs() {
let mut l1_provider = L1ProviderContentBuilder::new()
.with_bootstrapper(bootstrapper)
.with_txs([l1_handler(1), l1_handler(2)])
.with_state(ProviderState::Uninitialized)
.build_into_l1_provider();

l1_provider.initialize(BlockNumber(0), vec![]).await.expect("l1 provider initialize failed");
Expand Down Expand Up @@ -1058,8 +1062,10 @@ async fn commit_block_historical_height_short_circuits_bootstrap() {

let batcher_height_old = 4;
let bootstrapper = make_bootstrapper!(backlog: []);
let l1_provider_builder =
L1ProviderContentBuilder::new().with_bootstrapper(bootstrapper).with_txs([l1_handler(1)]);
let l1_provider_builder = L1ProviderContentBuilder::new()
.with_bootstrapper(bootstrapper)
.with_state(ProviderState::Uninitialized)
.with_txs([l1_handler(1)]);
let l1_provider_builder_clone = l1_provider_builder.clone();
let mut l1_provider = l1_provider_builder.clone().build_into_l1_provider();
l1_provider.initialize(STARTUP_HEIGHT, vec![]).await.expect("l1 provider initialize failed");
Expand Down Expand Up @@ -1400,7 +1406,9 @@ fn consuming_multiple_txs_selective_deletion_after_timelock() {
#[test]
fn bootstrap_commit_block_received_while_uninitialized() {
// Setup.
let mut l1_provider = L1ProviderContentBuilder::new().build_into_l1_provider();
let mut l1_provider = L1ProviderContentBuilder::new()
.with_state(ProviderState::Uninitialized)
.build_into_l1_provider();

// Test.
let result = l1_provider.commit_block([].into(), [].into(), BlockNumber(1));
Expand Down Expand Up @@ -1726,3 +1734,24 @@ async fn test_stuck_sync() {
tokio::time::sleep(config.startup_sync_sleep_retry_interval_seconds).await;
}
}

#[tokio::test]
async fn provider_initialized_in_pending_is_same_as_uninitialized_after_getting_initialize() {
// Setup.
const STARTUP_HEIGHT: BlockNumber = BlockNumber(2);
let mut provider_starts_uninitialized = L1ProviderContentBuilder::new()
.with_state(ProviderState::Uninitialized)
.build_into_l1_provider();
assert!(provider_starts_uninitialized.state.is_uninitialized());

let provider_starts_pending =
L1ProviderContentBuilder::new().with_height(STARTUP_HEIGHT).build_into_l1_provider();
assert_eq!(provider_starts_pending.state, ProviderState::Pending);

// Test.
provider_starts_uninitialized.initialize(STARTUP_HEIGHT, Default::default()).await.unwrap();
assert_eq!(provider_starts_uninitialized.state, ProviderState::Pending);

// Assert.
assert_eq!(provider_starts_uninitialized, provider_starts_pending);
}
4 changes: 3 additions & 1 deletion crates/apollo_l1_provider/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ impl From<L1ProviderContent> for L1Provider {
L1Provider {
config: content.config.unwrap_or_default(),
tx_manager: content.tx_manager_content.map(Into::into).unwrap_or_default(),
state: content.state.unwrap_or(ProviderState::Uninitialized),
// The real Provider starts as Uninitialized by default, but for testing purposes we
// start it as Pending.
state: content.state.unwrap_or(ProviderState::Pending),
bootstrapper,
current_height: content.current_height.unwrap_or_default(),
start_height: content.current_height,
Expand Down