33 boundary:: events:: settlement:: { GPv2SettlementContract , Indexer } ,
44 database:: {
55 Postgres ,
6+ ethflow_events:: event_retriever:: EthFlowRefundRetriever ,
67 onchain_order_events:: {
78 OnchainOrderParser ,
89 ethflow_events:: { EthFlowData , EthFlowDataForDb } ,
910 event_retriever:: CoWSwapOnchainOrdersContract ,
1011 } ,
1112 } ,
13+ domain:: settlement,
1214 event_updater:: EventUpdater ,
1315 } ,
1416 anyhow:: Result ,
1517 ethrpc:: block_stream:: { BlockInfo , CurrentBlockWatcher , into_stream} ,
16- futures:: StreamExt ,
18+ futures:: { FutureExt , StreamExt } ,
1719 prometheus:: {
1820 HistogramVec ,
1921 IntCounterVec ,
@@ -27,11 +29,13 @@ use {
2729 } ,
2830 tokio:: sync:: watch,
2931 tokio_stream:: wrappers:: WatchStream ,
32+ tracing:: Instrument ,
3033} ;
3134
3235/// Component to sync with the maintenance logic that runs in a background task.
33- /// This allows us to run the maintenance logic ASAP but still wait for it to
34- /// finish in a convenient manner.
36+ /// This allows us to run the maintenance logic as soon as we see a new block
37+ /// while still making the autopilot run loop only wait for updates that are
38+ /// essential for building new auctions.
3539#[ derive( Clone ) ]
3640pub struct MaintenanceSync {
3741 /// How long the autopilot wants to wait at most.
@@ -75,19 +79,26 @@ pub struct Maintenance {
7579 /// All indexing tasks to keep cow amms up to date.
7680 cow_amm_indexer : Vec < Arc < dyn Maintaining > > ,
7781 /// Tasks to index ethflow orders that were submitted onchain.
78- ethflow_indexer : Vec < EthflowIndexer > ,
82+ ethflow_order_indexer : Vec < EthflowOrderIndexer > ,
83+ /// Tasks to index ethflow refunds.
84+ ethflow_refund_indexer : Vec < EthflowRefundIndexer > ,
85+ /// Component to correctly attribute a settlement to a proposed solution.
86+ settlement_observer : settlement:: Observer ,
7987}
8088
8189impl Maintenance {
8290 pub fn new (
8391 settlement_indexer : EventUpdater < Indexer , GPv2SettlementContract > ,
8492 db_cleanup : Postgres ,
93+ settlement_observer : settlement:: Observer ,
8594 ) -> Self {
8695 Self {
8796 settlement_indexer,
8897 db_cleanup,
8998 cow_amm_indexer : Default :: default ( ) ,
90- ethflow_indexer : Default :: default ( ) ,
99+ ethflow_order_indexer : Default :: default ( ) ,
100+ ethflow_refund_indexer : Default :: default ( ) ,
101+ settlement_observer,
91102 }
92103 }
93104
@@ -108,7 +119,12 @@ impl Maintenance {
108119 . next ( )
109120 . await
110121 . expect ( "block stream terminated unexpectedly" ) ;
111- self . index_until_block ( block, & sender) . await ;
122+ self . index_until_block ( block, & sender)
123+ . instrument ( tracing:: info_span!(
124+ "autopilot_maintenance" ,
125+ block = block. number
126+ ) )
127+ . await ;
112128 }
113129 } ) ;
114130
@@ -122,33 +138,45 @@ impl Maintenance {
122138 metrics ( ) . last_seen_block . set ( block. number ) ;
123139 let start = Instant :: now ( ) ;
124140
125- if let Err ( err) = self . update_inner ( ) . await {
126- tracing:: warn!( ?err, block = block . number , "failed to run maintenance" ) ;
141+ if let Err ( err) = self . run_essential_maintenance ( ) . await {
142+ tracing:: warn!( ?err, "failed to run essential maintenance" ) ;
127143 metrics ( ) . updates . with_label_values ( & [ "error" ] ) . inc ( ) ;
128144 return ;
129145 }
130146
131147 tracing:: info!(
132- block = block. number,
133148 time = ?start. elapsed( ) ,
134- "successfully ran maintenance task "
149+ "successfully ran essential maintenance tasks "
135150 ) ;
136151 metrics ( ) . last_updated_block . set ( block. number ) ;
137152 metrics ( ) . updates . with_label_values ( & [ "success" ] ) . inc ( ) ;
138153 if let Err ( err) = last_processed_block. send ( block. number ) {
139154 tracing:: warn!( ?err, "nobody listening for processed blocks anymore" ) ;
140155 }
156+
157+ // only after we informed the run_loop that the essential updates are done we
158+ // kick off the optional maintenance tasks
159+ let start = Instant :: now ( ) ;
160+ if let Err ( err) = self . run_optional_maintenance ( ) . await {
161+ tracing:: warn!( ?err, "failed to run optional maintenance" ) ;
162+ return ;
163+ }
164+ tracing:: info!(
165+ time = ?start. elapsed( ) ,
166+ "successfully ran optional maintenance tasks"
167+ ) ;
141168 }
142169
143- async fn update_inner ( & self ) -> Result < ( ) > {
144- let _timer =
145- observe:: metrics:: metrics ( ) . on_auction_overhead_start ( "autopilot" , "maintenance_total" ) ;
170+ /// Runs all the maintenance tasks that are needed to ensure the next
171+ /// auction gets built using the most up-to-date information.
172+ async fn run_essential_maintenance ( & self ) -> Result < ( ) > {
173+ let _timer = observe:: metrics:: metrics ( )
174+ . on_auction_overhead_start ( "autopilot" , "maintenance_essential" ) ;
146175 tokio:: try_join!(
147176 Self :: timed_future(
148177 "settlement_indexer" ,
149178 self . settlement_indexer. run_maintenance( )
150179 ) ,
151- Self :: timed_future( "db_cleanup" , self . db_cleanup. run_maintenance( ) ) ,
152180 Self :: timed_future(
153181 "cow_amm_indexer" ,
154182 futures:: future:: try_join_all(
@@ -158,9 +186,9 @@ impl Maintenance {
158186 ) ,
159187 ) ,
160188 Self :: timed_future(
161- "ethflow_indexer " ,
189+ "ethflow_order_indexer " ,
162190 futures:: future:: try_join_all(
163- self . ethflow_indexer
191+ self . ethflow_order_indexer
164192 . iter( )
165193 . map( |indexer| indexer. run_maintenance( ) ) ,
166194 ) ,
@@ -170,10 +198,41 @@ impl Maintenance {
170198 Ok ( ( ) )
171199 }
172200
201+ /// Runs all the maintenance tasks that should run eventually but are not
202+ /// very time sensitive.
203+ async fn run_optional_maintenance ( & self ) -> Result < ( ) > {
204+ let _timer = observe:: metrics:: metrics ( )
205+ . on_auction_overhead_start ( "autopilot" , "maintenance_optional" ) ;
206+ tokio:: try_join!(
207+ Self :: timed_future( "db_cleanup" , self . db_cleanup. run_maintenance( ) ) ,
208+ Self :: timed_future(
209+ "ethflow_refund_indexer" ,
210+ futures:: future:: try_join_all(
211+ self . ethflow_refund_indexer
212+ . iter( )
213+ . map( |indexer| indexer. run_maintenance( ) ) ,
214+ ) ,
215+ ) ,
216+ Self :: timed_future(
217+ "settlement_attribution" ,
218+ self . settlement_observer
219+ . post_process_outstanding_settlement_transactions( )
220+ . map( |_| Ok ( ( ) ) )
221+ )
222+ ) ?;
223+
224+ Ok ( ( ) )
225+ }
226+
173227 /// Registers all maintenance tasks that are necessary to correctly support
174228 /// ethflow orders.
175- pub fn add_ethflow_indexer ( & mut self , ethflow_indexer : EthflowIndexer ) {
176- self . ethflow_indexer . push ( ethflow_indexer) ;
229+ pub fn add_ethflow_indexing (
230+ & mut self ,
231+ order_indexer : EthflowOrderIndexer ,
232+ refund_indexer : EthflowRefundIndexer ,
233+ ) {
234+ self . ethflow_order_indexer . push ( order_indexer) ;
235+ self . ethflow_refund_indexer . push ( refund_indexer) ;
177236 }
178237
179238 /// Registers all maintenance tasks that are necessary to correctly support
@@ -194,9 +253,11 @@ impl Maintenance {
194253 }
195254}
196255
197- type EthflowIndexer =
256+ type EthflowOrderIndexer =
198257 EventUpdater < OnchainOrderParser < EthFlowData , EthFlowDataForDb > , CoWSwapOnchainOrdersContract > ;
199258
259+ type EthflowRefundIndexer = EventUpdater < Postgres , EthFlowRefundRetriever > ;
260+
200261#[ derive( prometheus_metric_storage:: MetricStorage ) ]
201262#[ metric( subsystem = "autopilot_maintenance" ) ]
202263struct Metrics {
0 commit comments