Skip to content

Commit

Permalink
Add ping pong ibc example
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Aug 22, 2020
1 parent cbb5ea4 commit aa2bea0
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 121 deletions.
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
}
131 changes: 22 additions & 109 deletions x/wasm/internal/keeper/cosmwasm/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,115 +52,28 @@ type HandleResponse struct {
// base64-encoded bytes to return as ABCI.Data field
Data []byte `json:"data"`
// log message to return over abci interface
Log []LogAttribute `json:"log"`
Log []cosmwasmv1.LogAttribute `json:"log"`
}

// InitResult is the raw response from the handle call
type InitResult struct {
Ok *InitResponse `json:"Ok,omitempty"`
Err *cosmwasmv1.StdError `json:"Err,omitempty"`
}

// InitResponse defines the return value on a successful handle
type InitResponse struct {
// Messages comes directly from the contract and is it's request for action
Messages []CosmosMsg `json:"messages"`
// log message to return over abci interface
Log []LogAttribute `json:"log"`
}

// MigrateResult is the raw response from the handle call
type MigrateResult struct {
Ok *MigrateResponse `json:"Ok,omitempty"`
Err *cosmwasmv1.StdError `json:"Err,omitempty"`
}

// MigrateResponse defines the return value on a successful handle
type MigrateResponse struct {
// Messages comes directly from the contract and is it's request for action
Messages []CosmosMsg `json:"messages"`
// base64-encoded bytes to return as ABCI.Data field
Data []byte `json:"data"`
// log message to return over abci interface
Log []LogAttribute `json:"log"`
}

// LogAttribute
type LogAttribute struct {
Key string `json:"key"`
Value string `json:"value"`
}

type BankMsg struct {
Send *SendMsg `json:"send,omitempty"`
}

// SendMsg contains instructions for a Cosmos-SDK/SendMsg
// It has a fixed interface here and should be converted into the proper SDK format before dispatching
type SendMsg struct {
FromAddress string `json:"from_address"`
ToAddress string `json:"to_address"`
Amount cosmwasmv1.Coins `json:"amount"`
}

type StakingMsg struct {
Delegate *DelegateMsg `json:"delegate,omitempty"`
Undelegate *UndelegateMsg `json:"undelegate,omitempty"`
Redelegate *RedelegateMsg `json:"redelegate,omitempty"`
Withdraw *WithdrawMsg `json:"withdraw,omitempty"`
}

type DelegateMsg struct {
Validator string `json:"validator"`
Amount cosmwasmv1.Coins `json:"amount"`
}

type UndelegateMsg struct {
Validator string `json:"validator"`
Amount cosmwasmv1.Coins `json:"amount"`
}

type RedelegateMsg struct {
SrcValidator string `json:"src_validator"`
DstValidator string `json:"dst_validator"`
Amount cosmwasmv1.Coins `json:"amount"`
}

type WithdrawMsg struct {
Validator string `json:"validator"`
// this is optional
Recipient string `json:"recipient,omitempty"`
}

type WasmMsg struct {
Execute *ExecuteMsg `json:"execute,omitempty"`
Instantiate *InstantiateMsg `json:"instantiate,omitempty"`
}

// ExecuteMsg is used to call another defined contract on this chain.
// The calling contract requires the callee to be defined beforehand,
// and the address should have been defined in initialization.
// And we assume the developer tested the ABIs and coded them together.
//type WasmMsg struct {
// Execute *cosmwasmv1.ExecuteMsg `json:"execute,omitempty"`
// Instantiate *cosmwasmv1.InstantiateMsg `json:"instantiate,omitempty"`
//}
//
// Since a contract is immutable once it is deployed, we don't need to transform this.
// If it was properly coded and worked once, it will continue to work throughout upgrades.
type ExecuteMsg struct {
// ContractAddr is the sdk.AccAddress of the contract, which uniquely defines
// the contract ID and instance ID. The sdk module should maintain a reverse lookup table.
ContractAddr string `json:"contract_addr"`
// Msg is assumed to be a json-encoded message, which will be passed directly
// as `userMsg` when calling `Handle` on the above-defined contract
Msg []byte `json:"msg"`
// Send is an optional amount of coins this contract sends to the called contract
Send cosmwasmv1.Coins `json:"send"`
}

