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(gnoclient): add support for MsgAddPackage #1892

Merged
merged 9 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
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>)
leohhhn marked this conversation as resolved.
Show resolved Hide resolved

```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 @@
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 @@
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 @@
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 @@
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 @@
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

Check warning on line 261 in gno.land/pkg/gnoclient/client_txs.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoclient/client_txs.go#L261

Added line #L261 was not covered by tests
}

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

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

Check warning on line 268 in gno.land/pkg/gnoclient/client_txs.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoclient/client_txs.go#L268

Added line #L268 was not covered by tests
}

// 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

Check warning on line 282 in gno.land/pkg/gnoclient/client_txs.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoclient/client_txs.go#L282

Added line #L282 was not covered by tests
}

// 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
Loading