Skip to content

Commit

Permalink
feat(gnoclient): add support for MsgAddPackage (gnolang#1892)
Browse files Browse the repository at this point in the history
<!-- please provide a detailed description of the changes made in this
pull request. -->

## Description

This PR adds gnoclient support for `MsgAddPackage`, and updates the docs
to match the functionality. Docs preview:
https://www.loom.com/share/0dfa38e6e95e4e1195d686c8cbffa453?sid=4af29ee0-d065-442c-977e-ce9577796688

Closes gnolang#1840 

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

- [x] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] 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>
  • Loading branch information
leohhhn authored Apr 9, 2024
1 parent 59c6d3e commit 60c09b9
Show file tree
Hide file tree
Showing 5 changed files with 475 additions and 13 deletions.
27 changes: 23 additions & 4 deletions docs/reference/gnoclient/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,39 @@ type Client struct {
}
```

### func \(\*Client\) [Call](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L56>)
### func \(\*Client\) [AddPackage](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L236>)

```go
func (c *Client) AddPackage(cfg BaseTxCfg, msgs ...MsgAddPackage) (*ctypes.ResultBroadcastTxCommit, error)
```

`AddPackage` executes one or more [AddPackage](#type-msgaddpackage) calls on the blockchain.

### func \(\*Client\) [Call](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L62>)

```go
func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTxCommit, error)
```

`Call` executes a one or more [MsgCall](#type-msgcall) calls on the blockchain.

### func \(\*Client\) [Send](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L176>)
### func \(\*Client\) [Send](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L182>)

```go
func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTxCommit, error)
```

`Send` executes one or more [MsgSend](#type-msgsend) calls on the blockchain.

### func \(\*Client\) [Run](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L112>)
### func \(\*Client\) [Run](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L118>)

```go
func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCommit, error)
```

`Run` executes a one or more MsgRun calls on the blockchain.

### func \(*Client\) [QEval](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_queries.go#L108>)
### func \(\*Client\) [QEval](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_queries.go#L108>)

```go
func (c *Client) QEval(pkgPath string, expression string) (string, *ctypes.ResultABCIQuery, error)
Expand Down Expand Up @@ -101,6 +109,17 @@ type BaseTxCfg struct {
}
```

## type [MsgAddPackage](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L59-L59>)

`MsgAddPackage` \- syntax sugar for `vm.MsgAddPackage`.

```go
type MsgAddPackage struct {
Package *std.MemPackage // Package to add
Deposit string // Coin deposit
}
```

## type [MsgCall](<https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoclient/client_txs.go#L36-L41>)

`MsgCall` \- syntax sugar for `vm.MsgCall`.
Expand Down
191 changes: 191 additions & 0 deletions gno.land/pkg/gnoclient/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -888,3 +888,194 @@ func TestRunErrors(t *testing.T) {
})
}
}

// AddPackage tests
func TestAddPackageErrors(t *testing.T) {
t.Parallel()

testCases := []struct {
name string
client Client
cfg BaseTxCfg
msgs []MsgAddPackage
expectedError error
}{
{
name: "Invalid Signer",
client: Client{
Signer: nil,
RPCClient: &mockRPCClient{},
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{
{
Package: &std.MemPackage{
Name: "",
Path: "",
Files: []*std.MemFile{
{
Name: "file1.gno",
Body: "",
},
},
},
Deposit: "",
},
},
expectedError: ErrMissingSigner,
},
{
name: "Invalid RPCClient",
client: Client{
&mockSigner{},
nil,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{},
expectedError: ErrMissingRPCClient,
},
{
name: "Invalid Gas Fee",
client: Client{
Signer: &mockSigner{},
RPCClient: &mockRPCClient{},
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{
{
Package: &std.MemPackage{
Name: "",
Path: "",
Files: []*std.MemFile{
{
Name: "file1.gno",
Body: "",
},
},
},
Deposit: "",
},
},
expectedError: ErrInvalidGasFee,
},
{
name: "Negative Gas Wanted",
client: Client{
Signer: &mockSigner{},
RPCClient: &mockRPCClient{},
},
cfg: BaseTxCfg{
GasWanted: -1,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{
{
Package: &std.MemPackage{
Name: "",
Path: "",
Files: []*std.MemFile{
{
Name: "file1.gno",
Body: "",
},
},
},
Deposit: "",
},
},
expectedError: ErrInvalidGasWanted,
},
{
name: "0 Gas Wanted",
client: Client{
Signer: &mockSigner{},
RPCClient: &mockRPCClient{},
},
cfg: BaseTxCfg{
GasWanted: 0,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{
{
Package: &std.MemPackage{
Name: "",
Path: "",
Files: []*std.MemFile{
{
Name: "file1.gno",
Body: "",
},
},
},
Deposit: "",
},
},
expectedError: ErrInvalidGasWanted,
},
{
name: "Invalid Empty Package",
client: Client{
Signer: &mockSigner{
info: func() keys.Info {
return &mockKeysInfo{
getAddress: func() crypto.Address {
adr, _ := crypto.AddressFromBech32("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
return adr
},
}
},
},
RPCClient: &mockRPCClient{},
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgAddPackage{
{
Package: nil,
Deposit: "",
},
},
expectedError: ErrEmptyPackage,
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

res, err := tc.client.AddPackage(tc.cfg, tc.msgs...)
assert.Nil(t, res)
assert.ErrorIs(t, err, tc.expectedError)
})
}
}
83 changes: 75 additions & 8 deletions gno.land/pkg/gnoclient/client_txs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var (
ErrInvalidSendAmount = errors.New("invalid send amount")
)

// BaseTxCfg defines the base transaction configuration, shared by all message types.
// BaseTxCfg defines the base transaction configuration, shared by all message types
type BaseTxCfg struct {
GasFee string // Gas fee
GasWanted int64 // Gas wanted
Expand All @@ -32,27 +32,33 @@ type BaseTxCfg struct {
Memo string // Memo
}

// MsgCall - syntax sugar for vm.MsgCall.
// MsgCall - syntax sugar for vm.MsgCall
type MsgCall struct {
PkgPath string // Package path
FuncName string // Function name
Args []string // Function arguments
Send string // Send amount
}

// MsgSend - syntax sugar for bank.MsgSend.
// MsgSend - syntax sugar for bank.MsgSend
type MsgSend struct {
ToAddress crypto.Address // Send to address
Send string // Send amount
}

// MsgRun - syntax sugar for vm.MsgRun.
// MsgRun - syntax sugar for vm.MsgRun
type MsgRun struct {
Package *std.MemPackage // Package to run
Send string // Send amount
}

// Call executes a one or more MsgCall calls on the blockchain.
// MsgAddPackage - syntax sugar for vm.MsgAddPackage
type MsgAddPackage struct {
Package *std.MemPackage // Package to add
Deposit string // Coin deposit
}

// Call executes one or more MsgCall calls on the blockchain
func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTxCommit, error) {
// Validate required client fields.
if err := c.validateSigner(); err != nil {
Expand Down Expand Up @@ -108,7 +114,7 @@ func (c *Client) Call(cfg BaseTxCfg, msgs ...MsgCall) (*ctypes.ResultBroadcastTx
return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber)
}

// Run executes a one or more MsgRun calls on the blockchain.
// Run executes one or more MsgRun calls on the blockchain
func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCommit, error) {
// Validate required client fields.
if err := c.validateSigner(); err != nil {
Expand Down Expand Up @@ -172,7 +178,7 @@ func (c *Client) Run(cfg BaseTxCfg, msgs ...MsgRun) (*ctypes.ResultBroadcastTxCo
return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber)
}

// Send executes one or more MsgSend calls on the blockchain.
// Send executes one or more MsgSend calls on the blockchain
func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTxCommit, error) {
// Validate required client fields.
if err := c.validateSigner(); err != nil {
Expand Down Expand Up @@ -226,7 +232,68 @@ func (c *Client) Send(cfg BaseTxCfg, msgs ...MsgSend) (*ctypes.ResultBroadcastTx
return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber)
}

// signAndBroadcastTxCommit signs a transaction and broadcasts it, returning the result.
// AddPackage executes one or more AddPackage calls on the blockchain
func (c *Client) AddPackage(cfg BaseTxCfg, msgs ...MsgAddPackage) (*ctypes.ResultBroadcastTxCommit, error) {
// Validate required client fields.
if err := c.validateSigner(); err != nil {
return nil, err
}
if err := c.validateRPCClient(); err != nil {
return nil, err
}

// Validate base transaction config
if err := cfg.validateBaseTxConfig(); err != nil {
return nil, err
}

// Parse MsgRun slice
vmMsgs := make([]std.Msg, 0, len(msgs))
for _, msg := range msgs {
// Validate MsgCall fields
if err := msg.validateMsgAddPackage(); err != nil {
return nil, err
}

// Parse deposit coins
deposit, err := std.ParseCoins(msg.Deposit)
if err != nil {
return nil, err
}

caller := c.Signer.Info().GetAddress()

// Transpile and validate Gno syntax
if err = transpiler.TranspileAndCheckMempkg(msg.Package); err != nil {
return nil, err
}

// Unwrap syntax sugar to vm.MsgCall slice
vmMsgs = append(vmMsgs, std.Msg(vm.MsgAddPackage{
Creator: caller,
Package: msg.Package,
Deposit: deposit,
}))
}

// Parse gas fee
gasFeeCoins, err := std.ParseCoin(cfg.GasFee)
if err != nil {
return nil, err
}

// Pack transaction
tx := std.Tx{
Msgs: vmMsgs,
Fee: std.NewFee(cfg.GasWanted, gasFeeCoins),
Signatures: nil,
Memo: cfg.Memo,
}

return c.signAndBroadcastTxCommit(tx, cfg.AccountNumber, cfg.SequenceNumber)
}

// signAndBroadcastTxCommit signs a transaction and broadcasts it, returning the result
func (c *Client) signAndBroadcastTxCommit(tx std.Tx, accountNumber, sequenceNumber uint64) (*ctypes.ResultBroadcastTxCommit, error) {
caller := c.Signer.Info().GetAddress()

Expand Down
Loading

0 comments on commit 60c09b9

Please sign in to comment.