wasmd/tests/integration/proposal_integration_test.go

235 lines
7.7 KiB
Go

package integration
import (
"encoding/hex"
"encoding/json"
"fmt"
"testing"
wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
var (
CyberpunkCapabilities = []string{"staking", "mask", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "cosmwasm_1_3", "cosmwasm_1_4"}
ReflectCapabilities = []string{"staking", "mask", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "cosmwasm_1_3", "cosmwasm_1_4", "cosmwasm_2_0"}
)
func TestLoadStoredGovV1Beta1LegacyTypes(t *testing.T) {
capabilities := make([]string, len(ReflectCapabilities)+1)
copy(capabilities, ReflectCapabilities)
capabilities = append(capabilities, "iterator")
pCtx, keepers := keeper.CreateTestInput(t, false, capabilities)
k := keepers.WasmKeeper
keepers.GovKeeper.SetLegacyRouter(v1beta1.NewRouter().
AddRoute(types.ModuleName, keeper.NewLegacyWasmProposalHandler(k, types.EnableAllProposals)),
)
myAddress := keeper.RandomAccountAddress(t)
keepers.Faucet.Fund(pCtx, myAddress, sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewIntFromUint64(100_000_000)))
keepers.Faucet.Fund(pCtx, myAddress, sdk.NewCoin("denom", sdkmath.NewIntFromUint64(100_000_000)))
reflectExample := keeper.InstantiateReflectExampleContract(t, pCtx, keepers)
burnerExample := keeper.StoreBurnerExampleContract(t, pCtx, keepers)
hackatomExample := keeper.InstantiateHackatomExampleContract(t, pCtx, keepers)
type StealMsg struct {
Recipient string `json:"recipient"`
Amount []sdk.Coin `json:"amount"`
}
stealMsg := struct {
Steal StealMsg `json:"steal_funds"`
}{Steal: StealMsg{
Recipient: myAddress.String(),
Amount: []sdk.Coin{sdk.NewInt64Coin("denom", 75)},
}}
stealMsgBz := must(json.Marshal(stealMsg))
specs := map[string]struct {
legacyContent v1beta1.Content
}{
"store code": {
legacyContent: &types.StoreCodeProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Source: "https://example.com/",
Builder: "cosmwasm/workspace-optimizer:v0.12.8",
RunAs: myAddress.String(),
WASMByteCode: testdata.HackatomContractWasm(),
CodeHash: must(hex.DecodeString(testdata.ChecksumHackatom)),
},
},
"instantiate": {
legacyContent: &types.InstantiateContractProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
RunAs: myAddress.String(),
Admin: myAddress.String(),
CodeID: reflectExample.CodeID,
Label: "testing",
Msg: []byte("{}"),
},
},
"instantiate2": {
legacyContent: &types.InstantiateContract2Proposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
RunAs: myAddress.String(),
Admin: myAddress.String(),
CodeID: reflectExample.CodeID,
Label: "testing",
Msg: []byte("{}"),
Salt: []byte("mySalt"),
},
},
"store and instantiate": {
legacyContent: &types.StoreAndInstantiateContractProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
RunAs: myAddress.String(),
WASMByteCode: testdata.ReflectContractWasm(),
Admin: myAddress.String(),
Label: "testing",
Msg: []byte("{}"),
Source: "https://example.com/",
Builder: "cosmwasm/workspace-optimizer:v0.12.8",
CodeHash: reflectExample.Checksum,
},
},
"migrate": {
legacyContent: &types.MigrateContractProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Contract: reflectExample.Contract.String(),
CodeID: burnerExample.CodeID,
Msg: []byte(fmt.Sprintf(`{"payout": "%s"}`, myAddress)),
},
},
"execute": {
legacyContent: &types.ExecuteContractProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Contract: reflectExample.Contract.String(),
RunAs: reflectExample.CreatorAddr.String(),
Msg: must(json.Marshal(testdata.ReflectHandleMsg{
Reflect: &testdata.ReflectPayload{
Msgs: []wasmvmtypes.CosmosMsg{{
Bank: &wasmvmtypes.BankMsg{
Send: &wasmvmtypes.SendMsg{
ToAddress: myAddress.String(),
Amount: []wasmvmtypes.Coin{{Denom: "denom", Amount: "100"}},
},
},
}},
},
})),
},
},
"sudo": {
&types.SudoContractProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Contract: hackatomExample.Contract.String(),
Msg: stealMsgBz,
},
},
"update admin": {
legacyContent: &types.UpdateAdminProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Contract: reflectExample.Contract.String(),
NewAdmin: myAddress.String(),
},
},
"clear admin": {
legacyContent: &types.ClearAdminProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
Contract: reflectExample.Contract.String(),
},
},
"pin codes": {
legacyContent: &types.PinCodesProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
CodeIDs: []uint64{reflectExample.CodeID},
},
},
"unpin codes": {
legacyContent: &types.UnpinCodesProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
CodeIDs: []uint64{reflectExample.CodeID},
},
},
"update instantiate config": {
legacyContent: &types.UpdateInstantiateConfigProposal{ //nolint:staticcheck
Title: "Foo",
Description: "Bar",
AccessConfigUpdates: []types.AccessConfigUpdate{
{CodeID: reflectExample.CodeID, InstantiatePermission: types.AllowNobody},
},
},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
ctx, _ := pCtx.CacheContext()
propID := mustSubmitAndExecuteLegacyProposal(t, ctx, spec.legacyContent, myAddress.String(), keepers)
// when
proposal, err := keepers.GovKeeper.Proposals.Get(ctx, propID)
// then
require.NoError(t, err)
require.Len(t, proposal.Messages, 1)
assert.NotNil(t, proposal.Messages[0].GetCachedValue())
})
}
}
func mustSubmitAndExecuteLegacyProposal(t *testing.T, ctx sdk.Context, content v1beta1.Content, myActorAddress string, keepers keeper.TestKeepers) uint64 {
t.Helper()
govAuthority := keepers.AccountKeeper.GetModuleAddress(govtypes.ModuleName).String()
msgServer := govkeeper.NewMsgServerImpl(keepers.GovKeeper)
// ignore all submit events
contentMsg, rsp, err := submitLegacyProposal(t, ctx.WithEventManager(sdk.NewEventManager()), content, myActorAddress, govAuthority, msgServer)
require.NoError(t, err)
_, err = msgServer.ExecLegacyContent(ctx, v1.NewMsgExecLegacyContent(contentMsg.Content, govAuthority))
require.NoError(t, err)
return rsp.ProposalId
}
// does not fail on submit proposal
func submitLegacyProposal(t *testing.T, ctx sdk.Context, content v1beta1.Content, myActorAddress, govAuthority string, msgServer v1.MsgServer) (*v1.MsgExecLegacyContent, *v1.MsgSubmitProposalResponse, error) {
t.Helper()
contentMsg, err := v1.NewLegacyContent(content, govAuthority)
require.NoError(t, err)
proposal, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{contentMsg},
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewIntFromUint64(1_000_000))),
myActorAddress,
"",
content.GetTitle(),
content.GetDescription(),
false,
)
require.NoError(t, err)
// when stored
rsp, err := msgServer.SubmitProposal(ctx, proposal)
return contentMsg, rsp, err
}