mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
parent
b5c4098c53
commit
a6b74b82d1
@ -204,17 +204,19 @@ func (c *HTTP) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTP) TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
|
func (c *HTTP) TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error) {
|
||||||
results := new([]*ctypes.ResultTx)
|
result := new(ctypes.ResultTxSearch)
|
||||||
params := map[string]interface{}{
|
params := map[string]interface{}{
|
||||||
"query": query,
|
"query": query,
|
||||||
"prove": prove,
|
"prove": prove,
|
||||||
|
"page": page,
|
||||||
|
"per_page": perPage,
|
||||||
}
|
}
|
||||||
_, err := c.rpc.Call("tx_search", params, results)
|
_, err := c.rpc.Call("tx_search", params, result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "TxSearch")
|
return nil, errors.Wrap(err, "TxSearch")
|
||||||
}
|
}
|
||||||
return *results, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTP) Validators(height *int64) (*ctypes.ResultValidators, error) {
|
func (c *HTTP) Validators(height *int64) (*ctypes.ResultValidators, error) {
|
||||||
|
@ -50,7 +50,7 @@ type SignClient interface {
|
|||||||
Commit(height *int64) (*ctypes.ResultCommit, error)
|
Commit(height *int64) (*ctypes.ResultCommit, error)
|
||||||
Validators(height *int64) (*ctypes.ResultValidators, error)
|
Validators(height *int64) (*ctypes.ResultValidators, error)
|
||||||
Tx(hash []byte, prove bool) (*ctypes.ResultTx, error)
|
Tx(hash []byte, prove bool) (*ctypes.ResultTx, error)
|
||||||
TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error)
|
TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HistoryClient shows us data from genesis to now in large chunks.
|
// HistoryClient shows us data from genesis to now in large chunks.
|
||||||
|
@ -128,8 +128,8 @@ func (Local) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
return core.Tx(hash, prove)
|
return core.Tx(hash, prove)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Local) TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
|
func (Local) TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error) {
|
||||||
return core.TxSearch(query, prove)
|
return core.TxSearch(query, prove, page, perPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Local) Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error {
|
func (c *Local) Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error {
|
||||||
|
@ -334,11 +334,11 @@ func TestTxSearch(t *testing.T) {
|
|||||||
|
|
||||||
// now we query for the tx.
|
// now we query for the tx.
|
||||||
// since there's only one tx, we know index=0.
|
// since there's only one tx, we know index=0.
|
||||||
results, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", txHash), true)
|
result, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", txHash), true, 1, 30)
|
||||||
require.Nil(t, err, "%+v", err)
|
require.Nil(t, err, "%+v", err)
|
||||||
require.Len(t, results, 1)
|
require.Len(t, result.Txs, 1)
|
||||||
|
|
||||||
ptx := results[0]
|
ptx := result.Txs[0]
|
||||||
assert.EqualValues(t, txHeight, ptx.Height)
|
assert.EqualValues(t, txHeight, ptx.Height)
|
||||||
assert.EqualValues(t, tx, ptx.Tx)
|
assert.EqualValues(t, tx, ptx.Tx)
|
||||||
assert.Zero(t, ptx.Index)
|
assert.Zero(t, ptx.Index)
|
||||||
@ -352,14 +352,14 @@ func TestTxSearch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we query for non existing tx
|
// we query for non existing tx
|
||||||
results, err = c.TxSearch(fmt.Sprintf("tx.hash='%X'", anotherTxHash), false)
|
result, err = c.TxSearch(fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, 1, 30)
|
||||||
require.Nil(t, err, "%+v", err)
|
require.Nil(t, err, "%+v", err)
|
||||||
require.Len(t, results, 0)
|
require.Len(t, result.Txs, 0)
|
||||||
|
|
||||||
// we query using a tag (see kvstore application)
|
// we query using a tag (see kvstore application)
|
||||||
results, err = c.TxSearch("app.creator='jae'", false)
|
result, err = c.TxSearch("app.creator='jae'", false, 1, 30)
|
||||||
require.Nil(t, err, "%+v", err)
|
require.Nil(t, err, "%+v", err)
|
||||||
if len(results) == 0 {
|
if len(result.Txs) == 0 {
|
||||||
t.Fatal("expected a lot of transactions")
|
t.Fatal("expected a lot of transactions")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,3 +13,9 @@ go get github.com/melekes/godoc2md
|
|||||||
|
|
||||||
godoc2md -template rpc/core/doc_template.txt github.com/tendermint/tendermint/rpc/core | grep -v -e "pipe.go" -e "routes.go" -e "dev.go" | sed 's$/src/target$https://github.com/tendermint/tendermint/tree/master/rpc/core$'
|
godoc2md -template rpc/core/doc_template.txt github.com/tendermint/tendermint/rpc/core | grep -v -e "pipe.go" -e "routes.go" -e "dev.go" | sed 's$/src/target$https://github.com/tendermint/tendermint/tree/master/rpc/core$'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Pagination
|
||||||
|
|
||||||
|
Requests that return multiple items will be paginated to 30 items by default.
|
||||||
|
You can specify further pages with the ?page parameter. You can also set a
|
||||||
|
custom page size up to 100 with the ?per_page parameter.
|
||||||
|
@ -14,6 +14,12 @@ import (
|
|||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// see README
|
||||||
|
defaultPerPage = 30
|
||||||
|
maxPerPage = 100
|
||||||
|
)
|
||||||
|
|
||||||
var subscribeTimeout = 5 * time.Second
|
var subscribeTimeout = 5 * time.Second
|
||||||
|
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
@ -117,3 +123,17 @@ func SetLogger(l log.Logger) {
|
|||||||
func SetEventBus(b *types.EventBus) {
|
func SetEventBus(b *types.EventBus) {
|
||||||
eventBus = b
|
eventBus = b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validatePage(page int) int {
|
||||||
|
if page < 1 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return page
|
||||||
|
}
|
||||||
|
|
||||||
|
func validatePerPage(perPage int) int {
|
||||||
|
if perPage < 1 || perPage > maxPerPage {
|
||||||
|
return defaultPerPage
|
||||||
|
}
|
||||||
|
return perPage
|
||||||
|
}
|
||||||
|
@ -22,7 +22,7 @@ var Routes = map[string]*rpc.RPCFunc{
|
|||||||
"block_results": rpc.NewRPCFunc(BlockResults, "height"),
|
"block_results": rpc.NewRPCFunc(BlockResults, "height"),
|
||||||
"commit": rpc.NewRPCFunc(Commit, "height"),
|
"commit": rpc.NewRPCFunc(Commit, "height"),
|
||||||
"tx": rpc.NewRPCFunc(Tx, "hash,prove"),
|
"tx": rpc.NewRPCFunc(Tx, "hash,prove"),
|
||||||
"tx_search": rpc.NewRPCFunc(TxSearch, "query,prove"),
|
"tx_search": rpc.NewRPCFunc(TxSearch, "query,prove,page,per_page"),
|
||||||
"validators": rpc.NewRPCFunc(Validators, "height"),
|
"validators": rpc.NewRPCFunc(Validators, "height"),
|
||||||
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""),
|
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""),
|
||||||
"consensus_state": rpc.NewRPCFunc(ConsensusState, ""),
|
"consensus_state": rpc.NewRPCFunc(ConsensusState, ""),
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
"github.com/tendermint/tendermint/state/txindex/null"
|
"github.com/tendermint/tendermint/state/txindex/null"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
tmquery "github.com/tendermint/tmlibs/pubsub/query"
|
tmquery "github.com/tendermint/tmlibs/pubsub/query"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -104,7 +105,8 @@ func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxSearch allows you to query for multiple transactions results.
|
// TxSearch allows you to query for multiple transactions results. It returns a
|
||||||
|
// list of transactions (maximum ?per_page entries) and the total count.
|
||||||
//
|
//
|
||||||
// ```shell
|
// ```shell
|
||||||
// curl "localhost:46657/tx_search?query=\"account.owner='Ivan'\"&prove=true"
|
// curl "localhost:46657/tx_search?query=\"account.owner='Ivan'\"&prove=true"
|
||||||
@ -120,7 +122,10 @@ func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
//
|
//
|
||||||
// ```json
|
// ```json
|
||||||
// {
|
// {
|
||||||
// "result": [
|
// "jsonrpc": "2.0",
|
||||||
|
// "id": "",
|
||||||
|
// "result": {
|
||||||
|
// "txs": [
|
||||||
// {
|
// {
|
||||||
// "proof": {
|
// "proof": {
|
||||||
// "Proof": {
|
// "Proof": {
|
||||||
@ -144,19 +149,19 @@ func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
// "hash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"
|
// "hash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"
|
||||||
// }
|
// }
|
||||||
// ],
|
// ],
|
||||||
// "id": "",
|
// "total_count": 1
|
||||||
// "jsonrpc": "2.0"
|
// }
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// Returns transactions matching the given query.
|
|
||||||
//
|
|
||||||
// ### Query Parameters
|
// ### Query Parameters
|
||||||
//
|
//
|
||||||
// | Parameter | Type | Default | Required | Description |
|
// | Parameter | Type | Default | Required | Description |
|
||||||
// |-----------+--------+---------+----------+-----------------------------------------------------------|
|
// |-----------+--------+---------+----------+-----------------------------------------------------------|
|
||||||
// | query | string | "" | true | Query |
|
// | query | string | "" | true | Query |
|
||||||
// | prove | bool | false | false | Include proofs of the transactions inclusion in the block |
|
// | prove | bool | false | false | Include proofs of the transactions inclusion in the block |
|
||||||
|
// | page | int | 1 | false | Page number (1-based) |
|
||||||
|
// | per_page | int | 30 | false | Number of entries per page (max: 100) |
|
||||||
//
|
//
|
||||||
// ### Returns
|
// ### Returns
|
||||||
//
|
//
|
||||||
@ -166,7 +171,7 @@ func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
|||||||
// - `index`: `int` - index of the transaction
|
// - `index`: `int` - index of the transaction
|
||||||
// - `height`: `int` - height of the block where this transaction was in
|
// - `height`: `int` - height of the block where this transaction was in
|
||||||
// - `hash`: `[]byte` - hash of the transaction
|
// - `hash`: `[]byte` - hash of the transaction
|
||||||
func TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
|
func TxSearch(query string, prove bool, page, perPage int) (*ctypes.ResultTxSearch, error) {
|
||||||
// if index is disabled, return error
|
// if index is disabled, return error
|
||||||
if _, ok := txIndexer.(*null.TxIndex); ok {
|
if _, ok := txIndexer.(*null.TxIndex); ok {
|
||||||
return nil, fmt.Errorf("Transaction indexing is disabled")
|
return nil, fmt.Errorf("Transaction indexing is disabled")
|
||||||
@ -182,11 +187,15 @@ func TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we may want to consider putting a maximum on this length and somehow
|
totalCount := len(results)
|
||||||
// informing the user that things were truncated.
|
page = validatePage(page)
|
||||||
apiResults := make([]*ctypes.ResultTx, len(results))
|
perPage = validatePerPage(perPage)
|
||||||
|
skipCount := (page - 1) * perPage
|
||||||
|
|
||||||
|
apiResults := make([]*ctypes.ResultTx, cmn.MinInt(perPage, totalCount-skipCount))
|
||||||
var proof types.TxProof
|
var proof types.TxProof
|
||||||
for i, r := range results {
|
for i := 0; i < len(apiResults); i++ {
|
||||||
|
r := results[skipCount+i]
|
||||||
height := r.Height
|
height := r.Height
|
||||||
index := r.Index
|
index := r.Index
|
||||||
|
|
||||||
@ -205,5 +214,5 @@ func TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiResults, nil
|
return &ctypes.ResultTxSearch{Txs: apiResults, TotalCount: totalCount}, nil
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,12 @@ type ResultTx struct {
|
|||||||
Proof types.TxProof `json:"proof,omitempty"`
|
Proof types.TxProof `json:"proof,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Result of searching for txs
|
||||||
|
type ResultTxSearch struct {
|
||||||
|
Txs []*ResultTx `json:"txs"`
|
||||||
|
TotalCount int `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
// List of mempool txs
|
// List of mempool txs
|
||||||
type ResultUnconfirmedTxs struct {
|
type ResultUnconfirmedTxs struct {
|
||||||
N int `json:"n_txs"`
|
N int `json:"n_txs"`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user