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

Onion module #73

Open
wants to merge 16 commits into
base: next
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Remove unused wasm hooks and channel keeper
antstalepresh committed Jun 26, 2024
commit 3bd55077367fa2d7813588f1ee98f8adbfe4738e
27 changes: 1 addition & 26 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -300,8 +300,6 @@ type App struct {
ParamsKeeper paramskeeper.Keeper
IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
OnionKeeper *onionkeeper.Keeper
Ics20WasmHooks *onion.WasmHooks
HooksICS4Wrapper onion.ICS4Middleware
IBCFeeKeeper ibcfeekeeper.Keeper
ICAControllerKeeper icacontrollerkeeper.Keeper
ICAHostKeeper icahostkeeper.Keeper
@@ -558,15 +556,12 @@ func New(
app.OnionKeeper = onionkeeper.NewKeeper(
keys[oniontypes.StoreKey],
app.GetSubspace(oniontypes.ModuleName),
app.IBCKeeper.ChannelKeeper,
nil,
app.MsgServiceRouter(),
app.AccountKeeper,
txConfig.SignModeHandler(),
)

app.WireICS20PreWasmKeeper(appCodec, bApp, app.OnionKeeper)

// IBC Fee Module keeper

app.IBCFeeKeeper = ibcfeekeeper.NewKeeper(
@@ -725,10 +720,6 @@ func New(
wasmOpts...,
)

// Pass the contract keeper to all the structs (generally ICS4Wrappers for ibc middlewares) that need it
app.Ics20WasmHooks.ContractKeeper = &app.WasmKeeper
app.OnionKeeper.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper)

// Register the proposal types
// Deprecated: Avoid adding new handlers, instead use the new proposal flow
// by granting the governance module the right to execute the message.
@@ -783,7 +774,7 @@ func New(
var transferStack ibcporttypes.IBCModule
transferStack = transfer.NewIBCModule(app.TransferKeeper)
transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper)
transferStack = onion.NewIBCMiddleware(transferStack, &app.HooksICS4Wrapper, app.OnionKeeper, encodingConfig.TxConfig)
transferStack = onion.NewIBCModule(transferStack, app.OnionKeeper, encodingConfig.TxConfig)

// Create Interchain Accounts Stack
// SendPacket, since it is originating from the application to core IBC:
@@ -1207,22 +1198,6 @@ func New(
return app
}

// WireICS20PreWasmKeeper Create the IBC Transfer Stack from bottom to top:
func (app *App) WireICS20PreWasmKeeper(
appCodec codec.Codec,
bApp *baseapp.BaseApp,
hooksKeeper *onionkeeper.Keeper,
) {
// Setup the ICS4Wrapper used by the hooks middleware
addrPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
wasmHooks := onion.NewWasmHooks(hooksKeeper, nil, addrPrefix) // The contract keeper needs to be set later
app.Ics20WasmHooks = &wasmHooks
app.HooksICS4Wrapper = onion.NewICS4Middleware(
app.IBCKeeper.ChannelKeeper,
app.Ics20WasmHooks,
)
}

func (app *App) setPostHandler() {
postHandler, err := posthandler.NewPostHandler(
posthandler.HandlerOptions{},
2 changes: 0 additions & 2 deletions proto/kujira/onion/params.proto
Original file line number Diff line number Diff line change
@@ -8,6 +8,4 @@ import "google/protobuf/duration.proto";
option go_package = "github.com/Team-Kujira/core/x/onion/types";

message Params {
repeated string allowed_async_ack_contracts = 1
[ (gogoproto.moretags) = "yaml:\"allowed_async_ack_contracts\"" ];
}
15 changes: 0 additions & 15 deletions proto/kujira/onion/tx.proto
Original file line number Diff line number Diff line change
@@ -7,19 +7,4 @@ option go_package = "github.com/Team-Kujira/core/x/onion/types";

// Msg defines the Msg service.
service Msg {
// EmitIBCAck checks the sender can emit the ack and writes the IBC
// acknowledgement
rpc EmitIBCAck(MsgEmitIBCAck) returns (MsgEmitIBCAckResponse);
}

message MsgEmitIBCAck {
string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ];
uint64 packet_sequence = 2
[ (gogoproto.moretags) = "yaml:\"packet_sequence\"" ];
string channel = 3 [ (gogoproto.moretags) = "yaml:\"channel\"" ];
}
message MsgEmitIBCAckResponse {
string contract_result = 1
[ (gogoproto.moretags) = "yaml:\"contract_result\"" ];
string ibc_ack = 2 [ (gogoproto.moretags) = "yaml:\"ibc_ack\"" ];
}
39 changes: 0 additions & 39 deletions x/onion/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -3,16 +3,11 @@ package cli
import (
"context"
"fmt"
"strings"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/spf13/cobra"

"github.com/Team-Kujira/core/x/onion/keeper"

"github.com/Team-Kujira/core/x/onion/types"
)

@@ -40,45 +35,11 @@ func GetQueryCmd() *cobra.Command {
}

cmd.AddCommand(
GetCmdWasmSender(),
GetCmdQuerySequence(),
)
return cmd
}

// GetCmdPoolParams return pool params.
func GetCmdWasmSender() *cobra.Command {
cmd := &cobra.Command{
Use: "wasm-sender <channelID> <originalSender>",
Short: "Generate the local address for a wasm hooks sender",
Long: strings.TrimSpace(
fmt.Sprintf(`Generate the local address for a wasm hooks sender.
Example:
$ %s query ibc-hooks wasm-hooks-sender channel-42 juno12smx2wdlyttvyzvzg54y2vnqwq2qjatezqwqxu
`,
version.AppName,
),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
channelID := args[0]
originalSender := args[1]
// ToDo: Make this flexible as an arg
prefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
senderBech32, err := keeper.DeriveIntermediateSender(channelID, originalSender, prefix)
if err != nil {
return err
}
fmt.Println(senderBech32)
return nil
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetCmdQuerySequence implements the query sequence command.
func GetCmdQuerySequence() *cobra.Command {
cmd := &cobra.Command{
145 changes: 0 additions & 145 deletions x/onion/hooks.go

This file was deleted.

208 changes: 32 additions & 176 deletions x/onion/ibc_module.go
Original file line number Diff line number Diff line change
@@ -11,37 +11,33 @@ import (
// ibc-go
"github.com/Team-Kujira/core/x/onion/keeper"
"github.com/cosmos/cosmos-sdk/client"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types"
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
)

var _ porttypes.Middleware = &IBCMiddleware{}
var _ porttypes.IBCModule = IBCModule{}

type IBCMiddleware struct {
type IBCModule struct {
App porttypes.IBCModule
ICS4Middleware *ICS4Middleware
Keeper *keeper.Keeper
txEncodingConfig client.TxEncodingConfig
}

func NewIBCMiddleware(
func NewIBCModule(
app porttypes.IBCModule,
ics4 *ICS4Middleware,
Keeper *keeper.Keeper,
txEncodingConfig client.TxEncodingConfig,
) IBCMiddleware {
return IBCMiddleware{
) IBCModule {
return IBCModule{
App: app,
ICS4Middleware: ics4,
Keeper: Keeper,
txEncodingConfig: txEncodingConfig,
}
}

// OnChanOpenInit implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanOpenInit(
// OnChanOpenInit implements the IBCModule interface
func (im IBCModule) OnChanOpenInit(
ctx sdk.Context,
order channeltypes.Order,
connectionHops []string,
@@ -51,24 +47,11 @@ func (im IBCMiddleware) OnChanOpenInit(
counterparty channeltypes.Counterparty,
version string,
) (string, error) {
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitOverrideHooks); ok {
return hook.OnChanOpenInitOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitBeforeHooks); ok {
hook.OnChanOpenInitBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version)
}

finalVersion, err := im.App.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version)

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenInitAfterHooks); ok {
hook.OnChanOpenInitAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version, finalVersion, err)
}
return version, err
return im.App.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version)
}

// OnChanOpenTry implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanOpenTry(
// OnChanOpenTry implements the IBCModule interface
func (im IBCModule) OnChanOpenTry(
ctx sdk.Context,
order channeltypes.Order,
connectionHops []string,
@@ -78,111 +61,49 @@ func (im IBCMiddleware) OnChanOpenTry(
counterparty channeltypes.Counterparty,
counterpartyVersion string,
) (string, error) {
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryOverrideHooks); ok {
return hook.OnChanOpenTryOverride(im, ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryBeforeHooks); ok {
hook.OnChanOpenTryBeforeHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion)
}

version, err := im.App.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion)

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenTryAfterHooks); ok {
hook.OnChanOpenTryAfterHook(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion, version, err)
}
return version, err
return im.App.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion)
}

// OnChanOpenAck implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanOpenAck(
// OnChanOpenAck implements the IBCModule interface
func (im IBCModule) OnChanOpenAck(
ctx sdk.Context,
portID,
channelID string,
counterpartyChannelID string,
counterpartyVersion string,
) error {
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckOverrideHooks); ok {
return hook.OnChanOpenAckOverride(im, ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckBeforeHooks); ok {
hook.OnChanOpenAckBeforeHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
}
err := im.App.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenAckAfterHooks); ok {
hook.OnChanOpenAckAfterHook(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion, err)
}

return err
return im.App.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
}

// OnChanOpenConfirm implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanOpenConfirm(
// OnChanOpenConfirm implements the IBCModule interface
func (im IBCModule) OnChanOpenConfirm(
ctx sdk.Context,
portID,
channelID string,
) error {
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmOverrideHooks); ok {
return hook.OnChanOpenConfirmOverride(im, ctx, portID, channelID)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmBeforeHooks); ok {
hook.OnChanOpenConfirmBeforeHook(ctx, portID, channelID)
}
err := im.App.OnChanOpenConfirm(ctx, portID, channelID)
if hook, ok := im.ICS4Middleware.Hooks.(OnChanOpenConfirmAfterHooks); ok {
hook.OnChanOpenConfirmAfterHook(ctx, portID, channelID, err)
}
return err
return im.App.OnChanOpenConfirm(ctx, portID, channelID)
}

