Skip to content

Commit 4675726

Browse files
committed
WIP - remove uninitialized receiver session variant
1 parent 3950e85 commit 4675726

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

payjoin-cli/src/app/v2/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,6 @@ impl App {
345345
self.finalize_proposal(proposal, persister).await,
346346
ReceiveSession::PayjoinProposal(proposal) =>
347347
self.send_payjoin_proposal(proposal, persister).await,
348-
ReceiveSession::Uninitialized =>
349-
return Err(anyhow!("Uninitialized receiver session")),
350348
ReceiveSession::TerminalFailure =>
351349
return Err(anyhow!("Terminal receiver session")),
352350
}

payjoin/src/core/receive/v2/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ fn short_id_from_pubkey(pubkey: &HpkePublicKey) -> ShortId {
108108
sha256::Hash::hash(&pubkey.to_compressed_bytes()).into()
109109
}
110110

111+
pub(crate) fn process_initial_event(event: SessionEvent) -> Result<ReceiveSession, ReplayError> {
112+
match event {
113+
SessionEvent::Created(context) =>
114+
Ok(ReceiveSession::Initialized(Receiver { state: Initialized { context } })),
115+
_ => Err(InternalReplayError::InvalidEventForUninitializedSession(Box::new(event)).into()),
116+
}
117+
}
118+
111119
/// Represents the various states of a Payjoin receiver session during the protocol flow.
112120
/// Each variant parameterizes a `Receiver` with a specific state type, except for [`ReceiveSession::Uninitialized`] which
113121
/// has no context yet and [`ReceiveSession::TerminalFailure`] which indicates the session has ended or is invalid.
@@ -116,7 +124,6 @@ fn short_id_from_pubkey(pubkey: &HpkePublicKey) -> ShortId {
116124
/// and the state to be updated with the next event over a uniform interface.
117125
#[derive(Debug, Clone, PartialEq)]
118126
pub enum ReceiveSession {
119-
Uninitialized,
120127
Initialized(Receiver<Initialized>),
121128
UncheckedProposal(Receiver<UncheckedProposal>),
122129
MaybeInputsOwned(Receiver<MaybeInputsOwned>),

payjoin/src/core/receive/v2/session.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
55
use super::{ReceiveSession, SessionContext};
66
use crate::output_substitution::OutputSubstitution;
77
use crate::persist::SessionPersister;
8-
use crate::receive::v2::{extract_err_req, SessionError};
8+
use crate::receive::v2::{extract_err_req, process_initial_event, SessionError};
99
use crate::receive::{v1, JsonReply, Original};
1010
use crate::{ImplementationError, IntoUrl, PjUri, Request};
1111

@@ -18,6 +18,9 @@ impl std::fmt::Display for ReplayError {
1818
use InternalReplayError::*;
1919
match &self.0 {
2020
SessionExpired(expiry) => write!(f, "Session expired at {expiry:?}"),
21+
NoEvents => write!(f, "No events found in session"),
22+
InvalidEventForUninitializedSession(event) =>
23+
write!(f, "Invalid event ({event:?}) for uninitialized session",),
2124
InvalidStateAndEvent(state, event) => write!(
2225
f,
2326
"Invalid combination of state ({state:?}) and event ({event:?}) during replay",
@@ -36,6 +39,10 @@ impl From<InternalReplayError> for ReplayError {
3639
pub(crate) enum InternalReplayError {
3740
/// Session expired
3841
SessionExpired(SystemTime),
42+
/// No events found in session
43+
NoEvents,
44+
/// Invalid event for uninitialized session
45+
InvalidEventForUninitializedSession(Box<SessionEvent>),
3946
/// Invalid combination of state and event
4047
InvalidStateAndEvent(Box<ReceiveSession>, Box<SessionEvent>),
4148
/// Application storage error
@@ -49,10 +56,13 @@ where
4956
P: SessionPersister,
5057
P::SessionEvent: Into<SessionEvent> + Clone,
5158
{
52-
let logs = persister
59+
let mut logs = persister
5360
.load()
5461
.map_err(|e| InternalReplayError::PersistenceFailure(ImplementationError::new(e)))?;
55-
let mut receiver = ReceiveSession::Uninitialized;
62+
63+
let mut receiver =
64+
process_initial_event(logs.next().ok_or(InternalReplayError::NoEvents)?.into())
65+
.expect("Session should be initialized");
5666
let mut history = SessionHistory::default();
5767

5868
for event in logs {

payjoin/tests/integration.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@ mod integration {
364364
let check_broadcast_suitability = || {
365365
proposal
366366
.clone()
367-
.check_broadcast_suitability(None, |_| Ok(false))
367+
.check_broadcast_suitability(None, |_| {
368+
Err(ImplementationError::from("this should cause a fatal error"))
369+
})
368370
.save(&persister)
369371
};
370372
let server_error = check_broadcast_suitability()
@@ -373,7 +375,9 @@ mod integration {
373375
.expect("expected api error");
374376
// TODO: this should be replaced by comparing the error itself once the error types impl PartialEq
375377
// Issue: https://github.com/payjoin/rust-payjoin/issues/645
378+
// TODO: fix this
376379
assert_eq!(server_error.to_string(), "Can't broadcast. PSBT rejected by mempool.");
380+
// assert_eq!(server_error.to_string(), "Internal Server Error: this should cause a fatal error");
377381

378382
let (_, session_history) = replay_receiver_event_log(&persister)?;
379383
let (err_req, err_ctx) = session_history

0 commit comments

Comments
 (0)