Giter VIP home page Giter VIP logo

composable-ibc's Introduction

Centauri: Trustless Bridging Protocol

This is the concrete implementation of the centauri bridging protocol, based on IBC, Powered by light clients.

This is a no_std compatible crate that contains functions for verifying BEEFY commitments and Parachain headers which have been finalized by the BEEFY protocol.

This contains utility functions for assembling BEEFY proofs as well as parachain proofs from a running node, that can then be verified by the light-client crate.

A no_std compatible crate which contains primitive types which are shared by both crates.

This is a no_std compatible crate that contains functions for verifying GrandPa commitments and Parachain headers which have been finalized by the GrandPa protocol.

This contains utility functions for assembling Grandpa proofs as well as parachain proofs from a running node, that can then be verified by the light-client crate.

A no_std compatible crate which contains primitive types which are shared by both crates.

Looking for instructions on how to run the relayer? Check here

Rust implementation of the IBC relayer algorithm.

Goals

✅ Event driven architecture.
✅ Fully stateless with no caching, and instead relies on full nodes for data storage as a source of truth.
✅ Chain agnostic, so it can be extended to support new chains with little no changes to the core framework.

Named after a fictional technology in starwars for relaying deep space messages.

composable-ibc's People

Contributors

aeryz avatar andor0 avatar andyjsbell avatar anhductn2001 avatar blasrodri avatar ciejo avatar drewstone avatar dzmitry-lahoda avatar expertdicer avatar hussein-aitlahcen avatar kkast avatar kkx avatar lesterli avatar mina86 avatar nadeemb53 avatar nimboya avatar obsessed-cake avatar rjonczy avatar rustninja avatar seunlanlege avatar sventimir avatar vmarkushin avatar wizdave97 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

composable-ibc's Issues

EVM Decision Point + Comparison Grid - DEADLINE OCT 14

We need a comparison between all viable EVMs so we can decide on a single EVM network to tackle first. The ideal network will have minimal blockers to developing a light client, good network usage & liquidity, and collaborative protocol devs.

Definition of Done:

  • EVM Network selection (Pick 1)
  • Comparison Grid
    • Y axis: EVM networks (Eth2, Polygon, Avalanche, Fantom, BSC, Algorand, etc.)
    • X axis: Features/Variables (gas limits, signature verification schemes, liquidity, other costs, external dev support, etc.)
  • Existing IBC-EVM attempts
    • Have any of the EVM networks already attempted integrating IBC? If so find links and reports on their findings.

Adding Cosmos Support to hyperspace

To add a new chain to hyperspace, the chain needs to implement the Chain, IbcProvider, Keyprovider, Send and Sync traits. Each implemented method would then be registered in hyperspace/core/src/chain by calling them from their respective AnyChain method in the hyperspace core crate. (Maybe this can be refactored?)

https://github.com/ComposableFi/centauri/blob/master/hyperspace/core/src/chain.rs#L122

Possible Refactoring of the AnyChain Implementation:

Currently Chain, IbcProvider and KeyProvider traits are implemented on the AnyChain enum with the goal of supported chains being defined as variants on the enum. Each supported chain then has to call its equivalent methods from the AnyChain methods in a match case. https://github.com/ComposableFi/centauri/blob/master/hyperspace/core/src/chain.rs#L126-L151
This would lead to more code to maintain in match cases as more chains are support is added.

My suggestion is to return the Chain trait from the into_client method rather than returning the AnyChain enum type. I think @vmarkushin called it dynamic dispatching in rust. Using that removes the need to register every implemented method by every supported chain in that file.

IbcProvider Trait

The required query methods that need to be implemented to implement the IbcProvider trait can be found here https://github.com/ComposableFi/centauri/blob/master/hyperspace/primitives/src/lib.rs#L83

Some of the methods in the IbcProvider might not translate directly to a cosmos chain. Meaning they might either not be needed to process cosmos messages or the requirement of the method might not be possible in cosmos. Some of these uncertain methods are.

  • channel_whitelist
  • expected_block_time
  • query_client_update_time_and_height
  • connection_prefix
  • client_id
  • connection_id
  • client_type
  • query_timestamp_at
  • query_client_id_from_tx_hash
  • is_update_required

KeyProvider Trait

The required query methods that need to be implemented to implement the KeyProvider trait can be found here https://github.com/ComposableFi/centauri/blob/master/hyperspace/primitives/src/lib.rs#L337

Chain Config

A Cosmos chain config needs to be defined as struct such that chain configuration can be defined in a configuration file and parsed into the CosmosChainConfig struct. The defined config can then be used to initialize an hyperspace Cosmos Chain Client. A sample of how a Substrate Chain Client is initalized for a config here. https://github.com/ComposableFi/centauri/blob/master/hyperspace/core/src/chain.rs#L614-L621

