-
Notifications
You must be signed in to change notification settings - Fork 77
Look up RK instead of looping #1013
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -105,24 +105,16 @@ impl AppTrait for App { | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| PjParam::V2(pj_param) => { | ||||||||||||||||||||||||||||||||||
| let receiver_pubkey = pj_param.receiver_pubkey(); | ||||||||||||||||||||||||||||||||||
| let sender_state = | ||||||||||||||||||||||||||||||||||
| self.db.get_send_session_ids()?.into_iter().find_map(|session_id| { | ||||||||||||||||||||||||||||||||||
| let session_receiver_pubkey = self | ||||||||||||||||||||||||||||||||||
| .db | ||||||||||||||||||||||||||||||||||
| .get_send_session_receiver_pk(&session_id) | ||||||||||||||||||||||||||||||||||
| .expect("Receiver pubkey should exist if session id exists"); | ||||||||||||||||||||||||||||||||||
| if session_receiver_pubkey == *receiver_pubkey { | ||||||||||||||||||||||||||||||||||
| let sender_persister = | ||||||||||||||||||||||||||||||||||
| SenderPersister::from_id(self.db.clone(), session_id).ok()?; | ||||||||||||||||||||||||||||||||||
| let (send_session, _) = replay_sender_event_log(&sender_persister) | ||||||||||||||||||||||||||||||||||
| .map_err(|e| anyhow!("Failed to replay sender event log: {:?}", e)) | ||||||||||||||||||||||||||||||||||
| .ok()?; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Some((send_session, sender_persister)) | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||
| let session_id = self.db.get_send_session_id_with_receiver_pk(receiver_pubkey)?; | ||||||||||||||||||||||||||||||||||
| let sender_state = match session_id { | ||||||||||||||||||||||||||||||||||
| Some(session_id) => { | ||||||||||||||||||||||||||||||||||
| let sender_persister = | ||||||||||||||||||||||||||||||||||
| SenderPersister::from_id(self.db.clone(), session_id)?; | ||||||||||||||||||||||||||||||||||
| let (send_session, _) = replay_sender_event_log(&sender_persister)?; | ||||||||||||||||||||||||||||||||||
| Some((send_session, sender_persister)) | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| None => None, | ||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+108
to
+117
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: i'm not convinced this is really easier to follow with the suggestion is untested and definitely needs formatting it's probably multipline
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| let (sender_state, persister) = match sender_state { | ||||||||||||||||||||||||||||||||||
| Some((sender_state, persister)) => (sender_state, persister), | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ use payjoin::persist::SessionPersister; | |
| use payjoin::receive::v2::SessionEvent as ReceiverSessionEvent; | ||
| use payjoin::send::v2::SessionEvent as SenderSessionEvent; | ||
| use payjoin::HpkePublicKey; | ||
| use rusqlite::params; | ||
| use rusqlite::{params, OptionalExtension}; | ||
|
|
||
| use super::*; | ||
|
|
||
|
|
@@ -219,14 +219,16 @@ impl Database { | |
| Ok(session_ids) | ||
| } | ||
|
|
||
| pub(crate) fn get_send_session_receiver_pk( | ||
| pub(crate) fn get_send_session_id_with_receiver_pk( | ||
| &self, | ||
| session_id: &SessionId, | ||
| ) -> Result<HpkePublicKey> { | ||
| receiver_pk: &HpkePublicKey, | ||
| ) -> Result<Option<SessionId>> { | ||
| let conn = self.get_connection()?; | ||
| let mut stmt = | ||
| conn.prepare("SELECT receiver_pubkey FROM send_sessions WHERE session_id = ?1")?; | ||
| let receiver_pubkey: Vec<u8> = stmt.query_row(params![session_id.0], |row| row.get(0))?; | ||
| Ok(HpkePublicKey::from_compressed_bytes(&receiver_pubkey).expect("Valid receiver pubkey")) | ||
| conn.prepare("SELECT session_id FROM send_sessions WHERE receiver_pubkey = ?1")?; | ||
| let session_id = stmt | ||
| .query_row(params![receiver_pk.to_compressed_bytes()], |row| row.get(0)) | ||
| .optional()?; | ||
|
Comment on lines
+228
to
+231
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. firstly, i think this can be renamed secondly, this assumes no duplicate receiver pubkeys will ever be added to the database, i think that's fine for now (modulu suggestion re comparing other params) but more future proof would be to avoid
being a bit more strict about this would allow us to reliably detect errors in the future even if we eventually decide change the behavior to allow the sender to respond to a buggy receoiver which reuses ephemeral keys for some reason, but if the behavior is to ignore any subsequent matching sessions and with no |
||
| Ok(session_id.map(SessionId)) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the other bip21 params should be compared after recoveing
if feerate is being explicitly overridden that's fine, but if the requested amount or bitcoin address has changed that would be problematic (no harm in comparing pjos param but it's irrelevant here since this is for v2 sender)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. We would need to expose new methods to session history to extract amount and payee spk. What is the expected behavior if the amount and address are not the same? Reject the send or resume? In any case we should not create a new session with different params for the same rk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if we going to resume the existing session then I don't think we need to do any additional checks. Perhaps an explicit error makes the most sense here -- since the behavior is unexpected and problematic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely error IMO, even if we wanted to take the complexity hit in order to facilitate resuming in more situations, i don't see how that really makes sense because:
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thinking about this more, i don't even know if a receiver can resume its own receive session based on the URL that it gave out previously, that seems kind of weird, i'm almost more inclined to say we should remove the behavior of resuming only a specific session by redoing "send" and just allow sessions, print the session ID and allow that to be specified as a parameter to resume instead... is there a really good UX reason to prefer the already implemented behavior?
(and if you agree then any use of a duplicate URI or duplicate RK should error saying that that payment request was already allocated a session, and print its ID and/or original URI?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that sending to the same BIP21 implied resumption. However, I do think a clearer interface is one where an error (~"existing session for . use
resumeto resume) is reported instead of resumption of a send with potentially different parameters.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so i think we can do the following:
sendcommand for 1.0--session-idparam to theresumecommand that works for both sender and receiver sessionsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened an issue relating to this #1032, tl;dr we should also prevent concurrent resumes