Add api endpoint to get total count and volume
This commit is contained in:
parent
01b34a84e8
commit
d8723c056b
|
@ -9,9 +9,12 @@ import (
|
|||
)
|
||||
|
||||
type Scorecards struct {
|
||||
// Number of VAAs emitted since the creation of the network (does not include Pyth messages)
|
||||
// Total number of VAAs emitted since the creation of the network (does not include Pyth messages).
|
||||
TotalTxCount string
|
||||
|
||||
// Volume transferred through the token bridge since the creation of the network, in USD.
|
||||
TotalTxVolume string
|
||||
|
||||
// Number of VAAs emitted in the last 24 hours (does not include Pyth messages).
|
||||
TxCount24h string
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/common/storage/portalanalytic"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/fly/storage"
|
||||
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
@ -92,6 +94,7 @@ type Repository struct {
|
|||
bucketInfiniteRetention string
|
||||
bucket30DaysRetention string
|
||||
bucket24HoursRetention string
|
||||
portalAnalyticRepo *portalanalytic.Repository
|
||||
db *mongo.Database
|
||||
collections struct {
|
||||
globalTransactions *mongo.Collection
|
||||
|
@ -104,6 +107,7 @@ func NewRepository(
|
|||
org string,
|
||||
bucket24HoursRetention, bucket30DaysRetention, bucketInfiniteRetention string,
|
||||
db *mongo.Database,
|
||||
portalAnalyticRepo *portalanalytic.Repository,
|
||||
logger *zap.Logger,
|
||||
) *Repository {
|
||||
|
||||
|
@ -113,6 +117,7 @@ func NewRepository(
|
|||
bucket24HoursRetention: bucket24HoursRetention,
|
||||
bucket30DaysRetention: bucket30DaysRetention,
|
||||
bucketInfiniteRetention: bucketInfiniteRetention,
|
||||
portalAnalyticRepo: portalAnalyticRepo,
|
||||
db: db,
|
||||
collections: struct{ globalTransactions *mongo.Collection }{globalTransactions: db.Collection("globalTransactions")},
|
||||
logger: logger,
|
||||
|
@ -231,19 +236,19 @@ func (r *Repository) buildFindVolumeQuery(q *ChainActivityQuery) string {
|
|||
}
|
||||
|
||||
func (r *Repository) GetScorecards(ctx context.Context) (*Scorecards, error) {
|
||||
// get historic total count and volume.
|
||||
totalTxCount, totalTxVolume, err := r.getTotalCountAndVolume(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO the underlying query in this code is not using pre-summarized data.
|
||||
// We should fix that before re-enabling the metric.
|
||||
//totalTxCount, err := r.getTotalTxCount(ctx)
|
||||
//if err != nil {
|
||||
// return nil, fmt.Errorf("failed to query all-time tx count")
|
||||
//}
|
||||
|
||||
// get 24h transactions
|
||||
txCount24h, err := r.getTxCount24h(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query 24h transactions: %w", err)
|
||||
}
|
||||
|
||||
// get 24h volume
|
||||
volume24h, err := r.getVolume24h(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query 24h volume: %w", err)
|
||||
|
@ -251,40 +256,35 @@ func (r *Repository) GetScorecards(ctx context.Context) (*Scorecards, error) {
|
|||
|
||||
// build the result and return
|
||||
scorecards := Scorecards{
|
||||
//TotalTxCount: totalTxCount,
|
||||
TxCount24h: txCount24h,
|
||||
Volume24h: volume24h,
|
||||
TotalTxCount: fmt.Sprint(totalTxCount),
|
||||
TotalTxVolume: fmt.Sprint(totalTxVolume),
|
||||
TxCount24h: txCount24h,
|
||||
Volume24h: volume24h,
|
||||
}
|
||||
|
||||
return &scorecards, nil
|
||||
}
|
||||
|
||||
func (r *Repository) getTotalTxCount(ctx context.Context) (string, error) {
|
||||
|
||||
// query 24h transactions
|
||||
query := fmt.Sprintf(queryTemplateTotalTxCount, r.bucketInfiniteRetention)
|
||||
result, err := r.queryAPI.Query(ctx, query)
|
||||
// getTotalCountAndVolume get historic total count and volume.
|
||||
func (r *Repository) getTotalCountAndVolume(ctx context.Context) (storage.Uint64, storage.Uint64, error) {
|
||||
var totalTxCount, totalTxVolume storage.Uint64
|
||||
var ids = []string{"tx_volume_historic", "tx_volume", "tx_count_historic", "tx_count"}
|
||||
portalAnalytics, err := r.portalAnalyticRepo.GetPortalAnalyticByIds(ctx, ids)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to query total transaction count", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
if result.Err() != nil {
|
||||
r.logger.Error("total transaction count query result has errors", zap.Error(err))
|
||||
return "", result.Err()
|
||||
}
|
||||
if !result.Next() {
|
||||
return "", errors.New("expected at least one record in total transaction count query result")
|
||||
return 0, 0, err
|
||||
}
|
||||
for _, portalAnalytic := range portalAnalytics {
|
||||
if portalAnalytic.ID == "tx_count_historic" || portalAnalytic.ID == "tx_count" {
|
||||
totalTxCount = totalTxCount + portalAnalytic.Value
|
||||
continue
|
||||
}
|
||||
if portalAnalytic.ID == "tx_volume_historic" || portalAnalytic.ID == "tx_volume" {
|
||||
totalTxVolume = totalTxVolume + portalAnalytic.Value
|
||||
continue
|
||||
}
|
||||
|
||||
// deserialize the row returned
|
||||
row := struct {
|
||||
Value uint64 `mapstructure:"_value"`
|
||||
}{}
|
||||
if err := mapstructure.Decode(result.Record().Values(), &row); err != nil {
|
||||
return "", fmt.Errorf("failed to decode total transaction count query response: %w", err)
|
||||
}
|
||||
|
||||
return fmt.Sprint(row.Value), nil
|
||||
return totalTxCount, totalTxVolume, nil
|
||||
}
|
||||
|
||||
func (r *Repository) getTxCount24h(ctx context.Context) (string, error) {
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
wormscanCache "github.com/wormhole-foundation/wormhole-explorer/common/client/cache"
|
||||
wormscanNotionalCache "github.com/wormhole-foundation/wormhole-explorer/common/client/cache/notional"
|
||||
xlogger "github.com/wormhole-foundation/wormhole-explorer/common/logger"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/common/storage/portalanalytic"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -112,6 +113,7 @@ func main() {
|
|||
governorRepo := governor.NewRepository(db, rootLogger)
|
||||
infrastructureRepo := infrastructure.NewRepository(db, rootLogger)
|
||||
heartbeatsRepo := heartbeats.NewRepository(db, rootLogger)
|
||||
portalAnalytcRepo := portalanalytic.NewPortalAnalytic(db, rootLogger)
|
||||
transactionsRepo := transactions.NewRepository(
|
||||
influxCli,
|
||||
cfg.Influx.Organization,
|
||||
|
@ -119,6 +121,7 @@ func main() {
|
|||
cfg.Influx.Bucket30Days,
|
||||
cfg.Influx.BucketInfinite,
|
||||
db,
|
||||
portalAnalytcRepo,
|
||||
rootLogger,
|
||||
)
|
||||
|
||||
|
|
|
@ -77,9 +77,10 @@ func (c *Controller) GetScorecards(ctx *fiber.Ctx) error {
|
|||
|
||||
// Convert indicators to the response model
|
||||
response := ScorecardsResponse{
|
||||
TotalTxCount: scorecards.TotalTxCount,
|
||||
TxCount24h: scorecards.TxCount24h,
|
||||
Volume24h: scorecards.Volume24h,
|
||||
TotalTxCount: scorecards.TotalTxCount,
|
||||
TotalTxVolume: scorecards.TotalTxVolume,
|
||||
TxCount24h: scorecards.TxCount24h,
|
||||
Volume24h: scorecards.Volume24h,
|
||||
}
|
||||
|
||||
return ctx.JSON(response)
|
||||
|
|
|
@ -30,10 +30,11 @@ type ScorecardsResponse struct {
|
|||
// Number of VAAs emitted in the last 24 hours (includes Pyth messages).
|
||||
//Messages24h string `json:"24h_messages"`
|
||||
|
||||
// Number of VAAs emitted since the creation of the network (does not include Pyth messages)
|
||||
TotalTxCount string `json:"total_tx_count,omitempty"`
|
||||
// Total number of VAAs emitted since the creation of the network (does not include Pyth messages).
|
||||
TotalTxCount string `json:"total_tx_count"`
|
||||
|
||||
//TotalVolume string `json:"total_volume"`
|
||||
// Volume transferred through the token bridge since the creation of the network, in USD.
|
||||
TotalTxVolume string `json:"total_volume"`
|
||||
|
||||
//TVL string `json:"tvl"`
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package portalanalytic
|
||||
|
||||
import "github.com/wormhole-foundation/wormhole-explorer/common/storage"
|
||||
import "github.com/wormhole-foundation/wormhole-explorer/fly/storage"
|
||||
|
||||
// PortalAnalyticDoc is a portal analytic document.
|
||||
type PortalAnalyticdDoc struct {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package portalanalytic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -23,6 +25,6 @@ func NewPortalAnalytic(db *mongo.Database, log *zap.Logger) *Repository {
|
|||
}
|
||||
|
||||
// GetPortalAnalytic get portal analytic.
|
||||
func (r *Repository) GetPortalAnalyticByIds(ids []string) ([]*PortalAnalyticdDoc, error) {
|
||||
func (r *Repository) GetPortalAnalyticByIds(ctx context.Context, ids []string) ([]*PortalAnalyticdDoc, error) {
|
||||
return []*PortalAnalyticdDoc{}, nil
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
type Uint64 uint64
|
||||
|
||||
func (u Uint64) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
ui64Str := strconv.FormatUint(uint64(u), 10)
|
||||
d128, err := primitive.ParseDecimal128(ui64Str)
|
||||
return bsontype.Decimal128, bsoncore.AppendDecimal128(nil, d128), err
|
||||
}
|
||||
|
||||
func (u *Uint64) UnmarshalBSONValue(t bsontype.Type, b []byte) error {
|
||||
d128, _, ok := bsoncore.ReadDecimal128(b)
|
||||
if !ok {
|
||||
return errors.New("Uint64 UnmarshalBSONValue error")
|
||||
}
|
||||
|
||||
ui64, err := strconv.ParseUint(d128.String(), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*u = Uint64(ui64)
|
||||
return nil
|
||||
}
|
|
@ -65,6 +65,12 @@ func Run(db *mongo.Database) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Create vaaIdTxHash collection.
|
||||
err = db.CreateCollection(context.TODO(), "portalAnalytic")
|
||||
if err != nil && isNotAlreadyExistsError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
// create index in vaas collection by vaa key (emitterchain, emitterAddr, sequence)
|
||||
indexVaaByKey := mongo.IndexModel{
|
||||
Keys: bson.D{
|
||||
|
|
Loading…
Reference in New Issue