ibc icon indicating copy to clipboard operation
ibc copied to clipboard

ICS3: Flexible Id clarification

Open ancazamfir opened this issue 5 years ago • 6 comments

It is not clear to me how a relayer should deal with this. Take for example the connection handshake case.

It looks like a MsgConnOpenInit with "" counterparty connection id can be relayed to a chain, let's say A. So A will have the IdentifiedConnection : {id: "conn_on_A", state: "STATE_INIT", client_id: "clB_on_A", counterparty: {..,connection_id:"",...}}

If a relayer wants to build the MsgConnOpenTry from this:

  • it cannot determine the state of the connection on destination chain B unless there is a query that looks up a connection with `{id: "conn_on_A", client_id: "clB_on_A"} in its counterparty
  • it is not clear if the relayer is required to fill the DesiredConnectionId field in the Try message, it seems to be required (in SDK the msg validation fails without one and in ICS-03 this is required to be a valid id). I see this comment in ICS03: Chains may implement a function desiredIdentifier which chooses an identifier, e.g. by incrementing a counter. Is the relayer supposed to call this function?

ancazamfir avatar Oct 21 '20 12:10 ancazamfir

it cannot determine the state of the connection on destination chain B unless there is a query that looks up a connection with `{id: "conn_on_A", client_id: "clB_on_A"} in its counterparty

Yes, this is true. I don't see how to avoid this, though, this is the price we pay for allowing flexibility in identifiers. Assuming the logic on chain A is correct, such a query should return at most one result (since conn_on_A can have started only one connection handshake), so it would work, but it may require additional indexing to query efficiently.

it is not clear if the relayer is required to fill the DesiredConnectionId field in the Try message, it seems to be required (in SDK the msg validation fails without one and in ICS-03 this is required to be a valid id). I see this comment in ICS03: Chains may implement a function desiredIdentifier which chooses an identifier, e.g. by incrementing a counter. Is the relayer supposed to call this function?

The empty identifiers are presently used as sentinel values to allow the destination chain to pick any identifier. At the moment, the specification is written in a way which would allow the relayer to choose this identifier, but it could also be chosen by the chain itself (e.g. by incrementing a counter, to avoid conflicts). This isn't standardised at the moment because it's not security-critical, but I suppose we could standardise it and implement some automatic counter in the SDK if that would be helpful.

cwgoes avatar Oct 22 '20 11:10 cwgoes

At the moment, the specification is written in a way which would allow the relayer to choose this identifier,..

So at the moment the relayer MUST figure out some id, invent one or query the chain (if desiredIdentifer is implemented)

but it could also be chosen by the chain itself (e.g. by incrementing a counter, to avoid conflicts). This isn't standardised at the moment because it's not security-critical, but I suppose we could standardise it and implement some automatic counter in the SDK if that would be helpful.

Should it also ensure that value is not in use?

"could also be chosen by the chain itself" may mean two things:

  • the chain implements desiredIdentifier and the relayer uses this in the Try or
  • the chain accepts a Try message with empty connection id, picks the identifier and then validates the message

I thought the goal is the latter.

ancazamfir avatar Oct 22 '20 12:10 ancazamfir

Assuming the logic on chain A is correct, such a query should return at most one result (since conn_on_A can have started only one connection handskae),...

It is possible that on B there are two connections to A and C with same counterparty, if the two chains A and C are using the same local connection id conn-to-B and client id clB. So the query should also specify the client id used on B for either A or C. Or relayer can filter based on that.

ancazamfir avatar Oct 22 '20 12:10 ancazamfir

the chain accepts a Try message with empty connection id, picks the identifier and then validates the message

Agreed - this is what I mean. The former is also possible but not useful for e.g. preventing race conditions.

Should it also ensure that value is not in use?

If the chain increments a counter with a dedicated namespace, that will ensure that the identifier is not in use.

It is possible that on B there are two connections to A and C with same counterparty, if the two chains A and C are using the same local connection id conn-to-B and client id clB. So the query should also specify the client id used on B for either A or C. Or relayer can filter based on that.

Aye, the query/filter must be done on (client_id, counterparty_connection_id).

cwgoes avatar Oct 22 '20 14:10 cwgoes

Aye, the query/filter must be done on (client_id, counterparty_connection_id).

~~(client_id, (counterparty_client_id, counterparty_connection_id))?~~

you are right :)

ancazamfir avatar Oct 22 '20 15:10 ancazamfir

@cwgoes Is this issue still relevant?

mpoke avatar Mar 17 '22 12:03 mpoke

Closing the issue. It seems we don't to take any action or change anything.

crodriguezvega avatar Sep 25 '23 07:09 crodriguezvega