Skip to content

Commit

Permalink
Merge pull request #199 from code-monad/lightclient-rpc
Browse files Browse the repository at this point in the history
chore: using mocking to test lightclient
  • Loading branch information
quake authored Feb 15, 2023
2 parents 394cdcf + 3e8227d commit 3d858c9
Show file tree
Hide file tree
Showing 34 changed files with 2,794 additions and 48 deletions.
11 changes: 0 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,7 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: '1.17'
- name: Install Rust tools
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Checkout code
uses: actions/checkout@v2
- name: Install ckb-light-client
uses: actions-rs/cargo@v1
with:
command: install
args: --locked --git https://github.com/nervosnetwork/ckb-light-client.git
- name: Run CKB Light Client
run: wget https://raw.githubusercontent.com/nervosnetwork/ckb-light-client/develop/config/testnet.toml && ckb-light-client run --config-file testnet.toml &
- name: Test
run: go test ./... -short
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ go 1.17

require (
github.com/ethereum/go-ethereum v1.9.14
github.com/golang/mock v1.3.1
github.com/google/go-cmp v0.3.1
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.4.0
Expand Down
60 changes: 39 additions & 21 deletions lightclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rpc"
"github.com/nervosnetwork/ckb-sdk-go/v2/indexer"
"github.com/nervosnetwork/ckb-sdk-go/v2/mocking"
"github.com/nervosnetwork/ckb-sdk-go/v2/types"
)

Expand All @@ -26,20 +27,25 @@ type Client interface {
GetCellsCapacity(ctx context.Context, searchKey *indexer.SearchKey) (*indexer.Capacity, error)
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
Close()
GetRawClient() types.GenericRPCClient
}

type client struct {
c *rpc.Client
c types.GenericRPCClient
}

func (cli *client) GetRawClient() types.GenericRPCClient {
return cli.c
}

func (cli *client) SetScripts(ctx context.Context, scriptDetails []*ScriptDetail) error {
err := cli.c.CallContext(ctx, nil, "set_scripts", scriptDetails)
err := cli.GetRawClient().CallContext(ctx, nil, "set_scripts", scriptDetails)
return err
}

