Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gnodev): allow gnodev to load txs #2281

Merged
merged 5 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions contribs/gnodev/cmd/gnodev/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
root string
premineAccounts varPremineAccounts
balancesFile string
txsFile string

// Node Configuration
minimal bool
Expand Down Expand Up @@ -136,6 +137,13 @@
"load the provided balance file (refer to the documentation for format)",
)

fs.StringVar(
&c.txsFile,
"txs-file",
defaultDevOptions.txsFile,
"load the provided transactions file (refer to the documentation for format)",
)

Check warning on line 145 in contribs/gnodev/cmd/gnodev/main.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/main.go#L140-L145

Added lines #L140 - L145 were not covered by tests

fs.StringVar(
&c.deployKey,
"deploy-key",
Expand Down
17 changes: 15 additions & 2 deletions contribs/gnodev/cmd/gnodev/setup_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
gnodev "github.com/gnolang/gno/contribs/gnodev/pkg/dev"
"github.com/gnolang/gno/contribs/gnodev/pkg/emitter"
"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/tm2/pkg/std"
)

// setupDevNode initializes and returns a new DevNode.
Expand All @@ -21,19 +22,31 @@
balances gnoland.Balances,
pkgspath []gnodev.PackagePath,
) (*gnodev.Node, error) {
config := setupDevNodeConfig(cfg, balances, pkgspath)
// Load transactions.
txs, err := parseTxs(cfg.txsFile)
if err != nil {
return nil, fmt.Errorf("unable to load transactions: %w", err)

Check warning on line 28 in contribs/gnodev/cmd/gnodev/setup_node.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/setup_node.go#L26-L28

Added lines #L26 - L28 were not covered by tests
}

config := setupDevNodeConfig(cfg, balances, pkgspath, txs)

Check warning on line 31 in contribs/gnodev/cmd/gnodev/setup_node.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/setup_node.go#L31

Added line #L31 was not covered by tests
return gnodev.NewDevNode(ctx, logger, remitter, config)
}

