262 lines
7.5 KiB
Go
262 lines
7.5 KiB
Go
package transfer
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/spf13/cobra"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client/context"
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/types/module"
|
|
"github.com/cosmos/cosmos-sdk/x/capability"
|
|
channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel"
|
|
channelexported "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported"
|
|
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
|
port "github.com/cosmos/cosmos-sdk/x/ibc/05-port"
|
|
porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types"
|
|
"github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/cli"
|
|
"github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/client/rest"
|
|
"github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types"
|
|
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
|
|
)
|
|
|
|
var (
|
|
_ module.AppModule = AppModule{}
|
|
_ port.IBCModule = AppModule{}
|
|
_ module.AppModuleBasic = AppModuleBasic{}
|
|
)
|
|
|
|
// AppModuleBasic is the 20-transfer appmodulebasic
|
|
type AppModuleBasic struct{}
|
|
|
|
// Name implements AppModuleBasic interface
|
|
func (AppModuleBasic) Name() string {
|
|
return ModuleName
|
|
}
|
|
|
|
// RegisterCodec implements AppModuleBasic interface
|
|
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
|
RegisterCodec(cdc)
|
|
}
|
|
|
|
// DefaultGenesis returns default genesis state as raw bytes for the ibc
|
|
// transfer module.
|
|
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
|
|
return cdc.MustMarshalJSON(DefaultGenesis())
|
|
}
|
|
|
|
// ValidateGenesis performs genesis state validation for the ibc transfer module.
|
|
func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error {
|
|
return nil
|
|
}
|
|
|
|
// RegisterRESTRoutes implements AppModuleBasic interface
|
|
func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
|
|
rest.RegisterRoutes(ctx, rtr)
|
|
}
|
|
|
|
// GetTxCmd implements AppModuleBasic interface
|
|
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
|
return cli.GetTxCmd(cdc)
|
|
}
|
|
|
|
// GetQueryCmd implements AppModuleBasic interface
|
|
func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
|
|
return cli.GetQueryCmd(cdc, QuerierRoute)
|
|
}
|
|
|
|
// AppModule represents the AppModule for this module
|
|
type AppModule struct {
|
|
AppModuleBasic
|
|
keeper Keeper
|
|
}
|
|
|
|
// NewAppModule creates a new 20-transfer module
|
|
func NewAppModule(k Keeper) AppModule {
|
|
return AppModule{
|
|
keeper: k,
|
|
}
|
|
}
|
|
|
|
// RegisterInvariants implements the AppModule interface
|
|
func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
|
|
// TODO
|
|
}
|
|
|
|
// Route implements the AppModule interface
|
|
func (AppModule) Route() string {
|
|
return RouterKey
|
|
}
|
|
|
|
// NewHandler implements the AppModule interface
|
|
func (am AppModule) NewHandler() sdk.Handler {
|
|
return NewHandler(am.keeper)
|
|
}
|
|
|
|
// QuerierRoute implements the AppModule interface
|
|
func (AppModule) QuerierRoute() string {
|
|
return QuerierRoute
|
|
}
|
|
|
|
// NewQuerierHandler implements the AppModule interface
|
|
func (am AppModule) NewQuerierHandler() sdk.Querier {
|
|
return nil
|
|
}
|
|
|
|
// InitGenesis performs genesis initialization for the ibc transfer module. It returns
|
|
// no validator updates.
|
|
func (am AppModule) InitGenesis(ctx sdk.Context, _ codec.JSONMarshaler, _ json.RawMessage) []abci.ValidatorUpdate {
|
|
// check if the IBC transfer module account is set
|
|
InitGenesis(ctx, am.keeper)
|
|
return []abci.ValidatorUpdate{}
|
|
}
|
|
|
|
func (am AppModule) ExportGenesis(ctx sdk.Context, _ codec.JSONMarshaler) json.RawMessage {
|
|
return nil
|
|
}
|
|
|
|
// BeginBlock implements the AppModule interface
|
|
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
|
|
|
}
|
|
|
|
// EndBlock implements the AppModule interface
|
|
func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
|
|
return []abci.ValidatorUpdate{}
|
|
}
|
|
|
|
// Implement IBCModule callbacks
|
|
func (am AppModule) OnChanOpenInit(
|
|
ctx sdk.Context,
|
|
order channelexported.Order,
|
|
connectionHops []string,
|
|
portID string,
|
|
channelID string,
|
|
chanCap *capability.Capability,
|
|
counterparty channeltypes.Counterparty,
|
|
version string,
|
|
) error {
|
|
// TODO: Enforce ordering, currently relayers use ORDERED channels
|
|
|
|
if counterparty.PortID != types.PortID {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID)
|
|
}
|
|
|
|
if version != types.Version {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid version: %s, expected %s", version, "ics20-1")
|
|
}
|
|
|
|
// Claim channel capability passed back by IBC module
|
|
if err := am.keeper.ClaimCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)); err != nil {
|
|
return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error())
|
|
}
|
|
|
|
// TODO: escrow
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnChanOpenTry(
|
|
ctx sdk.Context,
|
|
order channelexported.Order,
|
|
connectionHops []string,
|
|
portID,
|
|
channelID string,
|
|
chanCap *capability.Capability,
|
|
counterparty channeltypes.Counterparty,
|
|
version,
|
|
counterpartyVersion string,
|
|
) error {
|
|
// TODO: Enforce ordering, currently relayers use ORDERED channels
|
|
|
|
if counterparty.PortID != types.PortID {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "counterparty has invalid portid. expected: %s, got %s", types.PortID, counterparty.PortID)
|
|
}
|
|
|
|
if version != types.Version {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid version: %s, expected %s", version, "ics20-1")
|
|
}
|
|
|
|
if counterpartyVersion != types.Version {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty version: %s, expected %s", counterpartyVersion, "ics20-1")
|
|
}
|
|
|
|
// Claim channel capability passed back by IBC module
|
|
if err := am.keeper.ClaimCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)); err != nil {
|
|
return sdkerrors.Wrap(channel.ErrChannelCapabilityNotFound, err.Error())
|
|
}
|
|
|
|
// TODO: escrow
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnChanOpenAck(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
counterpartyVersion string,
|
|
) error {
|
|
if counterpartyVersion != types.Version {
|
|
return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid counterparty version: %s, expected %s", counterpartyVersion, "ics20-1")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnChanOpenConfirm(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnChanCloseInit(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnChanCloseConfirm(
|
|
ctx sdk.Context,
|
|
portID,
|
|
channelID string,
|
|
) error {
|
|
return nil
|
|
}
|
|
|
|
func (am AppModule) OnRecvPacket(
|
|
ctx sdk.Context,
|
|
packet channeltypes.Packet,
|
|
) (*sdk.Result, error) {
|
|
var data FungibleTokenPacketData
|
|
if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil {
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error())
|
|
}
|
|
return handlePacketDataTransfer(ctx, am.keeper, packet, data)
|
|
}
|
|
|
|
func (am AppModule) OnAcknowledgementPacket(
|
|
ctx sdk.Context,
|
|
packet channeltypes.Packet,
|
|
acknowledment []byte,
|
|
) (*sdk.Result, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (am AppModule) OnTimeoutPacket(
|
|
ctx sdk.Context,
|
|
packet channeltypes.Packet,
|
|
) (*sdk.Result, error) {
|
|
var data FungibleTokenPacketData
|
|
if err := types.ModuleCdc.UnmarshalBinaryBare(packet.GetData(), &data); err != nil {
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error())
|
|
}
|
|
return handleTimeoutDataTransfer(ctx, am.keeper, packet, data)
|
|
}
|