-
Notifications
You must be signed in to change notification settings - Fork 42
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
Refactor function signatures where appropriate #481
base: master
Are you sure you want to change the base?
Conversation
Many of these function signaures were audited in payjoin#405 and implemented here.
@@ -88,6 +88,8 @@ impl AppTrait for App { | |||
.send() | |||
.await | |||
.with_context(|| "HTTP request failed")?; | |||
let response_str = response.text().await.with_context(|| "Failed to read seponse")?; |
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.
Does this seem like an ok way to turn this into a string?
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.
i think so.
previously the response body was copied into a Vec<u8>
, and then given as a io::Read
. .text()
, otoh, treats it as a utf8 string, not all &[u8]
-ish things can be made into a String
and subsequently a &str
, but since this is v1 that should be OK, the data should be base64 followed by query param encoded data, all of which should be ASCII.
however, it seems a bit more defensive, and consistent with v2 to think of all responses as &[u8]
, so that the payjoin crate is responsible for handling that error, if we change the signature to take a &str
, then payjoin-cli and other wallets would be responsible for enforcing this part of BIP78's rules which they should be rather agnostic about, similarly to how the payjoin crate should be agnostic to transport errors etc (and by the same token should not accept a response object as its argument).
nit:
let response_str = response.text().await.with_context(|| "Failed to read seponse")?; | |
let response_str = response.text().await.with_context(|| "Failed to read reponse")?; |
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.
It seems fine, though the extract context is probably unnecessary. I might also suggest doing it inline like it was before:
let psbt = ctx.process_response(&response.text().await?).map_err(|e| {
...
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.
Partial review, I'm not sure how strongly I feel about &[u8]
in place of &str
, I think I could be convinced that that's just bikeshedding but I think the separation of responsibilities arguments is more than just bikeshedding.
I would very much appreciate it if the commits were split up, some of it is trivial refactoring, other parts are a bit more semantic, it all looks good to me but I found it a little noisy to read the large diff as small changes touch many different files, and reviewing commit by commit would be easier, we can always squash later with no effort if that feels too noisy (but I'm personally partial to small commits):
validate_input_utxos
removetreat_missing_as_error
paramprocess_response
,&mut impl std::io::Read
->&[u8]
extract_v2
,Url
->&Url
new_v1
(Url, Vec<u8>)
->(&Url, &[u8])
- making
ohttp_decapsulate
pub(crate)
(seems appropriate but not sure i understand the rationale, if it's just because that's possible then cACK) decrypt_message_b
...
some of these are really trivial but touch many files
some of these are a bit more subtle
it would make sense IMO to have one commit per changed fn, and maybe even separate v1 and v2 code into separate pull requests?
@@ -88,6 +88,8 @@ impl AppTrait for App { | |||
.send() | |||
.await | |||
.with_context(|| "HTTP request failed")?; | |||
let response_str = response.text().await.with_context(|| "Failed to read seponse")?; |
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.
i think so.
previously the response body was copied into a Vec<u8>
, and then given as a io::Read
. .text()
, otoh, treats it as a utf8 string, not all &[u8]
-ish things can be made into a String
and subsequently a &str
, but since this is v1 that should be OK, the data should be base64 followed by query param encoded data, all of which should be ASCII.
however, it seems a bit more defensive, and consistent with v2 to think of all responses as &[u8]
, so that the payjoin crate is responsible for handling that error, if we change the signature to take a &str
, then payjoin-cli and other wallets would be responsible for enforcing this part of BIP78's rules which they should be rather agnostic about, similarly to how the payjoin crate should be agnostic to transport errors etc (and by the same token should not accept a response object as its argument).
nit:
let response_str = response.text().await.with_context(|| "Failed to read seponse")?; | |
let response_str = response.text().await.with_context(|| "Failed to read reponse")?; |
@@ -229,15 +229,15 @@ impl Sender { | |||
/// Extract serialized V1 Request and Context from a Payjoin Proposal | |||
pub fn extract_v1(&self) -> Result<(Request, V1Context), url::ParseError> { | |||
let url = serialize_url( | |||
self.endpoint.clone(), | |||
&self.endpoint.clone(), |
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.
I think this .clone()
is no longer necessary since we're passing a reference now.
let mut res_str = String::new(); | ||
response.read_to_string(&mut res_str).map_err(InternalValidationError::Io)?; | ||
let proposal = Psbt::from_str(&res_str).map_err(|_| ResponseError::parse(&res_str))?; | ||
pub fn process_response(self, response: &str) -> Result<Psbt, ResponseError> { |
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 note in #405 says response could be a &[u8]
, but I agree using &str
seems more straightforward.
@DanGould is there a reason we should use bytes instead of a string?
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.
Seems @nothingmuch addressed this same question in his review and I missed it when writing this.
@@ -88,6 +88,8 @@ impl AppTrait for App { | |||
.send() | |||
.await | |||
.with_context(|| "HTTP request failed")?; | |||
let response_str = response.text().await.with_context(|| "Failed to read seponse")?; |
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.
It seems fine, though the extract context is probably unnecessary. I might also suggest doing it inline like it was before:
let psbt = ctx.process_response(&response.text().await?).map_err(|e| {
...
Re rust-payjoin/payjoin/src/receive/v1.rs Lines 95 to 97 in 34ee78d
however, a similar limit was not included in payjoin-cli prior to this PR, or in the sender: rust-payjoin/payjoin/src/send/v1.rs Line 277 in 34ee78d
I opened #483, but since this PR changes the process_response function signature, maybe it'd be more convenient to address the payjoin-cli part of this in this PR at your discretion |
Many of these function signatures were audited in #405 and implemented here.
I am going to leave any new function signatures outside of the ones here to a new PR so I don't bloat this PR anymore than it already is.