Commit d70d64e
committed
Add
`SessionPersister` is an alternative to `Persister` designed to persist
not just the initial state of a BIP78 type state machine, but the full
sequence of state transitions. Its explicit purpose is to allow sessions
to be replayed from their event history and to give applications the
ability to introspect their session’s progress.
A `SessionPersister` is scoped to a specific BIP78 sender or receiver
session. Each session consists of events—discrete pieces of information
obtained during execution. These session events are stored via the
`save_event` method. When an application resumes a session, it loads
these events into a replayer (not included in this commit) to recover
the latest session state. If the type state reaches its terminal state
or a fatal error occurs, the session is marked as closed via `close()`.
Application developers should **not** interact directly with
`SessionPersister`. Instead, they interact indirectly by processing
state transition objects. These objects represent the possible outcomes
of attempting a state transition, and they must be processed for the
type state to advance or terminate.
There are six kinds of BIP78 state transition outcomes:
* A successful state transition that always progresses.
* A transition that may result in a **transient error**. In these cases,
the application should retry the session from its current state. These
errors originate outside of `rust-payjoin`. E.g an
`ImplementationError` triggered when executing an `InputsSeen` closure.
* A **fatal transition** that must close the session. These errors are
unrecoverable, requiring the fallback transaction to be broadcast.
Fatal transitions also include an event to be persisted for auditing
purposes and may also contain a transient error.
* Transitions that are either fatal or have no result (interpreted as
success). This is common for transitions handling responses to BIP78
subdirectory GET requests.
* A transition that marks the final, successful state of the type state.
* The **initial transition**, which is a special case. If it fails,
there is no prior state to retry from and nothing to save or close.
State transitions are opaque to the application. Each transition method
implements a `save()` function, which internally delegates to the
appropriate `InternalSessionPersister` trait method. These internal
methods are strongly typed to ensure correctness and are not accessible
to the application layer. Only the `save()` methods are exposed.
Each `save()` call returns a `Result` indicating either the next state
transition (on success) or a `PersistedError`, which captures all
possible failure modes e.g., `Fatal`, `Transient`, etc.SessionPersister trait1 parent 76b1b87 commit d70d64e
1 file changed
+988
-0
lines changed
0 commit comments