Skip to content

Commit

Permalink
Merge branch 'tunnel-ibc' into tunnel-ibc-hook
Browse files Browse the repository at this point in the history
  • Loading branch information
satawatnack committed Nov 25, 2024
2 parents 84fb20e + 758014a commit 92439a1
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 268 deletions.
343 changes: 172 additions & 171 deletions api/band/tunnel/v1beta1/route.pulsar.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions proto/band/tunnel/v1beta1/route.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ message IBCPacketReceipt {
uint64 sequence = 1;
}

// IBCPacket is the type for an IBC packet
message IBCPacket {
// TunnelPricesPacketData represents the IBC packet payload for the tunnel packet.
message TunnelPricesPacketData {
// tunnel_id is the tunnel ID
uint64 tunnel_id = 1 [(gogoproto.customname) = "TunnelID"];
// sequence is representing the sequence of the tunnel packet.
Expand Down
104 changes: 97 additions & 7 deletions x/tunnel/ibc_module.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tunnel

import (
"math"
"strings"

capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
Expand All @@ -18,6 +19,12 @@ import (
"github.com/bandprotocol/chain/v3/x/tunnel/types"
)

var (
_ porttypes.IBCModule = (*IBCModule)(nil)
_ porttypes.PacketDataUnmarshaler = (*IBCModule)(nil)
_ porttypes.UpgradableModule = (*IBCModule)(nil)
)

// IBCModule implements the ICS26 interface for tunnel given the tunnel keeper.
type IBCModule struct {
keeper keeper.Keeper
Expand All @@ -41,7 +48,7 @@ func (im IBCModule) OnChanOpenInit(
counterparty channeltypes.Counterparty,
version string,
) (string, error) {
err := validateChannelParams(ctx, im.keeper, order, portID)
err := ValidateTunnelChannelParams(ctx, im.keeper, order, portID, channelID)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -74,7 +81,7 @@ func (im IBCModule) OnChanOpenTry(
counterparty channeltypes.Counterparty,
counterpartyVersion string,
) (string, error) {
err := validateChannelParams(ctx, im.keeper, order, portID)
err := ValidateTunnelChannelParams(ctx, im.keeper, order, portID, channelID)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -181,17 +188,100 @@ func (im IBCModule) OnTimeoutPacket(
return nil
}

// validateChannelParams validates the parameters of a newly created tunnel channel.
// A valid tunnel channel must be ORDERED, use the correct port (default is 'tunnel').
func validateChannelParams(
// OnChanUpgradeInit implements the IBCModule interface
func (im IBCModule) OnChanUpgradeInit(
ctx sdk.Context,
portID, channelID string,
proposedOrder channeltypes.Order,
proposedConnectionHops []string,
proposedVersion string,
) (string, error) {
if err := ValidateTunnelChannelParams(ctx, im.keeper, proposedOrder, portID, channelID); err != nil {
return "", err
}

if proposedVersion != types.Version {
return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, proposedVersion)
}

return proposedVersion, nil
}

// OnChanUpgradeTry implements the IBCModule interface
func (im IBCModule) OnChanUpgradeTry(
ctx sdk.Context,
portID, channelID string,
proposedOrder channeltypes.Order,
proposedConnectionHops []string,
counterpartyVersion string,
) (string, error) {
if err := ValidateTunnelChannelParams(ctx, im.keeper, proposedOrder, portID, channelID); err != nil {
return "", err
}

if counterpartyVersion != types.Version {
return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, counterpartyVersion)
}

return counterpartyVersion, nil
}

// OnChanUpgradeAck implements the IBCModule interface
func (IBCModule) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error {
if counterpartyVersion != types.Version {
return errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, counterpartyVersion)
}

return nil
}

// OnChanUpgradeOpen implements the IBCModule interface
func (IBCModule) OnChanUpgradeOpen(
ctx sdk.Context,
portID, channelID string,
proposedOrder channeltypes.Order,
proposedConnectionHops []string,
proposedVersion string,
) {
}

// UnmarshalPacketData attempts to unmarshal the provided packet data bytes
// into a TunnelPricesPacketData. This function implements the optional
// PacketDataUnmarshaler interface required for ADR 008 support.
func (IBCModule) UnmarshalPacketData(bz []byte) (interface{}, error) {
var packetData types.TunnelPricesPacketData
if err := types.ModuleCdc.UnmarshalJSON(bz, &packetData); err != nil {
return nil, err
}

return packetData, nil
}

// ValidateTunnelChannelParams does validation of a newly created tunnel channel. A tunnel
// channel must be ORDERED, use the correct port (by default 'tunnel'), and use the current
// supported version. Only 2^32 channels are allowed to be created.
func ValidateTunnelChannelParams(
ctx sdk.Context,
keeper keeper.Keeper,
order channeltypes.Order,
portID string,
channelID string,
) error {
// NOTE: for escrow address security only 2^32 channels are allowed to be created
// Issue: https://github.com/cosmos/cosmos-sdk/issues/7737
channelSequence, err := channeltypes.ParseChannelSequence(channelID)
if err != nil {
return err
}
if channelSequence > uint64(math.MaxUint32) {
return types.ErrMaxTunnelChannels.Wrapf(
"channel sequence %d is greater than max allowed tunnel channels %d",
channelSequence,
uint64(math.MaxUint32),
)
}
if order != channeltypes.ORDERED {
return errorsmod.Wrapf(
channeltypes.ErrInvalidChannelOrdering,
return channeltypes.ErrInvalidChannelOrdering.Wrapf(
"expected %s channel, got %s",
channeltypes.ORDERED,
order,
Expand Down
63 changes: 63 additions & 0 deletions x/tunnel/ibc_module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package tunnel_test

import (
"testing"

"github.com/stretchr/testify/require"

feedstypes "github.com/bandprotocol/chain/v3/x/feeds/types"
"github.com/bandprotocol/chain/v3/x/tunnel"
"github.com/bandprotocol/chain/v3/x/tunnel/types"
)

func TestPacketDataUnmarshalerInterface(t *testing.T) {
var (
data []byte
expPacketData types.TunnelPricesPacketData
)

testCases := []struct {
name string
malleate func()
expPass bool
}{
{
"invalid packet data",
func() {
data = []byte("invalid packet data")
},
false,
},
{
"all good",
func() {
expPacketData = types.TunnelPricesPacketData{
TunnelID: 1,
Sequence: 1,
Prices: []feedstypes.Price{
{Status: feedstypes.PRICE_STATUS_NOT_IN_CURRENT_FEEDS, SignalID: "BTC", Price: 50000},
},
CreatedAt: 1633024800,
}
data = expPacketData.GetBytes()
},
true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.malleate()

packetData, err := tunnel.IBCModule{}.UnmarshalPacketData(data)

if tc.expPass {
require.NoError(t, err)
require.Equal(t, expPacketData, packetData)
} else {
require.Error(t, err)
require.Nil(t, packetData)
}
})
}
}
6 changes: 3 additions & 3 deletions x/tunnel/keeper/keeper_packet_ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func (k Keeper) SendIBCPacket(
return nil, types.ErrChannelCapabilityNotFound
}

// create the IBC packet bytes
packetBytes := types.NewIBCPacket(
// create the tunnel prices packet data bytes
packetBytes := types.NewTunnelPricesPacketData(
packet.TunnelID,
packet.Sequence,
packet.Prices,
Expand All @@ -49,5 +49,5 @@ func (k Keeper) SendIBCPacket(
return nil, err
}

return types.NewIBCPacketReceipt(route.ChannelID, sequence), nil
return types.NewIBCPacketReceipt(sequence), nil
}
1 change: 1 addition & 0 deletions x/tunnel/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ var (
ErrDeviationNotFound = errorsmod.Register(ModuleName, 20, "deviation not found")
ErrInvalidVersion = errorsmod.Register(ModuleName, 21, "invalid ICS20 version")
ErrChannelCapabilityNotFound = errorsmod.Register(ModuleName, 22, "channel capability not found")
ErrMaxTunnelChannels = errorsmod.Register(ModuleName, 23, "max tunnel channels exceeded")
)
Loading

0 comments on commit 92439a1

Please sign in to comment.