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

Add new API route to list transactions for epoch #31

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions services/api/pchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,40 @@ func newApiPChainOutputs(inputs []database.PChainTxOutput) []ApiPChainTxOutput {
}
return result
}

type ApiPChainTxListItem struct {
Type database.PChainTxType `json:"type"`
TxID *string `json:"txID"`
BlockHeight uint64 `json:"blockHeight"`
ChainID string `json:"chainID"`
NodeID string `json:"nodeID"`
StartTime *time.Time `json:"startTime"`
EndTime *time.Time `json:"endTime"`
Weight uint64 `json:"weight"`
InputAddress string `json:"inputAddress"`
InputIndex uint32 `json:"inputIndex"`
}

func newApiPChainTxListItem(tx *database.PChainTxData) ApiPChainTxListItem {
return ApiPChainTxListItem{
Type: tx.Type,
TxID: tx.TxID,
BlockHeight: tx.BlockHeight,
ChainID: tx.ChainID,
NodeID: tx.NodeID,
StartTime: tx.StartTime,
EndTime: tx.EndTime,
Weight: tx.Weight,
InputAddress: tx.InputAddress,
InputIndex: tx.InputIndex,
}
}

func NewApiPChainTxList(txs []database.PChainTxData) []ApiPChainTxListItem {
result := make([]ApiPChainTxListItem, len(txs))
for i, tx := range txs {
result[i] = newApiPChainTxListItem(&tx)
}

return result
}
11 changes: 7 additions & 4 deletions services/main/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,21 @@ func main() {
log.Fatal(err) // logger possibly not initialized here so use builtin log
}

epochs, err := utils.NewEpochInfo(ctx)
if err != nil {
log.Fatal(err)
}

muxRouter := mux.NewRouter()
router := utils.NewSwaggerRouter(muxRouter, "Flare P-Chain Indexer", "0.1.0")
routes.AddTransferRoutes(router, ctx)
routes.AddStakerRoutes(router, ctx)
routes.AddTransactionRoutes(router, ctx)
routes.AddTransactionRoutes(router, ctx, epochs)
routes.AddMirroringRoutes(router, ctx, epochs)

// Disabled -- state connector routes are currently not used
// routes.AddQueryRoutes(router, ctx)

if err := routes.AddMirroringRoutes(router, ctx); err != nil {
logger.Fatal("Failed to add mirroring routes: %v", err)
}
router.Finalize()

