From b108d5f8f7d2a5908e54d208dba9f69dc9c54c2b Mon Sep 17 00:00:00 2001 From: Antonio Navarro Date: Thu, 18 May 2023 13:22:59 +0200 Subject: [PATCH] feat: set cpu cycles from cli Before this change, some VM operations like loading a package or calling a public realm method had a hardcoded limit of 10M max allowed cycles. Whith this change that limit can be modified. Signed-off-by: Antonio Navarro --- gno.land/cmd/gnoland/main.go | 10 +++++++++- gno.land/pkg/gnoland/app.go | 4 ++-- tm2/pkg/sdk/vm/common_test.go | 3 +-- tm2/pkg/sdk/vm/keeper.go | 20 +++++++++++++++----- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/gno.land/cmd/gnoland/main.go b/gno.land/cmd/gnoland/main.go index 9a2c11146e8..6aaf6d1fde5 100644 --- a/gno.land/cmd/gnoland/main.go +++ b/gno.land/cmd/gnoland/main.go @@ -33,6 +33,7 @@ type gnolandCfg struct { chainID string genesisRemote string rootDir string + maxCycles int64 } func main() { @@ -105,6 +106,13 @@ func (c *gnolandCfg) RegisterFlags(fs *flag.FlagSet) { "localhost:26657", "replacement for '%%REMOTE%%' in genesis", ) + + fs.Int64Var( + &c.maxCycles, + "max-vm-cycles", + 10*1000*1000, + "set maximum allowed vm cycles per operation. Zero means no limit.", + ) } func exec(c *gnolandCfg) error { @@ -135,7 +143,7 @@ func exec(c *gnolandCfg) error { } // create application and node. - gnoApp, err := gnoland.NewApp(rootDir, c.skipFailingGenesisTxs, logger) + gnoApp, err := gnoland.NewApp(rootDir, c.skipFailingGenesisTxs, logger, c.maxCycles) if err != nil { return fmt.Errorf("error in creating new app: %w", err) } diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index 95fe9d2df8d..e33be9c04fe 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -21,7 +21,7 @@ import ( ) // NewApp creates the GnoLand application. -func NewApp(rootDir string, skipFailingGenesisTxs bool, logger log.Logger) (abci.Application, error) { +func NewApp(rootDir string, skipFailingGenesisTxs bool, logger log.Logger, maxCycles int64) (abci.Application, error) { // Get main DB. db, err := dbm.NewDB("gnolang", dbm.GoLevelDBBackend, filepath.Join(rootDir, "data")) if err != nil { @@ -44,7 +44,7 @@ func NewApp(rootDir string, skipFailingGenesisTxs bool, logger log.Logger) (abci acctKpr := auth.NewAccountKeeper(mainKey, ProtoGnoAccount) bankKpr := bank.NewBankKeeper(acctKpr) stdlibsDir := filepath.Join("..", "gnovm", "stdlibs") - vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir) + vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir, maxCycles) // Set InitChainer baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, skipFailingGenesisTxs)) diff --git a/tm2/pkg/sdk/vm/common_test.go b/tm2/pkg/sdk/vm/common_test.go index 62f83e94c8c..7a3a53e4fe3 100644 --- a/tm2/pkg/sdk/vm/common_test.go +++ b/tm2/pkg/sdk/vm/common_test.go @@ -8,7 +8,6 @@ import ( bft "github.com/gnolang/gno/tm2/pkg/bft/types" dbm "github.com/gnolang/gno/tm2/pkg/db" "github.com/gnolang/gno/tm2/pkg/log" - "github.com/gnolang/gno/tm2/pkg/sdk" authm "github.com/gnolang/gno/tm2/pkg/sdk/auth" bankm "github.com/gnolang/gno/tm2/pkg/sdk/bank" @@ -40,7 +39,7 @@ func setupTestEnv() testEnv { acck := authm.NewAccountKeeper(iavlCapKey, std.ProtoBaseAccount) bank := bankm.NewBankKeeper(acck) stdlibsDir := filepath.Join("..", "..", "..", "..", "gnovm", "stdlibs") - vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, stdlibsDir) + vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, stdlibsDir, 10*1000*1000) vmk.Initialize(ms.MultiCacheWrap()) diff --git a/tm2/pkg/sdk/vm/keeper.go b/tm2/pkg/sdk/vm/keeper.go index 8cff3e4c239..5a5eeb9303e 100644 --- a/tm2/pkg/sdk/vm/keeper.go +++ b/tm2/pkg/sdk/vm/keeper.go @@ -41,16 +41,26 @@ type VMKeeper struct { // cached, the DeliverTx persistent state. gnoStore gno.Store + + maxCycles int64 // max allowed cylces on VM executions } // NewVMKeeper returns a new VMKeeper. -func NewVMKeeper(baseKey store.StoreKey, iavlKey store.StoreKey, acck auth.AccountKeeper, bank bank.BankKeeper, stdlibsDir string) *VMKeeper { +func NewVMKeeper( + baseKey store.StoreKey, + iavlKey store.StoreKey, + acck auth.AccountKeeper, + bank bank.BankKeeper, + stdlibsDir string, + maxCycles int64, +) *VMKeeper { vmk := &VMKeeper{ baseKey: baseKey, iavlKey: iavlKey, acck: acck, bank: bank, stdlibsDir: stdlibsDir, + maxCycles: maxCycles, } return vmk } @@ -174,7 +184,7 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) error { Store: store, Alloc: store.GetAllocator(), Context: msgCtx, - MaxCycles: 10 * 1000 * 1000, // 10M cycles // XXX + MaxCycles: vm.maxCycles, }) defer m2.Release() m2.RunMemPackage(memPkg, true) @@ -248,7 +258,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { Store: store, Context: msgCtx, Alloc: store.GetAllocator(), - MaxCycles: 10 * 1000 * 1000, // 10M cycles // XXX + MaxCycles: vm.maxCycles, }) m.SetActivePackage(mpv) defer func() { @@ -369,7 +379,7 @@ func (vm *VMKeeper) QueryEval(ctx sdk.Context, pkgPath string, expr string) (res Store: store, Context: msgCtx, Alloc: alloc, - MaxCycles: 10 * 1000 * 1000, // 10M cycles // XXX + MaxCycles: vm.maxCycles, }) defer func() { if r := recover(); r != nil { @@ -429,7 +439,7 @@ func (vm *VMKeeper) QueryEvalString(ctx sdk.Context, pkgPath string, expr string Store: store, Context: msgCtx, Alloc: alloc, - MaxCycles: 10 * 1000 * 1000, // 10M cycles // XXX + MaxCycles: vm.maxCycles, }) defer func() { if r := recover(); r != nil {