Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Dynamic Capabilities with Routing #5888

Merged
merged 25 commits into from
Apr 7, 2020
Merged

R4R: Dynamic Capabilities with Routing #5888

merged 25 commits into from
Apr 7, 2020

Conversation

AdityaSripal
Copy link
Member

Closes: #5542

Description

Start routing implementation in new PR since it may require changes to design. Currently router from portID => module callbacks is in portkeeper

All routing gets handled within the IBC handler itself


For contributor use:

  • Targeted PR against correct branch (see CONTRIBUTING.md)
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards.
  • Wrote unit and integration tests
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/)
  • Added relevant godoc comments.
  • Added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer

For admin use:

  • Added appropriate labels to PR (ex. WIP, R4R, docs, etc)
  • Reviewers assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

x/ibc/04-channel/types/msgs.go Show resolved Hide resolved
x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
x/ibc/05-port/types/module.go Show resolved Hide resolved
packet channeltypes.Packet,
) (*sdk.Result, error)

GetCapability(ctx sdk.Context, name string) (capability.Capability, bool)
Copy link
Member Author

Choose a reason for hiding this comment

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

Put Get/Claim capability callbacks as well so that ibc can request a module to provide the right capability or pass a module a capability that it can claim

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I'm a bit confused by these - why would IBC need to request a capability from a module or vice-versa? Generally in an object-capability system it is very dangerous for a module to expose an API that allows other modules to just fetch capabilities.

@@ -13,20 +13,6 @@ func NewHandler(k Keeper) sdk.Handler {
switch msg := msg.(type) {
case MsgTransfer:
return handleMsgTransfer(ctx, k, msg)
case channeltypes.MsgPacket:
Copy link
Member Author

Choose a reason for hiding this comment

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

No longer handled in 20-transfer's Handler

}
}

func (am AppModule) OnAcknowledgementPacket(
Copy link
Member Author

Choose a reason for hiding this comment

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

Currently Acknowledgement callback doesn't exist, so i have a no-op. Will implement spec later

x/ibc/handler.go Outdated
@@ -37,22 +38,75 @@ func NewHandler(k Keeper) sdk.Handler {

// IBC channel msgs
case channel.MsgChannelOpenInit:
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg)
cbs := k.PortKeeper.LookupModule(ctx, msg.PortID)
portCap, _ := cbs.GetCapability(ctx, ibctypes.PortPath(msg.PortID))
Copy link
Member Author

Choose a reason for hiding this comment

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

Get port capability from module using callback

Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to look this up? The module should already have the port capability.

x/ibc/handler.go Outdated
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg)
cbs := k.PortKeeper.LookupModule(ctx, msg.PortID)
portCap, _ := cbs.GetCapability(ctx, ibctypes.PortPath(msg.PortID))
err := cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version)
Copy link
Member Author

Choose a reason for hiding this comment

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

Call user defined OnChanOpenInit callback

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, should this happen before or after HandleMsgChannelOpenInit?

Both are safe as long as the transaction is atomic. If it's after then it can expect the channel state to be there.

x/ibc/handler.go Outdated
return nil, err
}
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg)
cbs.ClaimCapability(ctx, cap, ibctypes.ChannelCapabilityPath(msg.PortID, msg.ChannelID))
Copy link
Member Author

Choose a reason for hiding this comment

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

Module claims created channel capability using callback

Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of doing it this way, how about passing the channel capability to OnChanOpenInit ? I think that's cleaner.

x/ibc/handler.go Outdated

// IBC packet msgs get routed to the appropriate module callback
case channel.MsgPacket:
cbs := k.PortKeeper.LookupModule(ctx, msg.Packet.DestinationPort)
Copy link
Member Author

Choose a reason for hiding this comment

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

Rather than assuming portID == moduleName and using baseapp Router, we lookup module here in IBC handler and call appropriate callback

Copy link
Contributor

Choose a reason for hiding this comment

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

This actually needs to be based on the channel capability, not the port capability

Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

Unfortunately I don't think we can safely use a map in this way - the routing table needs to be persisted in an analogous way to how dynamic capabilities are - perhaps the moduleName on scoped capability keepers can be used to help us out here? When an incoming packet comes in, for example, we should look up (in the capability ownership table) which module owns the channel capability associated with that packet, then call the callback on that module. Since the module set is fixed in app.go in all SDK apps, it's fine to have a static map of moduleName to callbacks.