// OnChanCloseInit implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanCloseInit(
// OnChanCloseInit implements the IBCModule interface
func (im IBCModule) OnChanCloseInit(
ctx sdk.Context,
portID,
channelID string,
) error {
// Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract
if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitOverrideHooks); ok {
return hook.OnChanCloseInitOverride(im, ctx, portID, channelID)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitBeforeHooks); ok {
hook.OnChanCloseInitBeforeHook(ctx, portID, channelID)
}
err := im.App.OnChanCloseInit(ctx, portID, channelID)
if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseInitAfterHooks); ok {
hook.OnChanCloseInitAfterHook(ctx, portID, channelID, err)
}

return err
return im.App.OnChanCloseInit(ctx, portID, channelID)
}

// OnChanCloseConfirm implements the IBCMiddleware interface
func (im IBCMiddleware) OnChanCloseConfirm(
// OnChanCloseConfirm implements the IBCModule interface
func (im IBCModule) OnChanCloseConfirm(
ctx sdk.Context,
portID,
channelID string,
) error {
// Here we can remove the limits when a new channel is closed. For now, they can remove them manually on the contract
if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmOverrideHooks); ok {
return hook.OnChanCloseConfirmOverride(im, ctx, portID, channelID)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmBeforeHooks); ok {
hook.OnChanCloseConfirmBeforeHook(ctx, portID, channelID)
}
err := im.App.OnChanCloseConfirm(ctx, portID, channelID)
if hook, ok := im.ICS4Middleware.Hooks.(OnChanCloseConfirmAfterHooks); ok {
hook.OnChanCloseConfirmAfterHook(ctx, portID, channelID, err)
}

return err
return im.App.OnChanCloseConfirm(ctx, portID, channelID)
}

