@@ -18,6 +18,9 @@ use mithril_common::{
18
18
19
19
use mithril_common:: StdError ;
20
20
21
+ /// Delete stake pools for Epoch older than this.
22
+ const STAKE_POOL_PRUNE_EPOCH_THRESHOLD : u64 = 2 ;
23
+
21
24
/// Stake pool as read from Chain.
22
25
/// TODO remove this compile directive ↓
23
26
#[ allow( dead_code) ]
@@ -186,20 +189,62 @@ impl<'conn> Provider<'conn> for UpdateStakePoolProvider<'conn> {
186
189
}
187
190
}
188
191
192
+ /// Provider to remove old data from the stake_pool table
193
+ pub struct DeleteStakePoolProvider < ' conn > {
194
+ connection : & ' conn Connection ,
195
+ }
196
+
197
+ impl < ' conn > Provider < ' conn > for DeleteStakePoolProvider < ' conn > {
198
+ type Entity = StakePool ;
199
+
200
+ fn get_connection ( & ' conn self ) -> & ' conn Connection {
201
+ self . connection
202
+ }
203
+
204
+ fn get_definition ( & self , condition : & str ) -> String {
205
+ // it is important to alias the fields with the same name as the table
206
+ // since the table cannot be aliased in a RETURNING statement in SQLite.
207
+ let projection = Self :: Entity :: get_projection ( )
208
+ . expand ( SourceAlias :: new ( & [ ( "{:stake_pool:}" , "stake_pool" ) ] ) ) ;
209
+
210
+ format ! ( "delete from stake_pool where {condition} returning {projection}" )
211
+ }
212
+ }
213
+
214
+ impl < ' conn > DeleteStakePoolProvider < ' conn > {
215
+ /// Create a new instance
216
+ pub fn new ( connection : & ' conn Connection ) -> Self {
217
+ Self { connection }
218
+ }
219
+
220
+ /// Create the SQL condition to prune data older than the given Epoch.
221
+ fn get_prune_condition ( & self , epoch_threshold : Epoch ) -> WhereCondition {
222
+ let epoch_value = Value :: Integer ( i64:: try_from ( epoch_threshold. 0 ) . unwrap ( ) ) ;
223
+
224
+ WhereCondition :: new ( "epoch < ?*" , vec ! [ epoch_value] )
225
+ }
226
+
227
+ /// Prune the stake pools data older than the given epoch.
228
+ pub fn prune ( & self , epoch_threshold : Epoch ) -> Result < EntityCursor < StakePool > , StdError > {
229
+ let filters = self . get_prune_condition ( epoch_threshold) ;
230
+
231
+ self . find ( filters)
232
+ }
233
+ }
189
234
/// Service to deal with stake pools (read & write).
190
- pub struct StakePoolRepository {
235
+ pub struct StakePoolStore {
191
236
connection : Arc < Mutex < Connection > > ,
192
237
}
193
238
194
- impl StakePoolRepository {
239
+ impl StakePoolStore {
195
240
/// Create a new StakePool service
196
241
pub fn new ( connection : Arc < Mutex < Connection > > ) -> Self {
197
242
Self { connection }
198
243
}
199
244
}
200
245
201
246
#[ async_trait]
202
- impl StakeStorer for StakePoolRepository {
247
+ impl StakeStorer for StakePoolStore {
203
248
async fn save_stakes (
204
249
& self ,
205
250
epoch : Epoch ,
@@ -221,6 +266,12 @@ impl StakeStorer for StakePoolRepository {
221
266
. map_err ( |e| AdapterError :: GeneralError ( format ! ( "{e}" ) ) ) ?;
222
267
new_stakes. insert ( pool_id. to_string ( ) , stake_pool. stake ) ;
223
268
}
269
+ // Clean useless old stake distributions if needed.
270
+ if epoch. 0 > STAKE_POOL_PRUNE_EPOCH_THRESHOLD {
271
+ let _ = DeleteStakePoolProvider :: new ( connection)
272
+ . prune ( Epoch ( epoch. 0 - STAKE_POOL_PRUNE_EPOCH_THRESHOLD ) )
273
+ . map_err ( AdapterError :: InitializationError ) ?;
274
+ }
224
275
connection
225
276
. execute ( "commit transaction" )
226
277
. map_err ( |e| AdapterError :: QueryError ( e. into ( ) ) ) ?;
@@ -293,4 +344,15 @@ mod tests {
293
344
params
294
345
) ;
295
346
}
347
+
348
+ #[ test]
349
+ fn prune ( ) {
350
+ let connection = Connection :: open ( ":memory:" ) . unwrap ( ) ;
351
+ let provider = DeleteStakePoolProvider :: new ( & connection) ;
352
+ let condition = provider. get_prune_condition ( Epoch ( 5 ) ) ;
353
+ let ( condition, params) = condition. expand ( ) ;
354
+
355
+ assert_eq ! ( "epoch < ?1" . to_string( ) , condition) ;
356
+ assert_eq ! ( vec![ Value :: Integer ( 5 ) ] , params) ;
357
+ }
296
358
}
0 commit comments