From 3b28de8cd6dc1b75d9775f7a28998c73f97cdd79 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Sat, 29 Jul 2023 20:40:03 +0200 Subject: [PATCH 01/24] feat: add 'gnokey maketx exec' Signed-off-by: Manfred Touron <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/msgs.go | 52 ++++++++++++++++++++++++++++ gno.land/pkg/sdk/vm/package.go | 1 + tm2/pkg/crypto/keys/client/maketx.go | 1 + 3 files changed, 54 insertions(+) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 3cfc6c58224..cc94d93e9e0 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -135,3 +135,55 @@ func (msg MsgCall) GetSigners() []crypto.Address { func (msg MsgCall) GetReceived() std.Coins { return msg.Send } + +//---------------------------------------- +// MsgExec + +// MsgExec - executes arbitrary Gno code. +type MsgExec struct { + Caller crypto.Address `json:"caller" yaml:"caller"` + Send std.Coins `json:"send" yaml:"send"` + Source string `json:"source" yaml:"source"` +} + +var _ std.Msg = MsgExec{} + +func NewMsgExec(caller crypto.Address, send std.Coins, source string) MsgExec { + return MsgExec{ + Caller: caller, + Send: send, + Source: source, + } +} + +// Implements Msg. +func (msg MsgExec) Route() string { return RouterKey } + +// Implements Msg. +func (msg MsgExec) Type() string { return "exec" } + +// Implements Msg. +func (msg MsgExec) ValidateBasic() error { + if msg.Caller.IsZero() { + return std.ErrInvalidAddress("missing caller address") + } + if msg.Source == "" { // XXX + return ErrInvalidExpr("missing source to exec") + } + return nil +} + +// Implements Msg. +func (msg MsgExec) GetSignBytes() []byte { + return std.MustSortJSON(amino.MustMarshalJSON(msg)) +} + +// Implements Msg. +func (msg MsgExec) GetSigners() []crypto.Address { + return []crypto.Address{msg.Caller} +} + +// Implements ReceiveMsg. +func (msg MsgExec) GetReceived() std.Coins { + return msg.Send +} diff --git a/gno.land/pkg/sdk/vm/package.go b/gno.land/pkg/sdk/vm/package.go index 5d05c108bd0..a172dc13e9f 100644 --- a/gno.land/pkg/sdk/vm/package.go +++ b/gno.land/pkg/sdk/vm/package.go @@ -13,6 +13,7 @@ var Package = amino.RegisterPackage(amino.NewPackage( std.Package, ).WithTypes( MsgCall{}, "m_call", + MsgExec{}, "m_exec", MsgAddPackage{}, "m_addpkg", // TODO rename both to MsgAddPkg? // errors diff --git a/tm2/pkg/crypto/keys/client/maketx.go b/tm2/pkg/crypto/keys/client/maketx.go index 36214a5a983..31865377d3c 100644 --- a/tm2/pkg/crypto/keys/client/maketx.go +++ b/tm2/pkg/crypto/keys/client/maketx.go @@ -36,6 +36,7 @@ func newMakeTxCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { newAddPkgCmd(cfg, io), newSendCmd(cfg, io), newCallCmd(cfg, io), + // newExecCmd(cfg, io), ) return cmd From 1178404bcca7477cd47f905c48c864f87bb9b0f7 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Sat, 29 Jul 2023 20:52:51 +0200 Subject: [PATCH 02/24] chore: fixup --- tm2/pkg/crypto/keys/client/exec.go | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tm2/pkg/crypto/keys/client/exec.go diff --git a/tm2/pkg/crypto/keys/client/exec.go b/tm2/pkg/crypto/keys/client/exec.go new file mode 100644 index 00000000000..f6fb859fa5e --- /dev/null +++ b/tm2/pkg/crypto/keys/client/exec.go @@ -0,0 +1,102 @@ +package client + +import ( + "context" + "flag" + "fmt" + + "github.com/gnolang/gno/tm2/pkg/amino" + "github.com/gnolang/gno/tm2/pkg/commands" + "github.com/gnolang/gno/tm2/pkg/crypto/keys" + "github.com/gnolang/gno/tm2/pkg/errors" + "github.com/gnolang/gno/tm2/pkg/sdk/vm" + "github.com/gnolang/gno/tm2/pkg/std" +) + +type execCfg struct { + rootCfg *makeTxCfg + send string + source string +} + +func newExecCmd(rootCfg *makeTxCfg) *commands.Command { + cfg := &execCfg{ + rootCfg: rootCfg, + } + + return commands.NewCommand( + commands.Metadata{ + Name: "exec", + ShortUsage: "exec [flags] ", + ShortHelp: "Executes arbitrary Gno code", + }, + cfg, + func(_ context.Context, args []string) error { + return execExec(cfg, args, commands.NewDefaultIO()) + }, + ) +} + +func (c *execCfg) RegisterFlags(fs *flag.FlagSet) {} + +func execExec(cfg *execCfg, args []string, io *commands.IO) error { + if len(args) != 1 { + return flag.ErrHelp + } + if cfg.rootCfg.gasWanted == 0 { + return errors.New("gas-wanted not specified") + } + if cfg.rootCfg.gasFee == "" { + return errors.New("gas-fee not specified") + } + + // read statement. + // TODO: parse stdin + source := cfg.source + source = "package main\nfunc main() {println(\"42\")}" + if source == "" { + return errors.New("empty source") + } + // TODO: validate source + + // read account pubkey. + nameOrBech32 := args[0] + kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.rootCfg.Home) + if err != nil { + return err + } + info, err := kb.GetByNameOrAddress(nameOrBech32) + if err != nil { + return err + } + caller := info.GetAddress() + + // parse gas wanted & fee. + gaswanted := cfg.rootCfg.gasWanted + gasfee, err := std.ParseCoin(cfg.rootCfg.gasFee) + if err != nil { + return errors.Wrap(err, "parsing gas fee coin") + } + + // construct msg & tx and marshal. + msg := vm.MsgExec{ + Caller: caller, + Source: source, + } + tx := std.Tx{ + Msgs: []std.Msg{msg}, + Fee: std.NewFee(gaswanted, gasfee), + Signatures: nil, + Memo: cfg.rootCfg.memo, + } + + if cfg.rootCfg.broadcast { + err := signAndBroadcast(cfg.rootCfg, args, tx, io) + if err != nil { + return err + } + } else { + fmt.Println(string(amino.MustMarshalJSON(tx))) + } + return nil +} From 4be7cbbca678d64d9df96f5a528e3666a9de8d2b Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Sun, 30 Jul 2023 15:11:56 +0200 Subject: [PATCH 03/24] chore: add convenient dev make rule --- gno.land/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gno.land/Makefile b/gno.land/Makefile index 1fd1aaa1f78..2e32cd302f9 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -14,6 +14,9 @@ build.gnofaucet:; go build -o build/gnofaucet ./cmd/gnofaucet build.gnokey:; go build -o build/gnokey ./cmd/gnokey build.gnotxsync:; go build -o build/gnotxsync ./cmd/gnotxsync +run.gnoland:; go run ./cmd/gnoland +run.gnoweb:; go run ./cmd/gnoweb + .PHONY: install install: install.gnoland install.gnoweb install.gnofaucet install.gnokey install.gnotxsync From 3f2ce02c5f9230a150ef512ffb8002eb0953c8a0 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Sun, 30 Jul 2023 15:46:26 +0200 Subject: [PATCH 04/24] chore: fixup --- gno.land/Makefile | 2 +- gno.land/pkg/sdk/vm/handler.go | 21 +++++++++++++++++++++ gno.land/pkg/sdk/vm/keeper.go | 6 ++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/gno.land/Makefile b/gno.land/Makefile index 2e32cd302f9..070381fa24f 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -14,7 +14,7 @@ build.gnofaucet:; go build -o build/gnofaucet ./cmd/gnofaucet build.gnokey:; go build -o build/gnokey ./cmd/gnokey build.gnotxsync:; go build -o build/gnotxsync ./cmd/gnotxsync -run.gnoland:; go run ./cmd/gnoland +run.gnoland:; go run ./cmd/gnoland start run.gnoweb:; go run ./cmd/gnoweb .PHONY: install diff --git a/gno.land/pkg/sdk/vm/handler.go b/gno.land/pkg/sdk/vm/handler.go index accaa70e059..f688842d35b 100644 --- a/gno.land/pkg/sdk/vm/handler.go +++ b/gno.land/pkg/sdk/vm/handler.go @@ -27,6 +27,8 @@ func (vh vmHandler) Process(ctx sdk.Context, msg std.Msg) sdk.Result { return vh.handleMsgAddPackage(ctx, msg) case MsgCall: return vh.handleMsgCall(ctx, msg) + case MsgExec: + return vh.handleMsgExec(ctx, msg) default: errMsg := fmt.Sprintf("unrecognized vm message type: %T", msg) return abciResult(std.ErrUnknownRequest(errMsg)) @@ -77,6 +79,25 @@ func (vh vmHandler) handleMsgCall(ctx sdk.Context, msg MsgCall) (res sdk.Result) */ } +// Handle MsgExec. +func (vh vmHandler) handleMsgExec(ctx sdk.Context, msg MsgExec) (res sdk.Result) { + amount, err := std.ParseCoins("1000000ugnot") // XXX calculate + if err != nil { + return abciResult(err) + } + err = vh.vm.bank.SendCoins(ctx, msg.Caller, auth.FeeCollectorAddress(), amount) + if err != nil { + return abciResult(err) + } + resstr := "" + resstr, err = vh.vm.Exec(ctx, msg) + if err != nil { + return abciResult(err) + } + res.Data = []byte(resstr) + return +} + //---------------------------------------- // Query diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 6f695e98558..57055079d77 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -27,6 +27,7 @@ const ( type VMKeeperI interface { AddPackage(ctx sdk.Context, msg MsgAddPackage) error Call(ctx sdk.Context, msg MsgCall) (res string, err error) + Exec(ctx sdk.Context, msg MsgExec) (res string, err error) } var _ VMKeeperI = &VMKeeper{} @@ -282,6 +283,11 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { // TODO pay for gas? TODO see context? } +// Exec executes Gno code. +func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { + panic("NOT IMPLEMENTED") +} + // QueryFuncs returns public facing function signatures. func (vm *VMKeeper) QueryFuncs(ctx sdk.Context, pkgPath string) (fsigs FunctionSignatures, err error) { store := vm.getGnoStore(ctx) From 99ed03ecf5498bd75d7a6e9a5f32cf6054b11640 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:22:54 -0400 Subject: [PATCH 05/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- tm2/pkg/crypto/keys/client/exec.go | 6 +++--- tm2/pkg/crypto/keys/client/maketx.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tm2/pkg/crypto/keys/client/exec.go b/tm2/pkg/crypto/keys/client/exec.go index f6fb859fa5e..85a63797377 100644 --- a/tm2/pkg/crypto/keys/client/exec.go +++ b/tm2/pkg/crypto/keys/client/exec.go @@ -5,11 +5,11 @@ import ( "flag" "fmt" + "github.com/gnolang/gno/gno.land/pkg/sdk/vm" "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/gnolang/gno/tm2/pkg/crypto/keys" "github.com/gnolang/gno/tm2/pkg/errors" - "github.com/gnolang/gno/tm2/pkg/sdk/vm" "github.com/gnolang/gno/tm2/pkg/std" ) @@ -19,7 +19,7 @@ type execCfg struct { source string } -func newExecCmd(rootCfg *makeTxCfg) *commands.Command { +func newExecCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { cfg := &execCfg{ rootCfg: rootCfg, } @@ -32,7 +32,7 @@ func newExecCmd(rootCfg *makeTxCfg) *commands.Command { }, cfg, func(_ context.Context, args []string) error { - return execExec(cfg, args, commands.NewDefaultIO()) + return execExec(cfg, args, io) }, ) } diff --git a/tm2/pkg/crypto/keys/client/maketx.go b/tm2/pkg/crypto/keys/client/maketx.go index 31865377d3c..f2ec91b2968 100644 --- a/tm2/pkg/crypto/keys/client/maketx.go +++ b/tm2/pkg/crypto/keys/client/maketx.go @@ -36,7 +36,7 @@ func newMakeTxCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { newAddPkgCmd(cfg, io), newSendCmd(cfg, io), newCallCmd(cfg, io), - // newExecCmd(cfg, io), + newExecCmd(cfg, io), ) return cmd From aec1e30e40730b707502e86768d50bf02dec56ec Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:14:06 -0400 Subject: [PATCH 06/24] chore: exec works, yeah Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 104 ++++++++++++++++++++++++++++- gno.land/pkg/sdk/vm/keeper_test.go | 27 ++++++++ gno.land/pkg/sdk/vm/msgs.go | 18 +++-- tm2/pkg/crypto/keys/client/exec.go | 66 ++++++++++++++---- 4 files changed, 192 insertions(+), 23 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 57055079d77..f80598c413f 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -3,6 +3,7 @@ package vm // TODO: move most of the logic in ROOT/gno.land/... import ( + "bytes" "fmt" "os" "strings" @@ -283,9 +284,108 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { // TODO pay for gas? TODO see context? } -// Exec executes Gno code. +// Exec executes arbitrary Gno code in the context of the caller's realm. func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { - panic("NOT IMPLEMENTED") + //pkgPath := "gno.land/r/main" // special user realm + caller := msg.Caller + pkgAddr := caller + store := vm.getGnoStore(ctx) + send := msg.Send + + /* addpkg */ + memPkg := msg.Package + + // Validate arguments. + callerAcc := vm.acck.GetAccount(ctx, caller) + if callerAcc == nil { + return "", std.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", caller)) + } + if err := msg.Package.Validate(); err != nil { + return "", ErrInvalidPkgPath(err.Error()) + } + /*if pv := store.GetPackage(pkgPath, false); pv != nil { + return "", ErrInvalidPkgPath("package already exists: " + pkgPath) + }*/ + + // Send send-coins to pkg from caller. + err = vm.bank.SendCoins(ctx, caller, pkgAddr, send) + if err != nil { + return "", err + } + + // Parse and run the files, construct *PV. + msgCtx := stdlibs.ExecContext{ + ChainID: ctx.ChainID(), + Height: ctx.BlockHeight(), + Timestamp: ctx.BlockTime().Unix(), + Msg: msg, + OrigCaller: caller.Bech32(), + OrigSend: send, + OrigSendSpent: new(std.Coins), + OrigPkgAddr: pkgAddr.Bech32(), + Banker: NewSDKBanker(vm, ctx), + } + // Parse and run the files, construct *PV. + buf := new(bytes.Buffer) + m := gno.NewMachineWithOptions( + gno.MachineOptions{ + //Output: os.Stdout, // XXX + PkgPath: "", + Output: buf, + Store: store, + Alloc: store.GetAllocator(), + Context: msgCtx, + MaxCycles: vm.maxCycles, + }) + defer m.Release() + _, pv := m.RunMemPackage(memPkg, true) // XXX: just save the contract, not the state + + ctx.Logger().Info("CPUCYCLES", "addpkg", m.Cycles) + /* /addpkg */ + + // Get the package and function type. + // pv := store.GetPackage(pkgPath, false) + // Make main Package with imports. + //mpn := gno.NewPackageNode("main", "main", nil) + //mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) + //mpv := mpn.NewPackage() + // Parse expression. + expr := fmt.Sprintf(`pkg.Main()`) + xn := gno.MustParseExpr(expr) + // Convert Args to gno values. + cx := xn.(*gno.CallExpr) + if cx.Varg { + panic("variadic calls not yet supported") + } + // Construct machine and evaluate. + /*m := gno.NewMachineWithOptions( + gno.MachineOptions{ + PkgPath: "", + Output: os.Stdout, // XXX + Store: store, + Context: msgCtx, + Alloc: store.GetAllocator(), + MaxCycles: vm.maxCycles, + })*/ + + //fset := gno.ParseMemPackage(memPkg) + mpn := gno.NewPackageNode("main", "main", nil) //fset) + // pv := mpn.NewPackage() + mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) + mpv := mpn.NewPackage() + m.SetActivePackage(mpv) + defer func() { + if r := recover(); r != nil { + err = errors.Wrap(fmt.Errorf("%v", r), "VM call panic: %v\n%s\n", + r, m.String()) + return + } + m.Release() + }() + m.Eval(xn) + ctx.Logger().Info("CPUCYCLES call: ", m.Cycles) + res = buf.String() + return res, nil } // QueryFuncs returns public facing function signatures. diff --git a/gno.land/pkg/sdk/vm/keeper_test.go b/gno.land/pkg/sdk/vm/keeper_test.go index 27a1054e914..4edaa0f31b1 100644 --- a/gno.land/pkg/sdk/vm/keeper_test.go +++ b/gno.land/pkg/sdk/vm/keeper_test.go @@ -337,3 +337,30 @@ func GetAdmin() string { assert.NoError(t, err) assert.Equal(t, res, addrString) } + +// Call Exec without imports, without variables. +func TestVMKeeperExecSimple(t *testing.T) { + env := setupTestEnv() + ctx := env.ctx + + // Give "addr1" some gnots. + addr := crypto.AddressFromPreimage([]byte("addr1")) + acc := env.acck.NewAccountWithAddress(ctx, addr) + env.acck.SetAccount(ctx, acc) + + files := []*std.MemFile{ + {"script.gno", ` +package main + +func Main() { + println("hello world!") +} +`}, + } + + coins := std.MustParseCoins("") + msg2 := NewMsgExec(addr, coins, files) + res, err := env.vmk.Exec(ctx, msg2) + assert.NoError(t, err) + assert.Equal(t, res, "hello world!\n") +} diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index cc94d93e9e0..c7858c2d8f1 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -141,18 +141,22 @@ func (msg MsgCall) GetReceived() std.Coins { // MsgExec - executes arbitrary Gno code. type MsgExec struct { - Caller crypto.Address `json:"caller" yaml:"caller"` - Send std.Coins `json:"send" yaml:"send"` - Source string `json:"source" yaml:"source"` + Caller crypto.Address `json:"caller" yaml:"caller"` + Send std.Coins `json:"send" yaml:"send"` + Package *std.MemPackage `json:"package" yaml:"package"` } var _ std.Msg = MsgExec{} -func NewMsgExec(caller crypto.Address, send std.Coins, source string) MsgExec { +func NewMsgExec(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgExec { return MsgExec{ Caller: caller, Send: send, - Source: source, + Package: &std.MemPackage{ + Name: "main", + Path: "gno.land/r/main", // XXX + Files: files, + }, } } @@ -167,8 +171,8 @@ func (msg MsgExec) ValidateBasic() error { if msg.Caller.IsZero() { return std.ErrInvalidAddress("missing caller address") } - if msg.Source == "" { // XXX - return ErrInvalidExpr("missing source to exec") + if msg.Package.Path == "" { // XXX + return ErrInvalidPkgPath("missing package path") } return nil } diff --git a/tm2/pkg/crypto/keys/client/exec.go b/tm2/pkg/crypto/keys/client/exec.go index 85a63797377..f02c96751e9 100644 --- a/tm2/pkg/crypto/keys/client/exec.go +++ b/tm2/pkg/crypto/keys/client/exec.go @@ -4,8 +4,11 @@ import ( "context" "flag" "fmt" + "io/ioutil" + "os" "github.com/gnolang/gno/gno.land/pkg/sdk/vm" + gno "github.com/gnolang/gno/gnovm/pkg/gnolang" "github.com/gnolang/gno/tm2/pkg/amino" "github.com/gnolang/gno/tm2/pkg/commands" "github.com/gnolang/gno/tm2/pkg/crypto/keys" @@ -16,7 +19,6 @@ import ( type execCfg struct { rootCfg *makeTxCfg send string - source string } func newExecCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { @@ -27,7 +29,7 @@ func newExecCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { return commands.NewCommand( commands.Metadata{ Name: "exec", - ShortUsage: "exec [flags] ", + ShortUsage: "exec [flags] ", ShortHelp: "Executes arbitrary Gno code", }, cfg, @@ -40,7 +42,7 @@ func newExecCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { func (c *execCfg) RegisterFlags(fs *flag.FlagSet) {} func execExec(cfg *execCfg, args []string, io *commands.IO) error { - if len(args) != 1 { + if len(args) != 2 { return flag.ErrHelp } if cfg.rootCfg.gasWanted == 0 { @@ -50,17 +52,10 @@ func execExec(cfg *execCfg, args []string, io *commands.IO) error { return errors.New("gas-fee not specified") } - // read statement. - // TODO: parse stdin - source := cfg.source - source = "package main\nfunc main() {println(\"42\")}" - if source == "" { - return errors.New("empty source") - } - // TODO: validate source + nameOrBech32 := args[0] + sourcePath := args[1] // can be a file path, a dir path, or '-' for stdin // read account pubkey. - nameOrBech32 := args[0] kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.rootCfg.Home) if err != nil { return err @@ -78,10 +73,53 @@ func execExec(cfg *execCfg, args []string, io *commands.IO) error { return errors.Wrap(err, "parsing gas fee coin") } + var memPkg = &std.MemPackage{} + if sourcePath == "-" { // stdin + data, err := ioutil.ReadAll(io.In) + if err != nil { + return fmt.Errorf("could not read stdin: %w", err) + } + memPkg.Files = []*std.MemFile{ + { + Name: "stdin.gno", + Body: string(data), + }, + } + } else { + info, err := os.Stat(sourcePath) + if err != nil { + return fmt.Errorf("could not read source path: %q, %w", sourcePath, err) + } + if info.IsDir() { + memPkg = gno.ReadMemPackage(sourcePath, "") + } else { // is file + b, err := os.ReadFile(sourcePath) + if err != nil { + return fmt.Errorf("could not read %q: %w", sourcePath, err) + } + memPkg.Files = []*std.MemFile{ + { + Name: info.Name(), + Body: string(b), + }, + } + } + } + memPkg.Name = "main" + memPkg.Path = "gno.land/r/main" + if memPkg.IsEmpty() { + panic(fmt.Sprintf("found an empty package %q", memPkg.Path)) + } + // precompile and validate syntax + err = gno.PrecompileAndCheckMempkg(memPkg) + if err != nil { + panic(err) + } + // construct msg & tx and marshal. msg := vm.MsgExec{ - Caller: caller, - Source: source, + Caller: caller, + Package: memPkg, } tx := std.Tx{ Msgs: []std.Msg{msg}, From 4c00a5885e43b8eb019f4d61f8d0c05eefd1352d Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:01:56 -0400 Subject: [PATCH 07/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 58 ++++++++++-------------------- gno.land/pkg/sdk/vm/keeper_test.go | 31 ++++++++++++++++ 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index f80598c413f..7a4bbae520f 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -286,13 +286,10 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { // Exec executes arbitrary Gno code in the context of the caller's realm. func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { - //pkgPath := "gno.land/r/main" // special user realm caller := msg.Caller pkgAddr := caller store := vm.getGnoStore(ctx) send := msg.Send - - /* addpkg */ memPkg := msg.Package // Validate arguments. @@ -303,9 +300,6 @@ func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { if err := msg.Package.Validate(); err != nil { return "", ErrInvalidPkgPath(err.Error()) } - /*if pv := store.GetPackage(pkgPath, false); pv != nil { - return "", ErrInvalidPkgPath("package already exists: " + pkgPath) - }*/ // Send send-coins to pkg from caller. err = vm.bank.SendCoins(ctx, caller, pkgAddr, send) @@ -329,7 +323,6 @@ func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { buf := new(bytes.Buffer) m := gno.NewMachineWithOptions( gno.MachineOptions{ - //Output: os.Stdout, // XXX PkgPath: "", Output: buf, Store: store, @@ -338,52 +331,39 @@ func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { MaxCycles: vm.maxCycles, }) defer m.Release() - _, pv := m.RunMemPackage(memPkg, true) // XXX: just save the contract, not the state + // memPkg.Path = "gno.land/r/main" + _, pv := m.RunMemPackage(memPkg, true) // XXX: just save the state, not the contract ctx.Logger().Info("CPUCYCLES", "addpkg", m.Cycles) - /* /addpkg */ - // Get the package and function type. - // pv := store.GetPackage(pkgPath, false) - // Make main Package with imports. - //mpn := gno.NewPackageNode("main", "main", nil) - //mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) - //mpv := mpn.NewPackage() - // Parse expression. expr := fmt.Sprintf(`pkg.Main()`) xn := gno.MustParseExpr(expr) - // Convert Args to gno values. - cx := xn.(*gno.CallExpr) - if cx.Varg { - panic("variadic calls not yet supported") - } - // Construct machine and evaluate. - /*m := gno.NewMachineWithOptions( - gno.MachineOptions{ - PkgPath: "", - Output: os.Stdout, // XXX - Store: store, - Context: msgCtx, - Alloc: store.GetAllocator(), - MaxCycles: vm.maxCycles, - })*/ - - //fset := gno.ParseMemPackage(memPkg) mpn := gno.NewPackageNode("main", "main", nil) //fset) - // pv := mpn.NewPackage() mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) mpv := mpn.NewPackage() - m.SetActivePackage(mpv) + + m2 := gno.NewMachineWithOptions( + gno.MachineOptions{ + PkgPath: "", + Output: buf, + Store: store, + Alloc: store.GetAllocator(), + Context: msgCtx, + MaxCycles: vm.maxCycles, + }) + //defer m2.Release() + + m2.SetActivePackage(mpv) defer func() { if r := recover(); r != nil { err = errors.Wrap(fmt.Errorf("%v", r), "VM call panic: %v\n%s\n", - r, m.String()) + r, m2.String()) return } - m.Release() + m2.Release() }() - m.Eval(xn) - ctx.Logger().Info("CPUCYCLES call: ", m.Cycles) + m2.Eval(xn) + ctx.Logger().Info("CPUCYCLES call: ", m2.Cycles) res = buf.String() return res, nil } diff --git a/gno.land/pkg/sdk/vm/keeper_test.go b/gno.land/pkg/sdk/vm/keeper_test.go index 4edaa0f31b1..d57bc3e6efb 100644 --- a/gno.land/pkg/sdk/vm/keeper_test.go +++ b/gno.land/pkg/sdk/vm/keeper_test.go @@ -364,3 +364,34 @@ func Main() { assert.NoError(t, err) assert.Equal(t, res, "hello world!\n") } + +// Call Exec with stdlibs. +func TestVMKeeperExecImportStdlibs(t *testing.T) { + env := setupTestEnv() + ctx := env.ctx + + // Give "addr1" some gnots. + addr := crypto.AddressFromPreimage([]byte("addr1")) + acc := env.acck.NewAccountWithAddress(ctx, addr) + env.acck.SetAccount(ctx, acc) + + files := []*std.MemFile{ + {"script.gno", ` +package main + +import "std" + +func Main() { + addr := std.GetOrigCaller() + println("hello world!", addr) +} +`}, + } + + coins := std.MustParseCoins("") + msg2 := NewMsgExec(addr, coins, files) + res, err := env.vmk.Exec(ctx, msg2) + assert.NoError(t, err) + expectedString := fmt.Sprintf("hello world! %s\n", addr.String()) + assert.Equal(t, res, expectedString) +} From 15b1a7d54d45262000169f688538b77795092211 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:41:54 -0400 Subject: [PATCH 08/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 3 +-- tm2/pkg/crypto/keys/client/exec.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 7a4bbae520f..9bcfc77cd3e 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -338,7 +338,7 @@ func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { expr := fmt.Sprintf(`pkg.Main()`) xn := gno.MustParseExpr(expr) - mpn := gno.NewPackageNode("main", "main", nil) //fset) + mpn := gno.NewPackageNode("main", "main", nil) mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) mpv := mpn.NewPackage() @@ -351,7 +351,6 @@ func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { Context: msgCtx, MaxCycles: vm.maxCycles, }) - //defer m2.Release() m2.SetActivePackage(mpv) defer func() { diff --git a/tm2/pkg/crypto/keys/client/exec.go b/tm2/pkg/crypto/keys/client/exec.go index f02c96751e9..c61925e4a1e 100644 --- a/tm2/pkg/crypto/keys/client/exec.go +++ b/tm2/pkg/crypto/keys/client/exec.go @@ -73,7 +73,7 @@ func execExec(cfg *execCfg, args []string, io *commands.IO) error { return errors.Wrap(err, "parsing gas fee coin") } - var memPkg = &std.MemPackage{} + memPkg := &std.MemPackage{} if sourcePath == "-" { // stdin data, err := ioutil.ReadAll(io.In) if err != nil { From f86a71f93343e6b406dfd6d216b79966e188f420 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:47:41 -0400 Subject: [PATCH 09/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/handler.go | 10 +++---- gno.land/pkg/sdk/vm/keeper.go | 8 +++--- gno.land/pkg/sdk/vm/keeper_test.go | 16 +++++------ gno.land/pkg/sdk/vm/msgs.go | 28 +++++++++---------- gno.land/pkg/sdk/vm/package.go | 2 +- tm2/pkg/crypto/keys/client/maketx.go | 2 +- .../crypto/keys/client/{exec.go => run.go} | 20 ++++++------- 7 files changed, 43 insertions(+), 43 deletions(-) rename tm2/pkg/crypto/keys/client/{exec.go => run.go} (86%) diff --git a/gno.land/pkg/sdk/vm/handler.go b/gno.land/pkg/sdk/vm/handler.go index f688842d35b..6c3a97696d6 100644 --- a/gno.land/pkg/sdk/vm/handler.go +++ b/gno.land/pkg/sdk/vm/handler.go @@ -27,8 +27,8 @@ func (vh vmHandler) Process(ctx sdk.Context, msg std.Msg) sdk.Result { return vh.handleMsgAddPackage(ctx, msg) case MsgCall: return vh.handleMsgCall(ctx, msg) - case MsgExec: - return vh.handleMsgExec(ctx, msg) + case MsgRun: + return vh.handleMsgRun(ctx, msg) default: errMsg := fmt.Sprintf("unrecognized vm message type: %T", msg) return abciResult(std.ErrUnknownRequest(errMsg)) @@ -79,8 +79,8 @@ func (vh vmHandler) handleMsgCall(ctx sdk.Context, msg MsgCall) (res sdk.Result) */ } -// Handle MsgExec. -func (vh vmHandler) handleMsgExec(ctx sdk.Context, msg MsgExec) (res sdk.Result) { +// Handle MsgRun. +func (vh vmHandler) handleMsgRun(ctx sdk.Context, msg MsgRun) (res sdk.Result) { amount, err := std.ParseCoins("1000000ugnot") // XXX calculate if err != nil { return abciResult(err) @@ -90,7 +90,7 @@ func (vh vmHandler) handleMsgExec(ctx sdk.Context, msg MsgExec) (res sdk.Result) return abciResult(err) } resstr := "" - resstr, err = vh.vm.Exec(ctx, msg) + resstr, err = vh.vm.Run(ctx, msg) if err != nil { return abciResult(err) } diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 9bcfc77cd3e..299fbeb0391 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -28,7 +28,7 @@ const ( type VMKeeperI interface { AddPackage(ctx sdk.Context, msg MsgAddPackage) error Call(ctx sdk.Context, msg MsgCall) (res string, err error) - Exec(ctx sdk.Context, msg MsgExec) (res string, err error) + Run(ctx sdk.Context, msg MsgRun) (res string, err error) } var _ VMKeeperI = &VMKeeper{} @@ -44,7 +44,7 @@ type VMKeeper struct { // cached, the DeliverTx persistent state. gnoStore gno.Store - maxCycles int64 // max allowed cylces on VM executions + maxCycles int64 // max allowed cylces on VM runutions } // NewVMKeeper returns a new VMKeeper. @@ -284,8 +284,8 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { // TODO pay for gas? TODO see context? } -// Exec executes arbitrary Gno code in the context of the caller's realm. -func (vm *VMKeeper) Exec(ctx sdk.Context, msg MsgExec) (res string, err error) { +// Run runutes arbitrary Gno code in the context of the caller's realm. +func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { caller := msg.Caller pkgAddr := caller store := vm.getGnoStore(ctx) diff --git a/gno.land/pkg/sdk/vm/keeper_test.go b/gno.land/pkg/sdk/vm/keeper_test.go index d57bc3e6efb..0cf3eacdc5d 100644 --- a/gno.land/pkg/sdk/vm/keeper_test.go +++ b/gno.land/pkg/sdk/vm/keeper_test.go @@ -338,8 +338,8 @@ func GetAdmin() string { assert.Equal(t, res, addrString) } -// Call Exec without imports, without variables. -func TestVMKeeperExecSimple(t *testing.T) { +// Call Run without imports, without variables. +func TestVMKeeperRunSimple(t *testing.T) { env := setupTestEnv() ctx := env.ctx @@ -359,14 +359,14 @@ func Main() { } coins := std.MustParseCoins("") - msg2 := NewMsgExec(addr, coins, files) - res, err := env.vmk.Exec(ctx, msg2) + msg2 := NewMsgRun(addr, coins, files) + res, err := env.vmk.Run(ctx, msg2) assert.NoError(t, err) assert.Equal(t, res, "hello world!\n") } -// Call Exec with stdlibs. -func TestVMKeeperExecImportStdlibs(t *testing.T) { +// Call Run with stdlibs. +func TestVMKeeperRunImportStdlibs(t *testing.T) { env := setupTestEnv() ctx := env.ctx @@ -389,8 +389,8 @@ func Main() { } coins := std.MustParseCoins("") - msg2 := NewMsgExec(addr, coins, files) - res, err := env.vmk.Exec(ctx, msg2) + msg2 := NewMsgRun(addr, coins, files) + res, err := env.vmk.Run(ctx, msg2) assert.NoError(t, err) expectedString := fmt.Sprintf("hello world! %s\n", addr.String()) assert.Equal(t, res, expectedString) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index c7858c2d8f1..84dfcd8d927 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -80,7 +80,7 @@ func (msg MsgAddPackage) GetReceived() std.Coins { //---------------------------------------- // MsgCall -// MsgCall - executes a Gno statement. +// MsgCall - runutes a Gno statement. type MsgCall struct { Caller crypto.Address `json:"caller" yaml:"caller"` Send std.Coins `json:"send" yaml:"send"` @@ -105,7 +105,7 @@ func NewMsgCall(caller crypto.Address, send sdk.Coins, pkgPath, fnc string, args func (msg MsgCall) Route() string { return RouterKey } // Implements Msg. -func (msg MsgCall) Type() string { return "exec" } +func (msg MsgCall) Type() string { return "run" } // Implements Msg. func (msg MsgCall) ValidateBasic() error { @@ -137,19 +137,19 @@ func (msg MsgCall) GetReceived() std.Coins { } //---------------------------------------- -// MsgExec +// MsgRun -// MsgExec - executes arbitrary Gno code. -type MsgExec struct { +// MsgRun - runutes arbitrary Gno code. +type MsgRun struct { Caller crypto.Address `json:"caller" yaml:"caller"` Send std.Coins `json:"send" yaml:"send"` Package *std.MemPackage `json:"package" yaml:"package"` } -var _ std.Msg = MsgExec{} +var _ std.Msg = MsgRun{} -func NewMsgExec(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgExec { - return MsgExec{ +func NewMsgRun(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgRun { + return MsgRun{ Caller: caller, Send: send, Package: &std.MemPackage{ @@ -161,13 +161,13 @@ func NewMsgExec(caller crypto.Address, send std.Coins, files []*std.MemFile) Msg } // Implements Msg. -func (msg MsgExec) Route() string { return RouterKey } +func (msg MsgRun) Route() string { return RouterKey } // Implements Msg. -func (msg MsgExec) Type() string { return "exec" } +func (msg MsgRun) Type() string { return "run" } // Implements Msg. -func (msg MsgExec) ValidateBasic() error { +func (msg MsgRun) ValidateBasic() error { if msg.Caller.IsZero() { return std.ErrInvalidAddress("missing caller address") } @@ -178,16 +178,16 @@ func (msg MsgExec) ValidateBasic() error { } // Implements Msg. -func (msg MsgExec) GetSignBytes() []byte { +func (msg MsgRun) GetSignBytes() []byte { return std.MustSortJSON(amino.MustMarshalJSON(msg)) } // Implements Msg. -func (msg MsgExec) GetSigners() []crypto.Address { +func (msg MsgRun) GetSigners() []crypto.Address { return []crypto.Address{msg.Caller} } // Implements ReceiveMsg. -func (msg MsgExec) GetReceived() std.Coins { +func (msg MsgRun) GetReceived() std.Coins { return msg.Send } diff --git a/gno.land/pkg/sdk/vm/package.go b/gno.land/pkg/sdk/vm/package.go index a172dc13e9f..01fad3284e3 100644 --- a/gno.land/pkg/sdk/vm/package.go +++ b/gno.land/pkg/sdk/vm/package.go @@ -13,7 +13,7 @@ var Package = amino.RegisterPackage(amino.NewPackage( std.Package, ).WithTypes( MsgCall{}, "m_call", - MsgExec{}, "m_exec", + MsgRun{}, "m_run", MsgAddPackage{}, "m_addpkg", // TODO rename both to MsgAddPkg? // errors diff --git a/tm2/pkg/crypto/keys/client/maketx.go b/tm2/pkg/crypto/keys/client/maketx.go index f2ec91b2968..d55c13f5045 100644 --- a/tm2/pkg/crypto/keys/client/maketx.go +++ b/tm2/pkg/crypto/keys/client/maketx.go @@ -36,7 +36,7 @@ func newMakeTxCmd(rootCfg *baseCfg, io *commands.IO) *commands.Command { newAddPkgCmd(cfg, io), newSendCmd(cfg, io), newCallCmd(cfg, io), - newExecCmd(cfg, io), + newRunCmd(cfg, io), ) return cmd diff --git a/tm2/pkg/crypto/keys/client/exec.go b/tm2/pkg/crypto/keys/client/run.go similarity index 86% rename from tm2/pkg/crypto/keys/client/exec.go rename to tm2/pkg/crypto/keys/client/run.go index c61925e4a1e..ff3546aafc9 100644 --- a/tm2/pkg/crypto/keys/client/exec.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -16,32 +16,32 @@ import ( "github.com/gnolang/gno/tm2/pkg/std" ) -type execCfg struct { +type runCfg struct { rootCfg *makeTxCfg send string } -func newExecCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { - cfg := &execCfg{ +func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { + cfg := &runCfg{ rootCfg: rootCfg, } return commands.NewCommand( commands.Metadata{ - Name: "exec", - ShortUsage: "exec [flags] ", - ShortHelp: "Executes arbitrary Gno code", + Name: "run", + ShortUsage: "run [flags] ", + ShortHelp: "Runutes arbitrary Gno code", }, cfg, func(_ context.Context, args []string) error { - return execExec(cfg, args, io) + return runRun(cfg, args, io) }, ) } -func (c *execCfg) RegisterFlags(fs *flag.FlagSet) {} +func (c *runCfg) RegisterFlags(fs *flag.FlagSet) {} -func execExec(cfg *execCfg, args []string, io *commands.IO) error { +func runRun(cfg *runCfg, args []string, io *commands.IO) error { if len(args) != 2 { return flag.ErrHelp } @@ -117,7 +117,7 @@ func execExec(cfg *execCfg, args []string, io *commands.IO) error { } // construct msg & tx and marshal. - msg := vm.MsgExec{ + msg := vm.MsgRun{ Caller: caller, Package: memPkg, } From 6d7dad77c39ebca781bf5ffbbac95cd1a6180eb8 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:01:30 -0400 Subject: [PATCH 10/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 4 ++-- gno.land/pkg/sdk/vm/msgs.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 299fbeb0391..bea41c23404 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -44,7 +44,7 @@ type VMKeeper struct { // cached, the DeliverTx persistent state. gnoStore gno.Store - maxCycles int64 // max allowed cylces on VM runutions + maxCycles int64 // max allowed cylces on VM executions } // NewVMKeeper returns a new VMKeeper. @@ -284,7 +284,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { // TODO pay for gas? TODO see context? } -// Run runutes arbitrary Gno code in the context of the caller's realm. +// Run executes arbitrary Gno code in the context of the caller's realm. func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { caller := msg.Caller pkgAddr := caller diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 84dfcd8d927..69697953438 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -80,7 +80,7 @@ func (msg MsgAddPackage) GetReceived() std.Coins { //---------------------------------------- // MsgCall -// MsgCall - runutes a Gno statement. +// MsgCall - executes a Gno statement. type MsgCall struct { Caller crypto.Address `json:"caller" yaml:"caller"` Send std.Coins `json:"send" yaml:"send"` @@ -139,7 +139,7 @@ func (msg MsgCall) GetReceived() std.Coins { //---------------------------------------- // MsgRun -// MsgRun - runutes arbitrary Gno code. +// MsgRun - executes arbitrary Gno code. type MsgRun struct { Caller crypto.Address `json:"caller" yaml:"caller"` Send std.Coins `json:"send" yaml:"send"` From 3290b42e5663554398dfde3dd1735f8a32eddaac Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:03:00 -0400 Subject: [PATCH 11/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 69697953438..6fcdf376823 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -164,7 +164,7 @@ func NewMsgRun(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgR func (msg MsgRun) Route() string { return RouterKey } // Implements Msg. -func (msg MsgRun) Type() string { return "run" } +func (msg MsgRun) Type() string { return "exec" } // Implements Msg. func (msg MsgRun) ValidateBasic() error { From 75aa855611aca9d1b7e0536fe27391d3f6b70b8b Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:03:49 -0400 Subject: [PATCH 12/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/msgs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 6fcdf376823..6bb29e718dd 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -105,7 +105,7 @@ func NewMsgCall(caller crypto.Address, send sdk.Coins, pkgPath, fnc string, args func (msg MsgCall) Route() string { return RouterKey } // Implements Msg. -func (msg MsgCall) Type() string { return "run" } +func (msg MsgCall) Type() string { return "exec" } // Implements Msg. func (msg MsgCall) ValidateBasic() error { @@ -164,7 +164,7 @@ func NewMsgRun(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgR func (msg MsgRun) Route() string { return RouterKey } // Implements Msg. -func (msg MsgRun) Type() string { return "exec" } +func (msg MsgRun) Type() string { return "run" } // Implements Msg. func (msg MsgRun) ValidateBasic() error { From cea959cd6272beb5f8082dc64f2377fd1c8fdbf8 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:20:09 -0400 Subject: [PATCH 13/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/msgs.go | 8 ++++++++ tm2/pkg/crypto/keys/client/run.go | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 6bb29e718dd..9c2d043e4ac 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -149,6 +149,14 @@ type MsgRun struct { var _ std.Msg = MsgRun{} func NewMsgRun(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgRun { + for _, file := range files { + if strings.HasSuffix(file.Name, ".gno") { + pkgName := string(gno.PackageNameFromFileBody(file.Name, file.Body)) + if pkgName != "main" { + panic("package name should be 'main'") + } + } + } return MsgRun{ Caller: caller, Send: send, diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index ff3546aafc9..ec0135d228a 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -105,8 +105,6 @@ func runRun(cfg *runCfg, args []string, io *commands.IO) error { } } } - memPkg.Name = "main" - memPkg.Path = "gno.land/r/main" if memPkg.IsEmpty() { panic(fmt.Sprintf("found an empty package %q", memPkg.Path)) } @@ -115,6 +113,8 @@ func runRun(cfg *runCfg, args []string, io *commands.IO) error { if err != nil { panic(err) } + memPkg.Name = "main" + memPkg.Path = "gno.land/r/main" // construct msg & tx and marshal. msg := vm.MsgRun{ From 296a6bbaa369e0eb0ad47e769c99c5fbc5410a43 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 00:59:23 -0400 Subject: [PATCH 14/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/cmd/gnoland/testdata/addpkg.txtar | 2 +- gno.land/cmd/gnoland/testdata/exec.txtar | 28 ++++++++++++++++++++++ tm2/pkg/crypto/keys/client/run.go | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 gno.land/cmd/gnoland/testdata/exec.txtar diff --git a/gno.land/cmd/gnoland/testdata/addpkg.txtar b/gno.land/cmd/gnoland/testdata/addpkg.txtar index 5e871b058ac..8cc60635d7d 100644 --- a/gno.land/cmd/gnoland/testdata/addpkg.txtar +++ b/gno.land/cmd/gnoland/testdata/addpkg.txtar @@ -23,4 +23,4 @@ func Render(path string) string { ("hello from foo" string) OK! GAS WANTED: 2000000 -GAS USED: 69163 \ No newline at end of file +GAS USED: 69163 diff --git a/gno.land/cmd/gnoland/testdata/exec.txtar b/gno.land/cmd/gnoland/testdata/exec.txtar new file mode 100644 index 00000000000..b2de2e56579 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/exec.txtar @@ -0,0 +1,28 @@ +## start a new node +gnoland start + +## add bar.gno package located in $WORK directory as gno.land/r/foobar/bar +gnokey maketx addpkg -pkgdir $WORK/bar -pkgpath gno.land/r/foobar/bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 + +## execute Render +gnokey maketx run -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 $WORK/script/script.gno + +## compare render +stdout '--- hello from foo ---' +stdout 'OK!' +stdout 'GAS WANTED: 200000' +stdout 'GAS USED: ' + +-- bar/bar.gno -- +package bar + +func Render(path string) string { + return "hello from foo" +} + +-- script/script.gno -- +package main +import "gno.land/r/foobar/bar" +func Main() { + println("---", bar.Render(""), "---") +} diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index ec0135d228a..c1f0208c7f0 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -30,7 +30,7 @@ func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { commands.Metadata{ Name: "run", ShortUsage: "run [flags] ", - ShortHelp: "Runutes arbitrary Gno code", + ShortHelp: "utes arbitrary Gno code", }, cfg, func(_ context.Context, args []string) error { From bbe039d1316d0f06814b7260ca96e2ad9a710ffe Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:01:44 -0400 Subject: [PATCH 15/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/cmd/gnoland/testdata/addpkg.txtar | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gno.land/cmd/gnoland/testdata/addpkg.txtar b/gno.land/cmd/gnoland/testdata/addpkg.txtar index 8cc60635d7d..f5024fdb59e 100644 --- a/gno.land/cmd/gnoland/testdata/addpkg.txtar +++ b/gno.land/cmd/gnoland/testdata/addpkg.txtar @@ -10,7 +10,10 @@ gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/foobar/bar -gas-fee 10000 gnokey maketx call -pkgpath gno.land/r/foobar/bar -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1 ## compare render -cmp stdout stdout.golden +stdout '("hello from foo" string)' +stdout 'OK!' +stdout 'GAS WANTED: 2000000' +stdout 'GAS USED: ' -- bar.gno -- package bar @@ -18,9 +21,3 @@ package bar func Render(path string) string { return "hello from foo" } - --- stdout.golden -- -("hello from foo" string) -OK! -GAS WANTED: 2000000 -GAS USED: 69163 From c1247b0cfad7a7cd68451fda677cf7e189f9ef0c Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:20:20 -0400 Subject: [PATCH 16/24] Update tm2/pkg/crypto/keys/client/run.go --- tm2/pkg/crypto/keys/client/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index c1f0208c7f0..45dc15fde26 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -30,7 +30,7 @@ func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { commands.Metadata{ Name: "run", ShortUsage: "run [flags] ", - ShortHelp: "utes arbitrary Gno code", + ShortHelp: "Executes arbitrary Gno code", }, cfg, func(_ context.Context, args []string) error { From 847ff8b4650701bfe530f827f99562a6ea27e5aa Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:31:38 -0400 Subject: [PATCH 17/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index bea41c23404..7ef34c1fc60 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -332,7 +332,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { }) defer m.Release() // memPkg.Path = "gno.land/r/main" - _, pv := m.RunMemPackage(memPkg, true) // XXX: just save the state, not the contract + _, pv := m.RunMemPackage(memPkg, false) ctx.Logger().Info("CPUCYCLES", "addpkg", m.Cycles) From 458e9fe0004c867ddbdd68f0d297541e3c054800 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:49:59 -0400 Subject: [PATCH 18/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- .../cmd/gnoland/testdata/{exec.txtar => run.txtar} | 6 +++--- gno.land/pkg/sdk/vm/keeper.go | 14 +++----------- 2 files changed, 6 insertions(+), 14 deletions(-) rename gno.land/cmd/gnoland/testdata/{exec.txtar => run.txtar} (87%) diff --git a/gno.land/cmd/gnoland/testdata/exec.txtar b/gno.land/cmd/gnoland/testdata/run.txtar similarity index 87% rename from gno.land/cmd/gnoland/testdata/exec.txtar rename to gno.land/cmd/gnoland/testdata/run.txtar index b2de2e56579..94b32de041e 100644 --- a/gno.land/cmd/gnoland/testdata/exec.txtar +++ b/gno.land/cmd/gnoland/testdata/run.txtar @@ -8,7 +8,7 @@ gnokey maketx addpkg -pkgdir $WORK/bar -pkgpath gno.land/r/foobar/bar -gas-fee 1 gnokey maketx run -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 $WORK/script/script.gno ## compare render -stdout '--- hello from foo ---' +stdout 'main: --- hello from foo ---' stdout 'OK!' stdout 'GAS WANTED: 200000' stdout 'GAS USED: ' @@ -23,6 +23,6 @@ func Render(path string) string { -- script/script.gno -- package main import "gno.land/r/foobar/bar" -func Main() { - println("---", bar.Render(""), "---") +func main() { + println("main: ---", bar.Render(""), "---") } diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 7ef34c1fc60..ec8e12bbf04 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -331,17 +331,10 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { MaxCycles: vm.maxCycles, }) defer m.Release() - // memPkg.Path = "gno.land/r/main" + memPkg.Path = "gno.land/r/" + caller.String() + "/run" _, pv := m.RunMemPackage(memPkg, false) - ctx.Logger().Info("CPUCYCLES", "addpkg", m.Cycles) - expr := fmt.Sprintf(`pkg.Main()`) - xn := gno.MustParseExpr(expr) - mpn := gno.NewPackageNode("main", "main", nil) - mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) - mpv := mpn.NewPackage() - m2 := gno.NewMachineWithOptions( gno.MachineOptions{ PkgPath: "", @@ -351,8 +344,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { Context: msgCtx, MaxCycles: vm.maxCycles, }) - - m2.SetActivePackage(mpv) + m2.SetActivePackage(pv) defer func() { if r := recover(); r != nil { err = errors.Wrap(fmt.Errorf("%v", r), "VM call panic: %v\n%s\n", @@ -361,7 +353,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { } m2.Release() }() - m2.Eval(xn) + m2.RunMain() ctx.Logger().Info("CPUCYCLES call: ", m2.Cycles) res = buf.String() return res, nil From 7040e8ff003d5413e5803988d0b425ef11951115 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:07:46 -0400 Subject: [PATCH 19/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index ec8e12bbf04..d65011dfa01 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -6,6 +6,7 @@ import ( "bytes" "fmt" "os" + "regexp" "strings" gno "github.com/gnolang/gno/gnovm/pkg/gnolang" @@ -130,6 +131,10 @@ func (vm *VMKeeper) getGnoStore(ctx sdk.Context) gno.Store { } } +const ( + reReservedPath = `gno\.land/r/g[a-z0-9]+/run` +) + // AddPackage adds a package with given fileset. func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) error { creator := msg.Creator @@ -152,6 +157,11 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) error { if pv := store.GetPackage(pkgPath, false); pv != nil { return ErrInvalidPkgPath("package already exists: " + pkgPath) } + + if ok, _ := regexp.MatchString(reReservedPath, pkgPath); ok { + return ErrInvalidPkgPath("reserved package name: " + pkgPath) + } + // Pay deposit from creator. pkgAddr := gno.DerivePkgAddr(pkgPath) From d50432b8426d038e114db19e8a30ebe22380db9a Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:41:17 -0400 Subject: [PATCH 20/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper.go | 1 - gno.land/pkg/sdk/vm/msgs.go | 2 +- tm2/pkg/crypto/keys/client/run.go | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index d65011dfa01..b0ae2180c36 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -341,7 +341,6 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { MaxCycles: vm.maxCycles, }) defer m.Release() - memPkg.Path = "gno.land/r/" + caller.String() + "/run" _, pv := m.RunMemPackage(memPkg, false) ctx.Logger().Info("CPUCYCLES", "addpkg", m.Cycles) diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index 9c2d043e4ac..f1e65ae25cb 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -162,7 +162,7 @@ func NewMsgRun(caller crypto.Address, send std.Coins, files []*std.MemFile) MsgR Send: send, Package: &std.MemPackage{ Name: "main", - Path: "gno.land/r/main", // XXX + Path: "gno.land/r/" + caller.String() + "/run", Files: files, }, } diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index 45dc15fde26..ba3089a3852 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -114,7 +114,7 @@ func runRun(cfg *runCfg, args []string, io *commands.IO) error { panic(err) } memPkg.Name = "main" - memPkg.Path = "gno.land/r/main" + memPkg.Path = "gno.land/r/" + caller.String() + "/run" // construct msg & tx and marshal. msg := vm.MsgRun{ From 39a30eff8ae095c8a9718d582012e1ed07b11a10 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:59:44 -0400 Subject: [PATCH 21/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- gno.land/pkg/sdk/vm/keeper_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gno.land/pkg/sdk/vm/keeper_test.go b/gno.land/pkg/sdk/vm/keeper_test.go index 0cf3eacdc5d..294efa66fa5 100644 --- a/gno.land/pkg/sdk/vm/keeper_test.go +++ b/gno.land/pkg/sdk/vm/keeper_test.go @@ -352,7 +352,7 @@ func TestVMKeeperRunSimple(t *testing.T) { {"script.gno", ` package main -func Main() { +func main() { println("hello world!") } `}, @@ -381,7 +381,7 @@ package main import "std" -func Main() { +func main() { addr := std.GetOrigCaller() println("hello world!", addr) } From 1bb8624ff43b4579e8cc560d622ee79e768a8d33 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:59:15 +0100 Subject: [PATCH 22/24] Update tm2/pkg/crypto/keys/client/run.go --- tm2/pkg/crypto/keys/client/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index ba3089a3852..1a5e2941a0e 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -30,7 +30,7 @@ func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { commands.Metadata{ Name: "run", ShortUsage: "run [flags] ", - ShortHelp: "Executes arbitrary Gno code", + ShortHelp: "Runs Gno code by invoking main() in a package", }, cfg, func(_ context.Context, args []string) error { From 492ae3ed63e2dba7b10d2f97d2de0f4341c3dc82 Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Fri, 17 Nov 2023 09:33:37 +0100 Subject: [PATCH 23/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- tm2/pkg/crypto/keys/client/run.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index 1a5e2941a0e..e56501befb0 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -21,7 +21,7 @@ type runCfg struct { send string } -func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { +func newRunCmd(rootCfg *makeTxCfg, io commands.IO) *commands.Command { cfg := &runCfg{ rootCfg: rootCfg, } @@ -41,7 +41,7 @@ func newRunCmd(rootCfg *makeTxCfg, io *commands.IO) *commands.Command { func (c *runCfg) RegisterFlags(fs *flag.FlagSet) {} -func runRun(cfg *runCfg, args []string, io *commands.IO) error { +func runRun(cfg *runCfg, args []string, io commands.IO) error { if len(args) != 2 { return flag.ErrHelp } @@ -75,7 +75,7 @@ func runRun(cfg *runCfg, args []string, io *commands.IO) error { memPkg := &std.MemPackage{} if sourcePath == "-" { // stdin - data, err := ioutil.ReadAll(io.In) + data, err := ioutil.ReadAll(io.In()) if err != nil { return fmt.Errorf("could not read stdin: %w", err) } From 3d677db532d023b06fadaff7ffd335f07ec077da Mon Sep 17 00:00:00 2001 From: moul <94029+moul@users.noreply.github.com> Date: Fri, 17 Nov 2023 09:40:51 +0100 Subject: [PATCH 24/24] chore: fixup Signed-off-by: moul <94029+moul@users.noreply.github.com> --- tm2/pkg/crypto/keys/client/run.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tm2/pkg/crypto/keys/client/run.go b/tm2/pkg/crypto/keys/client/run.go index e56501befb0..1ae702c990e 100644 --- a/tm2/pkg/crypto/keys/client/run.go +++ b/tm2/pkg/crypto/keys/client/run.go @@ -18,7 +18,6 @@ import ( type runCfg struct { rootCfg *makeTxCfg - send string } func newRunCmd(rootCfg *makeTxCfg, io commands.IO) *commands.Command {