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

make request and response ID handling spec-compliant. #83

Merged
merged 3 commits into from
Nov 7, 2022

Conversation

raulk
Copy link
Member

@raulk raulk commented Oct 21, 2022

The server part of this library only supports int64 IDs. This breaks the JSON-RPC 2.0 spec, which establishes that:

An identifier established by the Client that MUST contain a String, Number, or NULL value if included.
If it is not included it is assumed to be a notification.
The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2].

This patch makes the implementation compliant by making the ID field a wildcard type, and validating and coercing the ID to the respective type when receiving a message (yikes, really missing Rust tagged enums here).

I'm not too happy about the interface{} map key types as they are brittle, but I believe this logic deals only with values a never pointers, so we should be good.

Note that the proxy client here will always generate int64 request IDs; unfortunately client logic does have to change because it depends on shared types.


This is breaking compatibility with some prominent Ethereum JSON-RPC API clients of Lotus, like MetaMask, which sends string-encoded UUID request IDs.


TODO

This patch is missing a server integration test validating the newly supported ID types.

The server part of this library only supports int64 IDs. This breaks
the JSON-RPC 2.0 spec, which establishes that:

> An identifier established by the Client that MUST contain a String, Number, or NULL value if included.
> If it is not included it is assumed to be a notification.
> The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2].

This patch makes the implementation compliant by making the ID field a wildcard type,
and validating and coercing the ID to the respective type when receiving a message.
raulk added a commit to filecoin-project/lotus that referenced this pull request Oct 22, 2022
return clientResponse{}, xerrors.Errorf("failed to response ID: %w", err)
}

if resp.ID != cr.req.ID {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% sure that comparing interface{} things this way is actually safe

Copy link
Member Author

Choose a reason for hiding this comment

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

Should be ok. From the Go spec:

Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.

@magik6k magik6k merged commit 70f44a9 into master Nov 7, 2022
@raulk raulk deleted the raulk/fix-id branch November 7, 2022 15:29
vyzo pushed a commit to filecoin-project/lotus that referenced this pull request Nov 9, 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.

None yet

2 participants