// OnRecvPacket implements the IBCMiddleware interface
func (im IBCMiddleware) OnRecvPacket(
// OnRecvPacket implements the IBCModule interface
func (im IBCModule) OnRecvPacket(
ctx sdk.Context,
packet channeltypes.Packet,
relayer sdk.AccAddress,
@@ -207,89 +128,24 @@ func (im IBCMiddleware) OnRecvPacket(
}
}

if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketOverrideHooks); ok {
return hook.OnRecvPacketOverride(im, ctx, packet, relayer)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketBeforeHooks); ok {
hook.OnRecvPacketBeforeHook(ctx, packet, relayer)
}

ack := im.App.OnRecvPacket(ctx, packet, relayer)

if hook, ok := im.ICS4Middleware.Hooks.(OnRecvPacketAfterHooks); ok {
hook.OnRecvPacketAfterHook(ctx, packet, relayer, ack)
}

return ack
return im.App.OnRecvPacket(ctx, packet, relayer)
}

// OnAcknowledgementPacket implements the IBCMiddleware interface
func (im IBCMiddleware) OnAcknowledgementPacket(
// OnAcknowledgementPacket implements the IBCModule interface
func (im IBCModule) OnAcknowledgementPacket(
ctx sdk.Context,
packet channeltypes.Packet,
acknowledgement []byte,
relayer sdk.AccAddress,
) error {
if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketOverrideHooks); ok {
return hook.OnAcknowledgementPacketOverride(im, ctx, packet, acknowledgement, relayer)
}
if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketBeforeHooks); ok {
hook.OnAcknowledgementPacketBeforeHook(ctx, packet, acknowledgement, relayer)
}

