Skip to content

Commit

Permalink
Merge pull request #272 from CosmWasm/update-cosmwasm-0.11
Browse files Browse the repository at this point in the history
Update to cosmwasm 0.11
  • Loading branch information
ethanfrey authored Oct 5, 2020
2 parents 7551217 + 989830e commit 2d9bd47
Show file tree
Hide file tree
Showing 23 changed files with 138 additions and 82 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd
go 1.14

require (
github.com/CosmWasm/go-cosmwasm v0.10.0
github.com/CosmWasm/go-cosmwasm v0.11.0-alpha2
github.com/cosmos/cosmos-sdk v0.39.1-0.20200727135228-9d00f712e334
github.com/golang/mock v1.4.3 // indirect
github.com/google/gofuzz v1.0.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQ
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/CosmWasm/go-cosmwasm v0.10.0 h1:3DBOiGtLllevLgf8PQO5+hRCKKqYEQJIw6cgaZzr1Ag=
github.com/CosmWasm/go-cosmwasm v0.10.0/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/CosmWasm/go-cosmwasm v0.11.0-alpha1 h1:5c87JcnA+ncQlSJO/mEK6z9oIi/oS46CCsYduvRgPvw=
github.com/CosmWasm/go-cosmwasm v0.11.0-alpha1/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/CosmWasm/go-cosmwasm v0.11.0-alpha2 h1:w42GtYC4P/6dXOVlqEutr96tSsy/EO0aC9d3sbkk5hs=
github.com/CosmWasm/go-cosmwasm v0.11.0-alpha2/go.mod h1:gAFCwllx97ejI+m9SqJQrmd2SBW7HA0fOjvWWJjM2uc=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
Expand Down
2 changes: 1 addition & 1 deletion lcd_test/wasm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestWasmStoreCode(t *testing.T) {
require.NoError(t, err)
defer cleanup()

wasmCode, err := ioutil.ReadFile("../x/wasm/internal/keeper/testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("../x/wasm/internal/keeper/testdata/hackatom.wasm")
require.NoError(t, err)

var (
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/client/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

func GetTestData() ([]byte, []byte, []byte, error) {
wasmCode, err := ioutil.ReadFile("../../internal/keeper/testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("../../internal/keeper/testdata/hackatom.wasm")

if err != nil {
return nil, nil, nil, err
Expand Down
6 changes: 3 additions & 3 deletions x/wasm/internal/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
func TestGenesisExportImport(t *testing.T) {
srcKeeper, srcCtx, srcStoreKeys, srcCleanup := setupKeeper(t)
defer srcCleanup()
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

// store some test data
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestGenesisExportImport(t *testing.T) {
}

func TestFailFastImport(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

myCodeInfo := wasmTypes.CodeInfoFixture(wasmTypes.WithSHA256CodeHash(wasmCode))
Expand Down Expand Up @@ -402,7 +402,7 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) {
keeper, ctx, _, dstCleanup := setupKeeper(t)
defer dstCleanup()

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

wasmCodeHash := sha256.Sum256(wasmCode)
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/internal/keeper/ioutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (
)

func TestUncompress(t *testing.T) {
wasmRaw, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmRaw, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

wasmGzipped, err := ioutil.ReadFile("./testdata/contract.wasm.gzip")
wasmGzipped, err := ioutil.ReadFile("./testdata/hackatom.wasm.gzip")
require.NoError(t, err)

specs := map[string]struct {
Expand Down
27 changes: 16 additions & 11 deletions x/wasm/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type Keeper struct {
func NewKeeper(cdc *codec.Codec, storeKey sdk.StoreKey, paramSpace params.Subspace, accountKeeper auth.AccountKeeper, bankKeeper bank.Keeper,
stakingKeeper staking.Keeper,
router sdk.Router, homeDir string, wasmConfig types.WasmConfig, supportedFeatures string, customEncoders *MessageEncoders, customPlugins *QueryPlugins) Keeper {
wasmer, err := wasm.NewWasmer(filepath.Join(homeDir, "wasm"), supportedFeatures, wasmConfig.CacheSize)
wasmer, err := wasm.NewWasmer(filepath.Join(homeDir, "wasm"), supportedFeatures)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -212,7 +212,8 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A
}

// prepare params for contract instantiate call
params := types.NewEnv(ctx, creator, deposit, contractAddress)
env := types.NewEnv(ctx, contractAddress)
info := types.NewInfo(creator, deposit)

// create prefixed data store
// 0x03 | contractAddress (sdk.AccAddress)
Expand All @@ -227,14 +228,14 @@ func (k Keeper) instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A

// instantiate wasm contract
gas := gasForContract(ctx)
res, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, params, initMsg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas)
res, gasUsed, err := k.wasmer.Instantiate(codeInfo.CodeHash, env, info, initMsg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas)
consumeGas(ctx, gasUsed)
if err != nil {
return contractAddress, sdkerrors.Wrap(types.ErrInstantiateFailed, err.Error())
}

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

err = k.dispatchMessages(ctx, contractAddress, res.Messages)
Expand Down Expand Up @@ -271,7 +272,8 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
}
}

params := types.NewEnv(ctx, caller, coins, contractAddress)
env := types.NewEnv(ctx, contractAddress)
info := types.NewInfo(caller, coins)

// prepare querier
querier := QueryHandler{
Expand All @@ -280,14 +282,14 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
}

gas := gasForContract(ctx)
res, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, params, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gas)
res, gasUsed, execErr := k.wasmer.Execute(codeInfo.CodeHash, env, info, msg, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), 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)
events := types.ParseEvents(res.Attributes, contractAddress)
ctx.EventManager().EmitEvents(events)

err = k.dispatchMessages(ctx, contractAddress, res.Messages)
Expand Down Expand Up @@ -322,7 +324,8 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller
}

var noDeposit sdk.Coins
params := types.NewEnv(ctx, caller, noDeposit, contractAddress)
env := types.NewEnv(ctx, contractAddress)
info := types.NewInfo(caller, noDeposit)

// prepare querier
querier := QueryHandler{
Expand All @@ -333,14 +336,14 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller
prefixStoreKey := types.GetContractStorePrefixKey(contractAddress)
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey)
gas := gasForContract(ctx)
res, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, params, msg, &prefixStore, cosmwasmAPI, &querier, gasMeter(ctx), gas)
res, gasUsed, err := k.wasmer.Migrate(newCodeInfo.CodeHash, env, info, msg, &prefixStore, cosmwasmAPI, &querier, gasMeter(ctx), gas)
consumeGas(ctx, gasUsed)
if err != nil {
return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error())
}

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

historyEntry := contractInfo.AddMigration(ctx, newCodeID, msg)
Expand Down Expand Up @@ -408,7 +411,9 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b
Ctx: ctx,
Plugins: k.queryPlugins,
}
queryResult, gasUsed, qErr := k.wasmer.Query(codeInfo.CodeHash, req, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gasForContract(ctx))

env := types.NewEnv(ctx, contractAddr)
queryResult, gasUsed, qErr := k.wasmer.Query(codeInfo.CodeHash, env, req, prefixStore, cosmwasmAPI, querier, gasMeter(ctx), gasForContract(ctx))
consumeGas(ctx, gasUsed)
if qErr != nil {
return nil, sdkerrors.Wrap(types.ErrQueryFailed, qErr.Error())
Expand Down
48 changes: 26 additions & 22 deletions x/wasm/internal/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"encoding/json"
"errors"
"io/ioutil"
"os"
"testing"
Expand Down Expand Up @@ -42,7 +43,7 @@ func TestCreate(t *testing.T) {
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "any/builder:tag", nil)
Expand All @@ -55,7 +56,7 @@ func TestCreate(t *testing.T) {
}

func TestCreateStoresInstantiatePermission(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)
var (
deposit = sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
Expand Down Expand Up @@ -118,7 +119,7 @@ func TestCreateWithParamPermissions(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit)
otherAddr := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

specs := map[string]struct {
Expand Down Expand Up @@ -167,7 +168,7 @@ func TestCreateDuplicate(t *testing.T) {
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

// create one copy
Expand Down Expand Up @@ -202,7 +203,7 @@ func TestCreateWithSimulation(t *testing.T) {
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

// create this once in simulation mode
Expand Down Expand Up @@ -258,7 +259,7 @@ func TestCreateWithGzippedPayload(t *testing.T) {
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm.gzip")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm.gzip")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "", nil)
Expand All @@ -267,7 +268,7 @@ func TestCreateWithGzippedPayload(t *testing.T) {
// and verify content
storedCode, err := keeper.GetByteCode(ctx, contractID)
require.NoError(t, err)
rawCode, err := ioutil.ReadFile("./testdata/contract.wasm")
rawCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)
require.Equal(t, rawCode, storedCode)
}
Expand All @@ -282,7 +283,7 @@ func TestInstantiate(t *testing.T) {
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := createFakeFundedAccount(ctx, accKeeper, deposit)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

codeID, err := keeper.Create(ctx, creator, wasmCode, "https://github.com/CosmWasm/wasmd/blob/master/x/wasm/testdata/escrow.wasm", "", nil)
Expand All @@ -306,7 +307,7 @@ func TestInstantiate(t *testing.T) {
require.Equal(t, "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", contractAddr.String())

gasAfter := ctx.GasMeter().GasConsumed()
require.Equal(t, uint64(0x10c43), gasAfter-gasBefore)
require.Equal(t, uint64(0x10c50), gasAfter-gasBefore)

// ensure it is stored properly
info := keeper.GetContractInfo(ctx, contractAddr)
Expand All @@ -325,7 +326,7 @@ func TestInstantiate(t *testing.T) {
}

func TestInstantiateWithDeposit(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

var (
Expand Down Expand Up @@ -387,7 +388,7 @@ func TestInstantiateWithDeposit(t *testing.T) {
}

func TestInstantiateWithPermissions(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

var (
Expand Down Expand Up @@ -484,7 +485,7 @@ func TestExecute(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down Expand Up @@ -521,7 +522,8 @@ func TestExecute(t *testing.T) {
trialCtx := ctx.WithMultiStore(ctx.MultiStore().CacheWrap().(sdk.MultiStore))
res, err := keeper.Execute(trialCtx, addr, creator, []byte(`{"release":{}}`), nil)
require.Error(t, err)
require.Contains(t, err.Error(), "unauthorized")
require.True(t, errors.Is(err, types.ErrExecuteFailed))
require.Equal(t, err.Error(), "execute wasm contract failed: Unauthorized")

// verifier can execute, and get proper gas amount
start := time.Now()
Expand All @@ -534,7 +536,7 @@ func TestExecute(t *testing.T) {

// make sure gas is properly deducted from ctx
gasAfter := ctx.GasMeter().GasConsumed()
require.Equal(t, uint64(0x11617), gasAfter-gasBefore)
require.Equal(t, uint64(0x11615), gasAfter-gasBefore)

// ensure bob now exists and got both payments released
bobAcct = accKeeper.GetAccount(ctx, bob)
Expand All @@ -551,7 +553,7 @@ func TestExecute(t *testing.T) {
}

func TestExecuteWithDeposit(t *testing.T) {
wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

var (
Expand Down Expand Up @@ -654,7 +656,7 @@ func TestExecuteWithPanic(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand All @@ -674,6 +676,8 @@ func TestExecuteWithPanic(t *testing.T) {
// let's make sure we get a reasonable error, no panic/crash
_, err = keeper.Execute(ctx, addr, fred, []byte(`{"panic":{}}`), topUp)
require.Error(t, err)
require.True(t, errors.Is(err, types.ErrExecuteFailed))
require.Equal(t, err.Error(), "execute wasm contract failed: Out of gas")
}

func TestExecuteWithCpuLoop(t *testing.T) {
Expand All @@ -688,7 +692,7 @@ func TestExecuteWithCpuLoop(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down Expand Up @@ -736,7 +740,7 @@ func TestExecuteWithStorageLoop(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

contractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down Expand Up @@ -782,7 +786,7 @@ func TestMigrate(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)))

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

originalCodeID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down Expand Up @@ -926,7 +930,7 @@ func TestMigrateWithDispatchedMessage(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)))

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)
burnerCode, err := ioutil.ReadFile("./testdata/burner.wasm")
require.NoError(t, err)
Expand Down Expand Up @@ -1039,7 +1043,7 @@ func TestUpdateContractAdmin(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

originalContractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down Expand Up @@ -1114,7 +1118,7 @@ func TestClearContractAdmin(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, deposit.Add(deposit...))
fred := createFakeFundedAccount(ctx, accKeeper, topUp)

wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm")
wasmCode, err := ioutil.ReadFile("./testdata/hackatom.wasm")
require.NoError(t, err)

originalContractID, err := keeper.Create(ctx, creator, wasmCode, "", "", nil)
Expand Down
Loading

0 comments on commit 2d9bd47

Please sign in to comment.