// setupDevNodeConfig creates and returns a new dev.NodeConfig.
func setupDevNodeConfig(cfg *devCfg, balances gnoland.Balances, pkgspath []gnodev.PackagePath) *gnodev.NodeConfig {
func setupDevNodeConfig(
cfg *devCfg,
balances gnoland.Balances,
pkgspath []gnodev.PackagePath,
txs []std.Tx,
) *gnodev.NodeConfig {

Check warning on line 41 in contribs/gnodev/cmd/gnodev/setup_node.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/setup_node.go#L41

Added line #L41 was not covered by tests
config := gnodev.DefaultNodeConfig(cfg.root)
config.BalancesList = balances.List()
config.PackagesPathList = pkgspath
config.TMConfig.RPC.ListenAddress = resolveUnixOrTCPAddr(cfg.nodeRPCListenerAddr)
config.NoReplay = cfg.noReplay
config.MaxGasPerBlock = cfg.maxGas
config.ChainID = cfg.chainId
config.Txs = txs

Check warning on line 49 in contribs/gnodev/cmd/gnodev/setup_node.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/setup_node.go#L49

Added line #L49 was not covered by tests

// other listeners
config.TMConfig.P2P.ListenAddress = defaultDevOptions.nodeP2PListenerAddr
Expand Down
23 changes: 23 additions & 0 deletions contribs/gnodev/cmd/gnodev/txs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"context"
"fmt"
"os"

"github.com/gnolang/gno/tm2/pkg/std"
)

func parseTxs(txFile string) ([]std.Tx, error) {
if txFile == "" {
return nil, nil

Check warning on line 13 in contribs/gnodev/cmd/gnodev/txs.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/txs.go#L11-L13

Added lines #L11 - L13 were not covered by tests
}

file, loadErr := os.Open(txFile)
if loadErr != nil {
return nil, fmt.Errorf("unable to open tx file %s: %w", txFile, loadErr)

Check warning on line 18 in contribs/gnodev/cmd/gnodev/txs.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/txs.go#L16-L18

Added lines #L16 - L18 were not covered by tests
}
defer file.Close()

Check warning on line 20 in contribs/gnodev/cmd/gnodev/txs.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/txs.go#L20

Added line #L20 was not covered by tests

return std.ParseTxs(context.Background(), file)

Check warning on line 22 in contribs/gnodev/cmd/gnodev/txs.go

View check run for this annotation

Codecov / codecov/patch

contribs/gnodev/cmd/gnodev/txs.go#L22

Added line #L22 was not covered by tests
}
3 changes: 3 additions & 0 deletions contribs/gnodev/pkg/dev/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type NodeConfig struct {
NoReplay bool
MaxGasPerBlock int64
ChainID string
Txs []std.Tx
}

func DefaultNodeConfig(rootdir string) *NodeConfig {
Expand Down Expand Up @@ -107,6 +108,8 @@ func NewDevNode(ctx context.Context, logger *slog.Logger, emitter emitter.Emitte
Txs: pkgsTxs,
}

genesis.Txs = append(genesis.Txs, cfg.Txs...)

if err := devnode.rebuildNode(ctx, genesis); err != nil {
return nil, fmt.Errorf("unable to initialize the node: %w", err)
}
Expand Down
15 changes: 15 additions & 0 deletions docs/gno-tooling/cli/gnodev.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj=10000000000000ugnot # test2
# ...
```

### Transactions file

You can specify a transactions file using `--txs-file`. The file should contain a list of signed transactions
that will be applied when starting the in-memory node.
```
{"msg":[{"@type":"/vm.m_call","caller":"g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq","send":"","pkg_path":"gno.land/r/gnoland/blog","func":"ModAddPost","args":["post1","First post","Lorem Ipsum","2022-05-20T13:17:22Z","","tag1,tag2"]}],"fee":{"gas_wanted":"2000000","gas_fee":"1000000ugnot"},"signatures":[{"pub_key":{"@type":"/tm.PubKeySecp256k1","value":"AnK+a6mcFDjY6b/v6p7r8QFW1M1PgIoQxBgrwOoyY7v3"},"signature":"sHjOGXZEi9wt2FSXFHmkDDoVQyepvFHKRDDU0zgedHYnCYPx5/YndyihsDD5Y2Z7/RgNYBh4JlJwDMGFNStzBQ=="}],"memo":""}
{"msg":[{"@type":"/vm.m_call","caller":"g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq","send":"","pkg_path":"gno.land/r/gnoland/blog","func":"ModAddPost","args":["post2","Second post","Lorem Ipsum","2022-05-20T13:17:23Z","","tag1,tag3"]}],"fee":{"gas_wanted":"2000000","gas_fee":"1000000ugnot"},"signatures":[{"pub_key":{"@type":"/tm.PubKeySecp256k1","value":"AnK+a6mcFDjY6b/v6p7r8QFW1M1PgIoQxBgrwOoyY7v3"},"signature":"sHjOGXZEi9wt2FSXFHmkDDoVQyepvFHKRDDU0zgedHYnCYPx5/YndyihsDD5Y2Z7/RgNYBh4JlJwDMGFNStzBQ=="}],"memo":""}
```

#### Construction a transaction
`gnokey maketx ... >> "tx-file.json"`

#### Signing the transaction
`gnokey sign -tx-path tx-file.json ...`

### Deploy

All realms and packages will be deployed to the in-memory node by the address passed in with the
Expand Down
43 changes: 1 addition & 42 deletions gno.land/cmd/gnoland/genesis_txs_add.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package main

import (
"bufio"
"context"
"errors"
"fmt"
"io"
"os"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/bft/types"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/std"
Expand All @@ -18,7 +15,6 @@ import (
var (
errInvalidTxsFile = errors.New("unable to open transactions file")
errNoTxsFileSpecified = errors.New("no txs file specified")
errTxsParsingAborted = errors.New("transaction parsing aborted")
)

// newTxsAddCmd creates the genesis txs add subcommand
Expand Down Expand Up @@ -61,7 +57,7 @@ func execTxsAdd(
return fmt.Errorf("%w, %w", errInvalidTxsFile, loadErr)
}

txs, err := getTransactionsFromFile(ctx, file)
txs, err := std.ParseTxs(ctx, file)
if err != nil {
return fmt.Errorf("unable to read file, %w", err)
}
Expand Down Expand Up @@ -102,40 +98,3 @@ func execTxsAdd(

return nil
}

// getTransactionsFromFile fetches the transactions from the
// specified reader
func getTransactionsFromFile(ctx context.Context, reader io.Reader) ([]std.Tx, error) {
txs := make([]std.Tx, 0)

scanner := bufio.NewScanner(reader)

for scanner.Scan() {
select {
case <-ctx.Done():
return nil, errTxsParsingAborted
default:
// Parse the amino JSON
var tx std.Tx

if err := amino.UnmarshalJSON(scanner.Bytes(), &tx); err != nil {
return nil, fmt.Errorf(
"unable to unmarshal amino JSON, %w",
err,
)
}

txs = append(txs, tx)
}
}

// Check for scanning errors
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf(
"error encountered while reading file, %w",
err,
)
}

return txs, nil
}
43 changes: 42 additions & 1 deletion tm2/pkg/std/tx.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package std

import (
"bufio"
"context"
"fmt"
"io"

"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/crypto/multisig"
"github.com/gnolang/gno/tm2/pkg/errors"
)

var maxGasWanted = int64((1 << 60) - 1) // something smaller than math.MaxInt64
var (
maxGasWanted = int64((1 << 60) - 1) // something smaller than math.MaxInt64

ErrTxsLoadingAborted = errors.New("transaction loading aborted")
)

// Tx is a standard way to wrap a Msg with Fee and Signatures.
// NOTE: the first signature is the fee payer (Signatures must not be nil).
Expand Down Expand Up @@ -136,3 +144,36 @@
}
return bz
}

func ParseTxs(ctx context.Context, reader io.Reader) ([]Tx, error) {
var txs []Tx
scanner := bufio.NewScanner(reader)

Check warning on line 150 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L148-L150

Added lines #L148 - L150 were not covered by tests

for scanner.Scan() {
select {
case <-ctx.Done():
return nil, ErrTxsLoadingAborted
default:

Check warning on line 156 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L152-L156

Added lines #L152 - L156 were not covered by tests
// Parse the amino JSON
var tx Tx
if err := amino.UnmarshalJSON(scanner.Bytes(), &tx); err != nil {
return nil, fmt.Errorf(
"unable to unmarshal amino JSON, %w",
err,
)

Check warning on line 163 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L158-L163

Added lines #L158 - L163 were not covered by tests
}

txs = append(txs, tx)

Check warning on line 166 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L166

Added line #L166 was not covered by tests
}
}

// Check for scanning errors
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf(
"error encountered while reading file, %w",
err,
)

Check warning on line 175 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L171-L175

Added lines #L171 - L175 were not covered by tests
}

return txs, nil

Check warning on line 178 in tm2/pkg/std/tx.go

View check run for this annotation

Codecov / codecov/patch

tm2/pkg/std/tx.go#L178

Added line #L178 was not covered by tests
}
Loading