err := im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer)

if hook, ok := im.ICS4Middleware.Hooks.(OnAcknowledgementPacketAfterHooks); ok {
hook.OnAcknowledgementPacketAfterHook(ctx, packet, acknowledgement, relayer, err)
}

return err
return im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer)
}

// OnTimeoutPacket implements the IBCMiddleware interface
func (im IBCMiddleware) OnTimeoutPacket(
// OnTimeoutPacket implements the IBCModule interface
func (im IBCModule) OnTimeoutPacket(
ctx sdk.Context,
packet channeltypes.Packet,
relayer sdk.AccAddress,
) error {
if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketOverrideHooks); ok {
return hook.OnTimeoutPacketOverride(im, ctx, packet, relayer)
}

if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketBeforeHooks); ok {
hook.OnTimeoutPacketBeforeHook(ctx, packet, relayer)
}
err := im.App.OnTimeoutPacket(ctx, packet, relayer)
if hook, ok := im.ICS4Middleware.Hooks.(OnTimeoutPacketAfterHooks); ok {
hook.OnTimeoutPacketAfterHook(ctx, packet, relayer, err)
}

return err
}

// SendPacket implements the ICS4 Wrapper interface
func (im IBCMiddleware) SendPacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
sourcePort string, sourceChannel string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
data []byte,
) (sequence uint64, err error) {
return im.ICS4Middleware.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data)
}

// WriteAcknowledgement implements the ICS4 Wrapper interface
func (im IBCMiddleware) WriteAcknowledgement(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet ibcexported.PacketI,
ack ibcexported.Acknowledgement,
) error {
return im.ICS4Middleware.WriteAcknowledgement(ctx, chanCap, packet, ack)
}

func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
return im.ICS4Middleware.GetAppVersion(ctx, portID, channelID)
return im.App.OnTimeoutPacket(ctx, packet, relayer)
}
78 changes: 0 additions & 78 deletions x/onion/ibcutils.go

This file was deleted.

85 changes: 0 additions & 85 deletions x/onion/ics4_middleware.go

This file was deleted.

33 changes: 0 additions & 33 deletions x/onion/keeper/ibcutils.go

This file was deleted.

217 changes: 1 addition & 216 deletions x/onion/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
package keeper

