Skip to content

Commit

Permalink
api: new endpoint /chain/blocks
Browse files Browse the repository at this point in the history
accepts QueryParams:
     * GET /chain/blocks
       * page
       * limit
       * chainId
       * hash
       * proposerAddress

* api: add structs BlockList, BlockParams
* api: add consts ParamChainId, ParamHash, ParamProposerAddress
* api: rename chainBlockHandler -> chainBlockByHeightHandler
  • Loading branch information
altergui committed Aug 20, 2024
1 parent 4dce8aa commit d54b806
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 3 deletions.
3 changes: 3 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ const (
ParamWithResults = "withResults"
ParamFinalResults = "finalResults"
ParamManuallyEnded = "manuallyEnded"
ParamChainId = "chainId"
ParamHash = "hash"
ParamProposerAddress = "proposerAddress"
ParamHeight = "height"
ParamReference = "reference"
ParamType = "type"
Expand Down
14 changes: 14 additions & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ type TransactionParams struct {
Type string `json:"type,omitempty"`
}

// BlockParams allows the client to filter blocks
type BlockParams struct {
PaginationParams
ChainID string `json:"chainId,omitempty"`
Hash string `json:"hash,omitempty"`
ProposerAddress string `json:"proposerAddress,omitempty"`
}

// FeesParams allows the client to filter fees
type FeesParams struct {
PaginationParams
Expand Down Expand Up @@ -440,3 +448,9 @@ type Block struct {
Hash types.HexBytes `json:"hash" `
TxCount int64 `json:"txCount"`
}

// BlockList is used to return a paginated list to the client
type BlockList struct {
Blocks []*indexertypes.Block `json:"blocks"`
Pagination *Pagination `json:"pagination"`
}
86 changes: 83 additions & 3 deletions api/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (a *API) enableChainHandlers() error {
"/chain/blocks/{height}",
"GET",
apirest.MethodAccessTypePublic,
a.chainBlockHandler,
a.chainBlockByHeightHandler,
); err != nil {
return err
}
Expand All @@ -176,6 +176,14 @@ func (a *API) enableChainHandlers() error {
); err != nil {
return err
}
if err := a.Endpoint.RegisterMethod(
"/chain/blocks",
"GET",
apirest.MethodAccessTypePublic,
a.chainBlockListHandler,
); err != nil {
return err
}
if err := a.Endpoint.RegisterMethod(
"/chain/organizations/filter/page/{page}",
"POST",
Expand Down Expand Up @@ -846,7 +854,7 @@ func (a *API) chainValidatorsHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCon
return ctx.Send(data, apirest.HTTPstatusOK)
}

// chainBlockHandler
// chainBlockByHeightHandler
//
// @Summary Get block (by height)
// @Description Returns the full block information at the given height
Expand All @@ -856,7 +864,7 @@ func (a *API) chainValidatorsHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCon
// @Param height path int true "Block height"
// @Success 200 {object} api.Block
// @Router /chain/blocks/{height} [get]
func (a *API) chainBlockHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
func (a *API) chainBlockByHeightHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
height, err := strconv.ParseUint(ctx.URLParam(ParamHeight), 10, 64)
if err != nil {
return err
Expand Down Expand Up @@ -942,6 +950,63 @@ func (a *API) chainBlockByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo
return ctx.Send(convertKeysToCamel(data), apirest.HTTPstatusOK)
}

// chainBlockListHandler
//
// @Summary List all blocks
// @Description Returns the list of blocks, ordered by descending height.
// @Tags Chain
// @Accept json
// @Produce json
// @Param page query number false "Page"
// @Param limit query number false "Items per page"
// @Param chainId query string false "Filter by exact chainId"
// @Param hash query string false "Filter by partial hash"
// @Param proposerAddress query string false "Filter by exact proposerAddress"
// @Success 200 {object} BlockList
// @Router /chain/blocks [get]
func (a *API) chainBlockListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
params, err := parseBlockParams(
ctx.QueryParam(ParamPage),
ctx.QueryParam(ParamLimit),
ctx.QueryParam(ParamChainId),
ctx.QueryParam(ParamHash),
ctx.QueryParam(ParamProposerAddress),
)
if err != nil {
return err
}

return a.sendBlockList(ctx, params)
}

// sendBlockList produces a filtered, paginated BlockList,
// and sends it marshalled over ctx.Send
//
// Errors returned are always of type APIerror.
func (a *API) sendBlockList(ctx *httprouter.HTTPContext, params *BlockParams) error {
blocks, total, err := a.indexer.BlockList(
params.Limit,
params.Page*params.Limit,
params.ChainID,
params.Hash,
params.ProposerAddress,
)
if err != nil {
return ErrIndexerQueryFailed.WithErr(err)
}

pagination, err := calculatePagination(params.Page, params.Limit, total)
if err != nil {
return err
}

list := &BlockList{
Blocks: blocks,
Pagination: pagination,
}
return marshalAndSend(ctx, list)
}

// chainTransactionCountHandler
//
// @Summary Transactions count
Expand Down Expand Up @@ -1255,3 +1320,18 @@ func parseTransactionParams(paramPage, paramLimit, paramHeight, paramType string
Type: paramType,
}, nil
}

// parseBlockParams returns an BlockParams filled with the passed params
func parseBlockParams(paramPage, paramLimit, paramChainId, paramHash, paramProposerAddress string) (*BlockParams, error) {
pagination, err := parsePaginationParams(paramPage, paramLimit)
if err != nil {
return nil, err
}

return &BlockParams{
PaginationParams: pagination,
ChainID: paramChainId,
Hash: util.TrimHex(paramHash),
ProposerAddress: util.TrimHex(paramProposerAddress),
}, nil
}

0 comments on commit d54b806

Please sign in to comment.