Skip to content

Universal specs for JSON-RPC API methodsΒ #217

Closed
@cdetrio

Description

@cdetrio

Universal specs for JSON-RPC API methods

This is a pre-draft outline of a Hive-based multi-client test suite for the JSON-RPC API. The specification format is JSON schema (inspired by the Kodi API description).

Existing RPC test suites include ethereum/rpc-tests and bas-vk/hive/tree/rpc. The former is based on mocha.js and the latter on go-ethereum's ethclient.Client api. This proposal intends to be a language and client-agnostic test and specification format.

Here's an example JSON schema specification, for eth_getBlockTransactionCountByHash, annotated for explanation:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "eth_getBlockTransactionCountByHash",
    "title": "eth_getBlockTransactionCountByHash",
    "description": "eth_getBlockTransactionCountByHash JSON-RPC method request and response schema.",

    "request": {
      "id": "#request",
      "allOf": [ // allOf means the request must pass both sub-schemas
        { "$ref": "jsonrpc-request.json" }, // first-pass generic validation, see file https://github.com/cdetrio/interfaces/blob/master/rpc-specs-tests/schemas/jsonrpc-request.json
        { "$ref": "#/definitions/request-obj" } // second-pass validation, specific to the RPC method
      ],
      "definitions": {
        "request-obj": {
          "id": "#request-obj",
          "properties": {
            "method": {
              "type": "string",
              "enum": ["eth_getBlockTransactionCountByHash"]
            },
            "params": {
              "type": "array",
              "items": [
                {
                  "type": "string",
                  "description": "DATA, 32 Bytes - Hash of a block."
                }
              ]
            }
          }
        }
      }
    },

    "response": {
      "id": "#response",
      "allOf": [
        { "$ref": "jsonrpc-response.json" },
        { "$ref": "#/definitions/response-obj" }
      ],
      "definitions": {
        "response-obj": {
          "id": "#response-obj",
          "properties": {
        		"result": {
              "type": "string",
              "description": "QUANTITY - integer of the number of transactions in this block."
        		}
        	}
        }
      }
    }
}

The description fields are not used for validation, but for generating RPC API method documentation as seen on the wiki.

The JSON schema specifications are paired with test cases. Here's an example file with test cases for eth_getBlockTransactionCountByHash:

{
  "title" : "eth_getBlockTransactionCountByHash",

  "schema": {
    "$ref": "../schemas/eth_getBlockTransactionCountByHash.json"
  },

  "chainConfig" : {
    "$ref": "../configs/bcRPC_API_Test.json"
  },

  "tests": [
    {
      "title": "eth_getBlockTransactionCountByHash for block with one tx",
      "request" : {
        "method" : "eth_getBlockTransactionCountByHash",
        "params" : ["0x4e9a67b663f9abe03e7e9fd5452c9497998337077122f44ee78a466f6a7358de"]
      },
      "expectedResponse" : {
        "result": "0x1"
      },
      "asserts": [
        {
          "description": "response is not empty",
          "program": ".receivedResponse.result != null"
        },
        {
          "description" : "transaction count should be equal",
          "program" : ".receivedResponse.result == .expectedResponse.result"
        }
      ]
    }
  ]
}

The asserts array specifies jq programs or "filters", which are used to compare the received response against the expected response.

The chainConfig option points to a set of blocks/transactions to import. The current chain configuration is inherited from ethereum/rpc-tests, which in turn borrows from the state tests repo. This configuration file is loaded by the test runner, and imported by the hive clients.

After hive runs the RPC tests against a set of clients, the results are displayed as a compatibility table: http://cdetrio.github.io/eth-compat-table/ (inspired by the table for ES6).

Todos

One remaining task is to specify a test format for the pub/sub methods. One possibility is a transitionEvent field to specify an event (e.g. arrival of a block or a pending transaction), and an onTransition field to describe the expected notifications.

Test suite maintenance

An automated maintenance process for the RPC test suite will be described in a forthcoming Meta-EIP. The current plan is to maintain updates to the RPC test suite through a voting contract, with one-developer one-vote where developer identities are verified using devcon2 tokens. (There is a separate plan to expand the Devcon2 tokens into a web of trust, in order to enable participation by any and all Ethereum developers/stakeholders). Tentatively named EipSignal, this automated governance process is somewhat in the spirit of the Yellow Paper Committee; however, the outcome of EipSignal votes will only mandate changes to the RPC API specification and test suite as described above, and will NOT govern "core/consensus" protocol changes. The work-in-progress on EipSignal can seen here: MetaMask/IPFS-Ethereum-Hackathon#14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions