@@ -9,12 +9,15 @@ use mithril_common::entities::{
9
9
BlockHash , BlockNumber , BlockRange , CardanoTransaction , ImmutableFileNumber , SlotNumber ,
10
10
TransactionHash ,
11
11
} ;
12
+ use mithril_common:: signable_builder:: BlockRangeRootRetriever ;
12
13
use mithril_common:: StdResult ;
13
14
use mithril_persistence:: sqlite:: { Provider , SqliteConnection , WhereCondition } ;
15
+ use sqlite:: Value ;
14
16
15
17
use crate :: database:: provider:: {
16
- GetCardanoTransactionProvider , GetIntervalWithoutBlockRangeRootProvider ,
17
- InsertBlockRangeRootProvider , InsertCardanoTransactionProvider ,
18
+ GetBlockRangeRootProvider , GetCardanoTransactionProvider ,
19
+ GetIntervalWithoutBlockRangeRootProvider , InsertBlockRangeRootProvider ,
20
+ InsertCardanoTransactionProvider ,
18
21
} ;
19
22
use crate :: database:: record:: { BlockRangeRootRecord , CardanoTransactionRecord } ;
20
23
use crate :: TransactionStore ;
@@ -130,6 +133,48 @@ impl CardanoTransactionRepository {
130
133
131
134
Ok ( cursor. collect ( ) )
132
135
}
136
+
137
+ // TODO: remove this function when the Cardano transaction signature is based on block number instead of immutable number
138
+ async fn get_highest_block_number_for_immutable_number (
139
+ & self ,
140
+ immutable_file_number : ImmutableFileNumber ,
141
+ ) -> StdResult < Option < BlockNumber > > {
142
+ let sql =
143
+ "select max(block_number) as highest from cardano_tx where immutable_file_number <= $1;" ;
144
+ match self
145
+ . connection
146
+ . prepare ( sql)
147
+ . with_context ( || {
148
+ format ! (
149
+ "Prepare query error: SQL=`{}`" ,
150
+ & sql. replace( '\n' , " " ) . trim( )
151
+ )
152
+ } ) ?
153
+ . iter ( )
154
+ . bind :: < & [ ( _ , Value ) ] > ( & [ ( 1 , Value :: Integer ( immutable_file_number as i64 ) ) ] ) ?
155
+ . next ( )
156
+ {
157
+ None => Ok ( None ) ,
158
+ Some ( row) => {
159
+ let highest = row?. read :: < Option < i64 > , _ > ( 0 ) ;
160
+ highest
161
+ . map ( u64:: try_from)
162
+ . transpose ( )
163
+ . with_context ( ||
164
+ format ! ( "Integer field max(block_number) (value={highest:?}) is incompatible with u64 representation." )
165
+ )
166
+ }
167
+ }
168
+ }
169
+
170
+ #[ cfg( test) ]
171
+ pub ( crate ) async fn get_all ( & self ) -> StdResult < Vec < CardanoTransaction > > {
172
+ let provider = GetCardanoTransactionProvider :: new ( & self . connection ) ;
173
+ let filters = WhereCondition :: default ( ) ;
174
+ let transactions = provider. find ( filters) ?;
175
+
176
+ Ok ( transactions. map ( |record| record. into ( ) ) . collect :: < Vec < _ > > ( ) )
177
+ }
133
178
}
134
179
135
180
#[ cfg( test) ]
@@ -234,6 +279,29 @@ impl TransactionStore for CardanoTransactionRepository {
234
279
}
235
280
}
236
281
282
+ #[ async_trait]
283
+ impl BlockRangeRootRetriever for CardanoTransactionRepository {
284
+ async fn retrieve_block_range_roots (
285
+ & self ,
286
+ up_to_beacon : ImmutableFileNumber ,
287
+ ) -> StdResult < Box < dyn Iterator < Item = ( BlockRange , MKTreeNode ) > > > {
288
+ let block_number = self
289
+ . get_highest_block_number_for_immutable_number ( up_to_beacon)
290
+ . await ?
291
+ . unwrap_or ( 0 ) ;
292
+ let provider = GetBlockRangeRootProvider :: new ( & self . connection ) ;
293
+ let filters = provider. get_up_to_block_number_condition ( block_number) ;
294
+ let block_range_roots = provider. find ( filters) ?;
295
+ let iterator = block_range_roots
296
+ . into_iter ( )
297
+ . map ( |record| -> ( BlockRange , MKTreeNode ) { record. into ( ) } )
298
+ . collect :: < Vec < _ > > ( ) // TODO: remove this collect when we should ba able return the iterator directly
299
+ . into_iter ( ) ;
300
+
301
+ Ok ( Box :: new ( iterator) )
302
+ }
303
+ }
304
+
237
305
#[ cfg( test) ]
238
306
mod tests {
239
307
use mithril_persistence:: sqlite:: GetAllProvider ;
0 commit comments