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 2b2f5f2 commit e87008b
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 19 deletions.
35 changes: 19 additions & 16 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,25 @@ const (
//
//nolint:revive
const (
ParamAccountId = "accountId"
ParamCensusId = "censusId"
ParamElectionId = "electionId"
ParamOrganizationId = "organizationId"
ParamVoteId = "voteId"
ParamPage = "page"
ParamLimit = "limit"
ParamStatus = "status"
ParamWithResults = "withResults"
ParamFinalResults = "finalResults"
ParamManuallyEnded = "manuallyEnded"
ParamHeight = "height"
ParamReference = "reference"
ParamType = "type"
ParamAccountIdFrom = "accountIdFrom"
ParamAccountIdTo = "accountIdTo"
ParamAccountId = "accountId"
ParamCensusId = "censusId"
ParamElectionId = "electionId"
ParamOrganizationId = "organizationId"
ParamVoteId = "voteId"
ParamPage = "page"
ParamLimit = "limit"
ParamStatus = "status"
ParamWithResults = "withResults"
ParamFinalResults = "finalResults"
ParamManuallyEnded = "manuallyEnded"
ParamHeight = "height"
ParamReference = "reference"
ParamType = "type"
ParamAccountIdFrom = "accountIdFrom"
ParamAccountIdTo = "accountIdTo"
ParamChainId = "chainId"
ParamHash = "hash"
ParamProposerAddress = "proposerAddress"
)

var (
Expand Down
14 changes: 14 additions & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,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 @@ -436,3 +444,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 e87008b

Please sign in to comment.