refactor to accept multiple sourceChains,targetChains and appIds
This commit is contained in:
parent
ce1b7707fb
commit
b4d7e3284e
|
@ -111,51 +111,66 @@ type OperationQuery struct {
|
||||||
Pagination pagination.Pagination
|
Pagination pagination.Pagination
|
||||||
TxHash string
|
TxHash string
|
||||||
Address string
|
Address string
|
||||||
SourceChainID *vaa.ChainID
|
SourceChainIDs []vaa.ChainID
|
||||||
TargetChainID *vaa.ChainID
|
TargetChainIDs []vaa.ChainID
|
||||||
AppID string
|
AppID []string
|
||||||
ExclusiveAppId bool
|
ExclusiveAppId bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildQueryOperationsByChain(sourceChainID, targetChainID *vaa.ChainID) bson.D {
|
func buildQueryOperationsByChain(sourceChainIDs, targetChainIDs []vaa.ChainID) bson.D {
|
||||||
|
|
||||||
var allMatch bson.A
|
var allMatch bson.A
|
||||||
|
|
||||||
if sourceChainID != nil {
|
if len(sourceChainIDs) > 0 {
|
||||||
matchSourceChain := bson.M{"rawStandardizedProperties.fromChain": *sourceChainID}
|
matchSourceChain := bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": sourceChainIDs}}
|
||||||
allMatch = append(allMatch, matchSourceChain)
|
allMatch = append(allMatch, matchSourceChain)
|
||||||
}
|
}
|
||||||
|
|
||||||
if targetChainID != nil {
|
if len(targetChainIDs) > 0 {
|
||||||
matchTargetChain := bson.M{"rawStandardizedProperties.toChain": *targetChainID}
|
matchTargetChain := bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": targetChainIDs}}
|
||||||
allMatch = append(allMatch, matchTargetChain)
|
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{"$or": allMatch}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bson.D{{Key: "$match", Value: bson.M{"$and": 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
|
var result []bson.D
|
||||||
|
|
||||||
if appID == "" {
|
/*
|
||||||
result = append(result, bson.D{{Key: "$match", Value: bson.M{}}})
|
if appID == "" {
|
||||||
return result
|
result = append(result, bson.D{{Key: "$match", Value: bson.M{}}})
|
||||||
}
|
return result
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if exclusive {
|
if exclusive {
|
||||||
result = append(result, bson.D{{Key: "$match", Value: bson.M{
|
if len(appIDs) == 1 {
|
||||||
"$and": bson.A{
|
result = append(result, bson.D{{Key: "$match", Value: bson.M{
|
||||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": []string{appID}}},
|
"$and": bson.A{
|
||||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
|
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": appIDs}},
|
||||||
}}}})
|
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
|
||||||
return result
|
}}}})
|
||||||
|
} 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 {
|
} 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
|
return result
|
||||||
}
|
}
|
||||||
|
@ -238,8 +253,8 @@ func (r *Repository) FindByChainAndAppId(ctx context.Context, query OperationQue
|
||||||
|
|
||||||
var pipeline mongo.Pipeline
|
var pipeline mongo.Pipeline
|
||||||
|
|
||||||
if query.SourceChainID != nil || query.TargetChainID != nil {
|
if len(query.SourceChainIDs) != 0 || len(query.TargetChainIDs) != 0 {
|
||||||
matchBySourceTargetChain := buildQueryOperationsByChain(query.SourceChainID, query.TargetChainID)
|
matchBySourceTargetChain := buildQueryOperationsByChain(query.SourceChainIDs, query.TargetChainIDs)
|
||||||
pipeline = append(pipeline, matchBySourceTargetChain)
|
pipeline = append(pipeline, matchBySourceTargetChain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@ func (s *Service) FindById(ctx context.Context, chainID vaa.ChainID,
|
||||||
type OperationFilter struct {
|
type OperationFilter struct {
|
||||||
TxHash *types.TxHash
|
TxHash *types.TxHash
|
||||||
Address string
|
Address string
|
||||||
SourceChainID *vaa.ChainID
|
SourceChainIDs []vaa.ChainID
|
||||||
TargetChainID *vaa.ChainID
|
TargetChainIDs []vaa.ChainID
|
||||||
AppID string
|
AppID []string
|
||||||
ExclusiveAppId bool
|
ExclusiveAppId bool
|
||||||
Pagination pagination.Pagination
|
Pagination pagination.Pagination
|
||||||
}
|
}
|
||||||
|
@ -52,13 +52,13 @@ func (s *Service) FindAll(ctx context.Context, filter OperationFilter) ([]*Opera
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Address: filter.Address,
|
Address: filter.Address,
|
||||||
Pagination: filter.Pagination,
|
Pagination: filter.Pagination,
|
||||||
SourceChainID: filter.SourceChainID,
|
SourceChainIDs: filter.SourceChainIDs,
|
||||||
TargetChainID: filter.TargetChainID,
|
TargetChainIDs: filter.TargetChainIDs,
|
||||||
AppID: filter.AppID,
|
AppID: filter.AppID,
|
||||||
ExclusiveAppId: filter.ExclusiveAppId,
|
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)
|
return s.repo.FindByChainAndAppId(ctx, operationQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,14 +61,73 @@ func ExtractToChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
|
||||||
return &result, nil
|
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) {
|
func ExtractSourceChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
|
||||||
return extractChainQueryParam(c, l, "sourceChain")
|
return extractChainQueryParam(c, l, "sourceChain")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func ExtractTargetChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
|
func ExtractTargetChain(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
|
||||||
return extractChainQueryParam(c, l, "targetChain")
|
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) {
|
func extractChainQueryParam(c *fiber.Ctx, l *zap.Logger, queryParam string) (*sdk.ChainID, error) {
|
||||||
param := c.Query(queryParam)
|
param := c.Query(queryParam)
|
||||||
if param == "" {
|
if param == "" {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package operations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/operations"
|
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/operations"
|
||||||
|
@ -75,14 +76,16 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
return err
|
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)
|
exclusiveAppId, err := middleware.ExtractExclusiveAppId(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
searchBySourceTargetChain := sourceChain != nil || targetChain != nil
|
searchBySourceTargetChain := len(sourceChain) != 0 || targetChain != nil
|
||||||
searchByAppId := appID != ""
|
searchByAppId := len(appID) != 0
|
||||||
|
|
||||||
if (searchByAddress || searchByTxHash) && (searchBySourceTargetChain || searchByAppId) {
|
if (searchByAddress || searchByTxHash) && (searchBySourceTargetChain || searchByAppId) {
|
||||||
return response.NewInvalidParamError(ctx, "address/txHash cannot be combined with sourceChain/targetChain/appId query filter", nil)
|
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{
|
filter := operations.OperationFilter{
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Address: address,
|
Address: address,
|
||||||
SourceChainID: sourceChain,
|
SourceChainIDs: sourceChain,
|
||||||
TargetChainID: targetChain,
|
TargetChainIDs: targetChain,
|
||||||
AppID: appID,
|
AppID: appID,
|
||||||
ExclusiveAppId: exclusiveAppId,
|
ExclusiveAppId: exclusiveAppId,
|
||||||
Pagination: *pagination,
|
Pagination: *pagination,
|
||||||
|
|
Loading…
Reference in New Issue