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 MultiCall #1565

Merged
merged 45 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
bf6a79f
wip save
leohhhn Jan 20, 2024
738f70c
add msgcall wrapper & add batchcall func
leohhhn Jan 21, 2024
2de3712
remove comment
leohhhn Jan 21, 2024
de83a5b
add comment
leohhhn Jan 21, 2024
05aedff
fix lint
leohhhn Jan 21, 2024
ebaf516
remove multicall func, update struct, remove aliasing
leohhhn Jan 22, 2024
9a5fd71
extract errors to pkg level
leohhhn Jan 22, 2024
bdb9f60
remove aliasing
leohhhn Jan 22, 2024
fb2416d
add preliminary tests, remove some error wrapping
leohhhn Jan 22, 2024
948dc9f
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Jan 23, 2024
79cbe36
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Jan 24, 2024
ced737b
inline caller
leohhhn Jan 25, 2024
9c91240
add baseTxCfg, modify Call flow
leohhhn Jan 25, 2024
c9e85ea
add basecfg validation, comments, errors
leohhhn Jan 25, 2024
bb828df
add more unit tests, comments
leohhhn Jan 25, 2024
175bd5e
made unit tests better
leohhhn Jan 25, 2024
f0958d8
add testcase
leohhhn Jan 25, 2024
3ad650e
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Jan 26, 2024
a6fb52d
make errors public
leohhhn Jan 29, 2024
8be378e
remove fmt.errorf
leohhhn Jan 29, 2024
def2e0b
make error names clearer
leohhhn Jan 29, 2024
4f9febf
mocking wip
leohhhn Jan 29, 2024
cb7496f
add rpcclient mock, wip tests
leohhhn Jan 31, 2024
2cd4af3
expand txbroadcast res
leohhhn Jan 31, 2024
9f6cd76
wip more tests
leohhhn Jan 31, 2024
23fb5b4
add full rpcclient mock infra
leohhhn Jan 31, 2024
3ecf8f0
simplify tests
leohhhn Jan 31, 2024
a190219
typo fix
leohhhn Jan 31, 2024
7caf692
remove comment
leohhhn Jan 31, 2024
085ce3f
fix lint
leohhhn Jan 31, 2024
849ede2
fix test err
leohhhn Jan 31, 2024
788ccb9
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Jan 31, 2024
800d188
parallel test
leohhhn Feb 1, 2024
9e8c7e2
replace assert with require
leohhhn Feb 1, 2024
a4bf5cb
add errors.Is
leohhhn Feb 1, 2024
44a0657
remove panics
leohhhn Feb 1, 2024
1bad3de
add pointer receivers
leohhhn Feb 1, 2024
a663e8e
make fmt
leohhhn Feb 1, 2024
cd707ad
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Feb 1, 2024
f6e78d2
update imports, fix assert.ErrorIs
leohhhn Feb 1, 2024
c7481f0
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Feb 1, 2024
bd9ac4b
make fmt
leohhhn Feb 1, 2024
0e6300e
remove double assert
leohhhn Feb 1, 2024
60b5963
rename mock to mock_test
leohhhn Feb 1, 2024
7354457
Merge branch 'master' into feat/gnoclient-batchcall
leohhhn Feb 1, 2024
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
5 changes: 2 additions & 3 deletions gno.land/pkg/gnoclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gnoclient

import (
rpcclient "github.com/gnolang/gno/tm2/pkg/bft/rpc/client"
"github.com/gnolang/gno/tm2/pkg/errors"
)

// Client provides an interface for interacting with the blockchain.
Expand All @@ -14,15 +13,15 @@ type Client struct {
// validateSigner checks that the signer is correctly configured.
func (c Client) validateSigner() error {
if c.Signer == nil {
return errors.New("missing Signer")
return ErrMissingSigner
}
return nil
}

// validateRPCClient checks that the RPCClient is correctly configured.
func (c Client) validateRPCClient() error {
if c.RPCClient == nil {
return errors.New("missing RPCClient")
return ErrMissingRPCClient
}
return nil
}
244 changes: 212 additions & 32 deletions gno.land/pkg/gnoclient/client_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package gnoclient

import (
"github.com/jaekwon/testify/assert"
"testing"

"github.com/gnolang/gno/gno.land/pkg/integration"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
rpcclient "github.com/gnolang/gno/tm2/pkg/bft/rpc/client"
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
"github.com/gnolang/gno/tm2/pkg/log"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/jaekwon/testify/require"
)

Expand All @@ -32,7 +32,7 @@ func newInMemorySigner(t *testing.T, chainid string) *SignerFromKeybase {

func TestClient_Request(t *testing.T) {
config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir())
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNoopLogger(), config)
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config)
defer node.Stop()

