refactor to accept multiple sourceChains,targetChains and appIds

This commit is contained in:
Mariano 2024-04-25 17:46:09 -03:00
parent ce1b7707fb
commit b4d7e3284e
4 changed files with 111 additions and 34 deletions

View File

@ -111,51 +111,66 @@ type OperationQuery struct {
Pagination pagination.Pagination
TxHash string
Address string
SourceChainID *vaa.ChainID
TargetChainID *vaa.ChainID
AppID string
SourceChainIDs []vaa.ChainID
TargetChainIDs []vaa.ChainID
AppID []string
ExclusiveAppId bool
}
func buildQueryOperationsByChain(sourceChainID, targetChainID *vaa.ChainID) bson.D {
func buildQueryOperationsByChain(sourceChainIDs, targetChainIDs []vaa.ChainID) bson.D {
var allMatch bson.A
if sourceChainID != nil {
matchSourceChain := bson.M{"rawStandardizedProperties.fromChain": *sourceChainID}
if len(sourceChainIDs) > 0 {
matchSourceChain := bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": sourceChainIDs}}
allMatch = append(allMatch, matchSourceChain)
}
if targetChainID != nil {
matchTargetChain := bson.M{"rawStandardizedProperties.toChain": *targetChainID}
if len(targetChainIDs) > 0 {
matchTargetChain := bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": targetChainIDs}}
allMatch = append(allMatch, matchTargetChain)
}
if (sourceChainID != nil && targetChainID != nil) && (*sourceChainID == *targetChainID) {
if (len(sourceChainIDs) == 1 && len(targetChainIDs) == 1) && (sourceChainIDs[0] == targetChainIDs[0]) {
return bson.D{{Key: "$match", Value: bson.M{"$or": allMatch}}}
}
return bson.D{{Key: "$match", Value: bson.M{"$and": allMatch}}}
}
func buildQueryOperationsByAppID(appID string, exclusive bool) []bson.D {
func buildQueryOperationsByAppID(appIDs []string, exclusive bool) []bson.D {
var result []bson.D
if appID == "" {
result = append(result, bson.D{{Key: "$match", Value: bson.M{}}})
return result
}
/*
if appID == "" {
result = append(result, bson.D{{Key: "$match", Value: bson.M{}}})
return result
}
*/
if exclusive {
result = append(result, bson.D{{Key: "$match", Value: bson.M{
"$and": bson.A{
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": []string{appID}}},
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
}}}})
return result
if len(appIDs) == 1 {
result = append(result, bson.D{{Key: "$match", Value: bson.M{
"$and": bson.A{
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": appIDs}},
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
}}}})
} else {
a := bson.A{}
for _, appID := range appIDs {
cond := bson.M{
"$and": bson.A{
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": appID}},
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
}}
a = append(a, cond)
}
result = append(result, bson.D{{Key: "$match", Value: bson.M{
"$or": a}}})
}
} else {
result = append(result, bson.D{{Key: "$match", Value: bson.M{"rawStandardizedProperties.appIds": bson.M{"$in": []string{appID}}}}})
result = append(result, bson.D{{Key: "$match", Value: bson.M{"rawStandardizedProperties.appIds": bson.M{"$in": appIDs}}}})
}
return result
}
@ -238,8 +253,8 @@ func (r *Repository) FindByChainAndAppId(ctx context.Context, query OperationQue
var pipeline mongo.Pipeline
if query.SourceChainID != nil || query.TargetChainID != nil {
matchBySourceTargetChain := buildQueryOperationsByChain(query.SourceChainID, query.TargetChainID)
if len(query.SourceChainIDs) != 0 || len(query.TargetChainIDs) != 0 {
matchBySourceTargetChain := buildQueryOperationsByChain(query.SourceChainIDs, query.TargetChainIDs)
pipeline = append(pipeline, matchBySourceTargetChain)
}

View File

@ -34,9 +34,9 @@ func (s *Service) FindById(ctx context.Context, chainID vaa.ChainID,
type OperationFilter struct {
TxHash *types.TxHash
Address string
SourceChainID *vaa.ChainID
TargetChainID *vaa.ChainID
AppID string
SourceChainIDs []vaa.ChainID
TargetChainIDs []vaa.ChainID
AppID []string
ExclusiveAppId bool
Pagination pagination.Pagination
}
@ -52,13 +52,13 @@ func (s *Service) FindAll(ctx context.Context, filter OperationFilter) ([]*Opera
TxHash: txHash,
Address: filter.Address,
Pagination: filter.Pagination,
SourceChainID: filter.SourceChainID,
TargetChainID: filter.TargetChainID,
SourceChainIDs: filter.SourceChainIDs,
TargetChainIDs: filter.TargetChainIDs,
AppID: filter.AppID,
ExclusiveAppId: filter.ExclusiveAppId,
}
if operationQuery.AppID != "" || operationQuery.SourceChainID != nil || operationQuery.TargetChainID != nil {
if len(operationQuery.AppID) != 0 || len(operationQuery.SourceChainIDs) > 0 || len(operationQuery.TargetChainIDs) > 0 {
return s.repo.FindByChainAndAppId(ctx, operationQuery)
}

View File

@ -61,14 +61,73 @@ func ExtractToChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
return &result, nil
}
func ExtractChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
return extractChainQueryParam(c, l, "chain")
}
/*
func ExtractSourceChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
return extractChainQueryParam(c, l, "sourceChain")
}
func ExtractTargetChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
return extractChainQueryParam(c, l, "targetChain")
}
*/
func ExtractSourceChain(c *fiber.Ctx, l *zap.Logger) ([]sdk.ChainID, error) {
param := c.Query("sourceChain")
if param == "" {
return nil, nil
}
result := make([]sdk.ChainID, 0, len(param))
for _, val := range strings.Split(param, ",") {
chain, err := parseChainIDParam(val)
if err != nil {
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
l.Error("failed to parse sourceChain parameter",
zap.Error(err),
zap.String("requestID", requestID),
)
return nil, response.NewInvalidParamError(c, "INVALID SOURCE_CHAIN VALUE", errors.WithStack(err))
}
result = append(result, chain)
}
return result, nil
}
func ExtractTargetChain(c *fiber.Ctx, l *zap.Logger) ([]sdk.ChainID, error) {
param := c.Query("targetChain")
if param == "" {
return nil, nil
}
result := make([]sdk.ChainID, 0, len(param))
for _, val := range strings.Split(param, ",") {
chain, err := parseChainIDParam(val)
if err != nil {
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
l.Error("failed to parse targetChain parameter",
zap.Error(err),
zap.String("requestID", requestID),
)
return nil, response.NewInvalidParamError(c, "INVALID TARGET_CHAIN VALUE", errors.WithStack(err))
}
result = append(result, chain)
}
return result, nil
}
func parseChainIDParam(param string) (sdk.ChainID, error) {
chain, err := strconv.ParseInt(param, 10, 16)
if err != nil {
return sdk.ChainIDUnset, err
}
return sdk.ChainID(chain), nil
}
func extractChainQueryParam(c *fiber.Ctx, l *zap.Logger, queryParam string) (*sdk.ChainID, error) {
param := c.Query(queryParam)
if param == "" {

View File

@ -2,6 +2,7 @@ package operations
import (
"strconv"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/operations"
@ -75,14 +76,16 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
return err
}
appID := middleware.ExtractAppId(ctx, c.logger)
//appID := middleware.ExtractAppId(ctx, c.logger)
appID := strings.Split(ctx.Query("appId"), ",")
exclusiveAppId, err := middleware.ExtractExclusiveAppId(ctx)
if err != nil {
return err
}
searchBySourceTargetChain := sourceChain != nil || targetChain != nil
searchByAppId := appID != ""
searchBySourceTargetChain := len(sourceChain) != 0 || targetChain != nil
searchByAppId := len(appID) != 0
if (searchByAddress || searchByTxHash) && (searchBySourceTargetChain || searchByAppId) {
return response.NewInvalidParamError(ctx, "address/txHash cannot be combined with sourceChain/targetChain/appId query filter", nil)
@ -91,8 +94,8 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
filter := operations.OperationFilter{
TxHash: txHash,
Address: address,
SourceChainID: sourceChain,
TargetChainID: targetChain,
SourceChainIDs: sourceChain,
TargetChainIDs: targetChain,
AppID: appID,
ExclusiveAppId: exclusiveAppId,
Pagination: *pagination,