# ADR 057: RPC

# Changelog

  • 19-05-2020: created

# Context

Currently the RPC layer of Tendermint is using a variant of the JSON-RPC protocol. This ADR is meant to serve as a pro/con list for possible alternatives and JSON-RPC.

There are currently two options being discussed: gRPC & JSON-RPC.

# JSON-RPC

JSON-RPC is a JSON-based RPC protocol. Tendermint has implemented its own variant of JSON-RPC which is not compatible with the JSON-RPC 2.0 specification (opens new window).

Pros:

  • Easy to use & implement (by default)
  • Well-known and well-understood by users and integrators
  • Integrates reasonably well with web infrastructure (proxies, API gateways, service meshes, caches, etc)
  • human readable encoding (by default)

Cons:

  • No schema support
  • RPC clients must be hand-written
  • Streaming not built into protocol
  • Underspecified types (e.g. numbers and timestamps)
  • Tendermint has its own implementation (not standards compliant, maintenance overhead)
    • High maintenance cost associated to this
  • Stdlib jsonrpc package only supports JSON-RPC 1.0, no dominant package for JSON-RPC 2.0
  • Tooling around documentation/specification (e.g. Swagger) could be better
  • JSON data is larger (offset by HTTP compression)
  • Serializing is slow (~100% marshal, ~400% unmarshal (opens new window)); insignificant in absolute terms
  • Specification was last updated in 2013 and is way behind Swagger/OpenAPI

# gRPC + gRPC-gateway (REST + Swagger)

gRPC is a high performant RPC framework. It has been battle tested by a large number of users and is heavily relied on and maintained by countless large corporations.

Pros:

  • Efficient data retrieval for users, lite clients and other protocols
  • Easily implemented in supported languages (Go, Dart, JS, TS, rust, Elixir, Haskell, ...)
  • Defined schema with richer type system (Protocol Buffers)
  • Can use common schemas and types across all protocols and data stores (RPC, ABCI, blocks, etc)
  • Established conventions for forwards- and backwards-compatibility
  • Bi-directional streaming
  • Servers and clients are be autogenerated in many languages (e.g. Tendermint-rs)
  • Auto-generated swagger documentation for REST API
  • Backwards and forwards compatibility guarantees enforced at the protocol level.
  • Can be used with different codecs (JSON, CBOR, ...)

Cons:

  • Complex system involving cross-language schemas, code generation, and custom protocols
  • Type system does not always map cleanly to native language type system; integration woes
  • Many common types require Protobuf plugins (e.g. timestamps and duration)
  • Generated code may be non-idiomatic and hard to use
  • Migration will be disruptive and laborious

# Decision

This section explains all of the details of the proposed solution, including implementation details. It should also describe affects / corollary items that may need to be changed as a part of this. If the proposed change will be large, please also indicate a way to do the change to maximize ease of review. (e.g. the optimal split of things to do between separate PR's)

# Status

A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.

# Consequences

This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones.

# Positive

# Negative

# Neutral

# References

Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here!