code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/volume_rebate_stats.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package sqlstore
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"strings"
    22  
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	"code.vegaprotocol.io/vega/datanode/metrics"
    25  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    26  
    27  	"github.com/georgysavva/scany/pgxscan"
    28  )
    29  
    30  var volumeRebateStatsOrdering = TableOrdering{
    31  	ColumnOrdering{Name: "at_epoch", Sorting: DESC},
    32  	ColumnOrdering{Name: "party_id", Sorting: ASC, Ref: "stats->>'party_id'"},
    33  }
    34  
    35  type (
    36  	VolumeRebateStats struct {
    37  		*ConnectionSource
    38  	}
    39  )
    40  
    41  func NewVolumeRebateStats(connectionSource *ConnectionSource) *VolumeRebateStats {
    42  	return &VolumeRebateStats{
    43  		ConnectionSource: connectionSource,
    44  	}
    45  }
    46  
    47  func (s *VolumeRebateStats) Add(ctx context.Context, stats *entities.VolumeRebateStats) error {
    48  	defer metrics.StartSQLQuery("VolumeRebateStats", "Add")()
    49  	_, err := s.Exec(
    50  		ctx,
    51  		`INSERT INTO volume_rebate_stats(at_epoch, parties_volume_rebate_stats, vega_time)
    52  			values ($1, $2, $3)`,
    53  		stats.AtEpoch,
    54  		stats.PartiesVolumeRebateStats,
    55  		stats.VegaTime,
    56  	)
    57  
    58  	return err
    59  }
    60  
    61  func (s *VolumeRebateStats) Stats(ctx context.Context, atEpoch *uint64, partyID *string, pagination entities.CursorPagination) ([]entities.FlattenVolumeRebateStats, entities.PageInfo, error) {
    62  	defer metrics.StartSQLQuery("VolumeRebateStats", "VolumeRebateStats")()
    63  
    64  	var (
    65  		args     []any
    66  		pageInfo entities.PageInfo
    67  	)
    68  
    69  	filters := []string{}
    70  	filters = append(filters, "jsonb_typeof(parties_volume_rebate_stats) != 'null'")
    71  
    72  	if atEpoch != nil {
    73  		filters = append(filters, fmt.Sprintf("at_epoch = %s", nextBindVar(&args, atEpoch)))
    74  	}
    75  	if partyID != nil {
    76  		filters = append(filters, fmt.Sprintf("stats->>'party_id' = %s", nextBindVar(&args, partyID)))
    77  	}
    78  
    79  	if partyID == nil && atEpoch == nil {
    80  		filters = append(filters, "at_epoch = (SELECT MAX(at_epoch) FROM volume_rebate_stats)")
    81  	}
    82  
    83  	stats := []entities.FlattenVolumeRebateStats{}
    84  	query := `select at_epoch, stats->>'party_id' as party_id, stats->>'maker_volume_fraction' as maker_volume_fraction, stats->>'additional_rebate' as additional_rebate, stats->>'maker_fees_received' as maker_fees_received, vega_time from volume_rebate_stats, jsonb_array_elements(parties_volume_rebate_stats) AS stats`
    85  
    86  	if len(filters) > 0 {
    87  		query = fmt.Sprintf("%s where %s", query, strings.Join(filters, " and "))
    88  	}
    89  
    90  	query, args, err := PaginateQuery[entities.VolumeRebateStatsCursor](query, args, volumeRebateStatsOrdering, pagination)
    91  	if err != nil {
    92  		return nil, pageInfo, err
    93  	}
    94  
    95  	if err := pgxscan.Select(ctx, s.ConnectionSource, &stats, query, args...); err != nil {
    96  		return nil, pageInfo, err
    97  	}
    98  
    99  	stats, pageInfo = entities.PageEntities[*v2.VolumeRebateStatsEdge](stats, pagination)
   100  
   101  	return stats, pageInfo, nil
   102  }