140 lines
4.1 KiB
Go
140 lines
4.1 KiB
Go
package keeper
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
wasmTypes "github.com/confio/go-cosmwasm/types"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
)
|
|
|
|
// MaskInitMsg is {}
|
|
|
|
type MaskHandleMsg struct {
|
|
Reflect *reflectPayload `json:"reflectmsg,omitempty"`
|
|
Change *ownerPayload `json:"changeowner,omitempty"`
|
|
}
|
|
|
|
type ownerPayload struct {
|
|
Owner sdk.Address `json:"owner"`
|
|
}
|
|
|
|
type reflectPayload struct {
|
|
Msg wasmTypes.CosmosMsg `json:"msg"`
|
|
}
|
|
|
|
func TestMaskSend(t *testing.T) {
|
|
tempDir, err := ioutil.TempDir("", "wasm")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tempDir)
|
|
ctx, accKeeper, keeper := CreateTestInput(t, false, tempDir)
|
|
|
|
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
|
|
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
|
|
bob := createFakeFundedAccount(ctx, accKeeper, deposit)
|
|
_, _, fred := keyPubAddr()
|
|
|
|
// upload code
|
|
maskCode, err := ioutil.ReadFile("./testdata/mask.wasm")
|
|
require.NoError(t, err)
|
|
codeID, err := keeper.Create(ctx, creator, maskCode, "", "")
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(1), codeID)
|
|
|
|
// creator instantiates a contract and gives it tokens
|
|
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
|
|
contractAddr, err := keeper.Instantiate(ctx, codeID, creator, []byte("{}"), contractStart)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, contractAddr)
|
|
|
|
// set owner to bob
|
|
transfer := MaskHandleMsg{
|
|
Change: &ownerPayload{
|
|
Owner: bob,
|
|
},
|
|
}
|
|
transferBz, err := json.Marshal(transfer)
|
|
require.NoError(t, err)
|
|
// TODO: switch order of args Instantiate vs Execute (caller/code vs contract/caller), (msg/coins vs coins/msg)
|
|
_, err = keeper.Execute(ctx, contractAddr, creator, transferBz, nil)
|
|
require.NoError(t, err)
|
|
|
|
// check some account values
|
|
checkAccount(t, ctx, accKeeper, contractAddr, contractStart)
|
|
checkAccount(t, ctx, accKeeper, bob, deposit)
|
|
checkAccount(t, ctx, accKeeper, fred, nil)
|
|
|
|
// bob can send contract's tokens to fred (using SendMsg)
|
|
// TODO: fix this upstream
|
|
msg := wasmTypes.CosmosMsg{
|
|
Send: &wasmTypes.SendMsg{
|
|
FromAddress: contractAddr.String(),
|
|
ToAddress: fred.String(),
|
|
Amount: []wasmTypes.Coin{{
|
|
Denom: "denom",
|
|
Amount: "15000",
|
|
}},
|
|
},
|
|
}
|
|
reflectSend := MaskHandleMsg{
|
|
Reflect: &reflectPayload{
|
|
Msg: msg,
|
|
},
|
|
}
|
|
reflectSendBz, err := json.Marshal(reflectSend)
|
|
require.NoError(t, err)
|
|
// TODO: switch order of args Instantiate vs Execute (caller/code vs contract/caller), (msg/coins vs coins/msg)
|
|
_, err = keeper.Execute(ctx, contractAddr, bob, reflectSendBz, nil)
|
|
require.NoError(t, err)
|
|
|
|
// fred got coins
|
|
checkAccount(t, ctx, accKeeper, fred, sdk.NewCoins(sdk.NewInt64Coin("denom", 15000)))
|
|
// contract lost them
|
|
checkAccount(t, ctx, accKeeper, contractAddr, sdk.NewCoins(sdk.NewInt64Coin("denom", 25000)))
|
|
checkAccount(t, ctx, accKeeper, bob, deposit)
|
|
|
|
// construct an opaque message
|
|
var sdkSendMsg sdk.Msg = &bank.MsgSend{
|
|
FromAddress: contractAddr,
|
|
ToAddress: fred,
|
|
Amount: sdk.NewCoins(sdk.NewInt64Coin("denom", 23000)),
|
|
}
|
|
opaque, err := ToOpaqueMsg(keeper.cdc, sdkSendMsg)
|
|
require.NoError(t, err)
|
|
reflectOpaque := MaskHandleMsg{
|
|
Reflect: &reflectPayload{
|
|
Msg: wasmTypes.CosmosMsg{
|
|
Opaque: opaque,
|
|
},
|
|
},
|
|
}
|
|
reflectOpaqueBz, err := json.Marshal(reflectOpaque)
|
|
require.NoError(t, err)
|
|
|
|
// TODO: switch order of args Instantiate vs Execute (caller/code vs contract/caller), (msg/coins vs coins/msg)
|
|
_, err = keeper.Execute(ctx, contractAddr, bob, reflectOpaqueBz, nil)
|
|
require.NoError(t, err)
|
|
|
|
// fred got more coins
|
|
checkAccount(t, ctx, accKeeper, fred, sdk.NewCoins(sdk.NewInt64Coin("denom", 38000)))
|
|
// contract lost them
|
|
checkAccount(t, ctx, accKeeper, contractAddr, sdk.NewCoins(sdk.NewInt64Coin("denom", 2000)))
|
|
checkAccount(t, ctx, accKeeper, bob, deposit)
|
|
}
|
|
|
|
func checkAccount(t *testing.T, ctx sdk.Context, accKeeper auth.AccountKeeper, addr sdk.AccAddress, expected sdk.Coins) {
|
|
acct := accKeeper.GetAccount(ctx, addr)
|
|
if expected == nil {
|
|
require.Nil(t, acct)
|
|
} else {
|
|
require.NotNil(t, acct)
|
|
require.Equal(t, acct.GetCoins(), expected)
|
|
}
|
|
}
|