import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/Team-Kujira/core/x/onion/types"
"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/cometbft/cometbft/libs/log"
"github.com/cosmos/cosmos-sdk/baseapp"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
)

type (
Keeper struct {
storeKey storetypes.StoreKey
paramSpace paramtypes.Subspace

channelKeeper types.ChannelKeeper
ContractKeeper *wasmkeeper.PermissionedKeeper
accountKeeper types.AccountKeeper
accountKeeper types.AccountKeeper

router *baseapp.MsgServiceRouter
signModeHandler authsigning.SignModeHandler
@@ -38,7 +29,6 @@ type (
func NewKeeper(
storeKey storetypes.StoreKey,
paramSpace paramtypes.Subspace,
channelKeeper types.ChannelKeeper,
contractKeeper *wasmkeeper.PermissionedKeeper,
router *baseapp.MsgServiceRouter,
accountKeeper types.AccountKeeper,
@@ -50,8 +40,6 @@ func NewKeeper(
return &Keeper{
storeKey: storeKey,
paramSpace: paramSpace,
channelKeeper: channelKeeper,
ContractKeeper: contractKeeper,
router: router,
accountKeeper: accountKeeper,
signModeHandler: signModeHandler,
@@ -74,11 +62,6 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSpace.SetParamSet(ctx, &params)
}

// SetParam sets a specific ibc-hooks module's parameter with the provided parameter.
func (k Keeper) SetParam(ctx sdk.Context, key []byte, value interface{}) {
k.paramSpace.Set(ctx, key, value)
}

func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
k.SetParams(ctx, genState.Params)
for _, seq := range genState.Sequences {
@@ -92,201 +75,3 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
Sequences: k.GetAllSequences(ctx),
}
}

func GetPacketCallbackKey(channel string, packetSequence uint64) []byte {
return []byte(fmt.Sprintf("%s::%d", channel, packetSequence))
}

func GetPacketAckKey(channel string, packetSequence uint64) []byte {
return []byte(fmt.Sprintf("%s::%d::ack", channel, packetSequence))
}

func GeneratePacketAckValue(packet channeltypes.Packet, contract string) ([]byte, error) {
if _, err := sdk.AccAddressFromBech32(contract); err != nil {
return nil, sdkerrors.Wrap(types.ErrInvalidContractAddr, contract)
}

packetHash, err := hashPacket(packet)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not hash packet")
}

return []byte(fmt.Sprintf("%s::%s", contract, packetHash)), nil
}

// StorePacketCallback stores which contract will be listening for the ack or timeout of a packet
func (k Keeper) StorePacketCallback(ctx sdk.Context, channel string, packetSequence uint64, contract string) {
store := ctx.KVStore(k.storeKey)
store.Set(GetPacketCallbackKey(channel, packetSequence), []byte(contract))
}

// GetPacketCallback returns the bech32 addr of the contract that is expecting a callback from a packet
func (k Keeper) GetPacketCallback(ctx sdk.Context, channel string, packetSequence uint64) string {
store := ctx.KVStore(k.storeKey)
return string(store.Get(GetPacketCallbackKey(channel, packetSequence)))
}

// IsInAllowList checks the params to see if the contract is in the KeyAsyncAckAllowList param
func (k Keeper) IsInAllowList(ctx sdk.Context, contract string) bool {
var allowList []string
k.paramSpace.GetIfExists(ctx, types.KeyAsyncAckAllowList, &allowList)
for _, addr := range allowList {
if addr == contract {
return true
}
}
return false
}

// DeletePacketCallback deletes the callback from storage once it has been processed
func (k Keeper) DeletePacketCallback(ctx sdk.Context, channel string, packetSequence uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(GetPacketCallbackKey(channel, packetSequence))
}

// StorePacketAckActor stores which contract is allowed to send an ack for the packet
func (k Keeper) StorePacketAckActor(ctx sdk.Context, packet channeltypes.Packet, contract string) {
store := ctx.KVStore(k.storeKey)
channel := packet.GetSourceChannel()
packetSequence := packet.GetSequence()

val, err := GeneratePacketAckValue(packet, contract)
if err != nil {
panic(err)
}
store.Set(GetPacketAckKey(channel, packetSequence), val)
}

// GetPacketAckActor returns the bech32 addr of the contract that is allowed to send an ack for the packet and the packet hash
func (k Keeper) GetPacketAckActor(ctx sdk.Context, channel string, packetSequence uint64) (string, string) {
store := ctx.KVStore(k.storeKey)
rawData := store.Get(GetPacketAckKey(channel, packetSequence))
if rawData == nil {
return "", ""
}
data := strings.Split(string(rawData), "::")
if len(data) != 2 {
return "", ""
}
// validate that the contract is a valid bech32 addr
if _, err := sdk.AccAddressFromBech32(data[0]); err != nil {
return "", ""
}
// validate that the hash is a valid sha256sum hash
if _, err := hex.DecodeString(data[1]); err != nil {
return "", ""
}

return data[0], data[1]
}

// DeletePacketAckActor deletes the ack actor from storage once it has been used
func (k Keeper) DeletePacketAckActor(ctx sdk.Context, channel string, packetSequence uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(GetPacketAckKey(channel, packetSequence))
}

// DeriveIntermediateSender derives the sender address to be used when calling wasm hooks
func DeriveIntermediateSender(channel, originalSender, bech32Prefix string) (string, error) {
senderStr := fmt.Sprintf("%s/%s", channel, originalSender)
senderHash32 := address.Hash(types.SenderPrefix, []byte(senderStr))
sender := sdk.AccAddress(senderHash32[:])
return sdk.Bech32ifyAddressBytes(bech32Prefix, sender)
}

// EmitIBCAck emits an event that the IBC packet has been acknowledged
func (k Keeper) EmitIBCAck(ctx sdk.Context, sender, channel string, packetSequence uint64) ([]byte, error) {
contract, packetHash := k.GetPacketAckActor(ctx, channel, packetSequence)
if contract == "" {
return nil, fmt.Errorf("no ack actor set for channel %s packet %d", channel, packetSequence)
}
// Only the contract itself can request for the ack to be emitted. This will generally happen as a callback
// when the result of other IBC actions has finished, but it could be exposed directly by the contract if the
// proper checks are made
if sender != contract {
return nil, fmt.Errorf("sender %s is not allowed to send an ack for channel %s packet %d", sender, channel, packetSequence)
}

// Write the acknowledgement
_, cap, err := k.channelKeeper.LookupModuleByChannel(ctx, "transfer", channel)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
}

// Calling the contract. This could be made generic by using an interface if we want
// to support other types of AckActors, but keeping it here for now for simplicity.
contractAddr, err := sdk.AccAddressFromBech32(contract)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not parse contract address")
}

msg := types.IBCAsync{
RequestAck: types.RequestAck{RequestAckI: types.RequestAckI{
PacketSequence: packetSequence,
SourceChannel: channel,
}},
}
msgBytes, err := json.Marshal(msg)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not marshal message")
}
bz, err := k.ContractKeeper.Sudo(ctx, contractAddr, msgBytes)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not execute contract")
}