x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
@@ -45,6 +47,8 @@ func (k *Keeper) BindPort(ctx sdk.Context, portID string) capability.Capability
panic(err.Error())
}

k.router[portID] = cbs
Copy link
Contributor

Choose a reason for hiding this comment

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

The problem is that BindPort will not be re-called when e.g. gaiad is stopped & re-started

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we delete this now?

packet channeltypes.Packet,
) (*sdk.Result, error)

GetCapability(ctx sdk.Context, name string) (capability.Capability, bool)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I'm a bit confused by these - why would IBC need to request a capability from a module or vice-versa? Generally in an object-capability system it is very dangerous for a module to expose an API that allows other modules to just fetch capabilities.

counterparty channeltypes.Counterparty,
version string,
) error {
// TODO: Enforce ordering, currently relayers use ORDERED channels
Copy link
Contributor

Choose a reason for hiding this comment

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

In principle, token transfer channels can safely be unordered. I think we should test the relayer with both.

) error {
// TODO: Enforce ordering, currently relayers use ORDERED channels

if counterparty.PortID != types.PortID {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not necessarily, it's not "safety-critical", just convention. I think it's useful convention for now though.

x/ibc/handler.go Outdated
@@ -37,22 +38,75 @@ func NewHandler(k Keeper) sdk.Handler {

// IBC channel msgs
case channel.MsgChannelOpenInit:
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg)
cbs := k.PortKeeper.LookupModule(ctx, msg.PortID)
portCap, _ := cbs.GetCapability(ctx, ibctypes.PortPath(msg.PortID))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to look this up? The module should already have the port capability.

x/ibc/handler.go Outdated
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, msg)
cbs := k.PortKeeper.LookupModule(ctx, msg.PortID)
portCap, _ := cbs.GetCapability(ctx, ibctypes.PortPath(msg.PortID))
err := cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, msg.Channel.Counterparty, msg.Channel.Version)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, should this happen before or after HandleMsgChannelOpenInit?

Both are safe as long as the transaction is atomic. If it's after then it can expect the channel state to be there.

x/ibc/handler.go Outdated
return nil, err
}
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg)
cbs.ClaimCapability(ctx, cap, ibctypes.ChannelCapabilityPath(msg.PortID, msg.ChannelID))
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of doing it this way, how about passing the channel capability to OnChanOpenInit ? I think that's cleaner.

x/ibc/handler.go Outdated

// IBC packet msgs get routed to the appropriate module callback
case channel.MsgPacket:
cbs := k.PortKeeper.LookupModule(ctx, msg.Packet.DestinationPort)
Copy link
Contributor

Choose a reason for hiding this comment

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

This actually needs to be based on the channel capability, not the port capability

@cwgoes
Copy link
Contributor

cwgoes commented Mar 30, 2020

Basic pattern

  • Static map based on module name from scoped capability keeper to callbacks
  • When a message comes in for ConnOpenInit (analogously for ConnOpenTry)
    • Message has a port
    • Look up which module owns that port (for now: first module)
      • Needs new function on ScopedCapabilityKeeper to look up first other owning module
    • Find (in the capability mapping) the moduleName for that module
    • Use the static map to look up the callbacks
    • Call onConnOpenInit and pass the new channel capability as an argument (module must store)
  • For last two steps of handshake & packets, route based on channel capability instead

Notes

  • Routing has to exclude the IBC module's moduleName

Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

Almost there! A few minor concerns / cleanup remaining.

}
// the module that owns the channel, for now, is the first module that isn't "ibc"
// that owns the module
module := capOwners.Owners[1].Module
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we sure that the ordering will always be this way? Isn't it dependent on the module name?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah this needs a test case for sure

@@ -45,6 +47,8 @@ func (k *Keeper) BindPort(ctx sdk.Context, portID string) capability.Capability
panic(err.Error())
}

k.router[portID] = cbs
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we delete this now?

}
// the module that owns the port, for now, is the first module that isn't "ibc"
// that owns the module
module := capOwners.Owners[1].Module
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we sure that the ordering will always be this way? Isn't it dependent on the module name?

Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto test case

connectionHops []string,
portID,
channelID string,
portCap capability.Capability,
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't need to pass the port capability to the module

Copy link
Contributor

Choose a reason for hiding this comment

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

(we do need to pass the channel capability)

Copy link
Member Author

Choose a reason for hiding this comment

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

whoops misnamed

x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

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

