Skip to content

chore: Use prefix-based routing for IBCv2 contracts #2258

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

Draft
wants to merge 2 commits into
base: tkulik/feat/register_ibc2_contracts
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,6 @@ func NewWasmApp(
panic(fmt.Sprintf("error while reading wasm config: %s", err))
}

ibcRouterV2 := ibcapi.NewRouter()

// The last arguments can contain custom message handlers, and custom query handlers,
// if we want to allow any custom callbacks
app.WasmKeeper = wasmkeeper.NewKeeper(
Expand All @@ -604,7 +602,6 @@ func NewWasmApp(
wasmtypes.VMConfig{},
wasmkeeper.BuiltInCapabilities(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
ibcRouterV2,
wasmOpts...,
)

Expand Down Expand Up @@ -646,8 +643,11 @@ func NewWasmApp(
AddRoute(icahosttypes.SubModuleName, icaHostStack)
app.IBCKeeper.SetRouter(ibcRouter)

ibcRouterV2 := ibcapi.NewRouter()
ibcRouterV2 = ibcRouterV2.
AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper))
AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)).
AddRoute(wasmkeeper.PortIDPrefixV2, wasmkeeper.NewIBC2Handler(app.WasmKeeper))

app.IBCKeeper.SetRouterV2(ibcRouterV2)

clientKeeper := app.IBCKeeper.ClientKeeper
Expand Down Expand Up @@ -875,10 +875,6 @@ func NewWasmApp(
if err := app.WasmKeeper.InitializePinnedCodes(ctx); err != nil {
panic(fmt.Sprintf("failed initialize pinned codes %s", err))
}

// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278
// and add IBCv2 port ID prefix before calling `SetRouterV2` during WasmKeeper creation.
app.WasmKeeper.RegisterContractsInIbc2Router(ctx)
}

return app
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/ica_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ func TestICA(t *testing.T) {
path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
PortID: portID,
Version: version,
Order: channeltypes.ORDERED,
Order: channeltypes.UNORDERED,
}
path.EndpointB.ChannelID = ""
path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
PortID: icatypes.HostPortID,
Version: icatypes.Version,
Order: channeltypes.ORDERED,
Order: channeltypes.UNORDERED,
}
coord.CreateChannels(&path.Path)
path.CreateChannels()