ack, err := types.UnmarshalIBCAck(bz)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not unmarshal into IBCAckResponse or IBCAckError")

}
var newAck channeltypes.Acknowledgement
var packet channeltypes.Packet

switch ack.Type {
case "ack_response":
jsonAck, err := json.Marshal(ack.AckResponse.ContractAck)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not marshal acknowledgement")
}
packet = ack.AckResponse.Packet
newAck = channeltypes.NewResultAcknowledgement(jsonAck)
case "ack_error":
packet = ack.AckError.Packet
newAck = NewSuccessAckRepresentingAnError(ctx, types.ErrAckFromContract, []byte(ack.AckError.ErrorResponse), ack.AckError.ErrorDescription)
default:
return nil, sdkerrors.Wrap(err, "could not unmarshal into IBCAckResponse or IBCAckError")
}

// Validate that the packet returned by the contract matches the one we stored when sending
receivedPacketHash, err := hashPacket(packet)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not hash packet")
}
if receivedPacketHash != packetHash {
return nil, sdkerrors.Wrap(types.ErrAckPacketMismatch, fmt.Sprintf("packet hash mismatch. Expected %s, got %s", packetHash, receivedPacketHash))
}

// Now we can write the acknowledgement
err = k.channelKeeper.WriteAcknowledgement(ctx, cap, packet, newAck)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not write acknowledgement")
}

