Skip to content

Commit

Permalink
Add IBC Ping Pong contract demo (#259)
Browse files Browse the repository at this point in the history
* IBC callback redesign

* Add ping pong ibc example

* Cleanup some commented out code

* Apply review feedback

* Revert unintended renamings
  • Loading branch information
alpe authored Aug 25, 2020
1 parent 92f9b28 commit 9073b89
Show file tree
Hide file tree
Showing 20 changed files with 892 additions and 488 deletions.
2 changes: 1 addition & 1 deletion x/wasm/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ type (
MsgMigrateContract = types.MsgMigrateContract
MsgUpdateAdmin = types.MsgUpdateAdmin
MsgClearAdmin = types.MsgClearAdmin
MsgWasmIBCCall = types.MsgWasmIBCCall
MsgWasmIBCCall = types.MsgIBCSend
Model = types.Model
CodeInfo = types.CodeInfo
ContractInfo = types.ContractInfo
Expand Down
58 changes: 37 additions & 21 deletions x/wasm/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ func (i IBCHandler) OnChanOpenInit(ctx sdk.Context, order channeltypes.Order, co
return sdkerrors.Wrapf(err, "contract port id")
}

err = i.keeper.OnOpenChannel(ctx, contractAddr, order, version, connectionHops, cosmwasm.IBCInfo{
Port: portID,
Channel: channelID,
err = i.keeper.OnOpenChannel(ctx, contractAddr, cosmwasm.IBCChannel{
Endpoint: cosmwasm.IBCEndpoint{Port: portID, Channel: channelID},
CounterpartyEndpoint: cosmwasm.IBCEndpoint{Port: counterParty.PortId, Channel: counterParty.ChannelId},
Order: order,
Version: version,
})
if err != nil {
return err
Expand All @@ -50,9 +52,12 @@ func (i IBCHandler) OnChanOpenTry(ctx sdk.Context, order channeltypes.Order, con
return sdkerrors.Wrapf(err, "contract port id")
}

err = i.keeper.OnOpenChannel(ctx, contractAddr, order, version, connectionHops, cosmwasm.IBCInfo{
Port: portID,
Channel: channelID,
err = i.keeper.OnOpenChannel(ctx, contractAddr, cosmwasm.IBCChannel{
Endpoint: cosmwasm.IBCEndpoint{Port: portID, Channel: channelID},
CounterpartyEndpoint: cosmwasm.IBCEndpoint{Port: counterParty.PortId, Channel: counterParty.ChannelId},
Order: order,
Version: version,
CounterpartyVersion: &counterpartyVersion,
})
if err != nil {
return err
Expand All @@ -73,9 +78,12 @@ func (i IBCHandler) OnChanOpenAck(ctx sdk.Context, portID, channelID string, cou
if !ok {
return sdkerrors.Wrap(types.ErrInvalidCounterparty, "not found")
}
return i.keeper.OnConnectChannel(ctx, contractAddr, channelInfo.Counterparty, counterpartyVersion, cosmwasm.IBCInfo{
Port: portID,
Channel: channelID,
return i.keeper.OnConnectChannel(ctx, contractAddr, cosmwasm.IBCChannel{
Endpoint: cosmwasm.IBCEndpoint{Port: portID, Channel: channelID},
CounterpartyEndpoint: cosmwasm.IBCEndpoint{Port: channelInfo.Counterparty.PortId, Channel: channelInfo.Counterparty.ChannelId},
Order: channelInfo.Ordering,
Version: channelInfo.Version,
CounterpartyVersion: &counterpartyVersion,
})
}

Expand All @@ -88,9 +96,11 @@ func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string)
if !ok {
return sdkerrors.Wrap(types.ErrInvalidCounterparty, "not found")
}
return i.keeper.OnConnectChannel(ctx, contractAddr, channelInfo.Counterparty, channelInfo.Version, cosmwasm.IBCInfo{
Port: portID,
Channel: channelID,
return i.keeper.OnConnectChannel(ctx, contractAddr, cosmwasm.IBCChannel{
Endpoint: cosmwasm.IBCEndpoint{Port: portID, Channel: channelID},
CounterpartyEndpoint: cosmwasm.IBCEndpoint{Port: channelInfo.Counterparty.PortId, Channel: channelInfo.Counterparty.ChannelId},
Order: channelInfo.Ordering,
Version: channelInfo.Version,
})
}

Expand All @@ -116,7 +126,7 @@ func (i IBCHandler) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet) (*
if err != nil {
return nil, nil, sdkerrors.Wrapf(err, "contract port id")
}
msgBz, err := i.keeper.OnRecvPacket(ctx, contractAddr, packet.Data, ibcInfoFromPacket(packet))
msgBz, err := i.keeper.OnRecvPacket(ctx, contractAddr, newIBCPacket(packet))
if err != nil {
return nil, nil, err
}
Expand All @@ -140,12 +150,15 @@ func (i IBCHandler) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet) (*
}

func (i IBCHandler) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte) (*sdk.Result, error) {
contractAddr, err := ContractFromPortID(packet.DestinationPort)
contractAddr, err := ContractFromPortID(packet.SourcePort)
if err != nil {
return nil, sdkerrors.Wrapf(err, "contract port id")
}

err = i.keeper.OnAckPacket(ctx, contractAddr, packet.Data, acknowledgement, ibcInfoFromPacket(packet))
err = i.keeper.OnAckPacket(ctx, contractAddr, cosmwasm.IBCAcknowledgement{
Acknowledgement: acknowledgement,
OriginalPacket: newIBCPacket(packet),
})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -180,7 +193,7 @@ func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet)
if err != nil {
return nil, sdkerrors.Wrapf(err, "contract port id")
}
err = i.keeper.OnTimeoutPacket(ctx, contractAddr, packet.Data, ibcInfoFromPacket(packet))
err = i.keeper.OnTimeoutPacket(ctx, contractAddr, newIBCPacket(packet))
if err != nil {
return nil, err
}
Expand All @@ -200,10 +213,13 @@ func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet)

}

func ibcInfoFromPacket(packet channeltypes.Packet) cosmwasm.IBCInfo {
return cosmwasm.IBCInfo{
Port: packet.DestinationPort,
Channel: packet.DestinationChannel,
Packet: cosmwasm.NewIBCPacketInfo(packet.Sequence, packet.SourcePort, packet.SourceChannel, packet.TimeoutHeight, packet.TimeoutTimestamp),
func newIBCPacket(packet channeltypes.Packet) cosmwasm.IBCPacket {
return cosmwasm.IBCPacket{
Data: packet.Data,
Source: cosmwasm.IBCEndpoint{Channel: packet.SourceChannel, Port: packet.SourcePort},
Destination: cosmwasm.IBCEndpoint{Channel: packet.DestinationChannel, Port: packet.DestinationPort},
Sequence: packet.Sequence,
TimeoutHeight: packet.TimeoutHeight,
TimeoutTimestamp: packet.TimeoutTimestamp,
}
}
17 changes: 9 additions & 8 deletions x/wasm/ibc_testing/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ const (
TrustingPeriod time.Duration = time.Hour * 24 * 7 * 2
UnbondingPeriod time.Duration = time.Hour * 24 * 7 * 3
MaxClockDrift time.Duration = time.Second * 10

ChannelVersion = ibctransfertypes.Version
InvalidID = "IDisInvalid"
InvalidID = "IDisInvalid"

ConnectionIDPrefix = "connectionid"
)

//var ChannelVersion = ibctransfertypes.Version

// Default params variables used to create a TM client
var (
DefaultTrustLevel ibctmtypes.Fraction = ibctmtypes.DefaultTrustLevel
Expand Down Expand Up @@ -334,10 +334,11 @@ func (chain *TestChain) AddTestConnection(clientID, counterpartyClientID string)
// format:
// connectionid<index>
func (chain *TestChain) ConstructNextTestConnection(clientID, counterpartyClientID string) *TestConnection {
connectionID := ConnectionIDPrefix + strconv.Itoa(len(chain.Connections))
connectionID := chain.ChainID + ConnectionIDPrefix + strconv.Itoa(len(chain.Connections))
return &TestConnection{
ID: connectionID,
ClientID: clientID,
NextChannelVersion: ibctransfertypes.Version,
CounterpartyClientID: counterpartyClientID,
}
}
Expand Down Expand Up @@ -590,7 +591,7 @@ func (chain *TestChain) ChanOpenInit(
) error {
msg := channeltypes.NewMsgChannelOpenInit(
ch.PortID, ch.ID,
ChannelVersion, order, []string{connectionID},
ch.Version, order, []string{connectionID},
counterparty.PortID, counterparty.ID,
chain.SenderAccount.GetAddress(),
)
Expand All @@ -608,9 +609,9 @@ func (chain *TestChain) ChanOpenTry(

msg := channeltypes.NewMsgChannelOpenTry(
ch.PortID, ch.ID,
ChannelVersion, order, []string{connectionID},
ch.Version, order, []string{connectionID},
counterpartyCh.PortID, counterpartyCh.ID,
ChannelVersion,
counterpartyCh.Version,
proof, height,
chain.SenderAccount.GetAddress(),
)
Expand All @@ -626,7 +627,7 @@ func (chain *TestChain) ChanOpenAck(

msg := channeltypes.NewMsgChannelOpenAck(
ch.PortID, ch.ID,
ChannelVersion,
counterpartyCh.Version,
proof, height,
chain.SenderAccount.GetAddress(),
)
Expand Down
3 changes: 3 additions & 0 deletions x/wasm/ibc_testing/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type TestConnection struct {
ID string
ClientID string
CounterpartyClientID string
NextChannelVersion string
Channels []TestChannel
}

Expand All @@ -32,6 +33,7 @@ func (conn *TestConnection) AddTestChannel(portID string) TestChannel {
func (conn *TestConnection) NextTestChannel(portID string) TestChannel {
channelID := fmt.Sprintf("%s%d", conn.ID, len(conn.Channels))
return TestChannel{
Version: conn.NextChannelVersion,
PortID: portID,
ID: channelID,
ClientID: conn.ClientID,
Expand All @@ -58,4 +60,5 @@ type TestChannel struct {
ID string
ClientID string
CounterpartyClientID string
Version string
}
60 changes: 46 additions & 14 deletions x/wasm/internal/keeper/cosmwasm/contract.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,74 @@
package cosmwasm

import (
wasmTypes "github.com/CosmWasm/go-cosmwasm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
cosmwasmv1 "github.com/CosmWasm/go-cosmwasm/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
)

type IBCEndpoint struct {
Channel string `json:"channel"`
Port string `json:"port"`
}

type IBCChannel struct {
Endpoint IBCEndpoint
CounterpartyEndpoint IBCEndpoint
Order channeltypes.Order
Version string
// CounterpartyVersion can be nil when not known this context, yet
CounterpartyVersion *string `json:"counterparty_version,omitempty"`
}

type IBCPacket struct {
Data []byte
// identifies the channel and port on the sending chain.
Source IBCEndpoint
// identifies the channel and port on the receiving chain.
Destination IBCEndpoint
Sequence uint64
// block height after which the packet times out
TimeoutHeight uint64
// block timestamp (in nanoseconds) after which the packet times out
TimeoutTimestamp uint64
}

type IBCAcknowledgement struct {
Acknowledgement []byte `json:"acknowledgement"`
OriginalPacket IBCPacket `json:"original_packet"`
}

type IBCPacketReceiveResponse struct {
// Acknowledgement contains the data to acknowledge the ibc packet execution
Acknowledgement []byte `json:"acknowledgement"`
// Messages comes directly from the contract and is it's request for action
Messages []sdk.Msg `json:"messages,omitempty"`
Messages []CosmosMsg `json:"messages,omitempty"`
// Log contains event attributes to expose over abci interface
Log []wasmTypes.LogAttribute `json:"log,omitempty"`
Log []cosmwasmv1.LogAttribute `json:"log,omitempty"`
}

type IBCPacketAcknowledgementResponse struct {
Messages []sdk.Msg `json:"messages"`
Log []wasmTypes.LogAttribute `json:"log"`
Messages []CosmosMsg `json:"messages"`
Log []cosmwasmv1.LogAttribute `json:"log"`
}

type IBCPacketTimeoutResponse struct {
Messages []sdk.Msg `json:"messages"`
Log []wasmTypes.LogAttribute `json:"log"`
Messages []CosmosMsg `json:"messages"`
Log []cosmwasmv1.LogAttribute `json:"log"`
}

type IBCChannelOpenResponse struct {
// Result contains a boolean if the channel would be accepted
Result bool `json:"result"`
// Success contains a boolean if the channel would be accepted
Success bool `json:"result"`
// Reason optional description why it was not accepted
Reason string `json:"reason"`
}

type IBCChannelConnectResponse struct {
Messages []sdk.Msg `json:"messages"`
Log []wasmTypes.LogAttribute `json:"log"`
Messages []CosmosMsg `json:"messages"`
Log []cosmwasmv1.LogAttribute `json:"log"`
}

type IBCChannelCloseResponse struct {
Messages []sdk.Msg `json:"messages"`
Log []wasmTypes.LogAttribute `json:"log"`
Messages []CosmosMsg `json:"messages"`
Log []cosmwasmv1.LogAttribute `json:"log"`
}
45 changes: 0 additions & 45 deletions x/wasm/internal/keeper/cosmwasm/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import (
wasmtypes "github.com/CosmWasm/go-cosmwasm/types"
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
sdk "github.com/cosmos/cosmos-sdk/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
)

type Env struct {
Block wasmtypes.BlockInfo `json:"block"`
Message wasmtypes.MessageInfo `json:"message"`
Contract wasmtypes.ContractInfo `json:"contract"`
// optional IBC meta data only set when called in IBC context
IBC *IBCInfo `json:"ibc,omitempty"`
}

func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contractAddr sdk.AccAddress) Env {
Expand All @@ -38,45 +35,3 @@ func NewEnv(ctx sdk.Context, creator sdk.AccAddress, deposit sdk.Coins, contract
},
}
}

type IBCInfo struct {
// Port of the contract
Port string `json:"port"`
// Channel to the contract
Channel string `json:"channel"`
// Optional packet meta data when called on IBC packet functions
Packet *IBCPacketInfo `json:"packet,omitempty"`
}

func (i IBCInfo) AsPacket(data []byte) channeltypes.Packet {
r := channeltypes.Packet{
DestinationPort: i.Port,
DestinationChannel: i.Channel,
}
if i.Packet == nil {
return r
}
r.TimeoutHeight = i.Packet.TimeoutHeight
r.Sequence = i.Packet.Sequence
r.SourcePort = i.Packet.SourcePort
r.SourceChannel = i.Packet.SourceChannel
r.TimeoutTimestamp = i.Packet.TimeoutTimestamp
r.Data = data
return r
}

type IBCPacketInfo struct {
Sequence uint64
// identifies the port on the sending chain.
SourcePort string
// identifies the channel end on the sending chain.
SourceChannel string
// block height after which the packet times out
TimeoutHeight uint64
// block timestamp (in nanoseconds) after which the packet times out
TimeoutTimestamp uint64
}

func NewIBCPacketInfo(sequence uint64, sourcePort string, sourceChannel string, timeoutHeight uint64, timeoutTimestamp uint64) *IBCPacketInfo {
return &IBCPacketInfo{Sequence: sequence, SourcePort: sourcePort, SourceChannel: sourceChannel, TimeoutHeight: timeoutHeight, TimeoutTimestamp: timeoutTimestamp}
}
Loading

0 comments on commit 9073b89

Please sign in to comment.