Use reply key for replyable errors to v2 senders#981
Use reply key for replyable errors to v2 senders#981arminsabouri merged 4 commits intopayjoin:masterfrom
Conversation
fbcd995 to
1d288a9
Compare
1d288a9 to
6ef1772
Compare
Pull Request Test Coverage Report for Build 17306832046Details
💛 - Coveralls |
6ef1772 to
7b18d7b
Compare
| /// The mailbox ID where the receiver expects the sender's Original PSBT | ||
| /// payjoin proposal. | ||
| pub(crate) fn proposal_mailbox_id(&self) -> ShortId { | ||
| short_id_from_pubkey(self.receiver_key.public_key()) | ||
| } |
There was a problem hiding this comment.
"Original PSBT payjoin proposal" uses both names for the Original PSBT and the Payjoin Proposal. Which one is it? IF from sender, Original, if from receiver, Proposal.
There was a problem hiding this comment.
There was a problem hiding this comment.
yeah i hate that but in the code the typestate is UncheckedProposal so i felt like i had to put that in there to be less confusing...
i guess this should rename UncheckedProposal to UncheckedOriginalPSBT?
also do you mind if Original is renamed to OriginalPSBT for consistency with the spec? Original on its own seems harder to digest even if it's more accurate and less redundant
|
there's a big FIXME comment re session_history.extract_err_request, but because optionality of the reply key in the session is also used to distinguish v1/v2 requests internally and lifting reply_key to the Receiver typestate structs themselves is very boilerplate heavy, i left it as is for now even though i was hoping to make some progress on #929 i gave up on that for this PR |
51b838e to
beeb471
Compare
arminsabouri
left a comment
There was a problem hiding this comment.
Approach/utACK
Core logic for updating error request mailbox lgmt. The rest of the refactors and naming updates all seem sane as well. Thanks 👍
| // FIXME ideally this should be more like a method of | ||
| // Receiver<UncheckedProposal> and subsequent states instead of the | ||
| // history as a whole since it doesn't make sense to call it before, | ||
| // reaching that state. |
There was a problem hiding this comment.
The most ergonomic approach imo is to have v2 receiver errors to be convertable to json replies iff they are fatal errors. That way you can send the error reply after you fail to process a typestate or send it after you replay the SEL.
There was a problem hiding this comment.
hmm, that sounds right to me, but i don't see how this would specifically avoid this method of the context being callable even in states where it doesn't make sense... i guess the mailbox ID would be derived as part of that conversion? would it be captured into the fatal error?
either way do you mind opening an issue with a bit more detail than this comment? i would prefer to do it as a followup
There was a problem hiding this comment.
Yes. In fact we have this issues. But your comment about the different mailbox id is new context that we haven't considered yet. #793
d4b0295 to
373a802
Compare
|
@DanGould i've renamed as per your suggestions in DM, but having second thoughts about updating the spec since part of our rationale for "Original PSBT" is that it exactly matched BIP 78's terminology, confusing though it may be. i do think it's appropriate in the code since the state is not just the psbt but the psbt, the params and the reply key (although the |
|
i guess ship has sailed on calling them "sender's proposal" and "receiver's proposal" lol |
373a802 to
99b6b91
Compare
|
hmm, this now introduces mutant failures but i'm not convinced they're worth addressing, if i understand Armin's suggestions then I think that would eliminate them, the only caller of |
99b6b91 to
36580dd
Compare
Makes sense. No need to write tests rn that we would have to remove soon |
|
If I'm not mistaken these are the same mutants covered by these tests #915 (comment), right? |
|
Please push the mutations ignore and I will review and drop a re-ack Or migrate the tests mentioned here #981 (comment) |
oh right i had mentally filed that into the next PR to rebase forgetting that it's based on this one... i will add them to this one thanks again for that! |
Before some relatively recent spec changes, two messages were written to the same mailbox. The error path was not updated to reflect this, so the sender will not receive it (as it is polling a different mailbox), and the receiver further relied on the directory allowing mailbox contents to be overwritable (or at least accepting the POST request). With this change a replyable error to a v2 sender will be sent to the reply key, assuming one was obtained from the first message. If no key can be recovered from the message then there is no point in sending a reply as the peer is not adhering to the protocol.
Co-authored-by: Ben Allen <benalleng@gmail.com>
36580dd to
68608bf
Compare
| session_context: SHARED_CONTEXT.clone(), | ||
| original: OriginalPayload { psbt: PARSED_ORIGINAL_PSBT.clone(), params }, | ||
| session_context: SessionContext { | ||
| reply_key: Some(HpkeKeyPair::gen_keypair().public_key().clone()), |
There was a problem hiding this comment.
SHARED_CONTEXT should have a fresh keypair. Why would we create a new one here?
There was a problem hiding this comment.
pub(crate) static SHARED_CONTEXT: Lazy<SessionContext> = Lazy::new(|| SessionContext {
address: Address::from_str("tb1q6d3a2w975yny0asuvd9a67ner4nks58ff0q8g4")
.expect("valid address")
.assume_checked(),
directory: EXAMPLE_URL.clone(),
mailbox: None,
ohttp_keys: OhttpKeys(
ohttp::KeyConfig::new(KEY_ID, KEM, Vec::from(SYMMETRIC)).expect("valid key config"),
),
expiry: SystemTime::now() + Duration::from_secs(60),
receiver_key: HpkeKeyPair::gen_keypair(),
reply_key: None,
amount: None,
});There was a problem hiding this comment.
SHARED_CONTEXT is used in both uninitialized and uncheckedpayload tests, it's not correct to have a reply key set in the uninitialized state
Before some relatively recent spec changes, two messages were written to the same mailbox. The error path was not updated to reflect this, so the sender will not receive it (as it is polling a different mailbox), and the receiver further relied on the directory allowing mailbox contents to be overwritable (or at least accepting the POST request).
With this change a replyable error will be sent to the reply key, assuming one was obtained from the first message. If no key can be recovered from the message then there is no point in sending a reply as the peer is not adhering to the protocol.
Pull Request Checklist
Please confirm the following before requesting review: