@@ -336,14 +336,25 @@ pub enum OptionalTransitionOutcome<NextState, CurrentState> {
336336 Stasis ( CurrentState ) ,
337337}
338338
339+ /// Sealed trait to prevent external implementation of SessionEventTrait.
340+ pub ( crate ) mod sealed {
341+ pub trait Sealed { }
342+ }
343+
344+ /// Trait for session events that determines if an event represents a session closure.
345+ pub trait SessionEventTrait : sealed:: Sealed {
346+ /// Returns true if this event represents a session closure that should close the persister.
347+ fn is_closed_event ( & self ) -> bool ;
348+ }
349+
339350/// A session that can persist events to an append-only log.
340351/// A session represents a sequence of events generated by the BIP78 state machine.
341352/// The events can be replayed from the log to reconstruct the state machine's state.
342353pub trait SessionPersister {
343354 /// Errors that may arise from implementers storage layer
344355 type InternalStorageError : std:: error:: Error + Send + Sync + ' static ;
345356 /// Session events types that we are persisting
346- type SessionEvent ;
357+ type SessionEvent : SessionEventTrait ;
347358
348359 /// Appends to list of session updates, Receives generic events
349360 fn save_event ( & self , event : Self :: SessionEvent ) -> Result < ( ) , Self :: InternalStorageError > ;
@@ -512,12 +523,14 @@ trait InternalSessionPersister: SessionPersister {
512523 Err : std:: error:: Error ,
513524 {
514525 let RejectFatal ( event, error) = reject_fatal;
526+ let should_close = event. is_closed_event ( ) ;
515527 if let Err ( e) = self . save_event ( event) {
516528 return InternalPersistedError :: Storage ( e) ;
517529 }
518- // Session is in a terminal state, close it
519- if let Err ( e) = self . close ( ) {
520- return InternalPersistedError :: Storage ( e) ;
530+ if should_close {
531+ if let Err ( e) = self . close ( ) {
532+ return InternalPersistedError :: Storage ( e) ;
533+ }
521534 }
522535
523536 InternalPersistedError :: Fatal ( error)
@@ -531,14 +544,20 @@ impl<T: SessionPersister> InternalSessionPersister for T {}
531544#[ derive( Debug , Clone , serde:: Serialize , serde:: Deserialize ) ]
532545pub struct NoopPersisterEvent ;
533546
547+ impl sealed:: Sealed for NoopPersisterEvent { }
548+
549+ impl SessionEventTrait for NoopPersisterEvent {
550+ fn is_closed_event ( & self ) -> bool { false }
551+ }
552+
534553#[ derive( Debug , Clone ) ]
535554pub struct NoopSessionPersister < E = NoopPersisterEvent > ( std:: marker:: PhantomData < E > ) ;
536555
537556impl < E > Default for NoopSessionPersister < E > {
538557 fn default ( ) -> Self { Self ( std:: marker:: PhantomData ) }
539558}
540559
541- impl < E : ' static > SessionPersister for NoopSessionPersister < E > {
560+ impl < E : ' static + SessionEventTrait > SessionPersister for NoopSessionPersister < E > {
542561 type InternalStorageError = std:: convert:: Infallible ;
543562 type SessionEvent = E ;
544563
@@ -559,7 +578,7 @@ impl<E: 'static> SessionPersister for NoopSessionPersister<E> {
559578pub mod test_utils {
560579 use std:: sync:: { Arc , RwLock } ;
561580
562- use crate :: persist:: SessionPersister ;
581+ use crate :: persist:: { SessionEventTrait , SessionPersister } ;
563582
564583 #[ derive( Clone ) ]
565584 /// In-memory session persister for testing session replays and introspecting session events
@@ -583,7 +602,7 @@ pub mod test_utils {
583602
584603 impl < V > SessionPersister for InMemoryTestPersister < V >
585604 where
586- V : Clone + ' static ,
605+ V : Clone + ' static + SessionEventTrait ,
587606 {
588607 type InternalStorageError = std:: convert:: Infallible ;
589608 type SessionEvent = V ;
@@ -625,6 +644,12 @@ mod tests {
625644 #[ derive( Debug , Clone , Serialize , Deserialize ) ]
626645 pub struct InMemoryTestEvent ( String ) ;
627646
647+ impl crate :: persist:: sealed:: Sealed for InMemoryTestEvent { }
648+
649+ impl crate :: persist:: SessionEventTrait for InMemoryTestEvent {
650+ fn is_closed_event ( & self ) -> bool { self . 0 == "error close" }
651+ }
652+
628653 #[ derive( Debug , Clone , PartialEq ) ]
629654 /// Dummy error type for testing
630655 struct InMemoryTestError { }
@@ -783,6 +808,7 @@ mod tests {
783808 #[ test]
784809 fn test_maybe_success_transition ( ) {
785810 let event = InMemoryTestEvent ( "foo" . to_string ( ) ) ;
811+ let error_event = InMemoryTestEvent ( "error close" . to_string ( ) ) ;
786812 let test_cases: Vec <
787813 TestCase < ( ) , PersistedError < InMemoryTestError , std:: convert:: Infallible > > ,
788814 > = vec ! [
@@ -813,17 +839,14 @@ mod tests {
813839 // Fatal error
814840 TestCase {
815841 expected_result: ExpectedResult {
816- events: vec![ InMemoryTestEvent ( "error event" . to_string ( ) ) ] ,
842+ events: vec![ error_event . clone ( ) ] ,
817843 is_closed: true ,
818844 error: Some ( InternalPersistedError :: Fatal ( InMemoryTestError { } ) . into( ) ) ,
819845 success: None ,
820846 } ,
821847 test: Box :: new( move |persister| {
822- MaybeSuccessTransition :: fatal(
823- InMemoryTestEvent ( "error event" . to_string( ) ) ,
824- InMemoryTestError { } ,
825- )
826- . save( persister)
848+ MaybeSuccessTransition :: fatal( error_event. clone( ) , InMemoryTestError { } )
849+ . save( persister)
827850 } ) ,
828851 } ,
829852 ] ;
@@ -873,7 +896,7 @@ mod tests {
873896 TestCase {
874897 expected_result: ExpectedResult {
875898 events: vec![ error_event. clone( ) ] ,
876- is_closed: true ,
899+ is_closed: false ,
877900 error: Some ( InternalPersistedError :: Fatal ( InMemoryTestError { } ) . into( ) ) ,
878901 success: None ,
879902 } ,
@@ -893,7 +916,7 @@ mod tests {
893916 #[ test]
894917 fn test_maybe_success_transition_with_no_results ( ) {
895918 let event = InMemoryTestEvent ( "foo" . to_string ( ) ) ;
896- let error_event = InMemoryTestEvent ( "error event " . to_string ( ) ) ;
919+ let error_event = InMemoryTestEvent ( "error close " . to_string ( ) ) ;
897920 let current_state = "Current state" . to_string ( ) ;
898921 let success_value = "Success value" . to_string ( ) ;
899922 let test_cases: Vec <
@@ -1010,7 +1033,7 @@ mod tests {
10101033 TestCase {
10111034 expected_result: ExpectedResult {
10121035 events: vec![ error_event. clone( ) ] ,
1013- is_closed: true ,
1036+ is_closed: false ,
10141037 error: Some ( InternalPersistedError :: Fatal ( InMemoryTestError { } ) . into( ) ) ,
10151038 success: None ,
10161039 } ,
0 commit comments