Closed catShaark closed 2 years ago
This change is state breaking and require store migration, I think. Idk if that is okay or not ? If approved, I'll make a PR for this and close #1399 as well
Thanks for thinking about this problem, @catShaark. I think the solution that you propose is very clever!
Yes, so indeed we would need to run a migration to update the keys in the store... I think it's not a huge problem; we could release this as part of v4.0.0. We should make sure that we document the migration properly in the migration docs and that we thoroughly test it (both in integration and QA tests) to make sure it works well.
I guess the alternative would be otherwise to keep the store key as is but then try to do the order in code after retrieving the consensus states from the store...
On a second thought we might have a problem with this approach, since relayers will probably need to update their code to retrieve consensus state proofs from the updated path. So, for example in Hermes, they would need to update this path. The problem comes here that relayers would need to support both paths (since some chains would be running the old path and some chains the new one, until all of them upgrade to the new path) but there would be no way (unless we implement something) for relayers to know which path to use.
So even though I think the idea is good, the practical issues of deploying it might be too difficult to overcome...
On a second thought we might have a problem with this approach, since relayers will probably need to update their code to retrieve consensus state proofs from the updated path. So, for example in Hermes, they would need to update this path. The problem comes here that relayers would need to support both paths (since some chains would be running the old path and some chains the new one, until all of them upgrade to the new path) but there would be no way (unless we implement something) for relayers to know which path to use.
Ohhh I see, that's one annoying drawback that we have. Is this something that we should encounter every times we have a store migration in core ? If so, ibc-go should not accept store migrations in core or do we have "special plans" for them ?
Hi @catShaark , unfortunately this is something that we realized after shipping stargate but is a technical debt that is very hard to fix. The main reason is that it requires a network wide upgrade since the consensus state path is part of ICS-24 and thus chains will expect their counterparties to store the consensus state in the ICS-24 path which stores heights in string representation.
Is this something that we should encounter every times we have a store migration in core
It is only an issue if it is a store path that is part of ICS24 or expected to be stored in the public store as defined in the specs. Private store information that isn't getting proved on counterparties can be migrated without an issue.
https://github.com/cosmos/ibc-go/issues/64
As @colin-axner mentions in this issue, we have metadata stored in tendermint client that does store the consensus state in the efficient way.
https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/types/store.go#L227
If you can use the tendermint client to return the heights then this can be done numerically. From 02-client it is not so easy unless we replicate the consensus states under the efficient keys in 02-client as well.
thanks for the clarification, @AdityaSripal
Summary
We have problem where a
ConsensusStates
gRPC query return in lexicographic ordering ofHeight
, not numerical ordering. For example:_This problem is originally posted in this issue
Proposal
We index
ConsensusState
by convertingHeight.RevisionNumber
along withHeight.RevisionHeight
directly to 16 bytes ( 2 uint64 -> 16 bytes, big-endian ) in instead of turning them into a string ( uint64 -> string + "-" + uint64 -> string ) and then to bytes.Specifically :
exported.Height
interface02-client.types.Height
, we turnRevisionNumber
andRevisionHeight
to 16 bytes (like described above) and return that 16 bytesConsensusStateKey()
so that they useHeight.Byte()
to create key forConsensusState
instead of usingHeight.String()
For Admin Use