Skip to content

Commit

Permalink
Add context and hex port-id encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Nov 13, 2023
1 parent 2227803 commit 88ae8da
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 26 deletions.
18 changes: 9 additions & 9 deletions x/wasm/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (i IBCHandler) OnChanOpenInit(
if err := ValidateChannelParams(channelID); err != nil {
return "", err
}
contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return "", errorsmod.Wrapf(err, "contract port id")
}
Expand Down Expand Up @@ -102,7 +102,7 @@ func (i IBCHandler) OnChanOpenTry(
return "", err
}

contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return "", errorsmod.Wrapf(err, "contract port id")
}
Expand Down Expand Up @@ -150,7 +150,7 @@ func (i IBCHandler) OnChanOpenAck(
counterpartyChannelID string,
counterpartyVersion string,
) error {
contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand All @@ -176,7 +176,7 @@ func (i IBCHandler) OnChanOpenAck(

// OnChanOpenConfirm implements the IBCModule interface
func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error {
contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand All @@ -198,7 +198,7 @@ func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string)

// OnChanCloseInit implements the IBCModule interface
func (i IBCHandler) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error {
contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand Down Expand Up @@ -226,7 +226,7 @@ func (i IBCHandler) OnChanCloseInit(ctx sdk.Context, portID, channelID string) e
// OnChanCloseConfirm implements the IBCModule interface
func (i IBCHandler) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error {
// counterparty has closed the channel
contractAddr, err := i.keeper.ContractFromPortID(portID)
contractAddr, err := i.keeper.ContractFromPortID(ctx, portID)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand Down Expand Up @@ -267,7 +267,7 @@ func (i IBCHandler) OnRecvPacket(
packet channeltypes.Packet,
relayer sdk.AccAddress,
) ibcexported.Acknowledgement {
contractAddr, err := i.keeper.ContractFromPortID(packet.DestinationPort)
contractAddr, err := i.keeper.ContractFromPortID(ctx, packet.DestinationPort)
if err != nil {
// this must not happen as ports were registered before
panic(errorsmod.Wrapf(err, "contract port id"))
Expand Down Expand Up @@ -295,7 +295,7 @@ func (i IBCHandler) OnAcknowledgementPacket(
acknowledgement []byte,
relayer sdk.AccAddress,
) error {
contractAddr, err := i.keeper.ContractFromPortID(packet.SourcePort)
contractAddr, err := i.keeper.ContractFromPortID(ctx, packet.SourcePort)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand All @@ -313,7 +313,7 @@ func (i IBCHandler) OnAcknowledgementPacket(

// OnTimeoutPacket implements the IBCModule interface
func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error {
contractAddr, err := i.keeper.ContractFromPortID(packet.SourcePort)
contractAddr, err := i.keeper.ContractFromPortID(ctx, packet.SourcePort)
if err != nil {
return errorsmod.Wrapf(err, "contract port id")
}
Expand Down
7 changes: 4 additions & 3 deletions x/wasm/ibc_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wasm

import (
"context"
"testing"

wasmvmtypes "github.com/CosmWasm/wasmvm/types"
Expand Down Expand Up @@ -202,14 +203,14 @@ var _ types.IBCContractKeeper = &IBCContractKeeperMock{}
type IBCContractKeeperMock struct {
types.IBCContractKeeper
OnRecvPacketFn func(ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.IBCPacketReceiveMsg) (ibcexported.Acknowledgement, error)
ContractFromPortIDFn func(portID string) (sdk.AccAddress, error)
ContractFromPortIDFn func(ctx context.Context, portID string) (sdk.AccAddress, error)
}

func (m IBCContractKeeperMock) ContractFromPortID(portID string) (sdk.AccAddress, error) {
func (m IBCContractKeeperMock) ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error) {
if m.ContractFromPortIDFn == nil {
panic("not expected to be called")
}
return m.ContractFromPortIDFn(portID)
return m.ContractFromPortIDFn(ctx, portID)
}

func (m IBCContractKeeperMock) OnRecvPacket(ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.IBCPacketReceiveMsg) (ibcexported.Acknowledgement, error) {
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/keeper/handler_plugin_encoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ func EncodeIBCMsg(
switch {
case msg.CloseChannel != nil:
return []sdk.Msg{&channeltypes.MsgChannelCloseInit{
PortId: ibcPortAllocator.PortIDForContract(sender),
PortId: ibcPortAllocator.PortIDForContract(ctx, sender),
ChannelId: msg.CloseChannel.ChannelID,
Signer: sender.String(),
}}, nil
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/keeper/handler_plugin_encoders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/cosmos/gogoproto/proto"
ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down
33 changes: 28 additions & 5 deletions x/wasm/keeper/ibc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keeper

import (
"context"
"encoding/hex"
"strings"

capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
Expand All @@ -26,33 +28,54 @@ func (k Keeper) bindIbcPort(ctx sdk.Context, portID string) error {
// Returns success if we already registered or just registered and error if we cannot
// (lack of permissions or someone else has it)
func (k Keeper) ensureIBCPort(ctx sdk.Context, contractAddr sdk.AccAddress) (string, error) {
portID := k.ibcPortNameGenerator.PortIDForContract(contractAddr)
portID := k.ibcPortNameGenerator.PortIDForContract(ctx, contractAddr)
if _, ok := k.capabilityKeeper.GetCapability(ctx, host.PortPath(portID)); ok {
return portID, nil
}
return portID, k.bindIbcPort(ctx, portID)
}

type IBCPortNameGenerator interface {
PortIDForContract(addr sdk.AccAddress) string
ContractFromPortID(portID string) (sdk.AccAddress, error)
// PortIDForContract converts an address into an ibc port-id.
PortIDForContract(ctx context.Context, addr sdk.AccAddress) string
// ContractFromPortID returns the contract address for given port-id. The method does not check if the contract exists
ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error)
}

const portIDPrefix = "wasm."

// DefaultIBCPortNameGenerator uses Bech32 address string in port-id
type DefaultIBCPortNameGenerator struct{}

func (DefaultIBCPortNameGenerator) PortIDForContract(addr sdk.AccAddress) string {
// PortIDForContract coverts contract into port-id in the format "wasm.<bech32-address>"
func (DefaultIBCPortNameGenerator) PortIDForContract(ctx context.Context, addr sdk.AccAddress) string {
return portIDPrefix + addr.String()
}

func (DefaultIBCPortNameGenerator) ContractFromPortID(portID string) (sdk.AccAddress, error) {
// ContractFromPortID reads the contract address from bech32 address in the port-id.
func (DefaultIBCPortNameGenerator) ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error) {
if !strings.HasPrefix(portID, portIDPrefix) {
return nil, errorsmod.Wrapf(types.ErrInvalid, "without prefix")
}
return sdk.AccAddressFromBech32(portID[len(portIDPrefix):])
}

// HexIBCPortNameGenerator uses Hex address string
type HexIBCPortNameGenerator struct{}

// PortIDForContract coverts contract into port-id in the format "wasm.<hex-address>"
func (HexIBCPortNameGenerator) PortIDForContract(ctx context.Context, addr sdk.AccAddress) string {
return portIDPrefix + hex.EncodeToString(addr)

Check warning on line 68 in x/wasm/keeper/ibc.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/ibc.go#L67-L68

Added lines #L67 - L68 were not covered by tests
}

// ContractFromPortID reads the contract address from hex address in the port-id.
func (HexIBCPortNameGenerator) ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error) {
if !strings.HasPrefix(portID, portIDPrefix) {
return nil, errorsmod.Wrapf(types.ErrInvalid, "without prefix")

Check warning on line 74 in x/wasm/keeper/ibc.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/ibc.go#L72-L74

Added lines #L72 - L74 were not covered by tests
}
return sdk.AccAddressFromHexUnsafe(portID[len(portIDPrefix):])

Check warning on line 76 in x/wasm/keeper/ibc.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/ibc.go#L76

Added line #L76 was not covered by tests
}

// AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function
func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool {
return k.capabilityKeeper.AuthenticateCapability(ctx, cap, name)
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/keeper/ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestBindingPortForIBCContractOnInstantiate(t *testing.T) {
require.NoError(t, err)
require.NotEqual(t, example.Contract, addr)

portID2 := keepers.WasmKeeper.ibcPortNameGenerator.PortIDForContract(addr)
portID2 := keepers.WasmKeeper.ibcPortNameGenerator.PortIDForContract(ctx, addr)
owner, _, err = keepers.IBCKeeper.PortKeeper.LookupModuleByPort(ctx, portID2)
require.NoError(t, err)
require.Equal(t, "wasm", owner)
Expand Down Expand Up @@ -72,7 +72,7 @@ func TestContractFromPortID(t *testing.T) {
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
gotAddr, gotErr := DefaultIBCPortNameGenerator{}.ContractFromPortID(spec.srcPort)
gotAddr, gotErr := DefaultIBCPortNameGenerator{}.ContractFromPortID(nil, spec.srcPort)
if spec.expErr {
require.Error(t, gotErr)
return
Expand Down
5 changes: 3 additions & 2 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -1195,8 +1195,9 @@ func (k Keeper) importContract(ctx context.Context, contractAddr sdk.AccAddress,
return k.importContractState(ctx, contractAddr, state)
}

func (k Keeper) ContractFromPortID(portID string) (sdk.AccAddress, error) {
return k.ibcPortNameGenerator.ContractFromPortID(portID)
// ContractFromPortID returns the contract address for given port-id. The method does not check if the contract exists
func (k Keeper) ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error) {
return k.ibcPortNameGenerator.ContractFromPortID(ctx, portID)

Check warning on line 1200 in x/wasm/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/wasm/keeper/keeper.go#L1199-L1200

Added lines #L1199 - L1200 were not covered by tests
}

func (k Keeper) newQueryHandler(ctx sdk.Context, contractAddress sdk.AccAddress) QueryHandler {
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/relay_pingpong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ func TestPinPong(t *testing.T) {
pongContract.contractAddr = pongContractAddr

var (
sourcePortID = wasmkeeper.DefaultIBCPortNameGenerator{}.PortIDForContract(pingContractAddr)
counterpartyPortID = wasmkeeper.DefaultIBCPortNameGenerator{}.PortIDForContract(pongContractAddr)
sourcePortID = wasmkeeper.DefaultIBCPortNameGenerator{}.PortIDForContract(nil, pingContractAddr)
counterpartyPortID = wasmkeeper.DefaultIBCPortNameGenerator{}.PortIDForContract(nil, pongContractAddr)
)

path := wasmibctesting.NewPath(chainA, chainB)
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/types/exported_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,5 @@ type IBCContractKeeper interface {
AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool

// ContractFromPortID resolves contract address from the ibc port-di
ContractFromPortID(portID string) (sdk.AccAddress, error)
ContractFromPortID(ctx context.Context, portID string) (sdk.AccAddress, error)
}

0 comments on commit 88ae8da

Please sign in to comment.