@@ -11,7 +11,7 @@ use rand::RngCore;
1111use tokio:: fs:: { self , File } ;
1212use tokio:: io:: { self , AsyncReadExt , AsyncWriteExt } ;
1313use tokio:: sync:: { oneshot, Mutex } ;
14- use tracing:: trace;
14+ use tracing:: { trace, warn } ;
1515
1616use crate :: db:: { Db as DbTrait , Error as DbError } ;
1717
@@ -21,12 +21,6 @@ use crate::db::{Db as DbTrait, Error as DbError};
2121/// mailboxes/tx, ~4K txs/block, and ~144 blocks/24h.
2222const DEFAULT_CAPACITY : usize = 1 << ( 1 + 12 + 8 ) ;
2323
24- /// How long a mailbox is retained before being pruned, regardless of
25- /// whether it has been read.
26- /// Matches the default receiver session lifetime
27- /// (`TWENTY_FOUR_HOURS_DEFAULT_EXPIRATION` in `payjoin::receive::v2`)
28- const DEFAULT_TTL : Duration = Duration :: from_secs ( 60 * 60 * 24 ) ; // 24 hours
29-
3024#[ derive( Debug ) ]
3125struct V2WaitMapEntry {
3226 receiver : future:: Shared < oneshot:: Receiver < Arc < Vec < u8 > > > > ,
@@ -49,7 +43,6 @@ pub(crate) struct Mailboxes {
4943 pending_v2 : HashMap < ShortId , V2WaitMapEntry > ,
5044 insert_order : VecDeque < ( SystemTime , ShortId ) > ,
5145 ttl : Duration ,
52- early_removal_count : usize ,
5346}
5447
5548#[ derive( Debug ) ]
@@ -194,7 +187,7 @@ impl DiskStorage {
194187}
195188
196189impl Mailboxes {
197- async fn init ( dir : PathBuf ) -> io:: Result < Self > {
190+ async fn init ( dir : PathBuf , ttl : Duration ) -> io:: Result < Self > {
198191 let storage = DiskStorage :: init ( dir) . await ?;
199192 let insert_order = storage. insert_order ( ) . await ?. into ( ) ;
200193 Ok ( Self {
@@ -203,8 +196,7 @@ impl Mailboxes {
203196 capacity : DEFAULT_CAPACITY ,
204197 pending_v1 : HashMap :: default ( ) ,
205198 pending_v2 : HashMap :: default ( ) ,
206- ttl : DEFAULT_TTL ,
207- early_removal_count : 0 ,
199+ ttl,
208200 } )
209201 }
210202}
@@ -216,8 +208,8 @@ pub struct FilesDb {
216208}
217209
218210impl FilesDb {
219- pub async fn init ( timeout : Duration , path : PathBuf ) -> io:: Result < Self > {
220- Ok ( Self { timeout, mailboxes : Arc :: new ( Mutex :: new ( Mailboxes :: init ( path) . await ?) ) } )
211+ pub async fn init ( timeout : Duration , path : PathBuf , ttl : Duration ) -> io:: Result < Self > {
212+ Ok ( Self { timeout, mailboxes : Arc :: new ( Mutex :: new ( Mailboxes :: init ( path, ttl ) . await ?) ) } )
221213 }
222214
223215 pub async fn prune ( & self ) -> io:: Result < Duration > { self . mailboxes . lock ( ) . await . prune ( ) . await }
@@ -437,9 +429,7 @@ impl Mailboxes {
437429 }
438430
439431 fn len ( & self ) -> usize {
440- ( self . insert_order . len ( ) - self . early_removal_count )
441- + self . pending_v1 . len ( )
442- + self . pending_v2 . len ( )
432+ self . insert_order . len ( ) + self . pending_v1 . len ( ) + self . pending_v2 . len ( )
443433 }
444434
445435 async fn maybe_prune ( & mut self ) -> io:: Result < Duration > {
@@ -467,36 +457,17 @@ impl Mailboxes {
467457 // Prune any fully expired mailboxes
468458 while let Some ( ( created, id) ) = self . insert_order . front ( ) . cloned ( ) {
469459 if created + self . ttl < now {
470- debug_assert ! ( self . insert_order. len( ) >= self . early_removal_count) ;
471460 _ = self . insert_order . pop_front ( ) ;
472461 if self . remove ( & id) . await ?. is_none ( ) {
473- self . early_removal_count = self
474- . early_removal_count
475- . checked_sub ( 1 )
476- . expect ( "early removal adjustment should never underflow" ) ;
462+ warn ! ( "Mailbox file missing during prune; possible external deletion or disk error" ) ;
463+ } else {
464+ trace ! ( "Pruned old mailbox {id}" ) ;
477465 }
478- debug_assert ! ( self . insert_order. len( ) >= self . early_removal_count) ;
479- trace ! ( "Pruned old mailbox {id}" ) ;
480466 } else {
481467 break ;
482468 }
483469 }
484470
485- // If no room was created, try to prune the oldest mailbox if
486- // it's over the TTL
487- debug_assert ! ( self . len( ) <= self . capacity) ;
488- if self . len ( ) == self . capacity {
489- if let Some ( ( created, id) ) = self . insert_order . front ( ) . cloned ( ) {
490- if created + self . ttl < now {
491- _ = self . insert_order . pop_front ( ) ;
492- self . remove ( & id) . await ?;
493- trace ! ( "Pruned mailbox {id} to make room" ) ;
494- } else {
495- trace ! ( "Nothing to prune, {} entries remain" , self . len( ) ) ;
496- }
497- }
498- }
499-
500471 Ok ( self . next_prune ( ) )
501472 }
502473
@@ -704,9 +675,13 @@ async fn test_disk_storage_mailboxes() -> std::io::Result<()> {
704675async fn test_mailbox_storage ( ) -> std:: io:: Result < ( ) > {
705676 let dir = tempfile:: tempdir ( ) ?;
706677
707- let db = FilesDb :: init ( Duration :: from_millis ( 10 ) , dir. path ( ) . to_owned ( ) )
708- . await
709- . expect ( "initializing mailbox database should succeed" ) ;
678+ let db = FilesDb :: init (
679+ Duration :: from_millis ( 10 ) ,
680+ dir. path ( ) . to_owned ( ) ,
681+ Duration :: from_secs ( 60 * 60 * 24 * 7 ) ,
682+ )
683+ . await
684+ . expect ( "initializing mailbox database should succeed" ) ;
710685
711686 let id = ShortId ( [ 0u8 ; 8 ] ) ;
712687 let contents = b"foo bar" ;
@@ -725,9 +700,13 @@ async fn test_mailbox_storage() -> std::io::Result<()> {
725700async fn test_v2_wait ( ) -> std:: io:: Result < ( ) > {
726701 let dir = tempfile:: tempdir ( ) ?;
727702
728- let db = FilesDb :: init ( Duration :: from_millis ( 1 ) , dir. path ( ) . to_owned ( ) )
729- . await
730- . expect ( "initializing mailbox database should succeed" ) ;
703+ let db = FilesDb :: init (
704+ Duration :: from_millis ( 1 ) ,
705+ dir. path ( ) . to_owned ( ) ,
706+ Duration :: from_secs ( 60 * 60 * 24 * 7 ) ,
707+ )
708+ . await
709+ . expect ( "initializing mailbox database should succeed" ) ;
731710
732711 let id = ShortId ( [ 0u8 ; 8 ] ) ;
733712 let contents = b"foo bar" ;
@@ -782,9 +761,13 @@ async fn test_v1_wait() -> std::io::Result<()> {
782761 let dir = tempfile:: tempdir ( ) ?;
783762
784763 let db = Arc :: new (
785- FilesDb :: init ( Duration :: from_millis ( 1 ) , dir. path ( ) . to_owned ( ) )
786- . await
787- . expect ( "initializing mailbox database should succeed" ) ,
764+ FilesDb :: init (
765+ Duration :: from_millis ( 1 ) ,
766+ dir. path ( ) . to_owned ( ) ,
767+ Duration :: from_secs ( 60 * 60 * 24 * 7 ) ,
768+ )
769+ . await
770+ . expect ( "initializing mailbox database should succeed" ) ,
788771 ) ;
789772
790773 let id = ShortId ( [ 0u8 ; 8 ] ) ;
@@ -829,9 +812,13 @@ async fn test_v1_data_minimization() -> std::io::Result<()> {
829812 let dir = tempfile:: tempdir ( ) ?;
830813
831814 let db = Arc :: new (
832- FilesDb :: init ( Duration :: from_millis ( 500 ) , dir. path ( ) . to_owned ( ) )
833- . await
834- . expect ( "initializing mailbox database should succeed" ) ,
815+ FilesDb :: init (
816+ Duration :: from_millis ( 500 ) ,
817+ dir. path ( ) . to_owned ( ) ,
818+ Duration :: from_secs ( 60 * 60 * 24 * 7 ) ,
819+ )
820+ . await
821+ . expect ( "initializing mailbox database should succeed" ) ,
835822 ) ;
836823
837824 let id = ShortId ( [ 0u8 ; 8 ] ) ;
@@ -884,9 +871,13 @@ async fn test_v1_data_minimization() -> std::io::Result<()> {
884871async fn test_prune ( ) -> std:: io:: Result < ( ) > {
885872 let dir = tempfile:: tempdir ( ) ?;
886873
887- let db = FilesDb :: init ( Duration :: from_millis ( 2 ) , dir. path ( ) . to_owned ( ) )
888- . await
889- . expect ( "initializing mailbox database should succeed" ) ;
874+ let db = FilesDb :: init (
875+ Duration :: from_millis ( 2 ) ,
876+ dir. path ( ) . to_owned ( ) ,
877+ Duration :: from_secs ( 60 * 60 * 24 * 7 ) ,
878+ )
879+ . await
880+ . expect ( "initializing mailbox database should succeed" ) ;
890881
891882 let ttl = Duration :: from_secs ( 600 ) ;
892883
0 commit comments