type InstantiateMsg struct {
// CodeID is the reference to the wasm byte code as used by the Cosmos-SDK
CodeID uint64 `json:"code_id"`
// Msg is assumed to be a json-encoded message, which will be passed directly
// as `userMsg` when calling `Handle` on the above-defined contract
Msg []byte `json:"msg"`
// Send is an optional amount of coins this contract sends to the called contract
Send cosmwasmv1.Coins `json:"send"`
}
//// ExecuteMsg is used to call another defined contract on this chain.
//// The calling contract requires the callee to be defined beforehand,
//// and the address should have been defined in initialization.
//// And we assume the developer tested the ABIs and coded them together.
////
//// Since a contract is immutable once it is deployed, we don't need to transform this.
//// If it was properly coded and worked once, it will continue to work throughout upgrades.
//type ExecuteMsg struct {
// // ContractAddr is the sdk.AccAddress of the contract, which uniquely defines
// // the contract ID and instance ID. The sdk module should maintain a reverse lookup table.
// ContractAddr string `json:"contract_addr"`
// // Msg is assumed to be a json-encoded message, which will be passed directly
// // as `userMsg` when calling `Handle` on the above-defined contract
// Msg []byte `json:"msg"`
// // Send is an optional amount of coins this contract sends to the called contract
// Send cosmwasmv1.Coins `json:"send"`
//}
2 changes: 2 additions & 0 deletions x/wasm/internal/keeper/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"strings"

wasm "github.com/CosmWasm/go-cosmwasm"
wasmTypes "github.com/CosmWasm/go-cosmwasm/types"
"github.com/CosmWasm/wasmd/x/wasm/internal/keeper/cosmwasm"
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
Expand Down Expand Up @@ -81,6 +82,7 @@ type IBCContractCallbacks interface {
OnIBCChannelConnect(hash []byte, params cosmwasm.Env, channel cosmwasm.IBCChannel, store prefix.Store, api wasm.GoAPI, querier QueryHandler, meter sdk.GasMeter, gas uint64) (*cosmwasm.IBCChannelConnectResponse, uint64, error)
// OnIBCChannelConnect callback when a IBC channel is closed
OnIBCChannelClose(ctx sdk.Context, hash []byte, params cosmwasm.Env, channel cosmwasm.IBCChannel, meter sdk.GasMeter, gas uint64) (*cosmwasm.IBCChannelCloseResponse, uint64, error)
Execute(hash []byte, params wasmTypes.Env, msg []byte, store prefix.Store, api wasm.GoAPI, querier QueryHandler, meter sdk.GasMeter, gas uint64) (*cosmwasm.HandleResponse, uint64, error)
}

var MockContracts = make(map[string]IBCContractCallbacks, 0)
Expand Down
22 changes: 22 additions & 0 deletions x/wasm/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

wasm "github.com/CosmWasm/go-cosmwasm"
wasmTypes "github.com/CosmWasm/go-cosmwasm/types"
cosmwasmv2 "github.com/CosmWasm/wasmd/x/wasm/internal/keeper/cosmwasm"
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
Expand Down Expand Up @@ -309,6 +310,27 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
}

gas := gasForContract(ctx)

mock, ok := MockContracts[contractAddress.String()]
if ok {
res, gasUsed, execErr := mock.Execute(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, ctx.GasMeter(), gas)
consumeGas(ctx, gasUsed)
if execErr != nil {
return nil, sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error())
}

// emit all events from this contract itself
events := types.ParseEvents(res.Log, contractAddress)
ctx.EventManager().EmitEvents(events)

if err := k.messenger.DispatchV2(ctx, contractAddress, cosmwasmv2.IBCEndpoint{}, res.Messages...); err != nil {
return nil, err
}
return &sdk.Result{
Data: res.Data,
}, nil
}

res, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas)
consumeGas(ctx, gasUsed)
if execErr != nil {
Expand Down
Loading

0 comments on commit aa2bea0

Please sign in to comment.