response, err := json.Marshal(newAck)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not marshal acknowledgement")
}
return response, nil
}

func hashPacket(packet channeltypes.Packet) (string, error) {
// ignore the data here. We only care about the channel information
packet.Data = nil
bz, err := json.Marshal(packet)
if err != nil {
return "", sdkerrors.Wrap(err, "could not marshal packet")
}
packetHash := tmhash.Sum(bz)
return hex.EncodeToString(packetHash), nil
}
24 changes: 0 additions & 24 deletions x/onion/keeper/msg_server.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package keeper

import (
"context"
"strconv"

"github.com/Team-Kujira/core/x/onion/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type msgServer struct {
@@ -19,23 +15,3 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
}

var _ types.MsgServer = msgServer{}

func (m msgServer) EmitIBCAck(goCtx context.Context, msg *types.MsgEmitIBCAck) (*types.MsgEmitIBCAckResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.MsgEmitAckKey,
sdk.NewAttribute(types.AttributeSender, msg.Sender),
sdk.NewAttribute(types.AttributeChannel, msg.Channel),
sdk.NewAttribute(types.AttributePacketSequence, strconv.FormatUint(msg.PacketSequence, 10)),
),
)

ack, err := m.Keeper.EmitIBCAck(ctx, msg.Sender, msg.Channel, msg.PacketSequence)
if err != nil {
return nil, err
}

return &types.MsgEmitIBCAckResponse{ContractResult: string(ack), IbcAck: string(ack)}, nil
}
2 changes: 0 additions & 2 deletions x/onion/types/codec.go
Original file line number Diff line number Diff line change
@@ -11,13 +11,11 @@ import (
)

func RegisterCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgEmitIBCAck{}, "kujira/ibc-hooks/emit-ibc-ack", nil)
}

func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgEmitIBCAck{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
11 changes: 0 additions & 11 deletions x/onion/types/expected_keepers.go
Original file line number Diff line number Diff line change
@@ -3,19 +3,8 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)

type ChannelKeeper interface {
GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool)
GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte
GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool)
LookupModuleByChannel(ctx sdk.Context, portID, channelID string) (string, *capabilitytypes.Capability, error)
WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.PacketI, acknowledgement exported.Acknowledgement) error
}

type AccountKeeper interface {
GetParams(ctx sdk.Context) (params authtypes.Params)
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
31 changes: 0 additions & 31 deletions x/onion/types/msgs.go
Original file line number Diff line number Diff line change
@@ -1,32 +1 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// constants.
const (
TypeMsgEmitIBCAck = "emit-ibc-ack"
)

var _ sdk.Msg = &MsgEmitIBCAck{}

func (m MsgEmitIBCAck) Route() string { return RouterKey }
func (m MsgEmitIBCAck) Type() string { return TypeMsgEmitIBCAck }
func (m MsgEmitIBCAck) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(m.Sender)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err)
}
return nil
}

func (m MsgEmitIBCAck) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}

func (m MsgEmitIBCAck) GetSigners() []sdk.AccAddress {
sender, _ := sdk.AccAddressFromBech32(m.Sender)
return []sdk.AccAddress{sender}
}
39 changes: 5 additions & 34 deletions x/onion/types/params.go
Original file line number Diff line number Diff line change
@@ -1,62 +1,33 @@
package types

import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)

// Parameter store keys.
var (
KeyAsyncAckAllowList = []byte("AsyncAckAllowList")

_ paramtypes.ParamSet = &Params{}
)

func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
return paramtypes.NewKeyTable()
}