good work @AdityaSripal! Thanks for tackling this

x/ibc/04-channel/keeper/keeper.go Outdated Show resolved Hide resolved
}
// the module that owns the channel, for now, is the first module that isn't "ibc"
// that owns the module
module := capOwners.Owners[1].Module
Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah this needs a test case for sure

x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
}
// the module that owns the port, for now, is the first module that isn't "ibc"
// that owns the module
module := capOwners.Owners[1].Module
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto test case

x/ibc/05-port/types/module.go Show resolved Hide resolved
x/ibc/handler.go Outdated
// Lookup module by port capability
module, portCap, ok := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID)
if !ok {
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "could not retrieve module from portID")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "could not retrieve module from portID")
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "could not retrieve module from portID %s" msg.PortID)

x/ibc/handler.go Outdated
// Lookup module by port capability
module, portCap, ok := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID)
if !ok {
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "could not retrieve module from portID")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "could not retrieve module from portID")
return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "could not retrieve module from portID %s" msg.PortID)

x/ibc/handler.go Show resolved Hide resolved
x/ibc/handler.go Outdated Show resolved Hide resolved
x/ibc/handler.go Outdated Show resolved Hide resolved
@lgtm-com
Copy link

lgtm-com bot commented Mar 31, 2020

This pull request fixes 2 alerts when merging 8086e42 into 06e7b80 - view on LGTM.com

fixed alerts:

  • 2 for Useless assignment to local variable

Copy link
Collaborator

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

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

LGTM. minor suggestion

