Skip to content

Commit

Permalink
wasm40 upgrade (#211)
Browse files Browse the repository at this point in the history
* add gas table (#201)

* add gas table

* change depend wasmvm

* upgrade wasmvm (#199)

* update

* update

* update

* wasm create contract (#200)

* wasm create contract

* fix merge error

* Update go.mod

* wasmvm cross call (#203)

* add wasm cross call

* merge

* fix merge error (#204)

* update gomod (#205)

* support the initance for delcall (#207)

* add venus7 for wasm upgrade (#210)

* add venus7 for wasm upgrade

* update go.mod

* update go.mod

* upgrade go mod wasmvm version

* fix ut

---------

Co-authored-by: chengzhinei <[email protected]>
Co-authored-by: JianGuo <[email protected]>
Co-authored-by: ylsGit <[email protected]>
  • Loading branch information
4 people authored Aug 28, 2023
1 parent cecd23d commit bcdc8ed
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 68 deletions.
5 changes: 5 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ func NewOKBChainApp(
}
app.InitUpgrade(ctx)
app.WasmKeeper.UpdateGasRegister(ctx)
app.WasmKeeper.UpdateCurBlockNum(ctx)
}

app.ScopedIBCKeeper = scopedIBCKeeper
Expand All @@ -745,6 +746,10 @@ func (app *OKBChainApp) InitUpgrade(ctx sdk.Context) {
app.ParamsKeeper.ClaimReadyForUpgrade(tmtypes.MILESTONE_MERCURY, func(info paramstypes.UpgradeInfo) {
tmtypes.InitMilestoneMercuryHeight(int64(info.EffectiveHeight))
})
app.ParamsKeeper.ClaimReadyForUpgrade(tmtypes.MILESTONE_VENUS7_NAME, func(info paramstypes.UpgradeInfo) {
tmtypes.InitMilestoneVenus7Height(int64(info.EffectiveHeight))
app.WasmKeeper.UpdateMilestone(ctx, "wasm_v1", info.EffectiveHeight)
})
if err := app.ParamsKeeper.ApplyEffectiveUpgrade(ctx); err != nil {
tmos.Exit(fmt.Sprintf("failed apply effective upgrade height info: %s", err))
}
Expand Down
12 changes: 3 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/99designs/keyring v1.1.6
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d
github.com/CosmWasm/wasmvm v1.0.0
github.com/CosmWasm/wasmvm v1.3.0
github.com/VictoriaMetrics/fastcache v1.8.0
github.com/Workiva/go-datastructures v1.0.53
github.com/alicebob/miniredis/v2 v2.17.0
Expand Down Expand Up @@ -73,12 +73,11 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.12.0
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48
github.com/stretchr/testify v1.8.0
github.com/stretchr/testify v1.8.1
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tendermint/btcd v0.1.1
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15
github.com/tendermint/go-amino v0.16.0
github.com/tendermint/tm-db v0.6.7
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
github.com/valyala/fastjson v1.6.3
go.etcd.io/bbolt v1.3.6
Expand All @@ -95,7 +94,6 @@ require (
)

require (
github.com/DataDog/zstd v1.4.1 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect
Expand All @@ -104,18 +102,13 @@ require (
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/danieljoos/wincred v1.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/go-kit/log v0.2.0 // indirect
Expand Down Expand Up @@ -179,6 +172,7 @@ require (
)

replace (
github.com/CosmWasm/wasmvm => github.com/okx/wasmvm v1.3.5
github.com/buger/jsonparser => github.com/buger/jsonparser v1.0.0 // imported by nacos-go-sdk, upgraded to v1.0.0 in case of a known vulnerable bug
github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
github.com/cosmos/gorocksdb => github.com/okx/grocksdb v1.6.45-okc2
Expand Down
42 changes: 6 additions & 36 deletions go.sum

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions libs/cosmos-sdk/types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type Context struct {
statedb vm.StateDB
outOfGas bool
wasmSimulateCache map[string][]byte
wasmCallDepth uint32
}

// Proposed rename, not done to avoid API breakage
Expand Down Expand Up @@ -232,6 +233,18 @@ func (c *Context) MoveWasmSimulateCacheToPool() {
putBackWasmCacheMap(c.wasmSimulateCache)
}

func (c *Context) IncrementCallDepth() {
c.wasmCallDepth++
}

func (c *Context) DecrementCallDepth() {
c.wasmCallDepth--
}

func (c *Context) CallDepth() uint32 {
return c.wasmCallDepth
}

// TODO: remove???
func (c *Context) IsZero() bool {
return c.ms == nil
Expand Down
23 changes: 23 additions & 0 deletions libs/tendermint/types/milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var (
milestoneEarthHeight int64
milestoneVenus4Height int64
milestoneMercuryHeight int64
milestoneVenus7Height int64

// note: it stores the earlies height of the node,and it is used by cli
nodePruneHeight int64
Expand All @@ -26,6 +27,8 @@ const (
MILESTONE_EARTH = "earth"
MILESTONE_Venus4 = "venus4"
MILESTONE_MERCURY = "mercury"

MILESTONE_VENUS7_NAME = "venus7"
)

func SetupMainNetEnvironment(pruneH int64) {
Expand Down Expand Up @@ -139,3 +142,23 @@ func InitMilestoneMercuryHeight(h int64) {

// =========== Mercury ===============
// ==================================

// ==================================
// =========== Venus7 ===============
func HigherThanVenus7(h int64) bool {
if milestoneVenus7Height == 0 {
return false
}
return h > milestoneVenus7Height
}

func InitMilestoneVenus7Height(h int64) {
milestoneVenus7Height = h
}

func GetVenus7Height() int64 {
return milestoneVenus7Height
}

// =========== Venus7 ===============
// ==================================
42 changes: 42 additions & 0 deletions x/wasm/keeper/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
wasmvm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/okx/okbchain/libs/cosmos-sdk/types"
sdkerrors "github.com/okx/okbchain/libs/cosmos-sdk/types/errors"
"github.com/okx/okbchain/x/wasm/types"
"strconv"
)

const (
Expand All @@ -14,6 +17,8 @@ const (

// DefaultDeserializationCostPerByte The formular should be `len(data) * deserializationCostPerByte`
DefaultDeserializationCostPerByte = 1

CallCreateDepth = 20
)

var (
Expand Down Expand Up @@ -41,3 +46,40 @@ var cosmwasmAPI = wasmvm.GoAPI{
HumanAddress: humanAddress,
CanonicalAddress: canonicalAddress,
}

func contractExternal(ctx sdk.Context, k Keeper) func(request wasmvmtypes.ContractCreateRequest, gasLimit uint64) (string, uint64, error) {
return func(request wasmvmtypes.ContractCreateRequest, gasLimit uint64) (string, uint64, error) {
ctx.IncrementCallDepth()
if ctx.CallDepth() >= CallCreateDepth {
return "", 0, sdkerrors.Wrap(types.ErrExceedCallDepth, strconv.Itoa(int(ctx.CallDepth())))
}

gasMeter := ctx.GasMeter()
ctx.SetGasMeter(sdk.NewGasMeter(k.gasRegister.FromWasmVMGas(gasLimit)))
gasBefore := ctx.GasMeter().GasConsumed()

defer func() {
ctx.DecrementCallDepth()

// reset gas meter
gasCost := ctx.GasMeter().GasConsumed() - gasBefore
ctx.SetGasMeter(gasMeter)
ctx.GasMeter().ConsumeGas(gasCost, "contract sub-create")
}()

creator, err := sdk.WasmAddressFromBech32(request.Creator)
if err != nil {
return "", 0, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.Creator)
}
admin, err := sdk.WasmAddressFromBech32(request.AdminAddr)
if err != nil {
return "", 0, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.AdminAddr)
}
addr, _, err := k.CreateByContract(ctx, creator, request.WasmCode, request.CodeID, request.InitMsg, admin, request.Label, request.IsCreate2, request.Salt, nil)
if err != nil {
return "", k.gasRegister.ToWasmVMGas(ctx.GasMeter().GasConsumed()) - gasBefore, err
}

return addr.String(), k.gasRegister.ToWasmVMGas(ctx.GasMeter().GasConsumed() - gasBefore), nil
}
}
9 changes: 5 additions & 4 deletions x/wasm/keeper/contract_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ var _ types.ContractOpsKeeper = PermissionedKeeper{}

// decoratedKeeper contains a subset of the wasm keeper that are already or can be guarded by an authorization policy in the future
type decoratedKeeper interface {
create(ctx sdk.Context, creator sdk.WasmAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, err error)
instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.WasmAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.WasmAddress, []byte, error)
create(ctx sdk.Context, creator sdk.WasmAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, codeHash []byte, err error)
instantiate(ctx sdk.Context, codeID uint64, creator, admin, contractAddress sdk.WasmAddress, initMsg []byte, label string, deposit sdk.Coins, authZ AuthorizationPolicy) (sdk.WasmAddress, []byte, error)
migrate(ctx sdk.Context, contractAddress sdk.WasmAddress, caller sdk.WasmAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) ([]byte, error)
setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.WasmAddress, authZ AuthorizationPolicy) error
pinCode(ctx sdk.Context, codeID uint64) error
Expand Down Expand Up @@ -47,11 +47,12 @@ func NewDefaultPermissionKeeper(nested decoratedKeeper) *PermissionedKeeper {
}

func (p PermissionedKeeper) Create(ctx sdk.Context, creator sdk.WasmAddress, wasmCode []byte, instantiateAccess *types.AccessConfig) (codeID uint64, err error) {
return p.nested.create(ctx, creator, wasmCode, instantiateAccess, p.authZPolicy)
codeID, _, err = p.nested.create(ctx, creator, wasmCode, instantiateAccess, p.authZPolicy)
return
}

func (p PermissionedKeeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.WasmAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.WasmAddress, []byte, error) {
return p.nested.instantiate(ctx, codeID, creator, admin, initMsg, label, deposit, p.authZPolicy)
return p.nested.instantiate(ctx, codeID, creator, admin, nil, initMsg, label, deposit, p.authZPolicy)
}

func (p PermissionedKeeper) Execute(ctx sdk.Context, contractAddress sdk.WasmAddress, caller sdk.WasmAddress, msg []byte, coins sdk.Coins) ([]byte, error) {
Expand Down
85 changes: 85 additions & 0 deletions x/wasm/keeper/cross_contract_call.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package keeper

import (
"encoding/json"
wasmvm "github.com/CosmWasm/wasmvm"
sdk "github.com/okx/okbchain/libs/cosmos-sdk/types"
"github.com/okx/okbchain/x/wasm/types"
)

var (
wasmCache wasmvm.Cache
)

func SetWasmCache(cache wasmvm.Cache) {
wasmCache = cache
}

func GetWasmCacheInfo() wasmvm.Cache {
return wasmCache
}

func getCallerInfoFunc(ctx sdk.Context, keeper Keeper) func(contractAddress, storeAddress string) ([]byte, uint64, wasmvm.KVStore, wasmvm.Querier, wasmvm.GasMeter, error) {
return func(contractAddress, storeAddress string) ([]byte, uint64, wasmvm.KVStore, wasmvm.Querier, wasmvm.GasMeter, error) {
gasBefore := ctx.GasMeter().GasConsumed()
codeHash, store, querier, gasMeter, err := getCallerInfo(ctx, keeper, contractAddress, storeAddress)
gasAfter := ctx.GasMeter().GasConsumed()
return codeHash, keeper.gasRegister.ToWasmVMGas(gasAfter - gasBefore), store, querier, gasMeter, err
}
}

func getCallerInfo(ctx sdk.Context, keeper Keeper, contractAddress, storeAddress string) ([]byte, wasmvm.KVStore, wasmvm.Querier, wasmvm.GasMeter, error) {
cAddr, err := sdk.WasmAddressFromBech32(contractAddress)
if err != nil {
return nil, nil, nil, nil, err
}
// 1. get wasm code from contractAddress
_, codeInfo, prefixStore, err := keeper.contractInstance(ctx, cAddr)
if err != nil {
return nil, nil, nil, nil, err
}
// 2. contractAddress == storeAddress and direct return
if contractAddress == storeAddress {
queryHandler := keeper.newQueryHandler(ctx, cAddr)
return codeInfo.CodeHash, prefixStore, queryHandler, keeper.gasMeter(ctx), nil
}
// 3. get store from storeaddress
sAddr, err := sdk.WasmAddressFromBech32(storeAddress)
if err != nil {
return nil, nil, nil, nil, err
}
prefixStore = types.NewStoreAdapter(keeper.getStorageStore(ctx, sAddr))
queryHandler := keeper.newQueryHandler(ctx, sAddr)
return codeInfo.CodeHash, prefixStore, queryHandler, keeper.gasMeter(ctx), nil
}

func transferCoinsFunc(ctx sdk.Context, keeper Keeper) func(contractAddress, caller string, coinsData []byte) (uint64, error) {
return func(contractAddress, caller string, coinsData []byte) (uint64, error) {
var coins sdk.Coins
err := json.Unmarshal(coinsData, &coins)
if err != nil {
return 0, err
}
gasBefore := ctx.GasMeter().GasConsumed()
err = transferCoins(ctx, keeper, contractAddress, caller, coins)
gasAfter := ctx.GasMeter().GasConsumed()
return keeper.gasRegister.ToWasmVMGas(gasAfter - gasBefore), err
}
}

func transferCoins(ctx sdk.Context, keeper Keeper, contractAddress, caller string, coins sdk.Coins) error {
if !coins.IsZero() {
contractAddr, err := sdk.WasmAddressFromBech32(contractAddress)
if err != nil {
return err
}
callerAddr, err := sdk.WasmAddressFromBech32(caller)
if err != nil {
return err
}
if err := keeper.bank.TransferCoins(ctx, callerAddr, contractAddr, coins); err != nil {
return err
}
}
return nil
}
55 changes: 55 additions & 0 deletions x/wasm/keeper/cross_contract_call_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package keeper

import (
"encoding/json"
sdk "github.com/okx/okbchain/libs/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"testing"
)

func TestGetWasmCallInfo(t *testing.T) {
ctx, keepers := CreateTestInput(t, false, SupportedFeatures)
keeper := keepers.ContractKeeper

deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
creator := keepers.Faucet.NewFundedAccount(ctx, deposit...)

codeID, err := keeper.Create(ctx, creator, hackatomWasm, nil)
require.NoError(t, err)

_, _, bob := keyPubAddr()
_, _, fred := keyPubAddr()

initMsg := HackatomExampleInitMsg{
Verifier: fred,
Beneficiary: bob,
}
initMsgBz, err := json.Marshal(initMsg)
require.NoError(t, err)

em := sdk.NewEventManager()
// create with no balance is also legal
ctx.SetEventManager(em)
gotContractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, "demo contract 1", nil)
require.NoError(t, err)

wasmkeeper := *keepers.WasmKeeper
// 1. contractAddress is equal to storeAddress
_, _, _, _, err = getCallerInfo(ctx, wasmkeeper, gotContractAddr.String(), gotContractAddr.String())
require.NoError(t, err)

// 2. contractAddress is not exist
_, _, _, _, err = getCallerInfo(ctx, wasmkeeper, "0xE70e7466a2f18FAd8C97c45Ba8fEc57d90F3435E", "0xE70e7466a2f18FAd8C97c45Ba8fEc57d90F3435E")
require.NotNil(t, err)

// 3. storeAddress is not exist
_, _, _, _, err = getCallerInfo(ctx, wasmkeeper, gotContractAddr.String(), "0xE70e7466a2f18FAd8C97c45Ba8fEc57d90F3435E")
require.NoError(t, err)

// 4. contractAddress is not equal to storeAddress
gotContractAddr2, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, "demo contract 1", nil)
_, kvs, q, _, err := getCallerInfo(ctx, wasmkeeper, gotContractAddr.String(), gotContractAddr2.String())
require.NoError(t, err)
require.NotNil(t, kvs)
require.NotNil(t, q)
}
Loading

0 comments on commit bcdc8ed

Please sign in to comment.