11use anyhow:: Result ;
22use futures:: future:: BoxFuture ;
3- use katana_db:: abstraction:: { Database , DbCursor , DbTx , DbTxMut } ;
3+ use katana_db:: abstraction:: { Database , DbCursor , DbTxMut } ;
44use katana_db:: tables;
55use katana_gateway_types:: { BlockStatus , StateUpdate as GatewayStateUpdate , StateUpdateWithBlock } ;
66use katana_primitives:: block:: {
@@ -98,74 +98,69 @@ impl<B> Blocks<B> {
9898 /// This removes entries from the following tables:
9999 /// - Headers, BlockHashes, BlockNumbers, BlockBodyIndices, BlockStatusses
100100 /// - TxNumbers, TxBlocks, TxHashes, TxTraces, Transactions, Receipts
101- fn unwind_blocks < Db : Database > ( db : & Db , unwind_to : BlockNumber ) -> Result < ( ) , crate :: Error > {
102- db. update ( |db_tx| -> Result < ( ) , katana_provider:: api:: ProviderError > {
103- // Get the tx_offset for the unwind_to block to know where to start deleting txs
104- let mut last_tx_num = None ;
105- if let Some ( indices) = db_tx. get :: < tables:: BlockBodyIndices > ( unwind_to) ? {
106- last_tx_num = Some ( indices. tx_offset + indices. tx_count ) ;
107- }
101+ fn unwind_blocks ( tx : & impl DbTxMut , unwind_to : BlockNumber ) -> Result < ( ) , crate :: Error > {
102+ // Get the tx_offset for the unwind_to block to know where to start deleting txs
103+ let mut last_tx_num = None ;
104+ if let Some ( indices) = tx. get :: < tables:: BlockBodyIndices > ( unwind_to) ? {
105+ last_tx_num = Some ( indices. tx_offset + indices. tx_count ) ;
106+ }
108107
109- // Remove all blocks after unwind_to
110- let mut blocks_to_remove = Vec :: new ( ) ;
111- let mut cursor = db_tx . cursor_mut :: < tables:: Headers > ( ) ?;
108+ // Remove all blocks after unwind_to
109+ let mut blocks_to_remove = Vec :: new ( ) ;
110+ let mut cursor = tx . cursor_mut :: < tables:: Headers > ( ) ?;
112111
113- // Find all blocks after unwind_to
114- if let Some ( ( block_num, _) ) = cursor. seek ( unwind_to + 1 ) ? {
112+ // Find all blocks after unwind_to
113+ if let Some ( ( block_num, _) ) = cursor. seek ( unwind_to + 1 ) ? {
114+ blocks_to_remove. push ( block_num) ;
115+ while let Some ( ( block_num, _) ) = cursor. next ( ) ? {
115116 blocks_to_remove. push ( block_num) ;
116- while let Some ( ( block_num, _) ) = cursor. next ( ) ? {
117- blocks_to_remove. push ( block_num) ;
118- }
119117 }
120- drop ( cursor) ;
118+ }
119+ drop ( cursor) ;
121120
122- // Remove block data
123- for block_num in blocks_to_remove {
124- // Get block hash before deleting
125- let block_hash = db_tx . get :: < tables:: BlockHashes > ( block_num) ?;
121+ // Remove block data
122+ for block_num in blocks_to_remove {
123+ // Get block hash before deleting
124+ let block_hash = tx . get :: < tables:: BlockHashes > ( block_num) ?;
126125
127- db_tx . delete :: < tables:: Headers > ( block_num, None ) ?;
128- db_tx . delete :: < tables:: BlockHashes > ( block_num, None ) ?;
129- db_tx . delete :: < tables:: BlockBodyIndices > ( block_num, None ) ?;
130- db_tx . delete :: < tables:: BlockStatusses > ( block_num, None ) ?;
126+ tx . delete :: < tables:: Headers > ( block_num, None ) ?;
127+ tx . delete :: < tables:: BlockHashes > ( block_num, None ) ?;
128+ tx . delete :: < tables:: BlockBodyIndices > ( block_num, None ) ?;
129+ tx . delete :: < tables:: BlockStatusses > ( block_num, None ) ?;
131130
132- if let Some ( hash) = block_hash {
133- db_tx. delete :: < tables:: BlockNumbers > ( hash, None ) ?;
134- }
131+ if let Some ( hash) = block_hash {
132+ tx. delete :: < tables:: BlockNumbers > ( hash, None ) ?;
135133 }
134+ }
136135
137- // Remove transaction data if we have a last_tx_num
138- if let Some ( start_tx_num) = last_tx_num {
139- let mut txs_to_remove = Vec :: new ( ) ;
140- let mut cursor = db_tx . cursor_mut :: < tables:: Transactions > ( ) ?;
136+ // Remove transaction data if we have a last_tx_num
137+ if let Some ( start_tx_num) = last_tx_num {
138+ let mut txs_to_remove = Vec :: new ( ) ;
139+ let mut cursor = tx . cursor_mut :: < tables:: Transactions > ( ) ?;
141140
142- if let Some ( ( tx_num, _) ) = cursor. seek ( start_tx_num) ? {
141+ if let Some ( ( tx_num, _) ) = cursor. seek ( start_tx_num) ? {
142+ txs_to_remove. push ( tx_num) ;
143+ while let Some ( ( tx_num, _) ) = cursor. next ( ) ? {
143144 txs_to_remove. push ( tx_num) ;
144- while let Some ( ( tx_num, _) ) = cursor. next ( ) ? {
145- txs_to_remove. push ( tx_num) ;
146- }
147145 }
148- drop ( cursor) ;
146+ }
147+ drop ( cursor) ;
149148
150- for tx_num in txs_to_remove {
151- // Get tx hash before deleting
152- let tx_hash = db_tx . get :: < tables:: TxHashes > ( tx_num) ?;
149+ for tx_num in txs_to_remove {
150+ // Get tx hash before deleting
151+ let tx_hash = tx . get :: < tables:: TxHashes > ( tx_num) ?;
153152
154- db_tx . delete :: < tables:: Transactions > ( tx_num, None ) ?;
155- db_tx . delete :: < tables:: TxHashes > ( tx_num, None ) ?;
156- db_tx . delete :: < tables:: TxBlocks > ( tx_num, None ) ?;
157- db_tx . delete :: < tables:: Receipts > ( tx_num, None ) ?;
158- db_tx . delete :: < tables:: TxTraces > ( tx_num, None ) ?;
153+ tx . delete :: < tables:: Transactions > ( tx_num, None ) ?;
154+ tx . delete :: < tables:: TxHashes > ( tx_num, None ) ?;
155+ tx . delete :: < tables:: TxBlocks > ( tx_num, None ) ?;
156+ tx . delete :: < tables:: Receipts > ( tx_num, None ) ?;
157+ tx . delete :: < tables:: TxTraces > ( tx_num, None ) ?;
159158
160- if let Some ( hash) = tx_hash {
161- db_tx. delete :: < tables:: TxNumbers > ( hash, None ) ?;
162- }
159+ if let Some ( hash) = tx_hash {
160+ tx. delete :: < tables:: TxNumbers > ( hash, None ) ?;
163161 }
164162 }
165-
166- Ok ( ( ) )
167- } )
168- . map_err ( katana_provider:: api:: ProviderError :: from) ??;
163+ }
169164
170165 Ok ( ( ) )
171166 }
@@ -229,7 +224,7 @@ where
229224 debug ! ( target: "stage" , id = %self . id( ) , unwind_to = %unwind_to, "Unwinding blocks." ) ;
230225
231226 // Unwind blocks using the database directly
232- Self :: unwind_blocks ( self . provider . db ( ) , unwind_to) ?;
227+ self . provider . db ( ) . update ( |tx| Self :: unwind_blocks ( tx , unwind_to) ) ? ?;
233228
234229 // Update checkpoint
235230 let provider_mut = self . provider . provider_mut ( ) ;
@@ -250,6 +245,9 @@ pub enum Error {
250245 #[ error( transparent) ]
251246 Provider ( #[ from] ProviderError ) ,
252247
248+ #[ error( transparent) ]
249+ Database ( #[ from] katana_db:: error:: DatabaseError ) ,
250+
253251 #[ error(
254252 "chain invariant violation: block {block_num} parent hash {parent_hash:#x} does not match \
255253 previous block hash {expected_hash:#x}"
0 commit comments