github.com/wormhole-foundation/wormhole-explorer/common@v0.0.0-20240604151348-09585b5b97c5/repository/vaa.go (about)

     1  package repository
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
     8  	"go.mongodb.org/mongo-driver/bson"
     9  	"go.mongodb.org/mongo-driver/mongo"
    10  	"go.mongodb.org/mongo-driver/mongo/options"
    11  	"go.uber.org/zap"
    12  )
    13  
    14  // VaaRepository is a repository for VAA.
    15  type VaaRepository struct {
    16  	db     *mongo.Database
    17  	logger *zap.Logger
    18  	vaas   *mongo.Collection
    19  }
    20  
    21  // VaaDoc is a document for VAA.
    22  type VaaDoc struct {
    23  	ID               string     `bson:"_id" json:"id"`
    24  	Vaa              []byte     `bson:"vaas" json:"vaa"`
    25  	ChainID          uint16     `bson:"emitterChain"`
    26  	EmitterAddress   string     `bson:"emitterAddr"`
    27  	Sequence         string     `bson:"sequence"`
    28  	GuardianSetIndex uint32     `bson:"guardianSetIndex"`
    29  	IndexedAt        time.Time  `bson:"indexedAt"`
    30  	Timestamp        *time.Time `bson:"timestamp"`
    31  	UpdatedAt        *time.Time `bson:"updatedAt"`
    32  	TxHash           string     `bson:"txHash"`
    33  	Version          int        `bson:"version"`
    34  	Revision         int        `bson:"revision"`
    35  }
    36  
    37  // VaaQuery is a query for VAA.
    38  type VaaQuery struct {
    39  	StartTime      *time.Time
    40  	EndTime        *time.Time
    41  	EmitterChainID *sdk.ChainID
    42  	EmitterAddress *string
    43  	Sequence       *string
    44  }
    45  
    46  // Pagination is a pagination for VAA.
    47  type Pagination struct {
    48  	Page     int64
    49  	PageSize int64
    50  	SortAsc  bool
    51  }
    52  
    53  // NewVaaRepository create a new Vaa repository.
    54  func NewVaaRepository(db *mongo.Database, logger *zap.Logger) *VaaRepository {
    55  	return &VaaRepository{db: db,
    56  		logger: logger.With(zap.String("module", "VaaRepository")),
    57  		vaas:   db.Collection(Vaas),
    58  	}
    59  }
    60  
    61  // FindById finds VAA by id.
    62  func (r *VaaRepository) FindById(ctx context.Context, id string) (*VaaDoc, error) {
    63  	var vaaDoc VaaDoc
    64  	err := r.vaas.FindOne(ctx, bson.M{"_id": id}).Decode(&vaaDoc)
    65  	return &vaaDoc, err
    66  }
    67  
    68  // FindPageByTimeRange finds VAA by time range.
    69  func (r *VaaRepository) FindPageByTimeRange(ctx context.Context, startTime time.Time, endTime time.Time, page, pageSize int64, sortAsc bool) ([]*VaaDoc, error) {
    70  	filter := bson.M{
    71  		"timestamp": bson.M{
    72  			"$gte": startTime,
    73  			"$lt":  endTime,
    74  		},
    75  	}
    76  	sort := -1
    77  	if sortAsc {
    78  		sort = 1
    79  	}
    80  
    81  	skip := page * pageSize
    82  	opts := &options.FindOptions{Skip: &skip, Limit: &pageSize, Sort: bson.M{"timestamp": sort}}
    83  	cur, err := r.vaas.Find(ctx, filter, opts)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	var vaas []*VaaDoc
    88  	err = cur.All(ctx, &vaas)
    89  	return vaas, err
    90  }
    91  
    92  // FindPage finds VAA by query and pagination.
    93  func (r *VaaRepository) FindPage(ctx context.Context, query VaaQuery, pagination Pagination) ([]*VaaDoc, error) {
    94  
    95  	filter := bson.M{}
    96  
    97  	if query.StartTime != nil || query.EndTime != nil {
    98  		rangeTimestamp := bson.M{}
    99  		if query.StartTime != nil {
   100  			rangeTimestamp["$gte"] = query.StartTime
   101  		}
   102  		if query.EndTime != nil {
   103  			rangeTimestamp["$lt"] = query.EndTime
   104  		}
   105  		filter["timestamp"] = rangeTimestamp
   106  	}
   107  
   108  	if query.EmitterChainID != nil {
   109  		filter["emitterChain"] = query.EmitterChainID
   110  	}
   111  	if query.EmitterAddress != nil {
   112  		filter["emitterAddr"] = query.EmitterAddress
   113  	}
   114  	if query.Sequence != nil {
   115  		filter["sequence"] = query.Sequence
   116  	}
   117  
   118  	sort := -1
   119  	if pagination.SortAsc {
   120  		sort = 1
   121  	}
   122  
   123  	skip := pagination.Page * pagination.PageSize
   124  	opts := &options.FindOptions{Skip: &skip, Limit: &pagination.PageSize, Sort: bson.M{"timestamp": sort}}
   125  	cur, err := r.vaas.Find(ctx, filter, opts)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  	var vaas []*VaaDoc
   130  	err = cur.All(ctx, &vaas)
   131  	return vaas, err
   132  }