signer := newInMemorySigner(t, config.TMConfig.ChainID())
Expand All @@ -52,49 +52,229 @@ func TestClient_Request(t *testing.T) {
// XXX: need more test
}

func TestClient_Run(t *testing.T) {
func TestClient_Call(t *testing.T) {
t.Parallel()

config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir())
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNoopLogger(), config)
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config)
defer node.Stop()

signer := newInMemorySigner(t, config.TMConfig.ChainID())
rpcClient := rpcclient.NewHTTP(remoteAddr, "/websocket")

client := Client{
Signer: signer,
RPCClient: rpcclient.NewHTTP(remoteAddr, "/websocket"),
RPCClient: rpcClient,
}

code := `package main
cfg := BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
}

import (
"std"
msg := []MsgCall{
{
PkgPath: "gno.land/r/demo/deep/very/deep",
FuncName: "Render",
Args: []string{""},
Send: "100ugnot",
},
}

"gno.land/p/demo/ufmt"
"gno.land/r/demo/tests"
)
res, err := client.Call(cfg, msg...)
assert.NoError(t, err)
assert.NotNil(t, res)
}

func main() {
println(ufmt.Sprintf("- before: %d", tests.Counter()))
for i := 0; i < 10; i++ {
tests.IncCounter()
}
println(ufmt.Sprintf("- after: %d", tests.Counter()))
}`
memPkg := &std.MemPackage{
Files: []*std.MemFile{
{
Name: "main.gno",
Body: code,
func TestClient_Call_Errors(t *testing.T) {
t.Parallel()

// todo Replace with mock client
config, _ := integration.TestingNodeConfig(t, gnoenv.RootDir())
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config)
defer node.Stop()

signer := newInMemorySigner(t, config.TMConfig.ChainID())
rpcClient := rpcclient.NewHTTP(remoteAddr, "/websocket")

testCases := []struct {
name string
client Client
cfg BaseTxCfg
msgs []MsgCall
expectedError error
}{
{
name: "Invalid Signer",
client: Client{
nil,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "RandomName",
Send: "",
Args: []string{},
},
},
expectedError: ErrMissingSigner,
},
{
name: "Invalid RPCClient",
client: Client{
signer,
nil,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "RandomName",
Send: "",
Args: []string{},
},
},
expectedError: ErrMissingRPCClient,
},
{
name: "Invalid Gas Fee",
client: Client{
signer,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "RandomName",
},
},
expectedError: ErrInvalidGasFee,
},
{
name: "Negative Gas Wanted",
client: Client{
signer,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: -1,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "RandomName",
Send: "",
Args: []string{},
},
},
expectedError: ErrInvalidGasWanted,
},
{
name: "0 Gas Wanted",
client: Client{
signer,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: 0,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "RandomName",
Send: "",
Args: []string{},
},
},
expectedError: ErrInvalidGasWanted,
},
{
name: "Invalid PkgPath",
client: Client{
signer,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "",
FuncName: "RandomName",
Send: "",
Args: []string{},
},
},
expectedError: ErrEmptyPkgPath,
},
{
name: "Invalid FuncName",
client: Client{
signer,
rpcClient,
},
cfg: BaseTxCfg{
GasWanted: 100000,
GasFee: "10000ugnot",
AccountNumber: 1,
SequenceNumber: 1,
Memo: "Test memo",
},
msgs: []MsgCall{
{
PkgPath: "random/path",
FuncName: "",
Send: "",
Args: []string{},
},
},
expectedError: ErrEmptyFuncName,
},
}
res, err := client.Run(RunCfg{
Package: memPkg,
GasFee: "1ugnot",
GasWanted: 100000000,
})
require.NoError(t, err)
require.NotNil(t, res)
require.NotEmpty(t, res.DeliverTx.Data)
require.Equal(t, string(res.DeliverTx.Data), "- before: 0\n- after: 10\n")

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ajnavarro marked this conversation as resolved.
Show resolved Hide resolved
t.Parallel()

res, err := tc.client.Call(tc.cfg, tc.msgs...)
assert.Equal(t, err, tc.expectedError)
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
assert.Nil(t, res)
})
}
}
Loading
Loading