cosmology-tech / starship

A k8s based unified development environment for Cosmos Ecosystem (and beyond)
https://cosmology.zone/products/starship
MIT License
67 stars 20 forks source link

spike: ICS integration #175

Open Anmol1696 opened 10 months ago

Anmol1696 commented 10 months ago

Overview

Inorder to comeup with a config file directives for ICS chains, it would make sense to perform a spike to get ICS running in Starship

Anmol1696 commented 9 months ago

Chain

Since there can be many consumer chains for the same provider, we need to a way to define that in the config file. Here are a couple of ideas:

Scope

Chain defination we will not create the IBC channels and ports. Those are supposed to be part of the relayer definations. The chains[] defination will create the proper genesis.json files, prepare the nodes and start the nodes without the IBC stuff.

Option 1 (Prefered)

Each consumer chain is defined in chains[], provider chain just runs the version of gaiad that has the provider

chains:
- name: cosmoshub-4
  type: cosmos ## initially we will be running interchain-security-provider
  numValidators: 4
- name: neutron-2
  type: neutron
  ics:  # if specified, no need to specify numValidators, since the validator set is created and run by validators of the provider
    enabled: true
    provider: cosmoshub-4 
- name: stride-4
  type: stride
  ics:
    enabled: true
    provider: cosmoshub-4  

Note: we could specify .chains[].numValidators for consumer too. If the number of validator match the provider chain, then we can assume this is replicated security. If the number is less, then we can assume it to be opt in for the validators (future proof).

Option 2

Since the validator set of the consumer is same as the consumer, and the provider is supposed to run the nodes for the providers

chains:
- name: cosmoshub-4
  type: cosmos
  numValidators: 4
  ics:
    enabled: true              ## if true then will setup the chains such that consumer nodes are all setup and running
    consumers:                 ## will be similar to `.chains[]` but with some fields omitted
    - name: neutron-2
      type: neutron            ## chain of chain to run, same as `.chains[].type`
      image: <image>        ## optional override from type
      resources:
        ...
      ports:
        ...
    - name: stride-4
      type: stride

Questions

  1. How are the pods supposed to run? Are the consumer chain nodes supposed to run on the same pod as the provider chain ? Do we run it as sidecars?
  2. Do we allow addition of consumer chains after the provider has been spun up?
  3. How are relayers supposed to perform the initial setup between the chains?
  4. How are the consumer chain addition proposals handled? and where? Run as either: a k8s job, init container on the consumer, side car action on provider triggered by consumer init-container.
Anmol1696 commented 9 months ago

Relayers

For ICS setup, relayers play a key role in setup. This is a design for how the config would look like.

Commands to run

The actual commands to run on the relayer are:

hermes create connection \
    --a-chain consumer \
    --a-client 07-tendermint-0 \  # this is the client on consumer chain
    --b-client 07-tendermint-0    # this is the client on the provider chain, in prod this is never 07-tendermint-0

hermes create channel \
    --a-chain consumer \
    --a-port consumer \
    --b-port provider \
    --order ordered \
    --channel-version 1 \
    --a-connection connection-0

Option 1: Implicit

relayers:
- name: cosmos-neutron
  type: hermes
  replicas: 1
  chains:
  - cosmoshub-4
  - neutron-2

If the chains specified have ics.enabled set to true, then we can assume that it is implicit to create the ics channels.

Option 2: Explicit

Making ics channel creation explicit will also allow the ability to test out creating the channels externally

relayers:
- name: cosmos-neutron
  type: hermes
  replicas: 1
  chains:
  - cosmoshub-4
  - neutron-2
  ics:
    enabled: true

By default we can make the first chain as the provider and the second as a consumer.

Option 3: Explicit

relayers:
- name: cosmos-neutron
  type: hermes
  replicas: 1
  chains:
  - neutron-2               # chain-a
  - cosmoshub-4        # chain-b
  paths:                        # connection is defined implicitly between the chains
  - a-port: consumer
     b-port: provider
     order: ordered
     channel-version: 1

Option 4: Explicit (prefered)

Alternatively we can have paths as:

  paths:
  - ports:
    - consumer           # a-port
    - provider              # b-port
    order: ordered
    channel-version: 1
  - ports:
    - transfer
    - transfer
    order: unordered
    channel-version: 2
Anmol1696 commented 9 months ago

For chain initialization, here are the steps: consumer-start-process

Since ICS initialization requires steps on the consumer to be running steps on the provider. This can be done as part of init container of the ICS chain.

consumer-chain-genesis:
  initContainer:
    - init-genesis: # same as current genesis initialization
    - init-ics-consumer: # will perform various ICS specific tests
      steps:
        - create address on provider for ics initialization # use provider faucet
        - submit proposal on provider
        - pass proposal on provider
        - fetch ccv specific info from
    - init-priv-keys:
      steps:
        - fetch private keys of the provider from exposer

For the rest of the validators of the consumer chain, we will have similar steps.

consumer-chain-validator-i:
  initContainers:
    - init-validator: # same as current initialization
    - init-priv-keys:
      steps:
        - fetch private keys of the provider from exposer

Note: So far, provider chain does not need to know anything about the consumers.

Proposal

Inorder to achive this, we need capability of easily submitting and passing a gov proposal as part of the init-ics-consumer container. We have a couple of options for this.

Option 1: Exposer endpoint

Have a post request on exposer at endpoint /proposal which will submit and pass the gov proposal. This feature can have future usecases as well.

Option 2: Init Container (prefered)

We can run the init container with docker image of the provider itself, so that the init container script can create and submit proposal on the provider chain, natively. Since init-containers are seperate, this should be fine