Comment on lines 166 to 185
capOwners, ok := k.scopedKeeper.GetOwners(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
if !ok {
return "", nil, false
}
if len(capOwners.Owners) < 2 {
panic("more than one module has bound to this port; currently not supported")
}
// the module that owns the channel, for now, is the only module owner that isn't "ibc"
var module string
if capOwners.Owners[0].Module == "ibc" {
module = capOwners.Owners[1].Module
} else {
module = capOwners.Owners[0].Module
}

cap, found := k.scopedKeeper.GetCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
if !found {
return "", nil, false
}
return module, cap, true
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit, you can avoid duplication by abstracting this part and passing the path:

func (k ScopedKeeper) LookupModule(ctx sdk.Context, path string) (string, capability.Capability, bool) {
	capOwners, ok := k.GetOwners(ctx, path)
	if !ok {
		return "", nil, false
	}
	// For now, we enforce that only IBC and the module bound to port can own the capability
	// while future implementations may allow multiple modules to bind to a port, currently we
	// only allow one module to be bound to a port at any given time
	if len(capOwners.Owners) != 2 {
		panic("more than one module has bound to this port; currently not supported")
	}
	// the module that owns the port, for now, is the only module owner that isn't "ibc"
	var module string
	if capOwners.Owners[0].Module == "ibc" {
		module = capOwners.Owners[1].Module
	} else {
		module = capOwners.Owners[0].Module
	}
	cap, found := k.GetCapability(ctx, path)
	if !found {
		return "", nil, false
	}
	return module, cap, true
}

and then:

// LookupModuleByChannel will return the IBCModule along with the capability associated with a given channel defined by its portID and channelID
func (k Keeper) LookupModuleByChannel(ctx sdk.Context, portID, channelID string) (string, capability.Capability, bool) {
	return k.scopedKeeper.LookupModule(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm yea doesn't make sense to have the ibc special case in the scopedKeeper code, but I can just return string of modules from scoped keeper and then have a util function in ibc to enforce length-2 and pick non-ibc module

@lgtm-com
Copy link

lgtm-com bot commented Apr 1, 2020

This pull request fixes 3 alerts when merging b282f99 into 06e7b80 - view on LGTM.com

fixed alerts:

  • 3 for Useless assignment to local variable

algo := Secp256k1

n1, n2, n3 := "some dude", "a dudette", "dude-ish"
p1, p2, p3 := "1234", "foobar", "foobar"
Copy link
Contributor

Choose a reason for hiding this comment

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

string foobar has 3 occurrences, but such constant foobar already exists (from goconst)


algo := Secp256k1
n1, n2, n3 := "personal", "business", "other"
p1, p2 := "1234", "really-secure!@#$"
Copy link
Contributor

Choose a reason for hiding this comment

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

string 1234 has 5 occurrences, but such constant nums already exists (from goconst)


if cb(connection) {
if cb(types.IdentifiedConnectionEnd{connection, identifier}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

composites: github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types.IdentifiedConnectionEnd composite literal uses unkeyed fields (from govet)

@lgtm-com
Copy link

lgtm-com bot commented Apr 2, 2020

This pull request fixes 3 alerts when merging 9b1aeda into 06e7b80 - view on LGTM.com

fixed alerts:

  • 3 for Useless assignment to local variable

@@ -0,0 +1 @@
MANIFEST-000004
Copy link
Member Author

Choose a reason for hiding this comment

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

Seems like some test files got committed accidentally. Is there a command to clean these files up or should i manually delete them?

@alexanderbez

Copy link
Contributor

Choose a reason for hiding this comment

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

errr, not sure how this happened. These files exist on master due to @alessio's changes to the keybase. But I branched off of ibc-alpha, so not sure how these got in here. They also were not in my PR diff.

@@ -0,0 +1 @@
MANIFEST-000004
Copy link
Member Author

Choose a reason for hiding this comment

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

Seems like some test files got committed accidentally. Is there a command to clean these files up or should i manually delete them?

@alexanderbez

Copy link
Contributor

Choose a reason for hiding this comment

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

See above.

@AdityaSripal AdityaSripal changed the base branch from aditya/ics5 to ibc-alpha April 2, 2020 20:24
@AdityaSripal AdityaSripal changed the title WIP: IBC Routing Dynamic Capabilities with Routing Apr 2, 2020
@AdityaSripal AdityaSripal changed the title Dynamic Capabilities with Routing R4R: Dynamic Capabilities with Routing Apr 2, 2020
Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

Logic looks solid, seems like a few test-cases can be uncommented, a few nits.

x/ibc/04-channel/keeper/handshake_test.go Outdated Show resolved Hide resolved
x/ibc/04-channel/keeper/handshake_test.go Outdated Show resolved Hide resolved
x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
x/ibc/05-port/keeper/keeper.go Outdated Show resolved Hide resolved
x/ibc/05-port/types/module.go Outdated Show resolved Hide resolved
// GetRoute returns a IBCModule for a given module.
func (rtr *Router) GetRoute(module string) IBCModule {
if !rtr.HasRoute(module) {
panic(fmt.Sprintf("route does not exist for module %s", module))
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems potentially dangerous? What if a packet has a port/channel that isn't routed?

x/ibc/20-transfer/keeper/keeper.go Outdated Show resolved Hide resolved
return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error())
}

// TODO: escrow
Copy link
Contributor

Choose a reason for hiding this comment

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

Here is where we want to create the escrow address

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like the current implementation just calculates the escrow address from portID, and channelID and uses the bank keeper to send and receive money. This seems like it should work?

Should I make these escrow addresses module accounts instead?

https://github.com/cosmos/cosmos-sdk/blob/ibc-alpha/x/ibc/20-transfer/keeper/relay.go#L97

https://github.com/cosmos/cosmos-sdk/blob/ibc-alpha/x/ibc/20-transfer/keeper/relay.go#L186

Copy link
Contributor

Choose a reason for hiding this comment

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

This is OK for now, I suppose, maybe they should be module accounts but that can be a follow-up.

return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error())
}

// TODO: escrow
Copy link
Contributor

Choose a reason for hiding this comment

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

Here is where we want to create the escrow address

x/ibc/types/utils.go Outdated Show resolved Hide resolved
Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

utACK modulo question on ClaimCapability safety / permissions

@cwgoes cwgoes added R4R and removed WIP labels Apr 6, 2020
@fedekunze
Copy link
Collaborator

NOTE: Capability is no longer an interface but a concrete type

Comment on lines +41 to +60
// Lookup module by port capability
module, portCap, ok := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID)
if !ok {
return nil, sdkerrors.Wrap(port.ErrInvalidPort, "could not retrieve module from portID")
}
res, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg)
if err != nil {
return nil, err
}
// Retrieve callbacks from router
cbs, ok := k.Router.GetRoute(module)
if !ok {
return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module)
}
err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version)
if err != nil {
return nil, err
}

return res, nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit, can we move each of the cases to a private function to avoid bloating the switch and for ease of reading?

@cwgoes cwgoes merged commit 9448610 into ibc-alpha Apr 7, 2020
@cwgoes cwgoes deleted the aditya/ibc-routing branch April 7, 2020 11:20
@AdityaSripal AdityaSripal mentioned this pull request Apr 8, 2020
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants