@@ -58,6 +58,7 @@ use sp_runtime::{
5858} ;
5959
6060pub mod bls12_381;
61+ pub mod migrations;
6162pub mod types;
6263pub mod utils;
6364pub mod verifier;
@@ -91,6 +92,8 @@ pub const QUICKNET_CHAIN_HASH: &str =
9192const CHAIN_HASH : & str = QUICKNET_CHAIN_HASH ;
9293
9394pub const MAX_PULSES_TO_FETCH : u64 = 50 ;
95+ pub const MAX_KEPT_PULSES : u64 = 216_000 ; // 1 week
96+ pub const MAX_REMOVED_PULSES : u64 = 100 ;
9497
9598/// Defines application identifier for crypto keys of this module.
9699///
@@ -212,12 +215,24 @@ pub mod pallet {
212215 }
213216 }
214217
218+ /// Define a maximum length for the migration key
219+ type MigrationKeyMaxLen = ConstU32 < 128 > ;
220+
221+ /// Storage for migration run status
222+ #[ pallet:: storage]
223+ pub type HasMigrationRun < T : Config > =
224+ StorageMap < _ , Identity , BoundedVec < u8 , MigrationKeyMaxLen > , bool , ValueQuery > ;
225+
215226 /// map round number to pulse
216227 #[ pallet:: storage]
217228 pub type Pulses < T : Config > = StorageMap < _ , Blake2_128Concat , RoundNumber , Pulse , OptionQuery > ;
218229
219230 #[ pallet:: storage]
220- pub ( super ) type LastStoredRound < T : Config > = StorageValue < _ , RoundNumber , ValueQuery > ;
231+ pub type LastStoredRound < T : Config > = StorageValue < _ , RoundNumber , ValueQuery > ;
232+
233+ /// oldest stored round
234+ #[ pallet:: storage]
235+ pub type OldestStoredRound < T : Config > = StorageValue < _ , RoundNumber , ValueQuery > ;
221236
222237 /// Defines the block when next unsigned transaction will be accepted.
223238 ///
@@ -261,6 +276,14 @@ pub mod pallet {
261276 log:: debug!( "Drand: Failed to fetch pulse from drand. {e:?}" ) ;
262277 }
263278 }
279+ fn on_runtime_upgrade ( ) -> frame_support:: weights:: Weight {
280+ /* let weight = */
281+ frame_support:: weights:: Weight :: from_parts ( 0 , 0 ) /*;*/
282+
283+ //weight = weight.saturating_add(migrations::migrate_prune_old_pulses::<T>());
284+
285+ //weight
286+ }
264287 }
265288
266289 #[ pallet:: validate_unsigned]
@@ -308,8 +331,8 @@ pub mod pallet {
308331 /// Verify and write a pulse from the beacon into the runtime
309332 #[ pallet:: call_index( 0 ) ]
310333 #[ pallet:: weight( Weight :: from_parts( 5_708_000_000 , 0 )
311- . saturating_add( T :: DbWeight :: get( ) . reads( 2_u64 ) )
312- . saturating_add( T :: DbWeight :: get( ) . writes( 3_u64 ) ) ) ]
334+ . saturating_add( T :: DbWeight :: get( ) . reads( 3_u64 ) )
335+ . saturating_add( T :: DbWeight :: get( ) . writes( 4_u64 ) ) ) ]
313336 pub fn write_pulse (
314337 origin : OriginFor < T > ,
315338 pulses_payload : PulsesPayload < T :: Public , BlockNumberFor < T > > ,
@@ -321,6 +344,10 @@ pub mod pallet {
321344 let mut last_stored_round = LastStoredRound :: < T > :: get ( ) ;
322345 let mut new_rounds = Vec :: new ( ) ;
323346
347+ let oldest_stored_round = OldestStoredRound :: < T > :: get ( ) ;
348+ let is_first_storage = last_stored_round == 0 && oldest_stored_round == 0 ;
349+ let mut first_new_round: Option < RoundNumber > = None ;
350+
324351 for pulse in & pulses_payload. pulses {
325352 let is_verified = T :: Verifier :: verify ( config. clone ( ) , pulse. clone ( ) )
326353 . map_err ( |_| Error :: < T > :: PulseVerificationError ) ?;
@@ -339,12 +366,25 @@ pub mod pallet {
339366
340367 // Collect the new round
341368 new_rounds. push ( pulse. round ) ;
369+
370+ // Set the first new round if this is the initial storage
371+ if is_first_storage && first_new_round. is_none ( ) {
372+ first_new_round = Some ( pulse. round ) ;
373+ }
342374 }
343375 }
344376
345377 // Update LastStoredRound storage
346378 LastStoredRound :: < T > :: put ( last_stored_round) ;
347379
380+ // Set OldestStoredRound if this was the first storage
381+ if let Some ( first_round) = first_new_round {
382+ OldestStoredRound :: < T > :: put ( first_round) ;
383+ }
384+
385+ // Prune old pulses
386+ Self :: prune_old_pulses ( last_stored_round) ;
387+
348388 // Update the next unsigned block number
349389 let current_block = frame_system:: Pallet :: < T > :: block_number ( ) ;
350390 <NextUnsignedAt < T > >:: put ( current_block) ;
@@ -628,6 +668,24 @@ impl<T: Config> Pallet<T> {
628668 . propagate ( true )
629669 . build ( )
630670 }
671+
672+ fn prune_old_pulses ( last_stored_round : RoundNumber ) {
673+ let mut oldest = OldestStoredRound :: < T > :: get ( ) ;
674+ if oldest == 0 {
675+ return ;
676+ }
677+
678+ let mut removed: u64 = 0 ;
679+ while last_stored_round. saturating_sub ( oldest) + 1 > MAX_KEPT_PULSES
680+ && removed < MAX_REMOVED_PULSES
681+ {
682+ Pulses :: < T > :: remove ( oldest) ;
683+ oldest = oldest. saturating_add ( 1 ) ;
684+ removed = removed. saturating_add ( 1 ) ;
685+ }
686+
687+ OldestStoredRound :: < T > :: put ( oldest) ;
688+ }
631689}
632690
633691/// construct a message (e.g. signed by drand)
0 commit comments