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

Handling integer IDs in JSON-RPC requests -- fixes #2366 #2811

Merged
merged 6 commits into from Nov 26, 2018

Conversation

tomtau
Copy link
Contributor

@tomtau tomtau commented Nov 12, 2018

Addresses #2366

  • [n/a] Updated all relevant documentation in docs
  • Updated all code comments where relevant
  • Wrote tests
  • Updated CHANGELOG_PENDING.md

Hi everyone, we're using one JSON-RPC client library that only does integer IDs (incrementally), so rather than having a workaround for that, I guess it'd be better to fix this issue in Tendermint.
This is the first Go code I ever wrote, so apologies if it's too bad.
I decided to use this "interface wrapper with a single method" workaround for the lack of sum types in Go, as it seems to be an OK tradeoff between type safety (e.g. "empty interface" wrapper would work as well here, but passing in booleans / objects / arrays as IDs wouldn't result in an error) and boilerplate.

@codecov-io
Copy link

codecov-io commented Nov 12, 2018

Codecov Report

Merging #2811 into develop will decrease coverage by 0.23%.
The diff coverage is 45.31%.

@@             Coverage Diff             @@
##           develop    #2811      +/-   ##
===========================================
- Coverage     62.4%   62.16%   -0.24%     
===========================================
  Files          212      212              
  Lines        17254    17352      +98     
===========================================
+ Hits         10767    10787      +20     
- Misses        5583     5657      +74     
- Partials       904      908       +4
Impacted Files Coverage Δ
rpc/core/events.go 0% <0%> (ø) ⬆️
tools/tm-bench/transacter.go 8.49% <0%> (ø) ⬆️
rpc/lib/types/types.go 37.39% <46.77%> (+8.23%) ⬆️
privval/ipc_server.go 64.81% <0%> (-5.56%) ⬇️
lite/base_verifier.go 76% <0%> (-2.95%) ⬇️
privval/tcp_server.go 78.57% <0%> (-2.86%) ⬇️
p2p/pex/pex_reactor.go 71.51% <0%> (-0.95%) ⬇️
p2p/pex/addrbook.go 68.91% <0%> (-0.49%) ⬇️
consensus/reactor.go 66.62% <0%> (-0.12%) ⬇️
libs/db/remotedb/grpcdb/server.go 0% <0%> (ø) ⬆️
... and 1 more

Copy link
Contributor

@ebuchman ebuchman left a comment

Choose a reason for hiding this comment

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

Thanks for taking this on, and welcome to Tendermint dev!

A few minor points to address, but otherwise looks good :)

rpc/lib/types/types.go Show resolved Hide resolved
rpc/lib/types/types.go Show resolved Hide resolved
rpc/lib/types/types_test.go Outdated Show resolved Hide resolved
CHANGELOG_PENDING.md Outdated Show resolved Hide resolved
func NewRPCRequest(id string, method string, params json.RawMessage) RPCRequest {
// UnmarshalJSON custom JSON unmarshalling due to jsonrpcid being string or int
func (request *RPCRequest) UnmarshalJSON(data []byte) error {
type AliasStr RPCRequest
Copy link
Contributor

Choose a reason for hiding this comment

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

We should Unmarshal interface{} and then use switch for different possible types

switch ID.(type) {
  case string:
           XXX
  case int:
           YYY
  default:
    return fmt.Errorf("Unknown ID type. Got %T, expected string or int", ID)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

yes! also you can do without intermediate struct

unsafeResp := &struct {
            JSONRPC string          `json:"jsonrpc"`
            ID      interface{}     `json:"id"`
            Method  string          `json:"method"`
            Params  json.RawMessage `json:"params"` // must be map[string]interface{} or []interface{}
        }{}

you just use the original one

Copy link
Contributor Author

@tomtau tomtau Nov 19, 2018

Choose a reason for hiding this comment

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

@melekes @ebuchman I've changed it here: f2a71d7#diff-f595cd0be03b00ec17ec43d65afb7780

I'm not that experienced with Go, so not sure how to do it without the intermediate struct -- or by using the original, did you mean that jsonrpcid should be an empty interface and it should get rid of the extra ID type wrappers (JSONRPCStringID/JSONRPCIntID)?

Tomas Tauber added 3 commits November 19, 2018 11:45
…ndermint#2366)

* added a wrapper interface `jsonrpcid` that represents both string and int IDs in JSON-RPC requests/responses + custom JSON unmarshallers

* changed client-side code in RPC that uses it

* added extra tests for integer IDs
* added table driven tests for request type marshalling/unmarshalling
* expanded handler test to check IDs
* changed pending changelog note
@ebuchman
Copy link
Contributor

Pushed a commit to do some minor cleanup, hope you don't mind. PTAL! Otherwise LGTM

@ebuchman ebuchman merged commit b12488b into tendermint:develop Nov 26, 2018
danil-lashin pushed a commit to danil-lashin/tendermint that referenced this pull request Nov 27, 2018
* develop:
  types: Emit tags from BeginBlock/EndBlock (tendermint#2747)
  Fix fast sync stack with wrong block tendermint#2457 (tendermint#2731)
  It's better read from genDoc than from state.validators when appHeight==0 in replay (tendermint#2893)
  update encoding spec (tendermint#2903)
  return back initially allowed level if we encounter allowed key (tendermint#2889)
  Handling integer IDs in JSON-RPC requests -- fixes tendermint#2366 (tendermint#2811)

# Conflicts:
#	blockchain/reactor_test.go
#	blockchain/store_test.go
#	node/node_test.go
#	types/events.go
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

4 participants