97 lines
3.3 KiB
Go
97 lines
3.3 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/influxdata/influxdb-client-go/v2/api/write"
|
|
"github.com/shopspring/decimal"
|
|
"github.com/wormhole-foundation/wormhole-explorer/analytics/cmd/token"
|
|
"github.com/wormhole-foundation/wormhole-explorer/analytics/internal/metrics"
|
|
"github.com/wormhole-foundation/wormhole-explorer/analytics/metric"
|
|
"github.com/wormhole-foundation/wormhole-explorer/analytics/prices"
|
|
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
|
|
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
)
|
|
|
|
type VaaConverter struct {
|
|
MissingTokens map[sdk.Address]sdk.ChainID
|
|
MissingTokensCounter map[sdk.Address]int
|
|
PriceCache *prices.CoinPricesCache
|
|
Metrics metrics.Metrics
|
|
GetTransferredTokenByVaa token.GetTransferredTokenByVaa
|
|
TokenProvider *domain.TokenProvider
|
|
}
|
|
|
|
func NewVaaConverter(priceCache *prices.CoinPricesCache, GetTransferredTokenByVaa token.GetTransferredTokenByVaa, tokenProvider *domain.TokenProvider) *VaaConverter {
|
|
return &VaaConverter{
|
|
MissingTokens: make(map[sdk.Address]sdk.ChainID),
|
|
MissingTokensCounter: make(map[sdk.Address]int),
|
|
PriceCache: priceCache,
|
|
Metrics: metrics.NewNoopMetrics(),
|
|
GetTransferredTokenByVaa: GetTransferredTokenByVaa,
|
|
TokenProvider: tokenProvider,
|
|
}
|
|
}
|
|
|
|
func (c *VaaConverter) Convert(ctx context.Context, vaaBytes []byte) (string, error) {
|
|
|
|
// Parse the VAA and payload
|
|
vaa, err := sdk.Unmarshal(vaaBytes)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error unmarshaling vaa: %v", err)
|
|
}
|
|
transferredToken, err := c.GetTransferredTokenByVaa(ctx, vaa)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error decoding payload: %v", err)
|
|
}
|
|
|
|
// Look up token metadata
|
|
tokenMetadata, ok := c.TokenProvider.GetTokenByAddress(transferredToken.TokenChain, transferredToken.TokenAddress.String())
|
|
if !ok {
|
|
|
|
// if not found, add to missing tokens
|
|
c.MissingTokens[transferredToken.TokenAddress] = transferredToken.TokenChain
|
|
c.MissingTokensCounter[transferredToken.TokenAddress] = c.MissingTokensCounter[transferredToken.TokenAddress] + 1
|
|
|
|
return "", fmt.Errorf("unknown token: %s %s", transferredToken.TokenChain.String(), transferredToken.TokenAddress.String())
|
|
}
|
|
|
|
// Generate a data point for the VAA volume metric
|
|
var point *write.Point
|
|
{
|
|
p := metric.MakePointForVaaVolumeParams{
|
|
Vaa: vaa,
|
|
TokenPriceFunc: func(_ string, timestamp time.Time) (decimal.Decimal, error) {
|
|
|
|
// fetch the historic price from cache
|
|
price, err := c.PriceCache.GetPriceByTime(tokenMetadata.CoingeckoID, timestamp)
|
|
if err != nil {
|
|
return decimal.NewFromInt(0), err
|
|
}
|
|
|
|
return price, nil
|
|
},
|
|
Metrics: c.Metrics,
|
|
TransferredToken: transferredToken,
|
|
TokenProvider: c.TokenProvider,
|
|
}
|
|
|
|
var err error
|
|
point, err = metric.MakePointForVaaVolume(&p)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to create data point for VAA volume metric: %v", err)
|
|
}
|
|
if point == nil {
|
|
// Some VAAs don't generate any data points for this metric (e.g.: PythNet, non-token-bridge VAAs)
|
|
return "", errors.New("can't generate point for VAA volume metric")
|
|
}
|
|
}
|
|
|
|
// Convert the data point to line protocol
|
|
result := convertPointToLineProtocol(point)
|
|
return result, nil
|
|
}
|