func (cli *client) GetScripts(ctx context.Context) ([]*ScriptDetail, error) {
var result []*ScriptDetail
err := cli.c.CallContext(ctx, &result, "get_scripts")
err := cli.GetRawClient().CallContext(ctx, &result, "get_scripts")
if err != nil {
return nil, err
}
Expand All @@ -48,7 +54,7 @@ func (cli *client) GetScripts(ctx context.Context) ([]*ScriptDetail, error) {

func (cli *client) SendTransaction(ctx context.Context, tx *types.Transaction) (*types.Hash, error) {
var result types.Hash
err := cli.c.CallContext(ctx, &result, "send_transaction", *tx)
err := cli.GetRawClient().CallContext(ctx, &result, "send_transaction", *tx)
if err != nil {
return nil, err
}
Expand All @@ -57,7 +63,7 @@ func (cli *client) SendTransaction(ctx context.Context, tx *types.Transaction) (

func (cli *client) GetTipHeader(ctx context.Context) (*types.Header, error) {
var result types.Header
err := cli.c.CallContext(ctx, &result, "get_tip_header")
err := cli.GetRawClient().CallContext(ctx, &result, "get_tip_header")
if err != nil {
return nil, err
}
Expand All @@ -66,7 +72,7 @@ func (cli *client) GetTipHeader(ctx context.Context) (*types.Header, error) {

func (cli *client) GetGenesisBlock(ctx context.Context) (*types.Block, error) {
var result types.Block
err := cli.c.CallContext(ctx, &result, "get_genesis_block")
err := cli.GetRawClient().CallContext(ctx, &result, "get_genesis_block")
if err != nil {
return nil, err
}
Expand All @@ -75,7 +81,7 @@ func (cli *client) GetGenesisBlock(ctx context.Context) (*types.Block, error) {

func (cli *client) GetHeader(ctx context.Context, hash types.Hash) (*types.Header, error) {
var result types.Header
err := cli.c.CallContext(ctx, &result, "get_header", hash)
err := cli.GetRawClient().CallContext(ctx, &result, "get_header", hash)
if err != nil {
return nil, err
}
Expand All @@ -84,7 +90,7 @@ func (cli *client) GetHeader(ctx context.Context, hash types.Hash) (*types.Heade

func (cli *client) GetTransaction(ctx context.Context, hash types.Hash) (*TransactionStatus, error) {
var result TransactionStatus
err := cli.c.CallContext(ctx, &result, "get_transaction", hash)
err := cli.GetRawClient().CallContext(ctx, &result, "get_transaction", hash)
if err != nil {
return nil, err
}
Expand All @@ -93,7 +99,7 @@ func (cli *client) GetTransaction(ctx context.Context, hash types.Hash) (*Transa

func (cli *client) FetchHeader(ctx context.Context, hash types.Hash) (*FetchedHeader, error) {
var result FetchedHeader
err := cli.c.CallContext(ctx, &result, "fetch_header", hash)
err := cli.GetRawClient().CallContext(ctx, &result, "fetch_header", hash)
if err != nil {
return nil, err
}
Expand All @@ -102,7 +108,7 @@ func (cli *client) FetchHeader(ctx context.Context, hash types.Hash) (*FetchedHe

func (cli *client) FetchTransaction(ctx context.Context, hash types.Hash) (*FetchedTransaction, error) {
var result FetchedTransaction
err := cli.c.CallContext(ctx, &result, "fetch_transaction", hash)
err := cli.GetRawClient().CallContext(ctx, &result, "fetch_transaction", hash)
if err != nil {
return nil, err
}
Expand All @@ -112,7 +118,7 @@ func (cli *client) FetchTransaction(ctx context.Context, hash types.Hash) (*Fetc
func (cli *client) GetPeers(ctx context.Context) ([]*types.RemoteNode, error) {
var result []*types.RemoteNode

err := cli.c.CallContext(ctx, &result, "get_peers")
err := cli.GetRawClient().CallContext(ctx, &result, "get_peers")
if err != nil {
return nil, err
}
Expand All @@ -123,7 +129,7 @@ func (cli *client) GetPeers(ctx context.Context) ([]*types.RemoteNode, error) {
func (cli *client) LocalNodeInfo(ctx context.Context) (*types.LocalNode, error) {
var result types.LocalNode

err := cli.c.CallContext(ctx, &result, "local_node_info")
err := cli.GetRawClient().CallContext(ctx, &result, "local_node_info")
if err != nil {
return nil, err
}
Expand All @@ -137,9 +143,9 @@ func (cli *client) GetCells(ctx context.Context, searchKey *indexer.SearchKey, o
err error
)
if afterCursor == "" {
err = cli.c.CallContext(ctx, &result, "get_cells", searchKey, order, hexutil.Uint64(limit))
err = cli.GetRawClient().CallContext(ctx, &result, "get_cells", searchKey, order, hexutil.Uint64(limit))
} else {
err = cli.c.CallContext(ctx, &result, "get_cells", searchKey, order, hexutil.Uint64(limit), afterCursor)
err = cli.GetRawClient().CallContext(ctx, &result, "get_cells", searchKey, order, hexutil.Uint64(limit), afterCursor)
}
if err != nil {
return nil, err
Expand All @@ -154,9 +160,9 @@ func (cli *client) GetTransactions(ctx context.Context, searchKey *indexer.Searc
err error
)
if afterCursor == "" {
err = cli.c.CallContext(ctx, &result, "get_transactions", searchKey, order, hexutil.Uint64(limit))
err = cli.GetRawClient().CallContext(ctx, &result, "get_transactions", searchKey, order, hexutil.Uint64(limit))
} else {
err = cli.c.CallContext(ctx, &result, "get_transactions", searchKey, order, hexutil.Uint64(limit), afterCursor)
err = cli.GetRawClient().CallContext(ctx, &result, "get_transactions", searchKey, order, hexutil.Uint64(limit), afterCursor)
}
if err != nil {
return nil, err
Expand All @@ -175,9 +181,9 @@ func (cli *client) GetTransactionsGrouped(ctx context.Context, searchKey *indexe
var result TxsWithCells
var err error
if afterCursor == "" {
err = cli.c.CallContext(ctx, &result, "get_transactions", payload, order, hexutil.Uint64(limit))
err = cli.GetRawClient().CallContext(ctx, &result, "get_transactions", payload, order, hexutil.Uint64(limit))
} else {
err = cli.c.CallContext(ctx, &result, "get_transactions", payload, order, hexutil.Uint64(limit), afterCursor)
err = cli.GetRawClient().CallContext(ctx, &result, "get_transactions", payload, order, hexutil.Uint64(limit), afterCursor)
}
if err != nil {
return nil, err
Expand All @@ -187,23 +193,23 @@ func (cli *client) GetTransactionsGrouped(ctx context.Context, searchKey *indexe

func (cli *client) GetCellsCapacity(ctx context.Context, searchKey *indexer.SearchKey) (*indexer.Capacity, error) {
var result indexer.Capacity
err := cli.c.CallContext(ctx, &result, "get_cells_capacity", searchKey)
err := cli.GetRawClient().CallContext(ctx, &result, "get_cells_capacity", searchKey)
if err != nil {
return nil, err
}
return &result, nil
}

func (cli *client) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
err := cli.c.CallContext(ctx, result, method, args...)
err := cli.GetRawClient().CallContext(ctx, result, method, args...)
if err != nil {
return err
}
return nil
}

func (cli *client) Close() {
cli.c.Close()
cli.GetRawClient().Close()
}

func Dial(url string) (Client, error) {
Expand All @@ -218,6 +224,18 @@ func DialContext(ctx context.Context, url string) (Client, error) {
return NewClient(c), nil
}

func DialMockContext(ctx context.Context, url string) (Client, error) {
c, err := mocking.DialContext(ctx, url)
if err != nil {
return nil, err
}
return NewMockingClient(c), err
}

func NewClient(c *rpc.Client) Client {
return &client{c}
}

func NewMockingClient(c *mocking.MockClient) Client {
return &client{c}
}
41 changes: 27 additions & 14 deletions lightclient/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ package lightclient
import (
"context"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/nervosnetwork/ckb-sdk-go/v2/indexer"
"github.com/nervosnetwork/ckb-sdk-go/v2/mocking"
"github.com/nervosnetwork/ckb-sdk-go/v2/types"
"github.com/stretchr/testify/assert"
"os"
"testing"
)

var c, _ = DialContext(context.Background(), "http://localhost:9000")
var c, _ = DialMockContext(context.Background(), "http://localhost:9000") // We are using mocking client now, url is just a placeholder param and takes no effect to these tests
var ctx = context.Background()

var mockClient = interface{}(c.GetRawClient()).(*mocking.MockClient)
var scriptForTest = &types.Script{
CodeHash: types.HexToHash("0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8"),
HashType: types.HashTypeType,
Expand All @@ -33,11 +35,13 @@ func TestSetScripts(t *testing.T) {
ScriptType: types.ScriptTypeLock,
BlockNumber: 7033100,
}
mockClient.LoadMockingTestFromFile(t, "set_scripts", []*ScriptDetail{&scriptDetail})
err := c.SetScripts(context.Background(), []*ScriptDetail{&scriptDetail})
assert.NoError(t, err)
}

func TestGetScripts(t *testing.T) {
mockClient.LoadMockingTestFromFile(t, "get_scripts")
scriptDetails, err := c.GetScripts(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, scriptDetails)
Expand All @@ -46,14 +50,14 @@ func TestGetScripts(t *testing.T) {
}

func TestTipHeader(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "get_tip_header")
header, err := c.GetTipHeader(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, header)
}

func TestGetGenesisBlock(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "get_genesis_block")
block, err := c.GetGenesisBlock(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, block)
Expand All @@ -62,24 +66,24 @@ func TestGetGenesisBlock(t *testing.T) {
}

func TestGetHeader(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "get_header", types.HexToHash("0x10639e0895502b5688a6be8cf69460d76541bfa4821629d86d62ba0aae3f9606"))
header, err := c.GetHeader(ctx,
types.HexToHash("0x86487ca41db5141bb750a0b5dbea8b87c0b3a05dda1c1e587ca9f7ccae3b4ad5"))
types.HexToHash("0x10639e0895502b5688a6be8cf69460d76541bfa4821629d86d62ba0aae3f9606"))
assert.NoError(t, err)
assert.NotEmpty(t, header)
}

func TestGetTransaction(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "get_transaction", types.HexToHash("0x8f8c79eb6671709633fe6a46de93c0fedc9c1b8a6527a18d3983879542635c9f"))
txWitHeader, err := c.GetTransaction(ctx,
types.HexToHash("0x151d4d450c9e3bccf4b47d1ba6942d4e9c8c0eeeb7b9f708df827c164f035aa8"))
types.HexToHash("0x8f8c79eb6671709633fe6a46de93c0fedc9c1b8a6527a18d3983879542635c9f"))
assert.NoError(t, err)
assert.NotEmpty(t, txWitHeader.Transaction)
assert.NotEmpty(t, txWitHeader.TxStatus)
}

func TestFetchHeader(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "fetch_header", types.HexToHash("0xcb5eae958e3ea24b0486a393133aa33d51224ffaab3c4819350095b3446e4f70"))
fetchedHeader, err := c.FetchHeader(ctx,
types.HexToHash("0xcb5eae958e3ea24b0486a393133aa33d51224ffaab3c4819350095b3446e4f70"))
assert.NoError(t, err)
Expand All @@ -88,19 +92,19 @@ func TestFetchHeader(t *testing.T) {
}

func TestFetchTransaction(t *testing.T) {
skipCI(t)
mockClient.LoadMockingTestFromFile(t, "fetch_transaction", types.HexToHash("0x716e211698d3d9499aae7903867c744b67b539beeceddad330e73d1b6b617aef"))
fetchedTransaction, err := c.FetchTransaction(ctx,
types.HexToHash("0x716e211698d3d9499aae7903867c744b67b539beeceddad330e73d1b6b617aef"))
assert.NoError(t, err)
assert.NotEmpty(t, fetchedTransaction.Status)
}

func TestGetCells(t *testing.T) {
skipCI(t)
s := &indexer.SearchKey{
Script: scriptForTest,
ScriptType: types.ScriptTypeLock,
}
mockClient.LoadMockingTestFromFile(t, "get_cells", s, indexer.SearchOrderAsc, hexutil.Uint64(10)) // this is a special cast, make it same with the actual call
resp, err := c.GetCells(context.Background(), s, indexer.SearchOrderAsc, 10, "")
assert.NoError(t, err)
assert.NotEmpty(t, resp)
Expand All @@ -110,11 +114,11 @@ func TestGetCells(t *testing.T) {
}

func TestGetTransactions(t *testing.T) {
skipCI(t)
s := &indexer.SearchKey{
Script: scriptForTest,
ScriptType: types.ScriptTypeLock,
}
mockClient.LoadMockingTestFromFile(t, "get_transactions", s, indexer.SearchOrderAsc, hexutil.Uint64(10)) // this is a special cast, make it same with the actual call
resp, err := c.GetTransactions(context.Background(), s, indexer.SearchOrderAsc, 10, "")
assert.NoError(t, err)
assert.NotEmpty(t, resp)
Expand All @@ -124,11 +128,18 @@ func TestGetTransactions(t *testing.T) {
}

func TestGetTransactionsGrouped(t *testing.T) {
skipCI(t)
s := &indexer.SearchKey{
Script: scriptForTest,
ScriptType: types.ScriptTypeLock,
}
payload := &struct {
indexer.SearchKey
GroupByTransaction bool `json:"group_by_transaction"`
}{
SearchKey: *s,
GroupByTransaction: true,
}
mockClient.LoadMockingTestFromFilePatched(t, "get_transactions_grouped", "get_transactions", payload, indexer.SearchOrderAsc, hexutil.Uint64(10)) // this is a special cast, make it same with the actual call
resp, err := c.GetTransactionsGrouped(context.Background(), s, indexer.SearchOrderAsc, 10, "")
assert.NoError(t, err)
assert.NotEqual(t, 0, len(resp.Objects))
Expand All @@ -139,11 +150,11 @@ func TestGetTransactionsGrouped(t *testing.T) {
}

func TestGetCellsCapacity(t *testing.T) {
skipCI(t)
s := &indexer.SearchKey{
Script: scriptForTest,
ScriptType: types.ScriptTypeLock,
}
mockClient.LoadMockingTestFromFile(t, "get_cells_capacity", s)
resp, err := c.GetCellsCapacity(context.Background(), s)
assert.NoError(t, err)
assert.NotEmpty(t, resp.BlockNumber)
Expand All @@ -152,6 +163,7 @@ func TestGetCellsCapacity(t *testing.T) {
}

func TestGetPeers(t *testing.T) {
mockClient.LoadMockingTestFromFile(t, "get_peers")
peers, err := c.GetPeers(ctx)
if err != nil {
t.Fatal(err)
Expand All @@ -162,6 +174,7 @@ func TestGetPeers(t *testing.T) {
}

func TestClient_LocalNodeInfo(t *testing.T) {
mockClient.LoadMockingTestFromFile(t, "local_node_info")
nodeInfo, err := c.LocalNodeInfo(ctx)
if err != nil {
t.Fatal(err)
Expand Down
Loading

0 comments on commit 3d858c9

Please sign in to comment.