This sketches part of the requirements on the ocular library.
The main persona here is the relayer operator. I'll assume the perspective of Hermes relayer, since ocular is a Rust library and Hermes will most likely be a representative user of ocular.
There are two stories that come to mind and & would be useful to have.
1. Generate the relayer's configuration file starting from a tag
This story starts with a CLI that handles initialization of the relayer's config.toml starting from one TAG. The operator would invoke a CLI as follows:
This would generate a config.toml for Hermes with all the chains and all the paths from the chain registry that match the given TAG. We can define "match" to mean either a substr/regex or exact string equality, not sure yet, depending on the tag
type definition & content from the chain-registry.
Ocular requirement A
This use-case translates into an ocular requirement for an API roughly as follows:
fn get_paths_filtered(tag_filter: String) -> Vec<Path>
I imagine calling this method from the relayer (while executing hermes config x
) to result into a vector of Path
s which can be JsonValue
or similar types, filtered by their tags.
Of course, transforming these Path
s into their appropriate representation and generating the config.toml will be done on the Hermes side. To do so, we need one more API from ocular, documented below.
Ocular requirement B
To be able to fully generate the relayer's config.toml, we need additional pieces of information for each chain from the chain registry. The full set of details are as follows:
chain_id
: this is already part of each Path
object, we have it already
rpc_addr
, grpc_addr
websocket_addr
: needed, should be part of the chain registry (or added there)
account_prefix
: this is present in the chain registry already
key_name
: this could be handled by ocular directly (if ocular has a keystore)
store_prefix
is typically 'ibc': we can keep this hardcoded (not needed)
denom
: present in chain registry already
- consensus parameter
max_block_size
, we need this to compute the max_tx_size
that Hermes is allowed to submit to the chain
clock_drift
: needed, does not exist in chain registry, should be added
max_block_time
: needed, does not exist in chain registry, should be added
To summarize, in an ideal world ocular would provide an API as follows:
fn chain_info(chain_id: String) -> ChainInfo
Where ChainInfo
would comprise the corresponding attributes to describe the necessary fields. To recap: rpc_addr
, grpc_addr
websocket_addr
, account_prefix
, denom
, max_block_size
, clock_drift
, max_block_time
, and optionally key_name
if ocular supports key management. None of these are a hard requirement. However, the fewer of these fields are present, the less useful the API will be.
2. Append IBC paths to the relayer's config.toml
In this story, the config.toml is already pre-populated with most of the chain information (i.e., we don't need to call into chain_info
). The relayer operator is only interested in appending path information to each section of the configuration file. Path information in Hermes consists of a simple list (example, example) of channel identifiers, but is subject to change. In the future it will comprise connection and client also. Suppose this information is missing from config.toml and we'd want to add it automatically from chain registry.
The top-level relayer's CLI would look as follows:
Then Hermes would call into ocular to fetch path information for every pair of chains present in the config.toml. Suppose config.toml comprises three chains A, B, C
, then Hermes would call into ocular to fetch three paths: A <> B
, B <> C
, A <> C
. To do so, would be great if ocular exposed the following API:
Ocular requirement C
fn get_paths_pairwise(source_chain: ChainId, dest_chain: ChainId) -> Vec<Path>
The meaning is pretty straightforward. This should return a Path such as this one, which may be a vector, but not sure.