Fix transaction hash search for Aptos (#461)
### Description Tracking issue: https://github.com/wormhole-foundation/wormhole-explorer/issues/430 In `GET /api/v1/vaas?txHash={hash}`, searching for Aptos VAAs by transaction hash was not working correctly. This pull request fixes the issue.
This commit is contained in:
parent
471a6dad4d
commit
5663fed0c9
|
@ -47,22 +47,32 @@ func NewRepository(db *mongo.Database, logger *zap.Logger) *Repository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindVaasBySolanaTxHash searches the database for VAAs that match a given Solana transaction hash.
|
// FindVaasByTxHashWorkaround searches the database for VAAs that match a given transaction hash.
|
||||||
func (r *Repository) FindVaasBySolanaTxHash(
|
//
|
||||||
|
// This function exists to work around the issue that for Aptos and Solana, the real transaction
|
||||||
|
// hashes are stored in a different collection from other chains.
|
||||||
|
//
|
||||||
|
// When the `q.txHash` field is set, this function will look up transaction hashes in the `globalTransactions` collection.
|
||||||
|
// Then, if the transaction hash is not found, it will fall back to searching in the `vaas` collection.
|
||||||
|
func (r *Repository) FindVaasByTxHashWorkaround(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
txHash string,
|
query *VaaQuery,
|
||||||
includeParsedPayload bool,
|
|
||||||
) ([]*VaaDoc, error) {
|
) ([]*VaaDoc, error) {
|
||||||
|
|
||||||
// Find globalTransactions that match the given Solana TxHash
|
// Find globalTransactions that match the given TxHash
|
||||||
cur, err := r.collections.globalTransactions.Find(
|
cur, err := r.collections.globalTransactions.Find(
|
||||||
ctx,
|
ctx,
|
||||||
bson.D{bson.E{"originTx.nativeTxHash", txHash}},
|
bson.D{
|
||||||
|
{"$or", bson.A{
|
||||||
|
bson.D{{"originTx.nativeTxHash", bson.M{"$eq": query.txHash}}},
|
||||||
|
bson.D{{"originTx.nativeTxHash", bson.M{"$eq": "0x" + query.txHash}}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
requestID := fmt.Sprintf("%v", ctx.Value("requestid"))
|
||||||
r.logger.Error("failed to find globalTransactions by Solana TxHash",
|
r.logger.Error("failed to find globalTransactions by TxHash",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
zap.String("requestID", requestID),
|
zap.String("requestID", requestID),
|
||||||
)
|
)
|
||||||
|
@ -80,24 +90,29 @@ func (r *Repository) FindVaasBySolanaTxHash(
|
||||||
)
|
)
|
||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no results were found, return an empty slice instead of nil.
|
|
||||||
if len(globalTxs) == 0 {
|
|
||||||
result := make([]*VaaDoc, 0)
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
if len(globalTxs) > 1 {
|
if len(globalTxs) > 1 {
|
||||||
return nil, fmt.Errorf("expected at most one transaction, but found %d", len(globalTxs))
|
return nil, fmt.Errorf("expected at most one transaction, but found %d", len(globalTxs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no documents were found, look up the transaction hash in the `vaas` collection instead.
|
||||||
|
if len(globalTxs) == 0 {
|
||||||
|
return r.FindVaas(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
// Find VAAs that match the given VAA ID
|
// Find VAAs that match the given VAA ID
|
||||||
q := Query().
|
q := *query // making a copy to avoid modifying the struct passed by the caller
|
||||||
SetID(globalTxs[0].ID).
|
q.SetID(globalTxs[0].ID)
|
||||||
IncludeParsedPayload(includeParsedPayload)
|
// Disable txHash filter, but keep all the other filters.
|
||||||
return r.FindVaas(ctx, q)
|
// We have to do this because the transaction hashes in the `globalTransactions` collection
|
||||||
|
// may be different that the transaction hash in the `vaas` collection. This is the case
|
||||||
|
// for Aptos and Solana VAAs.
|
||||||
|
q.txHash = ""
|
||||||
|
return r.FindVaas(ctx, &q)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindVaas searches the database for VAAs matching the given filters.
|
// FindVaas searches the database for VAAs matching the given filters.
|
||||||
|
//
|
||||||
|
// When the `q.txHash` field is set, this function will look up transaction hashes in the `vaas` collection.
|
||||||
func (r *Repository) FindVaas(
|
func (r *Repository) FindVaas(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
q *VaaQuery,
|
q *VaaQuery,
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (s *Service) FindAll(
|
||||||
params *FindAllParams,
|
params *FindAllParams,
|
||||||
) (*response.Response[[]*VaaDoc], error) {
|
) (*response.Response[[]*VaaDoc], error) {
|
||||||
|
|
||||||
// set up query parameters
|
// Populate query parameters
|
||||||
query := Query().
|
query := Query().
|
||||||
IncludeParsedPayload(params.IncludeParsedPayload)
|
IncludeParsedPayload(params.IncludeParsedPayload)
|
||||||
if params.Pagination != nil {
|
if params.Pagination != nil {
|
||||||
|
@ -61,11 +61,16 @@ func (s *Service) FindAll(
|
||||||
query.SetAppId(params.AppId)
|
query.SetAppId(params.AppId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute the database query
|
// Execute the database query
|
||||||
|
//
|
||||||
|
// Unfortunately, for Aptos and Solana, the real transaction hashes are stored
|
||||||
|
// in a different collection from other chains.
|
||||||
|
//
|
||||||
|
// This block of code has additional logic to handle that case.
|
||||||
var err error
|
var err error
|
||||||
var vaas []*VaaDoc
|
var vaas []*VaaDoc
|
||||||
if params.TxHash != nil && params.TxHash.IsSolanaTxHash() {
|
if query.txHash != "" {
|
||||||
vaas, err = s.repo.FindVaasBySolanaTxHash(ctx, params.TxHash.String(), params.IncludeParsedPayload)
|
vaas, err = s.repo.FindVaasByTxHashWorkaround(ctx, query)
|
||||||
} else {
|
} else {
|
||||||
vaas, err = s.repo.FindVaas(ctx, query)
|
vaas, err = s.repo.FindVaas(ctx, query)
|
||||||
}
|
}
|
||||||
|
@ -73,7 +78,7 @@ func (s *Service) FindAll(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the matching documents
|
// Eeturn the matching documents
|
||||||
res := response.Response[[]*VaaDoc]{Data: vaas}
|
res := response.Response[[]*VaaDoc]{Data: vaas}
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue