Skip to content
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

Check string Id in response #644

Closed

Conversation

whalelephant
Copy link

Hi,

I would like to add support checking Repsonse.id as Id::Str(x) when client is parsing responses.

Not sure if this is something already the works so please let me know. thanks!

@whalelephant whalelephant requested a review from a team as a code owner January 9, 2022 17:17
@niklasad1
Copy link
Member

Hey @whalelephant

Thanks for your PR, the reason why we assert that the response ID must be a Number is because the library itself only transmit method calls with ID as Number.

Can you elaborate why you need IDs as String? If that's desired it's should be configurable to choose request ID type or allow users to provide their own IDs such as unique IDs or something..

@whalelephant
Copy link
Author

Hi @niklasad1

the reason why we assert that the response ID must be a Number is because the library itself only transmit method calls with ID as Number.

makes sense!

Can you elaborate why you need IDs as String? If that's desired it's should be configurable to choose request ID type or allow users to provide their own IDs such as unique IDs or something..

Sure! I think the main reason is that I cannot guarentee the server parses / deserializes to the same Id type in the response since Id supports both str and num. This all comes from the investigation related to deserializing the u64 type (mentioned #480 and here). A way to parse any type is to read the Id as serde_json::value::RawValue, which mean it may be returned as a string.

Thanks!

@niklasad1
Copy link
Member

niklasad1 commented Jan 10, 2022

https://github.com/AleoHQ/snarkOS/issues/1369 is not related this library but I see that you need to workaround this because it suffers from serde bug that it can't deduce the number type properly probably because of the arbitrary precision feature

FWIW, we are not supporting arbitrary precision in jsonrpsee servers and doesn't suffer from this bug so #480 is not an issue for this case but won't work for u128 or untagged serde enums (unless someone enables that feature on serde_json). We are not planning to support it, I should explain it in the issue.

From the "clients" point-of-view the server must be reply with the same id for the request to be completed ("id":1 == "id":1 && "id":1 != "id":"1"), the example https://github.com/AleoHQ/snarkOS/issues/1369 when replies with null the client can't know which request that failed (except HTTP).

With that said if you could implement a configuration on the clients in the builders to support numeric IDs or Strings (maybe random generated controlled by jsonrpsee) I would accept it and it will solve your problems right?

Copy link
Contributor

@maciejhirsz maciejhirsz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, minor grumbles.

Nevermind, I see there is another PR that replaces this one.

Comment on lines +145 to 159
if let Some(response_id) = response.id.as_number().copied() {
if response_id == *id.inner() {
Ok(response.result)
} else {
Err(Error::InvalidRequestId)
}
} else if let Some(response_id) = response.id.as_str() {
if response_id == id.inner().to_string() {
Ok(response.result)
} else {
Err(Error::InvalidRequestId)
}
} else {
Err(Error::InvalidRequestId)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would have been much cleaner if it was a match on the enum variants.

Comment on lines +195 to +213
match rp.id.as_number().copied() {
Some(id) => {
let pos = match request_set.get(&id) {
Some(pos) => *pos,
None => return Err(Error::InvalidRequestId),
};
responses[pos] = rp.result
}
None => match rp.id.as_str() {
Some(s) => {
let id: u64 = s.trim().parse().map_err(|_| Error::InvalidRequestId)?;
let pos = match request_set.get(&id) {
Some(pos) => *pos,
None => return Err(Error::InvalidRequestId),
};
responses[pos] = rp.result
}
None => return Err(Error::InvalidRequestId),
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@dvdplm
Copy link
Contributor

dvdplm commented Jan 21, 2022

Closing in favor of #659

@dvdplm dvdplm closed this Jan 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants