Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Feat/new register runtx flows #52

Merged
merged 21 commits into from
Jul 13, 2021
Merged

Conversation

seantking
Copy link
Contributor

@seantking seantking commented Jun 23, 2021

This PR updates the core interchain account module based on the new specification: cosmos/ibc#567

  • No longer need to pass port/channel id when registering an account
  • Bind port-id with owner address on register command (this will eventually call OnChanOpenInit which will emit an event the relayer can pick up and finish the channel handshake)
  • Register account on OnTryOpenChannel callback during channel creation
  • Each account now has an "active channel". Only the owner of the account can send IBC packets over the active channel.
  • When a channel closes, the account owner no longer loses access to the account. To regain access just create a new channel with the owners port-id. This will set a new "active channel" for the account
  • Remove TX encoder step. This is not necessary for the time being. We can focus on cosmos SDK chains only. see fix: removing tx encoder #53
  • Rename all references of IBC Account to Interchain Account
  • Update environment to use hermes 0.5.0
  • Update read me demo
  • Hermes relayer finishing channel-open handshake

How to run

Check out the latest readme to test -> https://github.com/cosmos/interchain-accounts/tree/feat/new-register-runtx-flows#readme

@seantking
Copy link
Contributor Author

.

return err
}

//TODO: Add call to OnChanOpenInit. The hermes relayer currently does not support this.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is being worked on at the moment by the hermes team

}

// Determine account's address that will be created.
func (k Keeper) GenerateAddress(identifier string, salt []byte) []byte {
return tmhash.SumTruncated(append([]byte(identifier), salt...))
func (k Keeper) GenerateAddress(identifier string) []byte {
Copy link
Contributor Author

@seantking seantking Jun 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milosevic I think this may be an issue.

We need to have a way to deterministically generate the interchain account address on both chains from an identifier. Right now this works as I'm just running the same chain x2 but I guess this would return a different address depending on chain configuration?

The controller chain needs to know what the registered account address is (perhaps for sending ics20 transfers). As we are registering the account in the channel handshake callbacks the sending side has no way to retrieve what the interchain account address is.

Although, the more I think on it, it's not a must-have. We can always set the interchain address on the controller side at a later time (maybe parse it from an ack packet) or just have the host side have a query to get the interchain account address (for the short term this is totally fine)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine to me from a deterministic point of view. Are you worried about collisions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only way around this, for now, is to add another command to set the address of the registered account on the controller side (we will need to parse it from the IBC ack). We need the address of the interchain account for practically every msg we want to send.

return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort)
}

if version != types.Version {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need to update this check. I was getting some errors, so I moved on.

return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort)
}

if version != types.Version {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.

channelID string,
counterpartyVersion string,
) error {
k.SetActiveChannel(ctx, portID, channelID)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking maybe it would be better to store the full Channel type rather than the id.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ID is fine, any reason to store full channel?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ID is also fine. Agreed.


// May want to use these for re-opening a channel when it is closed
//// OnChanCloseInit implements the IBCModule interface
//func (am AppModule) OnChanCloseInit(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could potentially try to reopen the channel when it closes here. Perhaps this adds to much edge case complexity tho.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't try to reopen. Just open a new channel with the same portID

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And "unset" the active channel here

// TryRunTx attemps to send messages to source channel.
func (k Keeper) TryRunTx(ctx sdk.Context, sourcePort, sourceChannel, typ string, data interface{}) ([]byte, error) {
sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel)
sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePortId, activeChannelId)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to check here if the channel is closed. It actually isn't doing this check at the moment. The error that returns from TryRunTx if there is no active channel is just the standard IBC error (because the channel is not open). It works as intended though, just not the correct error message.

}
func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IBCAccountPacketData, ack channeltypes.Acknowledgement) error {
switch ack.Response.(type) {
case *channeltypes.Acknowledgement_Error:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this to use the newer channeltypes.Acknowledgement. The latest ibc-go is using a newer standard but I'm still using an older version of the SDK at the moment.

@@ -13,27 +11,23 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)

const (
IcaPrefix string = "ics27-1-"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@milosevic Every registered port is prefixed with this. I was thinking it is a good way to track what version of ics27 an account was registered under (this may be useful for migrating accounts in the future, or even just to help with port collisions)

@@ -52,8 +52,7 @@ func (k Keeper) IBCAccountFromData(ctx context.Context, req *types.QueryIBCAccou
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
identifier := types.GetIdentifier(req.Port, req.Channel)
address := k.GenerateAddress(identifier, []byte(req.Data))
address := k.GenerateAddress("test")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to update the grpc_query stuff today, and probably add a new cli command for querying for interchain accounts.

Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work!! This looks so much cleaner!

My main requests are just copies from what i said in spec PR, mainly around the handshake callbacks

}

// Determine account's address that will be created.
func (k Keeper) GenerateAddress(identifier string, salt []byte) []byte {
return tmhash.SumTruncated(append([]byte(identifier), salt...))
func (k Keeper) GenerateAddress(identifier string) []byte {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine to me from a deterministic point of view. Are you worried about collisions?

if version != types.Version {
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid version: %s, expected %s", version, "ics20-1")
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should still check module has bound to given port and it is in expected format

@@ -54,15 +46,6 @@ func (k Keeper) OnChanOpenTry(
version,
counterpartyVersion string,
) error {
boundPort := k.GetPort(ctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

channelID string,
counterpartyVersion string,
) error {
k.SetActiveChannel(ctx, portID, channelID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ID is fine, any reason to store full channel?


// May want to use these for re-opening a channel when it is closed
//// OnChanCloseInit implements the IBCModule interface
//func (am AppModule) OnChanCloseInit(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't try to reopen. Just open a new channel with the same portID

// portID,
// channelID string,
//) error {
// return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"unset" active channel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we can create some issues for the work that is left to do. I.e. unset active channels + additional checks in the channel callbacks.

@@ -191,7 +188,7 @@ func (am AppModule) OnChanCloseInit(
channelID string,
) error {
// Disallow user-initiated channel closing for interchain account channels
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will allow anyone to close a channel. If you want to let people voluntarily close a channel, you need to do at least some kind of authentication here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this 👍

@@ -191,7 +188,7 @@ func (am AppModule) OnChanCloseInit(
channelID string,
) error {
// Disallow user-initiated channel closing for interchain account channels
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also "unset" active channel

@@ -191,7 +188,7 @@ func (am AppModule) OnChanCloseInit(
channelID string,
) error {
// Disallow user-initiated channel closing for interchain account channels
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
return nil
}

func (am AppModule) OnChanCloseConfirm(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unset active channel

host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"

"github.com/cosmos/interchain-accounts/x/ibc-account/types"
)

func (k Keeper) OnChanOpenInit(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions should also error if the active channel is already set

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point

@seantking seantking force-pushed the feat/new-register-runtx-flows branch from b9a8611 to a1d7e97 Compare July 4, 2021 20:04
@lgtm-com
Copy link

lgtm-com bot commented Jul 9, 2021

This pull request introduces 1 alert when merging 0643e22 into 63755ee - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable

@seantking seantking force-pushed the feat/new-register-runtx-flows branch from 7dc1c41 to b7f60f9 Compare July 9, 2021 16:09
@seantking seantking force-pushed the feat/new-register-runtx-flows branch from 13a28bc to f8b148c Compare July 9, 2021 16:25
@lgtm-com
Copy link

lgtm-com bot commented Jul 9, 2021

This pull request introduces 1 alert when merging f8b148c into 63755ee - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable

@seantking seantking force-pushed the feat/new-register-runtx-flows branch from 64150f0 to 8d6ad18 Compare July 13, 2021 07:05
@seantking seantking merged commit b8b76c0 into master Jul 13, 2021
@lgtm-com
Copy link

lgtm-com bot commented Jul 13, 2021

This pull request introduces 1 alert when merging 8d6ad18 into 63755ee - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable

@seantking seantking deleted the feat/new-register-runtx-flows branch July 22, 2021 17:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants