tendermint / cns

Chain Name System
Apache License 2.0
39 stars 11 forks source link

Issues with proving two clients belong to same chain #16

Open sahith-narahari opened 3 years ago

sahith-narahari commented 3 years ago

Description

Ref: #2 As one of the applications of CNS, we wanted to provide a balance query which identifies the chain from which the token was transferred. This is a wrapper around bank's GetBalance in order to make it easier for users to understand which token they have rather than looking at hash e.g.. 100ibc/C053D637CCA2A2BA030E2C5EE1B28A16F71CCB0E45E8BE52766DC1B241B77878 will be resolved as 100ibc/stake/testchain1

Problem:

Let's say there's C1 and C2. C1 is registered as part of CNS and mapped to a particular chain, but C2 was used for the transfer. We want to prove both C1 and C2 belong to the same chain and thereby resolve the token hash

The plan was to compare client states of both C1 and C2 with custom fields zeroed out. In order to ensure that C2 is not from a chain which duplicated original chain's parameters, we're trying to compare the consensus states of C1 and C2. The problem is we have the consensus states at different heights which make it impossible to compare consenus states.

Proposed Solutions: 1) We store a primary client ID in CNS and resolve it accordingly by doing a query for consensus states Pros: This approach is straight forward and won't require any changes from ibc modules Cons: The main issue being this may not be suitable for all use-cases as this involve multiple queries This helps only wallets/explorers to resolve the ibc denom hashes as belonging to a particular chain

2) Alternatively we can have a hook on cns side to register every client created to it's respective chain Id. Pros: This helps all users to be able to query their balances using cns, provided the chain is registered in cns Cons: For this we expect all the necessary implementation to be present in ibc module. We may also need to iterate over all the chain info registered to establish the link. This may also register in a significant increase in state size of cns module, though we want to encourage reuse of clients for transfers.

Is there a preferred method on how we want to do this, or any practices suggested by ibc team on what's the best way to utilise ibc module in applications like cns?

cc\ @fadeev @okwme @hxrts @cwgoes @AdityaSripal @colin-axner

cwgoes commented 3 years ago

Proving that two clients belong to the same chain will require proving that they use the same algorithm (same client type) and that they have the same client state at a particular height. Be careful with zero-ing out custom fields, because two light clients with e.g. different trusting periods are not really "of the same chain", they may diverge depending on how that chain behaves. We do not have strong guarantees about this, or at least it hasn't been reasoned through in detail yet. Also note that "semantic equality of algorithms" is in general not possible to check, there may always be a light client with nominally different but semantically equivalent code that in fact tracks the same chain.

You can also check whether one client (with the older consensus state) can be updated to the newer consensus state, this will require querying intermediate headers as necessary and running the light client update algorithm (though this can be done locally, it is not necessary to use the chain).

Please note that chain identifiers are not enforceably unique, anyone can create a new chain with any existing identifier. Client identifiers are enforceably unique but only for the IBC module instance on a particular chain.

Let me know if that helps clarify things.

colin-axner commented 3 years ago

I'd suggest starting with simple cases and building your way up.

What is really difficult is proving that 07-tendermint-0 on chainA and 07-tendermin-5 on chainB both refer to chainC. I would not try to solve this initially.

What is worth solving is using the client-id associated with a channel to determine that tokens sent on channel-0 and channel-1 come from the same chain since they use the exact same client. These tokens are still non-fungible, but we can at least know that both channels use a client which is registered on the CNS.

If I were designing the CNS, I would focus on making a client a first class citizen. A client is a representation of some specific set of valid header updates. As @cwgoes mentioned, the trusting period may be different on a per client basis, this could result in two clients following the same chain having different consensus states in the future. A future header may be invalid for clientA and valid for clientB depending on the trusting period. This applies to misbehaviour as well. Certain types of misbehaviour may only apply to certain clients, even if they both track the same chain

sahith-narahari commented 3 years ago

Thanks for the explanation @cwgoes, @colin-axner. From my understanding it's not something we would want to do it straight away - trying to verify if two clients belong to same chain. I feel storing all client information per chain as part of cns module is more of an overkill and using a query to fetch header and update consensus state isn't the flow we want to go ahead with. I defer to @fadeev on how we move forward with this, as I don't see a generalized way to decode denom hashes from ibc-transfer to more real time values

romeo4934 commented 3 years ago

@sahith-narahari it is not really a problem because you can have a relayer sending the same height for each clients so you can actually compare clients state and deduct which are the chains are connected to the CNS. I believe this information is absolutely critical to build a proper CNS that rely on IBC. Otherwise, we will not be able to bring intelligence to the cosmoshub and we will continue to have the cosmoshub kind of dumb as it is not aware of his immediate chain environnement.

AdityaSripal commented 3 years ago

I kind of wonder why we even need this feature. Can the CNS just say this client is the canonical client between say Hub->Osmosis and just store that on-chain? Most people can then just build connections/channels on top of the canonical client. Anyone who wants to use the non-canonical client can do their own due diligence

sahith-narahari commented 3 years ago

I kind of wonder why we even need this feature. Can the CNS just say this client is the canonical client between say Hub->Osmosis and just store that on-chain? Most people can then just build connections/channels on top of the canonical client. Anyone who wants to use the non-canonical client can do their own due diligence

The plan was to address the issue of using non canonical clients too, hence this was needed. If we want to go through the path of users using only canonical clients, we won't need this anymore.

romeo4934 commented 3 years ago

Ideally we want: 1)to be able to create a unique list of chainId based on clients connection. For that, we need to be able to deduplicate clients connection to a list of unique chains. 2) then we can attached to this unique list of chain any metadata information coming from the chain itself 2) any chain parameter should be able to be sent from a chain to the CNS with a simple IBC parameter data type message. This message could be sent by one of the clients connected to the chain.

If we are using IBC protocol well, we don't need to rely on any form of governance as any chain itself could send information to the CNS.

The current problem with the current CNS is the big machinery around governance and making sure the right person update the right parameter on the right chain. This problem disappear if we leverage the IBC infrastructure to make sure only the chain itself can update his own parameters.