Add pagination to /validators

- closes #3472

Signed-off-by: Marko Baricevic <marbar3778@yahoo.com>
This commit is contained in:
Marko Baricevic
2019-09-17 15:11:04 +02:00
parent 45ddd67bd6
commit 74a02b1d2b
6 changed files with 33 additions and 9 deletions

View File

@@ -106,7 +106,7 @@ func (p *provider) getValidatorSet(chainID string, height int64) (valset *types.
err = fmt.Errorf("expected height >= 1, got height %v", height)
return
}
res, err := p.client.Validators(&height)
res, err := p.client.Validators(&height, 0, 0) // page & perPage are hard coded to 0 to get the entire validator set in one request
if err != nil {
// TODO pass through other types of errors.
return nil, lerr.ErrUnknownValidators(chainID, height)

View File

@@ -126,7 +126,7 @@ func makeTxFunc(c rpcclient.Client) func(ctx *rpctypes.Context, hash []byte, pro
func makeValidatorsFunc(c rpcclient.Client) func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultValidators, error) {
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultValidators, error) {
return c.Validators(height)
return c.Validators(height, 0, 0)
}
}

View File

@@ -336,9 +336,13 @@ func (c *baseRPCClient) TxSearch(query string, prove bool, page, perPage int) (*
return result, nil
}
func (c *baseRPCClient) Validators(height *int64) (*ctypes.ResultValidators, error) {
func (c *baseRPCClient) Validators(height *int64, page, perPage int) (*ctypes.ResultValidators, error) {
result := new(ctypes.ResultValidators)
_, err := c.caller.Call("validators", map[string]interface{}{"height": height}, result)
_, err := c.caller.Call("validators", map[string]interface{}{
"height": height,
"page": page,
"per_page": perPage,
}, result)
if err != nil {
return nil, errors.Wrap(err, "Validators")
}

View File

@@ -66,7 +66,7 @@ type SignClient interface {
Block(height *int64) (*ctypes.ResultBlock, error)
BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
Commit(height *int64) (*ctypes.ResultCommit, error)
Validators(height *int64) (*ctypes.ResultValidators, error)
Validators(height *int64, page, perPage int) (*ctypes.ResultValidators, error)
Tx(hash []byte, prove bool) (*ctypes.ResultTx, error)
TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error)
}

View File

@@ -145,8 +145,8 @@ func (c *Local) Commit(height *int64) (*ctypes.ResultCommit, error) {
return core.Commit(c.ctx, height)
}
func (c *Local) Validators(height *int64) (*ctypes.ResultValidators, error) {
return core.Validators(c.ctx, height)
func (c *Local) Validators(height *int64, page, perPage int) (*ctypes.ResultValidators, error) {
return core.Validators(c.ctx, height, page, perPage)
}
func (c *Local) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {

View File

@@ -2,6 +2,7 @@ package core
import (
cm "github.com/tendermint/tendermint/consensus"
cmn "github.com/tendermint/tendermint/libs/common"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
rpctypes "github.com/tendermint/tendermint/rpc/lib/types"
sm "github.com/tendermint/tendermint/state"
@@ -50,7 +51,7 @@ import (
// "jsonrpc": "2.0"
// }
// ```
func Validators(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultValidators, error) {
func Validators(ctx *rpctypes.Context, heightPtr *int64, page, perPage int) (*ctypes.ResultValidators, error) {
// The latest validator that we know is the
// NextValidator of the last block.
height := consensusState.GetState().LastBlockHeight + 1
@@ -63,9 +64,28 @@ func Validators(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultValidato
if err != nil {
return nil, err
}
totalCount := len(validators.Validators)
perPage = validatePerPage(perPage)
page, err = validatePage(page, perPage, totalCount)
if err != nil {
return nil, err
}
skipCount := validateSkipCount(page, perPage)
apiResults := make([]*types.Validator, cmn.MinInt(perPage, totalCount-skipCount))
for i := 0; i < len(apiResults); i++ {
v := validators.Validators[skipCount+1]
apiResults[i] = &types.Validator{
Address: v.Address,
PubKey: v.PubKey,
VotingPower: v.VotingPower,
ProposerPriority: v.ProposerPriority,
}
}
return &ctypes.ResultValidators{
BlockHeight: height,
Validators: validators.Validators}, nil
Validators: apiResults}, nil
}
// DumpConsensusState dumps consensus state.