diff --git a/gno.land/cmd/gnoland/main.go b/gno.land/cmd/gnoland/main.go index dc31c6d5dba..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,6 +36,8 @@ type gnolandCfg struct { chainID string genesisRemote string rootDir string + genesisMaxVMCycles int64 + config string } func main() { @@ -42,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 { @@ -105,6 +114,20 @@ func (c *gnolandCfg) RegisterFlags(fs *flag.FlagSet) { "localhost:26657", "replacement for '%%REMOTE%%' in genesis", ) + + fs.Int64Var( + &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 { @@ -135,7 +158,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.genesisMaxVMCycles) 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..60a92906cb6 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_000_000) vmk.Initialize(ms.MultiCacheWrap()) diff --git a/tm2/pkg/sdk/vm/keeper.go b/tm2/pkg/sdk/vm/keeper.go index 8cff3e4c239..74cae60a0a3 100644 --- a/tm2/pkg/sdk/vm/keeper.go +++ b/tm2/pkg/sdk/vm/keeper.go @@ -41,16 +41,27 @@ 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 { + // TODO: create an Options struct to avoid too many constructor parameters vmk := &VMKeeper{ baseKey: baseKey, iavlKey: iavlKey, acck: acck, bank: bank, stdlibsDir: stdlibsDir, + maxCycles: maxCycles, } return vmk } @@ -174,7 +185,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 +259,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 +380,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 +440,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 {