@@ -2,30 +2,28 @@ use std::sync::atomic::{AtomicU8, Ordering};
22use std:: sync:: Arc ;
33use std:: time:: Duration ;
44
5- use apollo_batcher_types:: batcher_types:: GetHeightResponse ;
6- use apollo_batcher_types:: communication:: SharedBatcherClient ;
75use apollo_l1_provider_types:: SharedL1ProviderClient ;
86use apollo_state_sync_types:: communication:: SharedStateSyncClient ;
97use indexmap:: IndexSet ;
108use starknet_api:: block:: BlockNumber ;
119use starknet_api:: transaction:: TransactionHash ;
12- use tokio:: sync:: OnceCell ;
13- use tracing:: { debug, error, info} ;
10+ use tracing:: debug;
1411
15- pub type LazyCatchUpHeight = Arc < OnceCell < BlockNumber > > ;
12+ // When the Provider gets a commit_block that is too high, it starts bootstrapping.
13+ // The commit is rejected by the provider, so it must use sync to catch up to the height of the
14+ // commit, including that height. The sync task continues until reaching the target height,
15+ // inclusive, and only after the commit_block (from sync) causes the Provider's current height to be
16+ // one above the target height, is the backlog applied. Once done with the sync+backlog, the current
17+ // height should be one above the last commit in the backlog, which makes it ready for the next
18+ // commit_block from the batcher.
1619
1720/// Caches commits to be applied later. This flow is only relevant while the node is starting up.
1821#[ derive( Clone ) ]
1922pub struct Bootstrapper {
20- /// The catch-up height for the bootstrapper is the batcher height (unless overridden
21- /// explicitly). This value, due to infra constraints as of now, is only fetchable _after_
22- /// the provider is running, and not during its initialization, hence we are forced to
23- /// lazily fetch it at runtime.
24- pub catch_up_height : LazyCatchUpHeight ,
23+ pub catch_up_height : BlockNumber ,
2524 pub sync_retry_interval : Duration ,
2625 pub commit_block_backlog : Vec < CommitBlockBacklog > ,
2726 pub l1_provider_client : SharedL1ProviderClient ,
28- pub batcher_client : SharedBatcherClient ,
2927 pub sync_client : SharedStateSyncClient ,
3028 // Keep track of sync task for health checks and logging status.
3129 pub sync_task_handle : SyncTaskHandle ,
@@ -39,16 +37,14 @@ impl Bootstrapper {
3937
4038 pub fn new (
4139 l1_provider_client : SharedL1ProviderClient ,
42- batcher_client : SharedBatcherClient ,
4340 sync_client : SharedStateSyncClient ,
4441 sync_retry_interval : Duration ,
45- catch_up_height : LazyCatchUpHeight ,
42+ catch_up_height : BlockNumber ,
4643 ) -> Self {
4744 Self {
4845 sync_retry_interval,
4946 commit_block_backlog : Default :: default ( ) ,
5047 l1_provider_client,
51- batcher_client,
5248 sync_client,
5349 sync_task_handle : SyncTaskHandle :: NotStartedYet ,
5450 n_sync_health_check_failures : Default :: default ( ) ,
@@ -57,12 +53,8 @@ impl Bootstrapper {
5753 }
5854
5955 /// Check if the caller has caught up with the bootstrapper.
60- /// If catch_up_height is unset, the batcher isn't even ready yet.
6156 pub fn is_caught_up ( & self , current_provider_height : BlockNumber ) -> bool {
62- let is_caught_up = match self . catch_up_height ( ) {
63- Some ( catch_up_height) => current_provider_height > catch_up_height,
64- None => current_provider_height == BlockNumber ( 0 ) ,
65- } ;
57+ let is_caught_up = current_provider_height > self . catch_up_height ;
6658
6759 self . sync_task_health_check ( is_caught_up) ;
6860
@@ -88,25 +80,29 @@ impl Bootstrapper {
8880
8981 /// Spawns async task that produces and sends commit block messages to the provider, according
9082 /// to information from the batcher and sync clients, until the provider is caught up.
91- pub async fn start_l2_sync ( & mut self , current_provider_height : BlockNumber ) {
83+ pub fn start_l2_sync (
84+ & mut self ,
85+ current_provider_height : BlockNumber ,
86+ catch_up_height : BlockNumber ,
87+ ) {
88+ self . catch_up_height = catch_up_height;
9289 // FIXME: spawning a task like this is evil.
9390 // However, we aren't using the task executor, so no choice :(
9491 // Once we start using a centralized threadpool, spawn through it instead of the
9592 // tokio runtime.
9693 let sync_task_handle = tokio:: spawn ( l2_sync_task (
9794 self . l1_provider_client . clone ( ) ,
98- self . batcher_client . clone ( ) ,
9995 self . sync_client . clone ( ) ,
10096 current_provider_height,
101- self . catch_up_height . clone ( ) ,
97+ catch_up_height,
10298 self . sync_retry_interval ,
10399 ) ) ;
104100
105101 self . sync_task_handle = SyncTaskHandle :: Started ( sync_task_handle. into ( ) ) ;
106102 }
107103
108- pub fn catch_up_height ( & self ) -> Option < BlockNumber > {
109- self . catch_up_height . get ( ) . copied ( )
104+ pub fn catch_up_height ( & self ) -> BlockNumber {
105+ self . catch_up_height
110106 }
111107
112108 pub fn sync_started ( & self ) -> bool {
@@ -155,36 +151,17 @@ impl std::fmt::Debug for Bootstrapper {
155151
156152async fn l2_sync_task (
157153 l1_provider_client : SharedL1ProviderClient ,
158- batcher_client : SharedBatcherClient ,
159154 sync_client : SharedStateSyncClient ,
160155 mut current_height : BlockNumber ,
161- catch_up_height : LazyCatchUpHeight ,
156+ catch_up_height : BlockNumber ,
162157 retry_interval : Duration ,
163158) {
164- info ! ( "Try fetching batcher height to initialize catch up point" ) ;
165- while !catch_up_height. initialized ( ) {
166- let Ok ( GetHeightResponse { height : batcher_height } ) = batcher_client. get_height ( ) . await
167- else {
168- error ! ( "Batcher height request failed. Retrying..." ) ;
169- tokio:: time:: sleep ( retry_interval) . await ;
170- continue ;
171- } ;
172-
173- let Some ( batcher_latest_block_number) = batcher_height. prev ( ) else {
174- info ! ( "Batcher height is 0, no need to catch up. exiting..." ) ;
175- return ;
176- } ;
177-
178- info ! ( "Catch up height set: {batcher_latest_block_number}" ) ;
179- catch_up_height
180- . set ( batcher_latest_block_number)
181- . expect ( "This is the only write-point, cannot fail" )
182- }
183- let catch_up_height = * catch_up_height. get ( ) . expect ( "Initialized above" ) ;
184-
185159 while current_height <= catch_up_height {
186160 // TODO(Gilad): add tracing instrument.
187- debug ! ( "Try syncing L1Provider with L2 height: {}" , current_height) ;
161+ debug ! (
162+ "Syncing L1Provider with L2 height: {} to target height: {}" ,
163+ current_height, catch_up_height
164+ ) ;
188165 let block = sync_client. get_block ( current_height) . await . inspect_err ( |err| debug ! ( "{err}" ) ) ;
189166
190167 match block {
0 commit comments