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

movevm loaderv2 integration #284

Merged
merged 6 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ARG TARGETARCH
ARG GOARCH

# See https://github.com/initia-labs/movevm/releases
ENV LIBMOVEVM_VERSION=v0.5.1
ENV LIBMOVEVM_VERSION=v0.6.0

# Install necessary packages
RUN set -eux; apk add --no-cache ca-certificates build-base git cmake
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/hashicorp/go-metrics v0.5.3
github.com/initia-labs/OPinit v0.5.5
// we also need to update `LIBMOVEVM_VERSION` of Dockerfile#9
github.com/initia-labs/movevm v0.5.1
github.com/initia-labs/movevm v0.6.0
github.com/noble-assets/forwarding/v2 v2.0.0-20240521090705-86712c4c9e43
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -232,6 +232,7 @@ replace (
// Fix upstream GHSA-h395-qcrw-5vmq vulnerability.
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1

// Downgraded to avoid bugs in following commits which caused simulations to fail.
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,8 @@ github.com/initia-labs/OPinit/api v0.5.1 h1:zwyJf7HtKJCKvLJ1R9PjVfJO1L+d/jKoeFyT
github.com/initia-labs/OPinit/api v0.5.1/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU=
github.com/initia-labs/cometbft v0.0.0-20240923045653-ba99eb347236 h1:+HmPQ1uptOe4r5oQHuHMG5zF1F3maNoEba5uiTUMnlk=
github.com/initia-labs/cometbft v0.0.0-20240923045653-ba99eb347236/go.mod h1:GPHp3/pehPqgX1930HmK1BpBLZPxB75v/dZg8Viwy+o=
github.com/initia-labs/movevm v0.5.1 h1:Nl5SizJIfRLM6clz/zV8dOFUXcnlMP2wOQsZB/mmU2w=
github.com/initia-labs/movevm v0.5.1/go.mod h1:aUWdvFZPdULjJ2McQTE+mLnfnG3CLAz0TWJRFzFFUwg=
github.com/initia-labs/movevm v0.6.0 h1:46JjDfOId6hfeoqYqKWTzPeb5ESQzzm8AhhGWYnFOmE=
github.com/initia-labs/movevm v0.6.0/go.mod h1:aUWdvFZPdULjJ2McQTE+mLnfnG3CLAz0TWJRFzFFUwg=
github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls=
github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
Expand Down
16 changes: 16 additions & 0 deletions x/move/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,45 @@ import (

// DefaultContractSimulationGasLimit - default max simulation gas
const DefaultContractSimulationGasLimit = uint64(3_000_000)
const DefaultScriptCacheCapacity = uint64(100)
const DefaultModuleCacheCapacity = uint64(500)

const (
flagContractSimulationGasLimit = "move.contract-simulation-gas-limit"
flagScriptCacheCapacity = "move.script-cache-capacity"
flagModuleCacheCapacity = "move.module-cache-capacity"
)

// MoveConfig is the extra config required for move
type MoveConfig struct {
ContractSimulationGasLimit uint64 `mapstructure:"contract-simulation-gas-limit"`
ScriptCacheCapacity uint64 `mapstructure:"script-cache-capacity"`
ModuleCacheCapacity uint64 `mapstructure:"module-cache-capacity"`
}

// DefaultMoveConfig returns the default settings for MoveConfig
func DefaultMoveConfig() MoveConfig {
return MoveConfig{
ContractSimulationGasLimit: DefaultContractSimulationGasLimit,
ScriptCacheCapacity: DefaultScriptCacheCapacity,
ModuleCacheCapacity: DefaultModuleCacheCapacity,
}
}

// GetConfig load config values from the app options
func GetConfig(appOpts servertypes.AppOptions) MoveConfig {
return MoveConfig{
ContractSimulationGasLimit: cast.ToUint64(appOpts.Get(flagContractSimulationGasLimit)),
ScriptCacheCapacity: cast.ToUint64(appOpts.Get(flagScriptCacheCapacity)),
ModuleCacheCapacity: cast.ToUint64(appOpts.Get(flagModuleCacheCapacity)),
}
}

// AddConfigFlags implements servertypes.MoveConfigFlags interface.
func AddConfigFlags(startCmd *cobra.Command) {
startCmd.Flags().Uint64(flagContractSimulationGasLimit, DefaultContractSimulationGasLimit, "Set the max simulation gas for move contract execution")
startCmd.Flags().Uint64(flagScriptCacheCapacity, DefaultScriptCacheCapacity, "Set the script cache capacity")
startCmd.Flags().Uint64(flagModuleCacheCapacity, DefaultModuleCacheCapacity, "Set the module cache capacity")
}

// DefaultConfigTemplate default config template for move module
Expand All @@ -47,4 +59,8 @@ const DefaultConfigTemplate = `
[move]
# The maximum gas amount can be used in a tx simulation call.
contract-simulation-gas-limit = "{{ .MoveConfig.ContractSimulationGasLimit }}"
# The capacity of the script cache in (MiB).
script-cache-capacity = "{{ .MoveConfig.ScriptCacheCapacity }}"
# The capacity of the module cache in (MiB).
module-cache-capacity = "{{ .MoveConfig.ModuleCacheCapacity }}"
`
7 changes: 7 additions & 0 deletions x/move/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ import (
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"

ibcfee "github.com/cosmos/ibc-go/v8/modules/apps/29-fee"
ibctransfer "github.com/cosmos/ibc-go/v8/modules/apps/transfer"
ibcnfttransfer "github.com/initia-labs/initia/x/ibc/nft-transfer"

initiaapp "github.com/initia-labs/initia/app"
initiaappparams "github.com/initia-labs/initia/app/params"
"github.com/initia-labs/initia/x/bank"
Expand Down Expand Up @@ -90,6 +94,9 @@ var ModuleBasics = module.NewBasicManager(
slashing.AppModuleBasic{},
move.AppModuleBasic{},
oracle.AppModuleBasic{},
ibctransfer.AppModuleBasic{},
ibcnfttransfer.AppModuleBasic{},
ibcfee.AppModuleBasic{},
)

// Bond denom should be set for staking test
Expand Down
4 changes: 1 addition & 3 deletions x/move/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ func (k Keeper) Initialize(
}

vmStore := types.NewVMStore(ctx, k.VMStore)
execRes, err := execVM(ctx, k, func(vm types.VMEngine) (vmtypes.ExecutionResult, error) {
return vm.Initialize(vmStore, api, env, vmtypes.NewModuleBundle(modules...), _allowedPublishers)
})
execRes, err := k.initiaMoveVM.Initialize(vmStore, api, env, vmtypes.NewModuleBundle(modules...), _allowedPublishers)
if err != nil {
return err
}
Expand Down
110 changes: 34 additions & 76 deletions x/move/keeper/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,14 @@ func (k Keeper) executeEntryFunction(
sdkCtx = sdkCtx.WithGasMeter(storetypes.NewInfiniteGasMeter())

gasBalance := gasForRuntime
execRes, err := execVM(ctx, k, func(vm types.VMEngine) (vmtypes.ExecutionResult, error) {
return vm.ExecuteEntryFunction(
&gasBalance,
types.NewVMStore(sdkCtx, k.VMStore),
NewApi(k, sdkCtx),
types.NewEnv(sdkCtx, ac, ec),
senders,
payload,
)
})
execRes, err := k.initiaMoveVM.ExecuteEntryFunction(
&gasBalance,
types.NewVMStore(sdkCtx, k.VMStore),
NewApi(k, sdkCtx),
types.NewEnv(sdkCtx, ac, ec),
senders,
payload,
)
beer-1 marked this conversation as resolved.
Show resolved Hide resolved

// consume gas first and check error
gasUsed := gasForRuntime - gasBalance
Expand Down Expand Up @@ -309,16 +307,14 @@ func (k Keeper) executeScript(
sdkCtx = sdkCtx.WithGasMeter(storetypes.NewInfiniteGasMeter())

gasBalance := gasForRuntime
execRes, err := execVM(ctx, k, func(vm types.VMEngine) (vmtypes.ExecutionResult, error) {
return vm.ExecuteScript(
&gasBalance,
types.NewVMStore(sdkCtx, k.VMStore),
NewApi(k, sdkCtx),
types.NewEnv(sdkCtx, ac, ec),
senders,
payload,
)
})
execRes, err := k.initiaMoveVM.ExecuteScript(
&gasBalance,
types.NewVMStore(sdkCtx, k.VMStore),
NewApi(k, sdkCtx),
types.NewEnv(sdkCtx, ac, ec),
senders,
payload,
)
beer-1 marked this conversation as resolved.
Show resolved Hide resolved

// consume gas first and check error
gasUsed := gasForRuntime - gasBalance
Expand Down Expand Up @@ -419,10 +415,6 @@ func (k Keeper) DispatchMessages(ctx context.Context, messages []vmtypes.CosmosM
}

func (k Keeper) dispatchMessage(parentCtx sdk.Context, message vmtypes.CosmosMessage) (err error) {
var allowFailure bool
var callback *vmtypes.StargateCallback
var callbackSender vmtypes.AccountAddress

ctx, commit := parentCtx.CacheContext()
defer func() {
if r := recover(); r != nil {
Expand All @@ -439,7 +431,7 @@ func (k Keeper) dispatchMessage(parentCtx sdk.Context, message vmtypes.CosmosMes

if !success {
// return error if failed and not allowed to fail
if !allowFailure {
if !message.AllowFailure {
return
}

Expand All @@ -457,48 +449,27 @@ func (k Keeper) dispatchMessage(parentCtx sdk.Context, message vmtypes.CosmosMes
parentCtx.EventManager().EmitEvent(event)

// if callback exists, execute it with parent context becuase it's already committed
if callback != nil {
if message.Callback != nil {
err = k.ExecuteEntryFunctionJSON(
parentCtx,
callbackSender,
callback.ModuleAddress,
callback.ModuleName,
callback.FunctionName,
message.Sender,
message.Callback.ModuleAddress,
message.Callback.ModuleName,
message.Callback.FunctionName,
[]vmtypes.TypeTag{},
[]string{
fmt.Sprintf("\"%d\"", callback.Id),
fmt.Sprintf("\"%d\"", message.Callback.Id),
fmt.Sprintf("%v", success),
},
)
}
}()

// validate basic & signer check is done in HandleVMStargateMsg
var msg proto.Message
if stargateMsg, ok := message.(*vmtypes.CosmosMessage__Stargate); ok {
// callback only exists in stargate message
allowFailure = stargateMsg.Value.AllowFailure
callback = stargateMsg.Value.Callback
callbackSender = stargateMsg.Value.Sender

// validate basic & signer check is done in HandleVMStargateMsg
msg, err = k.HandleVMStargateMsg(ctx, &stargateMsg.Value)
if err != nil {
return
}
} else {
// signer check had been done in moveVM
msg, err = types.ConvertToSDKMessage(ctx, k.MoveBankKeeper(), NewNftKeeper(&k), message, k.ac, k.vc)
if err != nil {
return
}

// conduct validate basic
if msg, ok := msg.(sdk.HasValidateBasic); ok {
err = msg.ValidateBasic()
if err != nil {
return
}
}
msg, err = k.HandleVMStargateMsg(ctx, &message)
if err != nil {
return
}

// find the handler
Expand Down Expand Up @@ -653,15 +624,13 @@ func (k Keeper) executeViewFunction(
gasForRuntime := k.computeGasForRuntime(ctx, gasMeter)

gasBalance := gasForRuntime
viewRes, err := execVM(ctx, k, func(vm types.VMEngine) (vmtypes.ViewOutput, error) {
return vm.ExecuteViewFunction(
&gasBalance,
types.NewVMStore(ctx, k.VMStore),
api,
env,
payload,
)
})
viewRes, err := k.initiaMoveVM.ExecuteViewFunction(
&gasBalance,
types.NewVMStore(ctx, k.VMStore),
api,
env,
payload,
)
beer-1 marked this conversation as resolved.
Show resolved Hide resolved

// consume gas first and check error
gasUsed := gasForRuntime - gasBalance
Expand All @@ -673,17 +642,6 @@ func (k Keeper) executeViewFunction(
return viewRes, gasUsed, nil
}

// execVM runs vm in separate function statement to release right after execution
// to avoid deadlock even if the function panics
//
// TODO - remove this after loader v2 is installed
func execVM[T any](ctx context.Context, k Keeper, f func(types.VMEngine) (T, error)) (T, error) {
vm := k.acquireVM(ctx)
defer k.releaseVM()

return f(vm)
}

func (k Keeper) computeGasForRuntime(ctx context.Context, gasMeter storetypes.GasMeter) uint64 {
gasForRuntime := gasMeter.Limit() - gasMeter.GasConsumedToLimit()
if isSimulation(ctx) {
Expand Down
33 changes: 9 additions & 24 deletions x/move/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"context"
"errors"

"golang.org/x/sync/semaphore"

"cosmossdk.io/collections"
"cosmossdk.io/core/address"
corestoretypes "cosmossdk.io/core/store"
Expand Down Expand Up @@ -49,10 +47,7 @@ type Keeper struct {

config moveconfig.MoveConfig

// TODO - remove after loader v2
moveVMs []types.VMEngine
moveVMIdx *uint64
moveVMSemaphore *semaphore.Weighted
initiaMoveVM types.VMEngine

feeCollector string
authority string
Expand Down Expand Up @@ -95,21 +90,13 @@ func NewKeeper(
moveConfig.ContractSimulationGasLimit = moveconfig.DefaultContractSimulationGasLimit
}

// use only one VM for now because we need to clear the cache on every module upgrade.
// but if we have multiple VMs, only the VM that executed the module upgrade will have the cache cleared.
vmCount := 1
moveVMIdx := uint64(0)
vms := make([]types.VMEngine, vmCount)
for i := 0; i < vmCount; i++ {
moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{
// TODO: check this before mainnet
AllowUnstable: true,
})
if err != nil {
panic(err)
}

vms[i] = &moveVM
moveVM, err := vm.NewVM(vmtypes.InitiaVMConfig{
AllowUnstable: false,
ScriptCacheCapacity: moveConfig.ScriptCacheCapacity,
ModuleCacheCapacity: moveConfig.ModuleCacheCapacity,
})
if err != nil {
panic(err)
}

sb := collections.NewSchemaBuilder(storeService)
Expand All @@ -122,9 +109,7 @@ func NewKeeper(
msgRouter: msgRouter,
grpcRouter: grpcRouter,
config: moveConfig,
moveVMs: vms,
moveVMIdx: &moveVMIdx,
moveVMSemaphore: semaphore.NewWeighted(int64(vmCount)),
initiaMoveVM: &moveVM,
beer-1 marked this conversation as resolved.
Show resolved Hide resolved
distrKeeper: distrKeeper,
StakingKeeper: stakingKeeper,
RewardKeeper: rewardKeeper,
Expand Down
2 changes: 1 addition & 1 deletion x/move/keeper/vm_msg_stargate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
vmtypes "github.com/initia-labs/movevm/types"
)

func (k Keeper) HandleVMStargateMsg(ctx context.Context, req *vmtypes.StargateMessage) (proto.Message, error) {
func (k Keeper) HandleVMStargateMsg(ctx context.Context, req *vmtypes.CosmosMessage) (proto.Message, error) {
var sdkMsg sdk.Msg
err := k.cdc.UnmarshalInterfaceJSON(req.Data, &sdkMsg)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions x/move/keeper/vm_msg_stargate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ func Test_HandleVMStargateMsg(t *testing.T) {
}`, sdk.MsgTypeURL(&govtypes.MsgVote{}), addrs[1]))

// unauthorized test
_, err = input.MoveKeeper.HandleVMStargateMsg(ctx, &vmtypes.StargateMessage{
_, err = input.MoveKeeper.HandleVMStargateMsg(ctx, &vmtypes.CosmosMessage{
Sender: addr0,
Data: jsonData,
})
require.ErrorIs(t, err, sdkerrors.ErrUnauthorized)

// valid test
res, err := input.MoveKeeper.HandleVMStargateMsg(ctx, &vmtypes.StargateMessage{
res, err := input.MoveKeeper.HandleVMStargateMsg(ctx, &vmtypes.CosmosMessage{
Sender: addr1,
Data: jsonData,
})
Expand Down
4 changes: 4 additions & 0 deletions x/move/keeper/vm_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ func (k Keeper) queryCustom(ctx sdk.Context, req *vmtypes.CustomQuery) ([]byte,
return nil, types.ErrNotSupportedCustomQuery
}

// create cache context for query
ctx, _ = ctx.CacheContext()
return customQuery(ctx, req.Data)
}

Expand All @@ -44,6 +46,8 @@ func (k Keeper) queryStargate(ctx sdk.Context, req *vmtypes.StargateQuery) ([]by
return nil, err
}

// create cache context for query
ctx, _ = ctx.CacheContext()
res, err := route(ctx, &abci.RequestQuery{
Data: reqData,
Path: req.Path,
Expand Down
Loading
Loading