EPF Update -- Weeks 9, and 10 (Jordan Ellis Coppard)
October 9, 2023 ยท View on GitHub
EPF Update -- Weeks 9, and 10 (Jordan Ellis Coppard)
Once again my predictions have fallen short. API Blueprint has next to no maintained tooling available for it and Bun with Elysia does not work for the project's needs. I discovered TypeBox which can output JSON Schema while providing runtime validation against that same schema-set which will be useful for the documentation generation.
Hidden Problems
I thought it would be interesting to provide an example of how deceptively simple this kind of project can appear.
With the general roadblock from the last update overcome I took to implementing the simplest REST endpoint the specification will have /info/net which returns:
{
peers: 42,
chain: 1,
listening: true,
}
This is an amalgamation of RPC net_peerCount, net_version, net_listening. Savvy readers may be screaming "no, not net_version!" and I indeed discovered EIP-695 which is something I wasn't aware of before; this is one example of how something seemingly simple can have unexpected complications but not the example I am building up to. While still using net_version I noticed the RPC library I am using (as there's no value in me implementing one for this project) Viem incorrectly specifies the return type for net_version as an EIP-1474 QUANTITY instead of a string as the specification requires. So, continually double-checking is required lest errors creep in.
I'm using Elysia which itself uses TypeBox, and TypeBox can be used to construct the OpenAPI JSON Schema specification for the REST API. After dealing with a misrepresented type response for an RPC call using Viem I've elected to spend more time fleshing out using TypeBox as this demonstrates rigorous checking at all levels is required and so this takes up time even for "simple" things.
The real unexpected rabbit warren here though is uncovered when I asked myself two questions:
- What type can the values of chain id be?
- What range of chain id encompasses valid values?
Chain ids (as far as I can see) are all integers above zero. Is this constrained in a specification? Could I have a chain id of literally foobarbaz? If chain ids are only allowed to be integers (by specification and not convention) what is the maximum permitted value? Surely a ludicrously high value... say a googol is not allowed?
Apparently (to me) there is no consensus for this yet. EIP-2294 proposes explicit bounds, EIP-1344 specifies an EVM opcode to return the chain id where the value is constrained to 256-bits. MetaMask constrains chain id to a much lower value as at 2021-01-15; I am curious why MetaMask did-not/do-not use web standard BigInt which can represent arbitrarily large integers. Finally there is on-going discussion on Ethereum Magicians relating to EIP-2294 and EIP-1344.
I have decided to constrain the value to 256-bits and return it (in the REST API) as a BigInt to reflect the adopted EIP-1344 EVM opcode. I should check how widespread that adoption is (I only checked for Geth currently) but that's another problem that doesn't have an easy solution as far as I know. I'd like to be able to simply query a node to receive a list of EIPs it supports (as a standard). For now I peruse the source to determine whether an EIP is implemented or not.
So, wrapping three simple RPC methods turns into a debugging session (albeit a simple one) due to an incorrect type annotation, and a relatively deep dive into multiple EIP specifications to determine the bounded range the return value should have; and that's for the three simplest RPC methods to wrap.
REST API
Using Elysia so far has been good, it has a nice API to require a specific request and response schema and can generate Swagger documentation for you. I've been reading up a bit more on TypeBox since that is the meat of how these schemas are actually defined and checked.