@@ -215,12 +215,13 @@ impl CardanoTransactionRepository {
215215 Ok ( ( ) )
216216 }
217217
218- /// Get the block number for a given slot number
219- pub async fn get_block_number_by_slot_number (
218+ /// Get the closest block number above a given slot number
219+ pub async fn get_closest_block_number_above_slot_number (
220220 & self ,
221221 slot_number : SlotNumber ,
222222 ) -> StdResult < Option < BlockNumber > > {
223- let query = GetCardanoTransactionQuery :: by_slot_number ( slot_number) ;
223+ let query =
224+ GetCardanoTransactionQuery :: with_highest_block_number_below_slot_number ( slot_number) ;
224225 let record = self . connection_pool . connection ( ) ?. fetch_first ( query) ?;
225226
226227 Ok ( record. map ( |r| r. block_number ) )
@@ -277,7 +278,7 @@ impl CardanoTransactionRepository {
277278 ///
278279 /// * Remove transactions with block number strictly greater than the given block number
279280 /// * Remove block range roots that have lower bound range strictly above the given block number
280- pub async fn remove_rolled_back_transactions_and_block_range (
281+ pub async fn remove_rolled_back_transactions_and_block_range_by_block_number (
281282 & self ,
282283 block_number : BlockNumber ,
283284 ) -> StdResult < ( ) > {
@@ -293,6 +294,25 @@ impl CardanoTransactionRepository {
293294
294295 Ok ( ( ) )
295296 }
297+
298+ /// Remove transactions and block range roots that are in a rolled-back fork
299+ ///
300+ /// * Remove transactions with closest block number strictly greater than the given slot number if exists
301+ /// * Remove block range roots that have lower bound range strictly above the aforementioned block number
302+ pub async fn remove_rolled_back_transactions_and_block_range_by_slot_number (
303+ & self ,
304+ slot_number : SlotNumber ,
305+ ) -> StdResult < ( ) > {
306+ if let Some ( block_number) = self
307+ . get_closest_block_number_above_slot_number ( slot_number)
308+ . await ?
309+ {
310+ self . remove_rolled_back_transactions_and_block_range_by_block_number ( block_number)
311+ . await ?;
312+ }
313+
314+ Ok ( ( ) )
315+ }
296316}
297317
298318#[ async_trait]
@@ -910,7 +930,7 @@ mod tests {
910930 }
911931
912932 #[ tokio:: test]
913- async fn repository_get_block_number_by_slot_number ( ) {
933+ async fn repository_get_closest_block_number_by_slot_number ( ) {
914934 let connection = cardano_tx_db_connection ( ) . unwrap ( ) ;
915935 let repository = CardanoTransactionRepository :: new ( Arc :: new (
916936 SqliteConnectionPool :: build_from_connection ( connection) ,
@@ -927,7 +947,7 @@ mod tests {
927947 . unwrap ( ) ;
928948
929949 let transaction_block_number_retrieved = repository
930- . get_block_number_by_slot_number ( SlotNumber ( 500 ) )
950+ . get_closest_block_number_above_slot_number ( SlotNumber ( 500 ) )
931951 . await
932952 . unwrap ( ) ;
933953
@@ -1215,10 +1235,113 @@ mod tests {
12151235 . unwrap ( ) ;
12161236
12171237 repository
1218- . remove_rolled_back_transactions_and_block_range ( BlockRange :: LENGTH * 3 )
1238+ . remove_rolled_back_transactions_and_block_range_by_block_number ( BlockRange :: LENGTH * 3 )
12191239 . await
12201240 . unwrap ( ) ;
12211241 assert_eq ! ( 2 , repository. get_all_transactions( ) . await . unwrap( ) . len( ) ) ;
12221242 assert_eq ! ( 2 , repository. get_all_block_range_root( ) . unwrap( ) . len( ) ) ;
12231243 }
1244+
1245+ #[ tokio:: test]
1246+ async fn remove_rolled_back_transactions_and_block_range_by_slot_number ( ) {
1247+ fn transaction_record (
1248+ block_number : BlockNumber ,
1249+ slot_number : SlotNumber ,
1250+ tx_hash : & str ,
1251+ ) -> CardanoTransactionRecord {
1252+ CardanoTransactionRecord :: new (
1253+ tx_hash,
1254+ block_number,
1255+ slot_number,
1256+ format ! ( "block-hash-{}" , block_number) ,
1257+ )
1258+ }
1259+
1260+ let repository = CardanoTransactionRepository :: new ( Arc :: new (
1261+ SqliteConnectionPool :: build ( 1 , cardano_tx_db_connection) . unwrap ( ) ,
1262+ ) ) ;
1263+
1264+ repository
1265+ . create_transactions ( vec ! [
1266+ transaction_record( BlockNumber ( 10 ) , SlotNumber ( 50 ) , "tx-hash-1" ) ,
1267+ transaction_record( BlockNumber ( 11 ) , SlotNumber ( 51 ) , "tx-hash-2" ) ,
1268+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-3" ) ,
1269+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-4" ) ,
1270+ transaction_record( BlockNumber ( 101 ) , SlotNumber ( 100 ) , "tx-hash-5" ) ,
1271+ transaction_record( BlockNumber ( 202 ) , SlotNumber ( 200 ) , "tx-hash-56" ) ,
1272+ ] )
1273+ . await
1274+ . unwrap ( ) ;
1275+
1276+ {
1277+ repository
1278+ . remove_rolled_back_transactions_and_block_range_by_slot_number ( SlotNumber ( 110 ) )
1279+ . await
1280+ . expect ( "Failed to remove rolled back transactions" ) ;
1281+
1282+ let transactions = repository
1283+ . get_all ( )
1284+ . await
1285+ . unwrap ( )
1286+ . into_iter ( )
1287+ . map ( |v| v. into ( ) )
1288+ . collect :: < Vec < _ > > ( ) ;
1289+ assert_eq ! (
1290+ vec![
1291+ transaction_record( BlockNumber ( 10 ) , SlotNumber ( 50 ) , "tx-hash-1" ) ,
1292+ transaction_record( BlockNumber ( 11 ) , SlotNumber ( 51 ) , "tx-hash-2" ) ,
1293+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-3" ) ,
1294+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-4" ) ,
1295+ transaction_record( BlockNumber ( 101 ) , SlotNumber ( 100 ) , "tx-hash-5" ) ,
1296+ ] ,
1297+ transactions
1298+ ) ;
1299+ }
1300+
1301+ {
1302+ repository
1303+ . remove_rolled_back_transactions_and_block_range_by_slot_number ( SlotNumber ( 53 ) )
1304+ . await
1305+ . expect ( "Failed to remove rolled back transactions" ) ;
1306+
1307+ let transactions = repository
1308+ . get_all ( )
1309+ . await
1310+ . unwrap ( )
1311+ . into_iter ( )
1312+ . map ( |v| v. into ( ) )
1313+ . collect :: < Vec < _ > > ( ) ;
1314+ assert_eq ! (
1315+ vec![
1316+ transaction_record( BlockNumber ( 10 ) , SlotNumber ( 50 ) , "tx-hash-1" ) ,
1317+ transaction_record( BlockNumber ( 11 ) , SlotNumber ( 51 ) , "tx-hash-2" ) ,
1318+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-3" ) ,
1319+ transaction_record( BlockNumber ( 13 ) , SlotNumber ( 52 ) , "tx-hash-4" ) ,
1320+ ] ,
1321+ transactions
1322+ ) ;
1323+ }
1324+
1325+ {
1326+ repository
1327+ . remove_rolled_back_transactions_and_block_range_by_slot_number ( SlotNumber ( 51 ) )
1328+ . await
1329+ . expect ( "Failed to remove rolled back transactions" ) ;
1330+
1331+ let transactions = repository
1332+ . get_all ( )
1333+ . await
1334+ . unwrap ( )
1335+ . into_iter ( )
1336+ . map ( |v| v. into ( ) )
1337+ . collect :: < Vec < _ > > ( ) ;
1338+ assert_eq ! (
1339+ vec![
1340+ transaction_record( BlockNumber ( 10 ) , SlotNumber ( 50 ) , "tx-hash-1" ) ,
1341+ transaction_record( BlockNumber ( 11 ) , SlotNumber ( 51 ) , "tx-hash-2" ) ,
1342+ ] ,
1343+ transactions
1344+ ) ;
1345+ }
1346+ }
12241347}
0 commit comments