Skip to content

Commit

Permalink
feat: remove gnovm and gno.land dependencies from tm2 (#1483)
Browse files Browse the repository at this point in the history
This PR shares the same goal as #1438: to make `tm2` completely unaware
of `gnovm` and `gno.land`. However, it adopts a different strategy to
achieve this, following
#1438 (comment). It
will:
- Exposed almost everything from the `tm2/crypto/keys/client` package:
- `NewCommandXXX`, along with their specific structure configurations
and fields, are now exposed to allow the creation of composable CLI
tools.
- `XXXHandler` (including Sign, Verify, Broadcast, etc.) are now exposed
to enable external packages to reuse some logic from the `keys/client`
package.
- Moved specific `gnovm`/`gno.land` commands to the `gnokey` package:
`run`, `call`, and `addpkg`.
- In an effort to avoid duplicate code, an `ExecSignAndBroadcast` method
has been exposed. However, it appears too specific, and I am considering
duplicating it regardless. I would appreciate thoughts on this.




<details><summary>Contributors' checklist...</summary>

- [ ] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [ ] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com>
  • Loading branch information
gfanton authored Jan 15, 2024
1 parent ee19e1c commit 5ad12cd
Show file tree
Hide file tree
Showing 32 changed files with 745 additions and 593 deletions.
5 changes: 0 additions & 5 deletions contribs/gnokeykc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ require (
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/danieljoos/wincred v1.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dgraph-io/badger/v3 v3.2103.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
Expand All @@ -43,13 +41,10 @@ require (
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
go.etcd.io/bbolt v1.3.8 // indirect
go.opencensus.io v0.22.5 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/term v0.14.0 // indirect
golang.org/x/tools v0.13.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
10 changes: 0 additions & 10 deletions contribs/gnokeykc/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion gno.land/cmd/gnokey/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"os"

"github.com/gnolang/gno/gno.land/pkg/keyscli"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
Expand All @@ -15,6 +16,6 @@ func main() {
Remote: "127.0.0.1:26657",
}

cmd := client.NewRootCmdWithBaseConfig(commands.NewDefaultIO(), baseCfg)
cmd := keyscli.NewRootCmd(commands.NewDefaultIO(), baseCfg)
cmd.Execute(context.Background(), os.Args[1:])
}
3 changes: 2 additions & 1 deletion gno.land/pkg/integration/testing_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gno.land/pkg/keyscli"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/bft/node"
"github.com/gnolang/gno/tm2/pkg/commands"
Expand Down Expand Up @@ -214,7 +215,7 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
io := commands.NewTestIO()
io.SetOut(commands.WriteNopCloser(ts.Stdout()))
io.SetErr(commands.WriteNopCloser(ts.Stderr()))
cmd := client.NewRootCmd(io)
cmd := keyscli.NewRootCmd(io, client.DefaultBaseOptions)

io.SetIn(strings.NewReader("\n")) // Inject empty password to stdin.
defaultArgs := []string{
Expand Down
12 changes: 12 additions & 0 deletions gno.land/pkg/keyscli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## keycli

`keycli` is an extension of `tm2/keys/client`, enhancing its functionality. It provides the following features:

- **addpkg**: Allows you to upload a new package to the blockchain.
- **run**: Execute Gno code by invoking the main() function from the target package.
- **call**: Executes a single function call within a Realm.
- **maketx**: Compose a transaction (tx) document to sign (and possibly broadcast).

---

Most of these features have been extracted from `tm2/keys/client` to ensure that `tm2` remains completely independent of `gnovm` and `gno.land`. For more detailed information regarding this change, please refer to [PR#1483](https://github.com/gnolang/gno/pull/1483)
138 changes: 138 additions & 0 deletions gno.land/pkg/keyscli/addpkg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package keyscli

import (
"context"
"flag"
"fmt"

"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"
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
"github.com/gnolang/gno/tm2/pkg/errors"
"github.com/gnolang/gno/tm2/pkg/std"
)

type MakeAddPkgCfg struct {
RootCfg *client.MakeTxCfg

PkgPath string
PkgDir string
Deposit string
}

func NewMakeAddPkgCmd(rootCfg *client.MakeTxCfg, io commands.IO) *commands.Command {
cfg := &MakeAddPkgCfg{
RootCfg: rootCfg,
}

return commands.NewCommand(
commands.Metadata{
Name: "addpkg",
ShortUsage: "addpkg [flags] <key-name>",
ShortHelp: "Uploads a new package",
},
cfg,
func(_ context.Context, args []string) error {
return execMakeAddPkg(cfg, args, io)
},
)
}

func (c *MakeAddPkgCfg) RegisterFlags(fs *flag.FlagSet) {
fs.StringVar(
&c.PkgPath,
"pkgpath",
"",
"package path (required)",
)

fs.StringVar(
&c.PkgDir,
"pkgdir",
"",
"path to package files (required)",
)

fs.StringVar(
&c.Deposit,
"deposit",
"",
"deposit coins",
)
}

func execMakeAddPkg(cfg *MakeAddPkgCfg, args []string, io commands.IO) error {
if cfg.PkgPath == "" {
return errors.New("pkgpath not specified")
}
if cfg.PkgDir == "" {
return errors.New("pkgdir not specified")
}

if len(args) != 1 {
return flag.ErrHelp
}

// 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
}
creator := info.GetAddress()
// info.GetPubKey()

// parse deposit.
deposit, err := std.ParseCoins(cfg.Deposit)
if err != nil {
panic(err)
}

// open files in directory as MemPackage.
memPkg := gno.ReadMemPackage(cfg.PkgDir, cfg.PkgPath)
if memPkg.IsEmpty() {
panic(fmt.Sprintf("found an empty package %q", cfg.PkgPath))
}

// precompile and validate syntax
err = gno.PrecompileAndCheckMempkg(memPkg)
if err != nil {
panic(err)
}

// parse gas wanted & fee.
gaswanted := cfg.RootCfg.GasWanted
gasfee, err := std.ParseCoin(cfg.RootCfg.GasFee)
if err != nil {
panic(err)
}
// construct msg & tx and marshal.
msg := vm.MsgAddPackage{
Creator: creator,
Package: memPkg,
Deposit: deposit,
}
tx := std.Tx{
Msgs: []std.Msg{msg},
Fee: std.NewFee(gaswanted, gasfee),
Signatures: nil,
Memo: cfg.RootCfg.Memo,
}

if cfg.RootCfg.Broadcast {
err := client.ExecSignAndBroadcast(cfg.RootCfg, args, tx, io)
if err != nil {
return err
}
} else {
fmt.Println(string(amino.MustMarshalJSON(tx)))
}
return nil
}
Loading

0 comments on commit 5ad12cd

Please sign in to comment.