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

go-kosu: RPC numberPosters and totalOrders #224

Merged
merged 3 commits into from Aug 22, 2019
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Prev

go-kosu: implement network explorer methods

  • Loading branch information
gchaincl committed Aug 22, 2019
commit 1649148306d92b3aa4565f27fc3dd5ccb1ae6e29
@@ -4,13 +4,13 @@ import (
"context"
"errors"

"github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/libs/pubsub/query"
"github.com/tendermint/tendermint/rpc/client"
rpctypes "github.com/tendermint/tendermint/rpc/core/types"
tmtypes "github.com/tendermint/tendermint/types"

"go-kosu/abci/types"
"go-kosu/store"
)

var (
@@ -23,12 +23,13 @@ var (
type Client struct {
client.Client
key []byte
cdc store.Codec
}

// NewClient returns a new Client type.
// Key is the private key used to sign transactions.
func NewClient(c client.Client, key []byte) *Client {
return &Client{Client: c, key: key}
return &Client{Client: c, key: key, cdc: store.DefaultCodec}
}

// NewHTTPClient calls NewClient using a HTTPClient as ABCClient
@@ -121,7 +122,7 @@ func (c *Client) Unsubscribe(ctx context.Context, query string) error {
// QueryRoundInfo performs a ABCIQuery to "/roundinfo"
func (c *Client) QueryRoundInfo() (*types.RoundInfo, error) {
var pb types.RoundInfo
if err := c.query("/chain/key", []byte("roundinfo"), &pb); err != nil {
if err := c.Query("/chain/key", []byte("roundinfo"), &pb); err != nil {
return nil, err
}

@@ -131,7 +132,7 @@ func (c *Client) QueryRoundInfo() (*types.RoundInfo, error) {
// QueryConsensusParams performs a ABCI Query to "/consensusparams"
func (c *Client) QueryConsensusParams() (*types.ConsensusParams, error) {
var pb types.ConsensusParams
if err := c.query("/chain/key", []byte("consensusparams"), &pb); err != nil {
if err := c.Query("/chain/key", []byte("consensusparams"), &pb); err != nil {
return nil, err
}

@@ -141,7 +142,7 @@ func (c *Client) QueryConsensusParams() (*types.ConsensusParams, error) {
// QueryPoster performs a ABCI Query to "/posters/<addr>"
func (c *Client) QueryPoster(addr string) (*types.Poster, error) {
var pb types.Poster
if err := c.query("/poster/key", []byte(addr), &pb); err != nil {
if err := c.Query("/poster/key", []byte(addr), &pb); err != nil {
return nil, err
}

@@ -151,7 +152,7 @@ func (c *Client) QueryPoster(addr string) (*types.Poster, error) {
// QueryValidator performs a ABCI Query to "/validator/<addr>"
func (c *Client) QueryValidator(addr string) (*types.Validator, error) {
var pb types.Validator
if err := c.query("/validator/key", []byte(addr), &pb); err != nil {
if err := c.Query("/validator/key", []byte(addr), &pb); err != nil {
return nil, err
}

@@ -160,25 +161,17 @@ func (c *Client) QueryValidator(addr string) (*types.Validator, error) {

// QueryTotalOrders performs a ABCI Query to "/chain/totalorders"
func (c *Client) QueryTotalOrders() (uint64, error) {
out, err := c.ABCIQuery("/chain/key", []byte("totalorders"))
if err != nil {
var num uint64
if err := c.Query("/chain/key", []byte("totalorders"), &num); err != nil {
return 0, err
}

res := out.Response
if res.IsErr() {
return 0, errors.New(res.GetLog())
}

if len(res.Value) == 0 {
return 0, errors.New("empty")
}

pb := proto.NewBuffer(res.Value)
return pb.DecodeFixed64()
return num, nil
}

func (c *Client) query(path string, data []byte, pb proto.Message) error {
// Query is a generic query interface.
// It will use the store.DefaultCodec codec to decode the `response.Value`.
func (c *Client) Query(path string, data []byte, v interface{}) error {
out, err := c.ABCIQuery(path, data)
if err != nil {
return err
@@ -193,5 +186,5 @@ func (c *Client) query(path string, data []byte, pb proto.Message) error {
return ErrNotFound
}

return proto.Unmarshal(res.Value, pb)
return c.cdc.Decode(res.Value, v)
}
@@ -129,6 +129,16 @@ curl -X POST --data '{"jsonrpc":"2.0","method":"kosu_latestHeight", "id": 1}' lo
{ "jsonrpc": "2.0", "id": 1, "result": 260 }
```

### _NumberPosters_

NumberPosters returns the number of poster accounts

_Parameters:_

_Returns:_

- `number` - _uint64_

### _QueryPoster_

QueryPoster returns a poster given its address.
@@ -199,6 +209,16 @@ curl -X POST localhost:14341 \
}
```

### _RemainingLimit_

RemainingLimit returns the sum of all the poster's limit.

_Parameters:_

_Returns:_

- `number` - _uint64_

### _RoundInfo_

RoundInfo returns the current `RoundInfo`.
@@ -224,6 +244,17 @@ curl -X POST localhost:14341 \
{ "jsonrpc": "2.0", "id": 1, "result": { "number": 48, "starts_at": 2613, "ends_at": 2623, "limit": 10 } }
```

### _TotalOrders_

TotalOrders returns the total number of orders in the system.
This number is incremented each time one submits a new valid order

_Parameters:_

_Returns:_

- `number` - _uint64_

### _Validators_

Validators returns the full validator set
@@ -16,6 +16,21 @@ import (
"github.com/tendermint/tendermint/libs/db"
)

func waitForNewBlock(t *testing.T, client *rpc.Client) {
ch := make(chan interface{})
defer close(ch)

sub, err := client.Subscribe(context.Background(), "kosu", ch, "newBlocks")
require.NoError(t, err)
defer sub.Unsubscribe()

select {
case err := <-sub.Err():
t.Error(err)
case <-ch:
}
}

func TestRPC(t *testing.T) {
cases := []struct {
name string
@@ -35,7 +50,7 @@ func TestRPC(t *testing.T) {

appClient, err := app.NewClient()
require.NoError(t, err)
defer appClient.Stop()
defer appClient.Stop() // nolint:errcheck

rpcClient := rpc.DialInProc(NewServer(appClient))
defer rpcClient.Close()
@@ -51,31 +66,9 @@ func LatestHeight(t *testing.T, _ *abci.App, _ *abci.Client, rpcClient *rpc.Clie
require.NoError(t, rpcClient.Call(&latest, "kosu_latestHeight"))
assert.EqualValues(t, 0, latest)

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
fn := func(_ interface{}) {
// this is invoked when a block is mined
require.NoError(t, rpcClient.Call(&latest, "kosu_latestHeight"))
assert.EqualValues(t, 1, latest)
cancel()
}

ch := make(chan interface{})
defer close(ch)

sub, err := rpcClient.Subscribe(ctx, "kosu", ch, "newBlocks")
require.NoError(t, err)
defer sub.Unsubscribe()

for {
select {
case <-ctx.Done():
return
case err := <-sub.Err():
t.Error(err)
case e := <-ch:
fn(e)
}
}
waitForNewBlock(t, rpcClient)
require.NoError(t, rpcClient.Call(&latest, "kosu_latestHeight"))
assert.EqualValues(t, 1, latest)
}

func AddOrders(t *testing.T, app *abci.App, appClient *abci.Client, rpcClient *rpc.Client) {
@@ -94,18 +87,35 @@ func AddOrders(t *testing.T, app *abci.App, appClient *abci.Client, rpcClient *r
}

// this poster address is generated out of the validTx
app.Store().SetPoster("0x02fbf1aa49bc3b9631e8e96572935a5894879724", types.Poster{
poster := types.Poster{
Balance: types.NewBigIntFromInt(100),
})
Limit: 10,
}
app.Store().SetPoster("0x02fbf1aa49bc3b9631e8e96572935a5894879724", poster)

var remaining uint64
err := rpcClient.Call(&remaining, "kosu_remainingLimit")
require.NoError(t, err)
assert.Equal(t, poster.Limit, remaining)

params := []interface{}{validTx, invalidTx}
result := &AddOrdersResult{}

err := rpcClient.Call(result, "kosu_addOrders", params)
err = rpcClient.Call(result, "kosu_addOrders", params)
require.NoError(t, err)

assert.Len(t, result.Accepted, 1)
assert.Len(t, result.Rejected, 1)

waitForNewBlock(t, rpcClient)
var total uint64
err = rpcClient.Call(&total, "kosu_totalOrders")
require.NoError(t, err)
assert.EqualValues(t, 1, total)

err = rpcClient.Call(&remaining, "kosu_remainingLimit")
require.NoError(t, err)
assert.Equal(t, poster.Limit-1, remaining)
}

func newTestRebalanceTx(number, starts uint64) *types.TransactionRebalance {
@@ -5,7 +5,6 @@ import (
"encoding/hex"
"go-kosu/abci"
"go-kosu/abci/types"
"go-kosu/store"
"log"
"strings"

@@ -690,20 +689,55 @@ func (s *Service) QueryPoster(addr string) (*types.Poster, error) {
return s.abci.QueryPoster(addr)
}

// TotalOrders ...
/*
TotalOrders returns the total number of orders in the system.
This number is incremented each time one submits a new valid order
_Parameters:_
_Returns:_
- `number` - _uint64_
*/
func (s *Service) TotalOrders() (uint64, error) {
return s.abci.QueryTotalOrders()
}

// NumberPosters ...
/*
NumberPosters returns the number of poster accounts
_Parameters:_
_Returns:_
- `number` - _uint64_
*/
func (s *Service) NumberPosters() (uint64, error) {
res, err := s.abci.ABCIQuery("/poster/number", nil)
if err != nil {
var num uint64

if err := s.abci.Query("/poster/number", nil, &num); err != nil {
return 0, err
}

return num, nil
}

/*
RemainingLimit returns the sum of all the poster's limit.
_Parameters:_
_Returns:_
- `number` - _uint64_
*/
func (s *Service) RemainingLimit() (uint64, error) {
var num uint64
if err := store.DefaultCodec.Decode(res.Response.Value, &num); err != nil {

if err := s.abci.Query("/poster/remaininglimit", nil, &num); err != nil {
return 0, err
}

@@ -106,9 +106,13 @@ func (s *Store) LastCommitID() cosmos.CommitID { return s.cms.LastCommitID() }

// Query wrap the rootmulti.Query method
func (s *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
// TODO: move the switch to a sensible place (perhaps ./store or ./abci)
// this should not be local to the store implementation
switch req.Path {
case "/poster/number":
return s.queryPosterNumber()
case "/poster/remaininglimit":
return s.queryPosterRemainingLimit()
}
return s.cms.Query(req)
}
@@ -130,6 +134,23 @@ func (s *Store) queryPosterNumber() (resp abci.ResponseQuery) {
return resp
}

func (s *Store) queryPosterRemainingLimit() (resp abci.ResponseQuery) {
var num uint64
s.IteratePosters(func(_ string, p *types.Poster) {
num += p.Limit
})

buf, err := s.codec.Encode(num)
if err != nil {
resp.Code = 1
resp.Log = err.Error()
} else {
resp.Value = buf
}

return resp
}

// Codec returns the storage codec
func (s *Store) Codec() store.Codec { return s.codec }

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.