func NewParams(allowedAsyncAckContracts []string) Params {
return Params{
AllowedAsyncAckContracts: allowedAsyncAckContracts,
}
func NewParams() Params {
return Params{}
}

// DefaultParams returns default concentrated-liquidity module parameters.
func DefaultParams() Params {
return Params{
AllowedAsyncAckContracts: []string{},
}
return Params{}
}

// ParamSetPairs implements params.ParamSet.
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeyAsyncAckAllowList, &p.AllowedAsyncAckContracts, validateAsyncAckAllowList),
}
return paramtypes.ParamSetPairs{}
}

// Validate params.
func (p Params) Validate() error {
if err := validateAsyncAckAllowList(p.AllowedAsyncAckContracts); err != nil {
return err
}
return nil
}

func validateAsyncAckAllowList(i interface{}) error {
allowedContracts, ok := i.([]string)

if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}

for _, contract := range allowedContracts {
if _, err := sdk.AccAddressFromBech32(contract); err != nil {
return err
}
}

return nil
}
75 changes: 8 additions & 67 deletions x/onion/types/params.pb.go
668 changes: 13 additions & 655 deletions x/onion/types/tx.pb.go

Large diffs are not rendered by default.

84 changes: 0 additions & 84 deletions x/onion/types/types.go
Original file line number Diff line number Diff line change
@@ -1,85 +1 @@
package types

import (
"encoding/json"

channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
)

// Async: The following types represent the response sent by a contract on OnRecvPacket when it wants the ack to be async

// OnRecvPacketAsyncAckResponse the response a contract sends to instruct the module to make the ack async
type OnRecvPacketAsyncAckResponse struct {
IsAsyncAck bool `json:"is_async_ack"`
}

// Async The following types are used to ask a contract that has sent a packet to generate an ack for it

// RequestAckI internals of IBCAsync
type RequestAckI struct {
PacketSequence uint64 `json:"packet_sequence"`
SourceChannel string `json:"source_channel"`
}

// RequestAck internals of IBCAsync
type RequestAck struct {
RequestAckI `json:"request_ack"`
}

// IBCAsync is the sudo message to be sent to the contract for it to generate an ack for a sent packet
type IBCAsync struct {
RequestAck `json:"ibc_async"`
}

// General

// ContractAck is the response to be stored when a wasm hook is executed
type ContractAck struct {
ContractResult []byte `json:"contract_result"`
IbcAck []byte `json:"ibc_ack"`
}

// IBCAckResponse is the response that a contract returns from the sudo() call on OnRecvPacket or RequestAck
type IBCAckResponse struct {
Packet channeltypes.Packet `json:"packet"`
ContractAck ContractAck `json:"contract_ack"`
}

// IBCAckError is the error that a contract returns from the sudo() call on RequestAck
type IBCAckError struct {
Packet channeltypes.Packet `json:"packet"`
ErrorDescription string `json:"error_description"`
ErrorResponse string `json:"error_response"`
}

type IBCAck struct {
Type string `json:"type"`
Content json.RawMessage `json:"content"`
// Note: These two fields have to be pointers so that they can be null
// If they are not pointers, they will be empty structs when null,
// which will cause issues with json.Unmarshal.
AckResponse *IBCAckResponse `json:"response,omitempty"`
AckError *IBCAckError `json:"error,omitempty"`
}

func UnmarshalIBCAck(bz []byte) (*IBCAck, error) {
var ack IBCAck
if err := json.Unmarshal(bz, &ack); err != nil {
return nil, err
}

switch ack.Type {
case "ack_response":
ack.AckResponse = &IBCAckResponse{}
if err := json.Unmarshal(ack.Content, ack.AckResponse); err != nil {
return nil, err
}
case "ack_error":
ack.AckError = &IBCAckError{}
if err := json.Unmarshal(ack.Content, ack.AckError); err != nil {
return nil, err
}
}

return &ack, nil
}
381 changes: 0 additions & 381 deletions x/onion/wasm_hook.go

This file was deleted.