// assert ICA exists on controller
contApp := controllerChain.GetWasmApp()
Expand Down
10 changes: 5 additions & 5 deletions tests/integration/ibc_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,17 @@ func TestIBCReflectContract(t *testing.T) {
path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{
PortID: sourcePortID,
Version: "ibc-reflect-v1",
Order: channeltypes.ORDERED,
Order: channeltypes.UNORDERED,
}
path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{
PortID: counterpartPortID,
Version: "ibc-reflect-v1",
Order: channeltypes.ORDERED,
Order: channeltypes.UNORDERED,
}

coordinator.SetupConnections(&path.Path)

coordinator.CreateChannels(&path.Path)
path.CreateChannels()

// TODO: query both contracts directly to ensure they have registered the proper connection
// (and the chainB has created a reflect contract)
Expand Down Expand Up @@ -329,7 +329,7 @@ func TestOnIBCPacketReceive(t *testing.T) {
}

coord.SetupConnections(&path.Path)
coord.CreateChannels(&path.Path)
path.CreateChannels()
coord.CommitBlock(chainA.TestChain, chainB.TestChain)
require.Equal(t, 0, len(*chainA.PendingSendPackets))
require.Equal(t, 0, len(*chainB.PendingSendPackets))
Expand Down Expand Up @@ -404,7 +404,7 @@ func TestIBCAsyncAck(t *testing.T) {
}

coord.SetupConnections(&path.Path)
coord.CreateChannels(&path.Path)
path.CreateChannels()
coord.CommitBlock(chainA.TestChain, chainB.TestChain)
require.Equal(t, 0, len(*chainA.PendingSendPackets))
require.Equal(t, 0, len(*chainB.PendingSendPackets))
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/relay_pingpong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestPingPong(t *testing.T) {
Order: channeltypes.ORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

// trigger start game via execute
const startValue uint64 = 100
Expand Down
14 changes: 7 additions & 7 deletions tests/integration/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestFromIBCTransferToContract(t *testing.T) {
}

coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

originalChainABalance := chainA.Balance(chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
// when transfer via sdk transfer from A (module) -> B (contract)
Expand Down Expand Up @@ -196,7 +196,7 @@ func TestContractCanInitiateIBCTransferMsg(t *testing.T) {
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

// when contract is triggered to send IBCTransferMsg
receiverAddress := chainB.SenderAccount.GetAddress()
Expand Down Expand Up @@ -268,7 +268,7 @@ func TestContractCanEmulateIBCTransferMessage(t *testing.T) {
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

// when contract is triggered to send the ibc package to chain B
timeout := uint64(chainB.LatestCommittedHeader.Header.Time.Add(time.Hour).UnixNano()) // enough time to not timeout
Expand Down Expand Up @@ -343,7 +343,7 @@ func TestContractCanEmulateIBCTransferMessageWithTimeout(t *testing.T) {
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()
coordinator.UpdateTime()

// when contract is triggered to send the ibc package to chain B
Expand Down Expand Up @@ -430,7 +430,7 @@ func TestContractEmulateIBCTransferMessageOnDiffContractIBCChannel(t *testing.T)
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

// when contract is triggered to send the ibc package to chain B
timeout := uint64(chainB.LatestCommittedHeader.Header.Time.Add(time.Hour).UnixNano()) // enough time to not timeout
Expand Down Expand Up @@ -491,7 +491,7 @@ func TestContractHandlesChannelClose(t *testing.T) {
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()
wasmibctesting.CloseChannel(coordinator, &path.Path)
assert.True(t, myContractB.closeCalled)
}
Expand Down Expand Up @@ -541,7 +541,7 @@ func TestContractHandlesChannelCloseNotOwned(t *testing.T) {
Order: channeltypes.UNORDERED,
}
coordinator.SetupConnections(&path.Path)
coordinator.CreateChannels(&path.Path)
path.CreateChannels()

closeIBCChannelMsg := &types.MsgExecuteContract{
Sender: chainA.SenderAccount.GetAddress().String(),
Expand Down
2 changes: 0 additions & 2 deletions x/wasm/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
abci "github.com/cometbft/cometbft/abci/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
dbm "github.com/cosmos/cosmos-db"
ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -699,7 +698,6 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context) {
types.VMConfig{},
AvailableCapabilities,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
ibcapi.NewRouter(),
)
return &srcKeeper, ctx
}
Expand Down
8 changes: 4 additions & 4 deletions x/wasm/keeper/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ func ContractFromPortID(portID string) (sdk.AccAddress, error) {
}

// The port prefix refers to "CosmWasm over IBC v2" and ensures packets are routed to the right entry points
const portIDPrefixV2 = "wasm2"
const PortIDPrefixV2 = "wasm2"

func PortIDForContractV2(addr sdk.AccAddress) string {
blockchainPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
return portIDPrefixV2 + strings.TrimPrefix(addr.String(), blockchainPrefix)
return PortIDPrefixV2 + strings.TrimPrefix(addr.String(), blockchainPrefix)
}

func ContractFromPortID2(portID string) (sdk.AccAddress, error) {
if !strings.HasPrefix(portID, portIDPrefixV2) {
if !strings.HasPrefix(portID, PortIDPrefixV2) {
return nil, errorsmod.Wrapf(types.ErrInvalid, "without prefix")
}
blockchainPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
return sdk.AccAddressFromBech32(blockchainPrefix + portID[len(portIDPrefixV2):])
return sdk.AccAddressFromBech32(blockchainPrefix + portID[len(PortIDPrefixV2):])
}
41 changes: 3 additions & 38 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
wasmvm "github.com/CosmWasm/wasmvm/v3"
wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types"
ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api"

"cosmossdk.io/collections"
corestoretypes "cosmossdk.io/core/store"
Expand Down Expand Up @@ -111,12 +110,6 @@ type Keeper struct {

// wasmLimits contains the limits sent to wasmvm on init
wasmLimits wasmvmtypes.WasmLimits

ibcRouterV2 *ibcapi.Router
}

func (k Keeper) GetIBCRouterV2() *ibcapi.Router {
return k.ibcRouterV2
}

func (k Keeper) getUploadAccessConfig(ctx context.Context) types.AccessConfig {
Expand Down Expand Up @@ -379,13 +372,7 @@ func (k Keeper) instantiate(
contractInfo.IBCPortID = ibcPort
}

ibc2Port := PortIDForContractV2(contractAddress)
contractInfo.IBC2PortID = ibc2Port

// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278
if !k.ibcRouterV2.HasRoute(ibc2Port) {
k.ibcRouterV2.AddRoute(ibc2Port, NewIBC2Handler(k))
}
contractInfo.IBC2PortID = PortIDForContractV2(contractAddress)

// store contract before dispatch so that contract could be called back
historyEntry := contractInfo.InitialHistory(initMsg)
Expand Down Expand Up @@ -554,6 +541,8 @@ func (k Keeper) migrate(
}
k.mustStoreContractInfo(ctx, contractAddress, contractInfo)

contractInfo.IBC2PortID = PortIDForContractV2(contractAddress)

sdkCtx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeMigrate,
sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(newCodeID, 10)),
Expand Down Expand Up @@ -1092,12 +1081,6 @@ func (k Keeper) importContractState(ctx context.Context, contractAddress sdk.Acc
prefixStore.Set(model.Key, model.Value)
}

// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278
contractPortIBC2ID := PortIDForContractV2(contractAddress)
if !k.ibcRouterV2.HasRoute(contractPortIBC2ID) {
k.ibcRouterV2.AddRoute(contractPortIBC2ID, NewIBC2Handler(k))
}

return nil
}

Expand Down Expand Up @@ -1139,24 +1122,6 @@ func (k Keeper) IterateCodeInfos(ctx context.Context, cb func(uint64, types.Code
}
}

// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278 (remove this method)
func (k Keeper) IterateContractAddresses(ctx context.Context, cb func(sdk.AccAddress)) {
prefixStore := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.ContractKeyPrefix)
iter := prefixStore.Iterator(nil, nil)
defer iter.Close()

for ; iter.Valid(); iter.Next() {
cb(iter.Key())
}
}

// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278 (remove this method)
func (k Keeper) RegisterContractsInIbc2Router(ctx context.Context) {
k.IterateContractAddresses(ctx, func(contractAddr sdk.AccAddress) {
k.ibcRouterV2.AddRoute(PortIDForContractV2(contractAddr), NewIBC2Handler(k))
})
}

func (k Keeper) GetByteCode(ctx context.Context, codeID uint64) ([]byte, error) {
store := k.storeService.OpenKVStore(ctx)
var codeInfo types.CodeInfo
Expand Down
7 changes: 2 additions & 5 deletions x/wasm/keeper/keeper_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

wasmvm "github.com/CosmWasm/wasmvm/v3"
wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api"

"cosmossdk.io/collections"
corestoretypes "cosmossdk.io/core/store"
Expand Down Expand Up @@ -37,7 +36,6 @@ func NewKeeper(
vmConfig types.VMConfig,
availableCapabilities []string,
authority string,
ibcRouterV2 *ibcapi.Router,
opts ...Option,
) Keeper {
sb := collections.NewSchemaBuilder(storeService)
Expand All @@ -57,9 +55,8 @@ func NewKeeper(
propagateGovAuthorization: map[types.AuthorizationPolicyAction]struct{}{
types.AuthZActionInstantiate: {},
},
authority: authority,
wasmLimits: vmConfig.WasmLimits,
ibcRouterV2: ibcRouterV2,
authority: authority,
wasmLimits: vmConfig.WasmLimits,
}
keeper.messenger = NewDefaultMessageHandler(keeper, router, ics4Wrapper, channelKeeperV2, bankKeeper, cdc, portSource)
keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distrKeeper, channelKeeper, keeper)
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/keeper/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestConstructorOptions(t *testing.T) {
opt := spec.srcOpt
_, gotPostOptMarker := opt.(postOptsFn)
require.Equal(t, spec.isPostOpt, gotPostOptMarker)
k := NewKeeper(codec, runtime.NewKVStoreService(storeKey), authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, nil, tempDir, types.DefaultNodeConfig(), types.VMConfig{}, AvailableCapabilities, "", nil, spec.srcOpt)
k := NewKeeper(codec, runtime.NewKVStoreService(storeKey), authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, nil, tempDir, types.DefaultNodeConfig(), types.VMConfig{}, AvailableCapabilities, "", spec.srcOpt)
spec.verify(t, k)
})
}
Expand Down
2 changes: 0 additions & 2 deletions x/wasm/keeper/snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ func restoreV1(_ sdk.Context, k *Keeper, compressedCode []byte) error {
}

func finalizeV1(ctx sdk.Context, k *Keeper) error {
// TODO: Remove the registration of each contract in https://github.com/CosmWasm/wasmd/issues/2278
k.RegisterContractsInIbc2Router(ctx)
// FIXME: ensure all codes have been uploaded?
return k.InitializePinnedCodes(ctx)
}
Expand Down
2 changes: 0 additions & 2 deletions x/wasm/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/cosmos/ibc-go/v10/modules/apps/transfer"
ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v10/modules/core"
ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api"
ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported"
ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -389,7 +388,6 @@ func createTestInput(
vmConfig,
availableCapabilities,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
ibcapi.NewRouter(),
opts...,
)
require.NoError(t, keeper.SetParams(ctx, types.DefaultParams()))
Expand Down