cors := cors.New(cors.Options{
Expand Down
37 changes: 4 additions & 33 deletions services/routes/mirroring.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package routes

import (
"errors"
globalConfig "flare-indexer/config"
"flare-indexer/database"
"flare-indexer/services/config"
"flare-indexer/services/context"
"flare-indexer/services/utils"
"flare-indexer/utils/contracts/mirroring"
"flare-indexer/utils/contracts/voting"
"flare-indexer/utils/staking"
"fmt"
"net/http"
Expand Down Expand Up @@ -50,32 +47,11 @@ type mirroringRouteHandlers struct {
epochs staking.EpochInfo
}

func newMirroringRouteHandlers(ctx context.ServicesContext) (*mirroringRouteHandlers, error) {
cfg := ctx.Config()

start, period, err := getEpochStartAndPeriod(cfg)
if err != nil {
return nil, err
}

func newMirroringRouteHandlers(ctx context.ServicesContext, epochs staking.EpochInfo) *mirroringRouteHandlers {
return &mirroringRouteHandlers{
db: NewMirrorDBGorm(ctx.DB()),
epochs: staking.NewEpochInfo(&globalConfig.EpochConfig{}, start, period),
}, nil
}

func getEpochStartAndPeriod(cfg *config.Config) (time.Time, time.Duration, error) {
eth, err := cfg.Chain.DialETH()
if err != nil {
return time.Time{}, 0, err
epochs: epochs,
}

votingContract, err := voting.NewVoting(cfg.ContractAddresses.Voting, eth)
if err != nil {
return time.Time{}, 0, err
}

return staking.GetEpochConfig(votingContract)
}

func (rh *mirroringRouteHandlers) listMirroringTransactions() utils.RouteHandler {
Expand All @@ -101,16 +77,11 @@ func (rh *mirroringRouteHandlers) listMirroringTransactions() utils.RouteHandler
GetMirroringResponse{})
}

func AddMirroringRoutes(router utils.Router, ctx context.ServicesContext) error {
rh, err := newMirroringRouteHandlers(ctx)
if err != nil {
return err
}
func AddMirroringRoutes(router utils.Router, ctx context.ServicesContext, epochs staking.EpochInfo) {
rh := newMirroringRouteHandlers(ctx, epochs)

mirroringSubrouter := router.WithPrefix("/mirroring", "Mirroring")
mirroringSubrouter.AddRoute("/tx_data/{tx_id:[0-9a-zA-Z]+}", rh.listMirroringTransactions())

return nil
}

func (rh *mirroringRouteHandlers) createMirroringData(tx *database.PChainTx) ([]MirroringResponse, error) {
Expand Down
43 changes: 38 additions & 5 deletions services/routes/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ import (
"flare-indexer/services/api"
"flare-indexer/services/context"
"flare-indexer/services/utils"
"flare-indexer/utils/staking"
"net/http"
"strconv"

"gorm.io/gorm"
)

type transactionRouteHandlers struct {
db *gorm.DB
db *gorm.DB
epochs staking.EpochInfo
}

func newTransactionRouteHandlers(ctx context.ServicesContext) *transactionRouteHandlers {
func newTransactionRouteHandlers(ctx context.ServicesContext, epochs staking.EpochInfo) *transactionRouteHandlers {
return &transactionRouteHandlers{
db: ctx.DB(),
db: ctx.DB(),
epochs: epochs,
}
}

Expand All @@ -41,8 +45,37 @@ func (rh *transactionRouteHandlers) getTransaction() utils.RouteHandler {
&api.ApiPChainTx{})
}

func AddTransactionRoutes(router utils.Router, ctx context.ServicesContext) {
vr := newTransactionRouteHandlers(ctx)
func (rh *transactionRouteHandlers) listTransactions() utils.RouteHandler {
handler := func(params map[string]string) ([]api.ApiPChainTxListItem, *utils.ErrorHandler) {
epoch, err := strconv.ParseInt(params["epoch"], 10, 64)
if err != nil {
return nil, utils.HttpErrorHandler(http.StatusBadRequest, "Invalid epoch")
}

startTimestamp, endTimestamp := rh.epochs.GetTimeRange(epoch)
txs, err := database.GetPChainTxsForEpoch(&database.GetPChainTxsForEpochInput{
DB: rh.db,
StartTimestamp: startTimestamp,
EndTimestamp: endTimestamp,
})
if err != nil {
return nil, utils.InternalServerErrorHandler(err)
}

return api.NewApiPChainTxList(txs), nil
}

return utils.NewParamRouteHandler(handler, http.MethodGet,
map[string]string{"epoch:[0-9]+": "Epoch"},
[]api.ApiPChainTxListItem{},
)
}

func AddTransactionRoutes(
router utils.Router, ctx context.ServicesContext, epochs staking.EpochInfo,
) {
vr := newTransactionRouteHandlers(ctx, epochs)
subrouter := router.WithPrefix("/transactions", "Transactions")
subrouter.AddRoute("/get/{tx_id:[0-9a-zA-Z]+}", vr.getTransaction())
subrouter.AddRoute("/list/{epoch:[0-9]+}", vr.listTransactions())
}
35 changes: 35 additions & 0 deletions services/utils/epochs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package utils

import (
globalconfig "flare-indexer/config"
"flare-indexer/services/config"
"flare-indexer/services/context"
"flare-indexer/utils/contracts/voting"
"flare-indexer/utils/staking"
"time"
)

func NewEpochInfo(ctx context.ServicesContext) (staking.EpochInfo, error) {
cfg := ctx.Config()

start, period, err := getEpochStartAndPeriod(cfg)
if err != nil {
return staking.EpochInfo{}, err
}

return staking.NewEpochInfo(&globalconfig.EpochConfig{}, start, period), nil
}

func getEpochStartAndPeriod(cfg *config.Config) (time.Time, time.Duration, error) {
eth, err := cfg.Chain.DialETH()
if err != nil {
return time.Time{}, 0, err
}

votingContract, err := voting.NewVoting(cfg.ContractAddresses.Voting, eth)
if err != nil {
return time.Time{}, 0, err
}

return staking.GetEpochConfig(votingContract)
}
Loading