Skip to content

Commit

Permalink
[Feature] remove readvm-pool feature (#601)
Browse files Browse the repository at this point in the history
* remove readvm-pool feature
* change query depth implementation to use context instead wasmvm to store depth
  • Loading branch information
yys authored Nov 1, 2021
1 parent 3fcaa62 commit deae71c
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 196 deletions.
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
44 changes: 13 additions & 31 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 @@ -71,12 +59,6 @@ contract-query-gas-limit = "{{ .WASMConfig.ContractQueryGasLimit }}"
# The flag to specify whether print contract logs or not
contract-debug-mode = "{{ .WASMConfig.ContractDebugMode }}"
# The write WASM VM memory cache size in MiB not bytes
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 }}"
# The WASM VM memory cache size in MiB not bytes
contract-memory-cache-size = "{{ .WASMConfig.ContractMemoryCacheSize }}"
`
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 @@ -426,21 +427,13 @@ 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 and increase query depth
ctx, err = assertAndIncreaseQueryDepth(ctx)
if err != nil {
return nil, err
}
defer wasmVM.DecreaseQueryDepth()

queryResult, gasUsed, err := wasmVM.Query(
queryResult, gasUsed, err := k.wasmVM.Query(
codeInfo.CodeHash,
env,
queryMsg,
Expand All @@ -461,6 +454,24 @@ func (k Keeper) queryToContract(ctx sdk.Context, contractAddress sdk.AccAddress,
return queryResult, err
}

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

if queryDepth > types.ContractMaxQueryDepth {
return ctx, types.ErrExceedMaxQueryDepth
}

// set next query depth
ctx = ctx.WithContext(context.WithValue(ctx.Context(), types.WasmVMQueryDepthContextKey, queryDepth+1))

return ctx, nil
}

func (k Keeper) getContractDetails(ctx sdk.Context, contractAddress sdk.AccAddress) (codeInfo types.CodeInfo, contractStorePrefix prefix.Store, err error) {
store := ctx.KVStore(k.storeKey)

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

0 comments on commit deae71c

Please sign in to comment.