158 lines
4.7 KiB
Go
158 lines
4.7 KiB
Go
package vaa
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/certusone/wormhole/node/pkg/vaa"
|
|
"github.com/pkg/errors"
|
|
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
|
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Repository definition
|
|
type Repository struct {
|
|
db *mongo.Database
|
|
logger *zap.Logger
|
|
collections struct {
|
|
vaas *mongo.Collection
|
|
invalidVaas *mongo.Collection
|
|
vaaCount *mongo.Collection
|
|
}
|
|
}
|
|
|
|
// NewRepository create a new Repository.
|
|
func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
|
return &Repository{db: db,
|
|
logger: logger.With(zap.String("module", "VaaRepository")),
|
|
collections: struct {
|
|
vaas *mongo.Collection
|
|
invalidVaas *mongo.Collection
|
|
vaaCount *mongo.Collection
|
|
}{vaas: db.Collection("vaas"), invalidVaas: db.Collection("invalid_vaas"),
|
|
vaaCount: db.Collection("vaaCounts")}}
|
|
}
|
|
|
|
// Find get a list of *VaaDoc.
|
|
// The input parameter [q *VaaQuery] define the filters to apply in the query.
|
|
func (r *Repository) Find(ctx context.Context, q *VaaQuery) ([]*VaaDoc, error) {
|
|
if q == nil {
|
|
q = Query()
|
|
}
|
|
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
|
cur, err := r.collections.vaas.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
|
if err != nil {
|
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
|
r.logger.Error("failed execute Find command to get vaas",
|
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
var vaas []*VaaDoc
|
|
err = cur.All(ctx, &vaas)
|
|
if err != nil {
|
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
|
r.logger.Error("failed decoding cursor to []*VaaDoc", zap.Error(err), zap.Any("q", q),
|
|
zap.String("requestID", requestID))
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
return vaas, err
|
|
}
|
|
|
|
// FindOne get *VaaDoc.
|
|
// The input parameter [q *VaaQuery] define the filters to apply in the query.
|
|
func (r *Repository) FindOne(ctx context.Context, q *VaaQuery) (*VaaDoc, error) {
|
|
var vaaDoc VaaDoc
|
|
err := r.collections.vaas.FindOne(ctx, q.toBSON()).Decode(&vaaDoc)
|
|
if err != nil {
|
|
if errors.Is(err, mongo.ErrNoDocuments) {
|
|
return nil, errs.ErrNotFound
|
|
}
|
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
|
r.logger.Error("failed execute FindOne command to get vaas",
|
|
zap.Error(err), zap.Any("q", q), zap.String("requestID", requestID))
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
return &vaaDoc, err
|
|
}
|
|
|
|
// GetVaaCount get a count of vaa by chainID.
|
|
func (r *Repository) GetVaaCount(ctx context.Context, q *VaaQuery) ([]*VaaStats, error) {
|
|
if q == nil {
|
|
q = Query()
|
|
}
|
|
sort := bson.D{{q.SortBy, q.GetSortInt()}}
|
|
cur, err := r.collections.vaaCount.Find(ctx, q.toBSON(), options.Find().SetLimit(q.PageSize).SetSkip(q.Offset).SetSort(sort))
|
|
if err != nil {
|
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
|
r.logger.Error("failed execute Find command to get vaaCount",
|
|
zap.Error(err), zap.String("requestID", requestID))
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
var varCounts []*VaaStats
|
|
err = cur.All(ctx, &varCounts)
|
|
if err != nil {
|
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
|
r.logger.Error("failed decoding cursor to []*VaaStats", zap.Error(err), zap.Any("q", q),
|
|
zap.String("requestID", requestID))
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
return varCounts, nil
|
|
}
|
|
|
|
// VaaQuery respresent a query for the vaa mongodb document.
|
|
type VaaQuery struct {
|
|
pagination.Pagination
|
|
chainId vaa.ChainID
|
|
emitter string
|
|
sequence uint64
|
|
}
|
|
|
|
// Query create a new VaaQuery with default pagination vaues.
|
|
func Query() *VaaQuery {
|
|
page := pagination.FirstPage()
|
|
return &VaaQuery{Pagination: *page}
|
|
}
|
|
|
|
// SetChain set the chainId field of the VaaQuery struct.
|
|
func (q *VaaQuery) SetChain(chainID vaa.ChainID) *VaaQuery {
|
|
q.chainId = chainID
|
|
return q
|
|
}
|
|
|
|
// SetEmitter set the emitter field of the VaaQuery struct.
|
|
func (q *VaaQuery) SetEmitter(emitter string) *VaaQuery {
|
|
q.emitter = emitter
|
|
return q
|
|
}
|
|
|
|
// SetSequence set the sequence field of the VaaQuery struct.
|
|
func (q *VaaQuery) SetSequence(seq uint64) *VaaQuery {
|
|
q.sequence = seq
|
|
return q
|
|
}
|
|
|
|
// SetPagination set the pagination field of the VaaQuery struct.
|
|
func (q *VaaQuery) SetPagination(p *pagination.Pagination) *VaaQuery {
|
|
q.Pagination = *p
|
|
return q
|
|
}
|
|
|
|
func (q *VaaQuery) toBSON() *bson.D {
|
|
r := bson.D{}
|
|
if q.chainId > 0 {
|
|
r = append(r, bson.E{"emitterChain", q.chainId})
|
|
}
|
|
if q.emitter != "" {
|
|
r = append(r, bson.E{"emitterAddr", q.emitter})
|
|
}
|
|
if q.sequence > 0 {
|
|
r = append(r, bson.E{"sequence", q.sequence})
|
|
}
|
|
return &r
|
|
}
|