From c8268bd2ec88334df9696ce6bb75e5a528cc6c7f Mon Sep 17 00:00:00 2001 From: Antonio Navarro Date: Thu, 18 May 2023 13:22:59 +0200 Subject: [PATCH 1/2] 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 dc31c6d5dba..5ce977bbf3d 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 { From 4c85bdf1a7bce60ec6b8725c9d61280b869e576a Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Mon, 5 Jun 2023 10:52:51 +0200 Subject: [PATCH 2/2] Requested changes Signed-off-by: Antonio Navarro Perez --- gno.land/cmd/gnoland/main.go | 25 ++++++++++++++++++++----- tm2/pkg/sdk/vm/common_test.go | 2 +- tm2/pkg/sdk/vm/keeper.go | 1 + 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/gno.land/cmd/gnoland/main.go b/gno.land/cmd/gnoland/main.go index 5ce977bbf3d..0ebc3d7058a 100644 --- a/gno.land/cmd/gnoland/main.go +++ b/gno.land/cmd/gnoland/main.go @@ -9,6 +9,9 @@ import ( "strings" "time" + "github.com/peterbourgon/ff/v3" + "github.com/peterbourgon/ff/v3/fftoml" + "github.com/gnolang/gno/gno.land/pkg/gnoland" gno "github.com/gnolang/gno/gnovm/pkg/gnolang" "github.com/gnolang/gno/tm2/pkg/amino" @@ -33,7 +36,8 @@ type gnolandCfg struct { chainID string genesisRemote string rootDir string - maxCycles int64 + genesisMaxVMCycles int64 + config string } func main() { @@ -43,6 +47,10 @@ func main() { commands.Metadata{ ShortUsage: "[flags] [...]", LongHelp: "Starts the gnoland blockchain node", + Options: []ff.Option{ + ff.WithConfigFileFlag("config"), + ff.WithConfigFileParser(fftoml.Parser), + }, }, cfg, func(_ context.Context, _ []string) error { @@ -108,11 +116,18 @@ func (c *gnolandCfg) RegisterFlags(fs *flag.FlagSet) { ) fs.Int64Var( - &c.maxCycles, - "max-vm-cycles", - 10*1000*1000, + &c.genesisMaxVMCycles, + "genesis-max-vm-cycles", + 10_000_000, "set maximum allowed vm cycles per operation. Zero means no limit.", ) + + fs.StringVar( + &c.config, + "config", + "", + "config file (optional)", + ) } func exec(c *gnolandCfg) error { @@ -143,7 +158,7 @@ func exec(c *gnolandCfg) error { } // create application and node. - gnoApp, err := gnoland.NewApp(rootDir, c.skipFailingGenesisTxs, logger, c.maxCycles) + gnoApp, err := gnoland.NewApp(rootDir, c.skipFailingGenesisTxs, logger, c.genesisMaxVMCycles) if err != nil { return fmt.Errorf("error in creating new app: %w", err) } diff --git a/tm2/pkg/sdk/vm/common_test.go b/tm2/pkg/sdk/vm/common_test.go index 7a3a53e4fe3..60a92906cb6 100644 --- a/tm2/pkg/sdk/vm/common_test.go +++ b/tm2/pkg/sdk/vm/common_test.go @@ -39,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, 10*1000*1000) + vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, stdlibsDir, 10_000_000) vmk.Initialize(ms.MultiCacheWrap()) diff --git a/tm2/pkg/sdk/vm/keeper.go b/tm2/pkg/sdk/vm/keeper.go index 5a5eeb9303e..74cae60a0a3 100644 --- a/tm2/pkg/sdk/vm/keeper.go +++ b/tm2/pkg/sdk/vm/keeper.go @@ -54,6 +54,7 @@ func NewVMKeeper( stdlibsDir string, maxCycles int64, ) *VMKeeper { + // TODO: create an Options struct to avoid too many constructor parameters vmk := &VMKeeper{ baseKey: baseKey, iavlKey: iavlKey,