Transaction search by address: fix case sensitivity (#591)

### Description

Tracking issue: https://github.com/wormhole-foundation/wormhole-explorer/issues/587

The endpoint `GET /api/v1/transactions?address={addr}` was incorrectly handling EVM addresses containing uppercase characters. This pull request fixes the issue.
This commit is contained in:
agodnic 2023-07-28 12:27:48 -03:00 committed by GitHub
parent afbfac05bd
commit d267d3ae1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 15 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
"github.com/wormhole-foundation/wormhole-explorer/api/internal/tvl"
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
"github.com/wormhole-foundation/wormhole-explorer/common/utils"
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
@ -896,13 +897,23 @@ func (r *Repository) ListTransactionsByAddress(
var pipeline mongo.Pipeline
{
// filter transactions by destination address
pipeline = append(pipeline, bson.D{
{"$match", bson.D{
{"$or", bson.A{
bson.D{{"standardizedProperties.toAddress", bson.M{"$eq": address}}},
bson.D{{"standardizedProperties.toAddress", bson.M{"$eq": "0x" + address}}},
}},
}}})
{
const fieldName = "standardizedProperties.toAddress"
// If the address is non-EVM, it could be case sensitive (i.e. Solana), so we can't alter it.
var nonEvmFilter = bson.D{{fieldName, bson.M{"$eq": address}}}
// If the address is EVM, we must normalize it to the format used in the database,
// which is a 0x prefix and all lowercase characters.
var evmFilter bson.D
if utils.StartsWith0x(address) {
evmFilter = bson.D{{fieldName, bson.M{"$eq": strings.ToLower(address)}}}
} else {
evmFilter = bson.D{{fieldName, bson.M{"$eq": "0x" + strings.ToLower(address)}}}
}
pipeline = append(pipeline, bson.D{{"$match", bson.D{{"$or", bson.A{nonEvmFilter, evmFilter}}}}})
}
// specify sorting criteria
pipeline = append(pipeline, bson.D{

View File

@ -1,10 +1,14 @@
package support
package utils
import (
"strconv"
"strings"
)
func StartsWith0x(input string) bool {
return strings.HasPrefix(input, "0x") || strings.HasPrefix(input, "0X")
}
func Remove0x(input string) string {
return strings.Replace(input, "0x", "", -1)
}

View File

@ -6,8 +6,8 @@ import (
"net/http"
"github.com/go-resty/resty/v2"
"github.com/wormhole-foundation/wormhole-explorer/common/utils"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/metrics"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/support"
"go.uber.org/ratelimit"
)
@ -55,12 +55,12 @@ func (s *EvmSDK) GetLatestBlock(ctx context.Context) (uint64, error) {
if result == nil {
return 0, fmt.Errorf("empty response")
}
return support.DecodeUint64(result.Result)
return utils.DecodeUint64(result.Result)
}
func (s *EvmSDK) GetBlock(ctx context.Context, block uint64) (*GetBlockResult, error) {
s.rl.Take()
req := newEvmRequest("eth_getBlockByNumber", support.EncodeHex(block), true)
req := newEvmRequest("eth_getBlockByNumber", utils.EncodeHex(block), true)
resp, err := s.client.R().
SetContext(ctx).
SetBody(req).

View File

@ -8,9 +8,9 @@ import (
"time"
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
"github.com/wormhole-foundation/wormhole-explorer/common/utils"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/support"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
"go.uber.org/zap"
)
@ -88,7 +88,7 @@ func parseInput(input string) (*vaa.VAA, error) {
}
func getBlockNumber(s string, logger *zap.Logger) string {
value, err := strconv.ParseInt(support.Remove0x(s), 16, 64)
value, err := strconv.ParseInt(utils.Remove0x(s), 16, 64)
if err != nil {
logger.Error("cannot convert to int", zap.Error(err))
return s
@ -97,7 +97,7 @@ func getBlockNumber(s string, logger *zap.Logger) string {
}
func getTimestamp(s string, logger *zap.Logger) *time.Time {
value, err := strconv.ParseInt(support.Remove0x(s), 16, 64)
value, err := strconv.ParseInt(utils.Remove0x(s), 16, 64)
if err != nil {
logger.Error("cannot convert to timestamp", zap.Error(err))
return nil
@ -147,7 +147,7 @@ func processTransaction(ctx context.Context, chainID vaa.ChainID, tx *EvmTransac
ChainID: chainID,
Status: getTxStatus(txStatusCode),
Method: method.Name,
TxHash: support.Remove0x(tx.Hash),
TxHash: utils.Remove0x(tx.Hash),
To: tx.To,
From: tx.From,
BlockNumber: getBlockNumber(tx.BlockNumber, log),