Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] remove readvm-pool feature #601

Merged
merged 6 commits into from
Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## [unreleased]

### Improvements
- [\#593](https://github.com/terra-money/core/pull/588) revert jemalloc integration from wasmvm & add troubleshoot section to docs
- [\#601](https://github.com/terra-money/core/pull/601) revert readvm-pool feature
- [\#593](https://github.com/terra-money/core/pull/593) revert jemalloc integration from wasmvm & add troubleshoot section to docs

## [v0.5.9]

Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ require (
github.com/stretchr/testify v1.7.0
github.com/tendermint/tendermint v0.34.13
github.com/tendermint/tm-db v0.6.4
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c
google.golang.org/grpc v1.40.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
42 changes: 12 additions & 30 deletions x/wasm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import (

// config default values
const (
DefaultContractQueryGasLimit = uint64(3000000)
DefaultContractDebugMode = false
DefaultWriteVMMemoryCacheSize = uint32(500)
DefaultReadVMMemoryCacheSize = uint32(300)
DefaultNumReadVM = uint32(1)
DefaultContractQueryGasLimit = uint64(3000000)
DefaultContractDebugMode = false
DefaultContractMemoryCacheSize = uint32(100)
)

// DBDir used to store wasm data to
Expand All @@ -28,35 +26,25 @@ type Config struct {
// The flag to specify whether print contract logs or not
ContractDebugMode bool `mapstructure:"contract-debug-mode"`

// The write WASM VM memory cache size in MiB not bytes
WriteVMMemoryCacheSize uint32 `mapstructure:"write-vm-memory-cache-size"`

// The read WASM VM memory cache size in MiB not bytes
ReadVMMemoryCacheSize uint32 `mapstructure:"read-vm-memory-cache-size"`

// The number of read WASM VMs
NumReadVMs uint32 `mapstructure:"num-read-vms"`
// The WASM VM memory cache size in MiB not bytes
ContractMemoryCacheSize uint32 `mapstructure:"contract-memory-cache-size"`
}

// DefaultConfig returns the default settings for WasmConfig
func DefaultConfig() *Config {
return &Config{
ContractQueryGasLimit: DefaultContractQueryGasLimit,
ContractDebugMode: DefaultContractDebugMode,
WriteVMMemoryCacheSize: DefaultWriteVMMemoryCacheSize,
ReadVMMemoryCacheSize: DefaultReadVMMemoryCacheSize,
NumReadVMs: DefaultNumReadVM,
ContractQueryGasLimit: DefaultContractQueryGasLimit,
ContractDebugMode: DefaultContractDebugMode,
ContractMemoryCacheSize: DefaultContractMemoryCacheSize,
}
}

// GetConfig load config values from the app options
func GetConfig(appOpts servertypes.AppOptions) *Config {
return &Config{
ContractQueryGasLimit: cast.ToUint64(appOpts.Get("wasm.contract-query-gas-limit")),
ContractDebugMode: cast.ToBool(appOpts.Get("wasm.contract-debug-mode")),
WriteVMMemoryCacheSize: cast.ToUint32(appOpts.Get("wasm.write-vm-memory-cache-size")),
ReadVMMemoryCacheSize: cast.ToUint32(appOpts.Get("wasm.read-vm-memory-cache-size")),
NumReadVMs: cast.ToUint32(appOpts.Get("wasm.num-read-vms")),
ContractQueryGasLimit: cast.ToUint64(appOpts.Get("wasm.contract-query-gas-limit")),
ContractDebugMode: cast.ToBool(appOpts.Get("wasm.contract-debug-mode")),
ContractMemoryCacheSize: cast.ToUint32(appOpts.Get("wasm.contract-memory-cache-size")),
}
}

Expand All @@ -72,11 +60,5 @@ contract-query-gas-limit = "{{ .WASMConfig.ContractQueryGasLimit }}"
contract-debug-mode = "{{ .WASMConfig.ContractDebugMode }}"

# The write WASM VM memory cache size in MiB not bytes
yun-yeo marked this conversation as resolved.
Show resolved Hide resolved
write-vm-memory-cache-size = "{{ .WASMConfig.WriteVMMemoryCacheSize }}"

# The read WASM VM memory cache size in MiB not bytes
read-vm-memory-cache-size = "{{ .WASMConfig.ReadVMMemoryCacheSize }}"

# The number of read WASM VMs
num-read-vms = "{{ .WASMConfig.NumReadVMs }}"
write-vm-memory-cache-size = "{{ .WASMConfig.ContractMemoryCacheSize }}"
yun-yeo marked this conversation as resolved.
Show resolved Hide resolved
`
35 changes: 23 additions & 12 deletions x/wasm/keeper/contract.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"context"
"time"

wasmvmtypes "github.com/CosmWasm/wasmvm/types"
Expand Down Expand Up @@ -415,6 +416,21 @@ func (k Keeper) queryToStore(ctx sdk.Context, contractAddress sdk.AccAddress, ke
return prefixStore.Get(key)
}

func assertQueryDepth(ctx sdk.Context) (uint8, error) {
var queryDepth uint8
if depth := ctx.Context().Value(types.WasmVMQueryDepthContextKey); depth != nil {
queryDepth = depth.(uint8)
} else {
queryDepth = 1
}

if queryDepth > types.ContractMaxQueryDepth {
yun-yeo marked this conversation as resolved.
Show resolved Hide resolved
return queryDepth, types.ErrExceedMaxQueryDepth
}

return queryDepth, nil
}

func (k Keeper) queryToContract(ctx sdk.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) {
defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-smart")
ctx.GasMeter().ConsumeGas(types.InstantiateContractCosts(len(queryMsg)), "Loading CosmWasm module: query")
Expand All @@ -426,21 +442,16 @@ func (k Keeper) queryToContract(ctx sdk.Context, contractAddress sdk.AccAddress,

env := types.NewEnv(ctx, contractAddress)

// when the vm is given, use that given vm
var wasmVM types.WasmerEngine
if vm := ctx.Context().Value(types.QueryWasmVMContextKey); vm != nil {
wasmVM = vm.(types.WasmerEngine)
} else {
wasmVM = k.wasmVM
}

// assert max depth to prevent stack overflow
if err := wasmVM.IncreaseQueryDepth(); err != nil {
// assert query depth and set new query depth for the next query
queryDepth, err := assertQueryDepth(ctx)
if err != nil {
return nil, err
}
defer wasmVM.DecreaseQueryDepth()

queryResult, gasUsed, err := wasmVM.Query(
// set next query depth
ctx = ctx.WithContext(context.WithValue(ctx.Context(), types.WasmVMQueryDepthContextKey, queryDepth+1))

queryResult, gasUsed, err := k.wasmVM.Query(
codeInfo.CodeHash,
env,
queryMsg,
Expand Down
75 changes: 20 additions & 55 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import (
"encoding/binary"
"fmt"
"path/filepath"
"sync"

"github.com/tendermint/tendermint/libs/log"
"golang.org/x/sync/semaphore"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
Expand All @@ -34,10 +32,7 @@ type Keeper struct {
serviceRouter types.MsgServiceRouter
queryRouter types.GRPCQueryRouter

wasmVM types.WasmerEngine
wasmReadVMPool *[]types.WasmerEngine
wasmReadVMSemaphore *semaphore.Weighted
wasmReadVMMutex *sync.Mutex
wasmVM types.WasmerEngine

querier types.Querier
msgParser types.MsgParser
Expand Down Expand Up @@ -66,65 +61,35 @@ func NewKeeper(
}

// prevent zero write vm cache
if wasmConfig.WriteVMMemoryCacheSize == 0 {
wasmConfig.WriteVMMemoryCacheSize = config.DefaultWriteVMMemoryCacheSize
if wasmConfig.ContractMemoryCacheSize == 0 {
wasmConfig.ContractMemoryCacheSize = config.DefaultContractMemoryCacheSize
}

var writeWasmVM types.WasmerEngine
if vm, err := wasmvm.NewVM(
vm, err := wasmvm.NewVM(
filepath.Join(homePath, config.DBDir),
supportedFeatures,
types.ContractMemoryLimit,
wasmConfig.ContractDebugMode,
wasmConfig.WriteVMMemoryCacheSize,
); err != nil {
panic(err)
} else {
writeWasmVM = types.NewWasmerEngineWithQueryDepth(vm)
}
wasmConfig.ContractMemoryCacheSize,
)

// prevent zero read vm
if wasmConfig.NumReadVMs == 0 {
wasmConfig.NumReadVMs = config.DefaultNumReadVM
}

// prevent zero read vm cache
if wasmConfig.ReadVMMemoryCacheSize == 0 {
wasmConfig.ReadVMMemoryCacheSize = config.DefaultReadVMMemoryCacheSize
}

numReadVms := wasmConfig.NumReadVMs
wasmReadVMPool := make([]types.WasmerEngine, numReadVms)
for i := uint32(0); i < numReadVms; i++ {
if vm, err := wasmvm.NewVM(
filepath.Join(homePath, config.DBDir),
supportedFeatures,
types.ContractMemoryLimit,
wasmConfig.ContractDebugMode,
wasmConfig.ReadVMMemoryCacheSize,
); err != nil {
panic(err)
} else {
wasmReadVMPool[i] = types.NewWasmerEngineWithQueryDepth(vm)
}
if err != nil {
panic(err)
}

return Keeper{
storeKey: storeKey,
cdc: cdc,
paramSpace: paramspace,
wasmVM: writeWasmVM,
wasmReadVMPool: &wasmReadVMPool,
wasmReadVMSemaphore: semaphore.NewWeighted(int64(numReadVms)),
wasmReadVMMutex: &sync.Mutex{},
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
treasuryKeeper: treasuryKeeper,
serviceRouter: serviceRouter,
queryRouter: queryRouter,
wasmConfig: wasmConfig,
msgParser: types.NewWasmMsgParser(),
querier: types.NewWasmQuerier(),
storeKey: storeKey,
cdc: cdc,
paramSpace: paramspace,
wasmVM: vm,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
treasuryKeeper: treasuryKeeper,
serviceRouter: serviceRouter,
queryRouter: queryRouter,
wasmConfig: wasmConfig,
msgParser: types.NewWasmMsgParser(),
querier: types.NewWasmQuerier(),
}
}

Expand Down
10 changes: 0 additions & 10 deletions x/wasm/keeper/legacy_querier.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package keeper

import (
"context"
"fmt"
"runtime/debug"

Expand Down Expand Up @@ -117,15 +116,8 @@ func queryContractStore(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacy
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}

wasmVM, err := k.acquireWasmVM(sdk.WrapSDKContext(ctx))
if err != nil {
return nil, sdkerrors.Wrap(types.ErrContractQueryFailed, err.Error())
}

// recover from out-of-gas panic
defer func() {
k.releaseWasmVM(wasmVM)

if r := recover(); r != nil {
switch rType := r.(type) {
case sdk.ErrorOutOfGas:
Expand All @@ -148,8 +140,6 @@ func queryContractStore(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacy
}
}()

// store query wasmvm in the context
ctx = ctx.WithContext(context.WithValue(ctx.Context(), types.QueryWasmVMContextKey, wasmVM))
bz, err = k.queryToContract(ctx, params.ContractAddress, params.Msg)

return
Expand Down
29 changes: 0 additions & 29 deletions x/wasm/keeper/pool.go

This file was deleted.

8 changes: 0 additions & 8 deletions x/wasm/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,8 @@ func (q querier) ContractStore(c context.Context, req *types.QueryContractStoreR
return nil, status.Error(codes.InvalidArgument, err.Error())
}

wasmVM, err := q.acquireWasmVM(c)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

// recover from out-of-gas panic
defer func() {
q.releaseWasmVM(wasmVM)

if r := recover(); r != nil {
switch rType := r.(type) {
Expand All @@ -120,8 +114,6 @@ func (q querier) ContractStore(c context.Context, req *types.QueryContractStoreR
}
}()

// store query wasmvm in the context
ctx = ctx.WithContext(context.WithValue(ctx.Context(), types.QueryWasmVMContextKey, wasmVM))
bz, err := q.queryToContract(ctx, contractAddr, req.QueryMsg)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
Expand Down
9 changes: 1 addition & 8 deletions x/wasm/keeper/recursive_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package keeper

import (
"context"
"encoding/json"
"io/ioutil"
"testing"
Expand Down Expand Up @@ -346,19 +345,13 @@ func TestLimitRecursiveQueryGas(t *testing.T) {

func TestLimitRecursiveQueryDepth(t *testing.T) {
contractAddr, _, ctx, keeper, _ := initRecurseContract(t)
// pick query wasmvm
wasmvm, err := keeper.acquireWasmVM(ctx.Context())
require.NoError(t, err)
defer keeper.releaseWasmVM(wasmvm)

ctx = ctx.WithContext(context.WithValue(ctx.Context(), types.QueryWasmVMContextKey, wasmvm))

// exceed max query depth
msg := buildQuery(t, Recurse{
Depth: types.ContractMaxQueryDepth,
})

_, err = keeper.queryToContract(ctx, contractAddr, msg)
_, err := keeper.queryToContract(ctx, contractAddr, msg)
require.Error(t, err)

msg = buildQuery(t, Recurse{
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const (
// RouterKey is the msg router key for the wasm module
RouterKey = ModuleName

// QueryWasmVMContextKey is the context key to store wasmvm in query context
QueryWasmVMContextKey = "wasmvm"
// WasmVMQueryDepthContextKey context key to keep query depth
WasmVMQueryDepthContextKey = "wasmvm-query-depth"
)

// Keys for wasm store
Expand Down
Loading