Hyperspace test suite

We're already writing tests for parachain <> Parachain messaging. Where in fact these tests can be made Chain agnostic.

We should re-write the tests so that it's trivial to plug anything that implements Chain

The v1 of the suite should cover:

  • timeout with connnection delay
    • packet relay with height timeout allowing it expire
    • packet relay with timestamp timeout allowing it expire.
  • basic packet relay with connection delay
    • ordered channel
    • unordered channel
  • channel closing semantics
    • channel close processing
    • packet timeout on channel close

implement create connection for cosmos chains

To add create connections for cosmos chains the following need to be satisfied.

  • implement ibc_events method
  • implement finality_notifications method
  • implement query_client_state
  • implement query_latest_ibc_events method
  • estimate_weight: return 0 from estimate weight so that tx submit is immediately processed for cosmos.

Part of this work was already started on #103, implementations from the PR will be reused.

#pallet not enough parameters to on_chan_open_ack and on_chan_close_init to build Cosmwasm open channel message

issue

IBC module callbacks provides some metadata.

We call with that metadata Cosmwasm SDK.

todo! marks what is lacking in these callbacks

	fn on_chan_open_ack(
		&mut self,
		_output: &mut ModuleOutputBuilder,
		port_id: &PortId,
		channel_id: &ChannelId,
		counterparty_version: &IbcVersion,
	) -> Result<(), IbcError> {
		let address = Self::port_to_address(port_id)?;
		let contract_info = Self::to_ibc_contract(&address)?;

		let message = IbcChannelConnectMsg::OpenAck {
			channel: IbcChannel {
				endpoint: todo!(),
				counterparty_endpoint: todo!(),
				order: todo!(),
				version: todo!(),
				connection_id: todo!(),
			},
			counterparty_version: counterparty_version.to_string(),
		};
	fn on_chan_close_init(
		&mut self,
		_output: &mut ModuleOutputBuilder,
		port_id: &PortId,
		channel_id: &ChannelId,
	) -> Result<(), IbcError> {
		let address = Self::port_to_address(port_id)?;
		let contract_info = Self::to_ibc_contract(&address)?;
		let message = IbcChannelCloseMsg::CloseInit {
			channel: IbcChannel {
				endpoint: IbcEndpoint {
					port_id: port_id.to_string(),
					channel_id: channel_id.to_string(),
				},
				counterparty_endpoint: todo!("https://github.com/ComposableFi/centauri/issues/120"),
				order: todo!("https://github.com/ComposableFi/centauri/issues/120"),
				version: todo!("https://github.com/ComposableFi/centauri/issues/120"),
				connection_id: todo!("https://github.com/ComposableFi/centauri/issues/120"),
			},
		};

expected

Metadata is provided in callback or via some trait

Remove `sp*` types from public interfaces

As part of making hyperspace purely chain agnostic, it would be great to remove substrate dependencies from public interfaces.

From our discussion with the Informal team

FS: `sp-std` and `sp-core`
These types are Substrate-specific, they should not appear in chain-agnostic interfaces.
Blas: Agree, we can abstract those away.
David: We can limit that exposure to Parachain-specific implementations.

Export logic for constructing light client updates

Currently we are maintaining code for constructing a beefy header in multiple repos, it's better that piece of functionality is consolidated in beefy-rs

Requirements

  1. Export the code required to fetch and construct light client updates
  2. Update errors with better descriptions.
  3. Export all functionality specific to light client that is duplicated in other repos.

Consolidate the events and errors in `deliver` transaction

Motivation

In the deliver transaction, events and errors are emitted separately for each message, so it's not possible to relate between each other, which is required when validating events in hyperspace.

Suggested Solution

Consolidate events and errors together or add the index/hash of a message to the corresponding event record.

Centauri CI Guide

Ci steps. If any step panics, terminate CI.

Lints

  • cargo fmt
  • cargo udeps

check --workspace

  • cargo +nightly check --workspace --locked

no_std checks

  • cargo check -p beefy-light-client-primitives --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p beefy-light-client --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p grandpa-light-client-primitives --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p grandpa-light-client --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p ibc --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p ics07-tendermint --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p ics10-grandpa --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p ics11-beefy --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p ics13-beefy --no-default-features --target=wasm32-unknown-unknown
  • cargo check -p pallet-ibc --no-default-features --target=wasm32-unknown-unknown

Pallet-ibc benchmarks

  • cargo test -p pallet-ibc --features=runtime-benchmarks

(polkadot-launch must be running at this point)

subxt checks

 cargo build --release -p codegen --bin codegen 
 ./target/release/codegen --path ./utils/subxt/generated/src
cargo fmt
git diff # assert there's no change or panic

Testing

cargo test --workspace --locked --release

Remove child trie iteration logic from ICS23 in pallet-ibc

Why? Because when we iterate over the child trie, its non-deterministic and touches a lot of unrelated storage items which now have to be included in our POV.

We want to drop our POV use to be as minimal as humanly possible, removing this iteration is a good optimization for better throughput.

Pallet-IBC has extraneous associated types

The Balance and AssetId type could be derived from the Fungibles and Currency types: https://github.com/ComposableFi/centauri/blob/0888dde9c11e63dd4c3241e9bb80e38b9fef4fda/contracts/pallet-ibc/src/lib.rs#L215

This is a minor nit, as the current config cannot be misused, but upstream users would have slightly less code to maintain.

Currently we say:

Balance = T
AssetId = U
Fungibles where Fungibles::Balance == T & Fungibles::AssetId == U
Currency where Currency::Balance == T

But more succinctly we could say:

Fungibles where Fungibles::Balance == Currency::Balance & Fungibles::AssetId: bounds

Introduce Prometheus metrics

As part of the client configuration options, the user to should be able to configure a prometheus endpoint to collect metrics about

  • Total number of sent packets

  • Total number of header updates

  • Transaction length for every sent tx bundle

  • Total number of timed out packets

  • number of undelivered packets over time

  • number of undelivered acknowledgements over time

  • Total number of sent acknowledgments

  • Gas cost for every sent tx bundle

Observe connection delay before relaying packets

The relayer is meant to read the connection delay and only relay packets after this delay period has elapsed after each client update.
This gives the fishermen nodes the time to challenge the client update before before any Ibc packets are sent.

Refactor AnyChain Implementation

Currently Chain, IbcProvider and KeyProvider traits are implemented on the AnyChain enum with the goal of supported chains being defined as variants on the enum. Each supported chain then has to call its equivalent methods from the AnyChain methods in a match case. https://github.com/ComposableFi/centauri/blob/master/hyperspace/core/src/chain.rs#L126-L151
This would lead to more code to maintain in match cases as more chains are support is added.

rather than returning the AnyChain enum type, return the Chain trait from the into_client method. Doing that removes the need to register every implemented method by every supported chain in that file.

CosmWasm GRANDPA Light Client

Context

As part of the KSM<>COSMOS bridge, we need to deploy a CW smart contract of our GRANDA Light client in a one/multiple Cosmos chains. It's important to state that this task goes hand with hand with the ICS08 implementation. This is because
the smart contract will be called from the Cosmos SDK (Golang context) using the CW VM (note that this is a WIP right now).

This task groups everything that needs to be done to have this piece ready.

  • #100
  • #89
  • PoC/dummy implementation with integration with ICS08 (Blas leading at least the ICS08 piece)

#pallet `on_chan_open_init` to provide weight limit and allow to return used gas

Issue

on_chan_open_init signature does not provide gas limit nor allow to return back used gas.

on_chan_open_init invokes Cosmwasm VM, which needs a gas limit and returns the gas used value.

Actual

IBC does not provide a way to negotiate prices. Expected that the sender of the IBC message will tell his price, and it will be provided as a weight to a module.

Expected

on_chan_open_init to provide gas limit as Weight. And return value to allow return gas used.

Investigate issues using the offchain indexing API in pallet ibc

Problem definition

While running integration tests with the relayer, it was noticed that extrinsics that called the offchain api to store packet data offchain were discarded from the transaction pool as Invalid transactions, the same extrinsics were not discarded if their execution did not reach a point where the offchain API was called.
This needs to be fixed because packet data needs to be stored offchain.

E2E Monitoring Event Updates

We need port/channel information in the emitted events in order to monitor events properly, TransferInitiated, TransferReceived, TransferCompleted, TransferFailed.

We also need to update/regenerate the javascript library composablejs-types once these events have been updated.

Once that is completed, my team can continue to perform additional e2e testing on the nodes+relayer when performing ibc transfers

[Meta] Substrate IBC Completion guide

This a tracking issue for the issues that need to be completed to get the ibc implementation on substrate to the finish line.
More issues will be added as time passes.

Ibc-rs

Pallet Ibc

Hyperspace

Introduce polling

Lol yes we're still event driven, but because of connection delays we cannot respond to packets immediately and need to wait.

We should introduce a polling mechanism at every finality event for new packets that can be sent at the new chain height.

Game theoretically sound bridging

Currently writing a more detailed article about securing cryptographically sound bridges with game theory.

But the gist of this issue is that currently our bridge is vulnerable to eclipse attacks (todo: references) where the validators for a blockchain might collude and sign a single malicious header which they don't gossip in the p2p swarm, but instead update the light client running on our chain.

This attack is absolutely devastating and is capable of destroying the peg of an existing bridged asset, where the validators essentially sign a forged header which in turn contains a forged ibc commitment trie that makes a huge transfer of existing bridged assets in the forged header.

In order to mitigate this attack we need a new game theory protocol:

First a challenge window for newly updated headers in our light client, could be 5-10 mins. This will give enough time for a new participant of the bridge system (colloquially called fishermen, todo: references) to challenge the header by presenting another header that would have been valid at the same height. Allowing us to leverage IBC semantics and freeze the light client immediately.

Secondly all bridged chains will need to have an equivocation protocol:

An equivocation protocol is a property of Proof of stake systems where staked validators can be slashed if they are found to have signed 2 headers that would've been valid at the same height. The reason we need this equivocation protocol is so that fishermen, in parallel to freezing the light client on our chain, can claim the rewards for securing our bridge by reporting this misbehavior to the counterparty chain, where the malicious validators will be slashed and their stake ideally is split between the network and the fishermen. Without an equivocation protocol, there's no way to incentivize fishermen and disincentivize eclipse attack attempts.

Action Items:

  • #75
  • Research equivocation protocol for cosmos & Near

Refactor IBC Handler

Provide a method fn handle_ibc_message(message: HandlerMessage) -> Result<(), Error> that accepts an enum with variants

pub enum HandlerMessage {
    OpenChannel { ... },
    CloseChannel { ... },
    Transfer { ... },
    SendPacket { ... }
} 

Benchmark and research batch signature verification in solidity

Research validity and benchmark performance of batch ECDSA and ECDSA* signature verification in solidity.

So, what I think it could be beneficial for the bridging strategy, in incremental order of complexity/time to production/scalability benefit:

  • 1: A heuristic to analyze same signer/same message strategy.
    If the validator set remains constant during the epoch, we can precompute some of the signature verification. The same applies if we are verifying the same message (block).
    We can take some common factor and optimize signature verification.
  • 2: Apply the batching algorithm presented in the paper. Using ECDSA*, we can get up to 30-40% more efficient.
  • 3: Employ ZK to send proof of the validity of the signatures.
    The idea is to use a recursive recursive ZK proofs to proof the validity of all signatures in a given block. As in all recursive relationships there is a base and general case.
    • Base case: You proof the first signature.
    • General case: You have a circuit to prove the t signature and the t-1 proof.
      At the end you have a single proof that verifies all the previous T signatures. This is expensive for the prover and the process it's sequential, but I think it can be all done off-chain. We can have relayers became provers.

based on the slack message: https://composablefinance.slack.com/archives/C0418RW2UH2/p1664554688135079

Signature verification efforts

This issue compiles the short-term journey for the R&D (math-focused) team.

In particular:

  1. Give pen + paper understanding of the topology of the circuit: number of constraints + on-chain costs (call data + proving times?)
  2. Assess room for improvement
  3. Compare to alternative implementation/frameworks (gnark/circom?)

Skeleton of CosmWasm GRANDPA Light Client

Create a new crate for the light client. The client should contain:

  • Minimal CosmWASM smart-contract with ExecuteMsg enum containing all possible functions that can be called from the contract
  • A Context, implementing IBC ReaderContext trait (concrete implementation of the methods can be omitted)
  • ICS23 realization to check storage operations
  • Based on the above, implement calls of specific functions of ics10-grandpa corresponding to the variants from ExecuteMsg

Main issue: #88

Create tendermint <> beefy clients

To create a tendermint client on parachains and beefy clients on cosmos chains, the hyperspace CosmosChainClient would need to:

  • declare a CosmosConfig struct type declaring cosmos chain configs as fields
  • parse CosmosConfig into a CosmosChainClient
  • implement account_id from the KeyProvider trait. submit from the Chain trait and query_client_id_from_tx_hash from the IbcProvider trait.

Grandpa light client audit-01 fixes

Fix issues raised in the first audit of grandpa light client

  • GRANDPA JUSTIFICATION - MISSING COMMIT VALIDATION
  • GRANDPA JUSTIFICATION - MISSING VOTERS VALIDATION
  • -GRANDPA PROVER -DENIAL OF SERVICE

Implement gas metering abstraction

So currently we naively relay all packets to the counter party chain. In production its more likely that these batches will be too expensive (probably even more than is allowed into a block) to relay all at once. So we probably want to first estimate the gas cost somehow then split them up into batches based on this estimate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.