code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/funding_period.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  
    22  	"code.vegaprotocol.io/vega/datanode/entities"
    23  	"code.vegaprotocol.io/vega/datanode/metrics"
    24  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    25  
    26  	"github.com/georgysavva/scany/pgxscan"
    27  )
    28  
    29  type FundingPeriods struct {
    30  	*ConnectionSource
    31  }
    32  
    33  var fundingPeriodOrdering = TableOrdering{
    34  	ColumnOrdering{Name: "start_time", Sorting: ASC},
    35  	ColumnOrdering{Name: "market_id", Sorting: ASC},
    36  	ColumnOrdering{Name: "funding_period_seq", Sorting: ASC},
    37  }
    38  
    39  var fundingPeriodDataPointOrdering = TableOrdering{
    40  	ColumnOrdering{Name: "timestamp", Sorting: ASC},
    41  	ColumnOrdering{Name: "market_id", Sorting: ASC},
    42  	ColumnOrdering{Name: "funding_period_seq", Sorting: ASC},
    43  	ColumnOrdering{Name: "data_point_type", Sorting: ASC},
    44  }
    45  
    46  func NewFundingPeriods(connectionSource *ConnectionSource) *FundingPeriods {
    47  	return &FundingPeriods{
    48  		ConnectionSource: connectionSource,
    49  	}
    50  }
    51  
    52  func (fp *FundingPeriods) AddFundingPeriod(ctx context.Context, period *entities.FundingPeriod) error {
    53  	defer metrics.StartSQLQuery("FundingPeriods", "AddFundingPeriod")()
    54  	_, err := fp.Exec(ctx,
    55  		`insert into funding_period(market_id, funding_period_seq, start_time, end_time, funding_payment, funding_rate,
    56                             external_twap, internal_twap, vega_time, tx_hash)
    57  values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) on conflict (market_id, funding_period_seq) do update
    58  	set end_time = EXCLUDED.end_time,
    59  	    funding_payment = EXCLUDED.funding_payment,
    60  	    funding_rate = EXCLUDED.funding_rate,
    61  	    external_twap = EXCLUDED.external_twap,
    62  	    internal_twap = EXCLUDED.internal_twap,
    63  	    vega_time = EXCLUDED.vega_time,
    64  	    tx_hash = EXCLUDED.tx_hash`,
    65  		period.MarketID, period.FundingPeriodSeq, period.StartTime, period.EndTime, period.FundingPayment, period.FundingRate,
    66  		period.ExternalTwap, period.InternalTwap, period.VegaTime, period.TxHash)
    67  
    68  	return err
    69  }
    70  
    71  func (fp *FundingPeriods) AddDataPoint(ctx context.Context, dataPoint *entities.FundingPeriodDataPoint) error {
    72  	defer metrics.StartSQLQuery("FundingPeriodDataPoint", "AddDataPoint")()
    73  
    74  	_, err := fp.Exec(ctx,
    75  		`insert into funding_period_data_points(market_id, funding_period_seq, data_point_type, price, timestamp, twap, vega_time, tx_hash)
    76  values ($1, $2, $3, $4, $5, $6, $7, $8) on conflict (market_id, funding_period_seq, data_point_type, vega_time) do update
    77  	set price = EXCLUDED.price, twap = EXCLUDED.twap, timestamp = EXCLUDED.timestamp, tx_hash = EXCLUDED.tx_hash`,
    78  		dataPoint.MarketID, dataPoint.FundingPeriodSeq, dataPoint.DataPointType, dataPoint.Price, dataPoint.Timestamp, dataPoint.Twap, dataPoint.VegaTime, dataPoint.TxHash)
    79  
    80  	return err
    81  }
    82  
    83  func (fp *FundingPeriods) ListFundingPeriods(ctx context.Context, marketID entities.MarketID, dateRange entities.DateRange, pagination entities.CursorPagination) (
    84  	[]entities.FundingPeriod, entities.PageInfo, error,
    85  ) {
    86  	defer metrics.StartSQLQuery("FundingPeriods", "ListFundingPeriods")()
    87  	var periods []entities.FundingPeriod
    88  	var pageInfo entities.PageInfo
    89  	var args []interface{}
    90  	var err error
    91  
    92  	query := fmt.Sprintf(`select * from funding_period where market_id = %s`, nextBindVar(&args, marketID))
    93  	if dateRange.Start != nil {
    94  		query = fmt.Sprintf("%s and start_time >= %s", query, nextBindVar(&args, dateRange.Start))
    95  	}
    96  
    97  	if dateRange.End != nil {
    98  		query = fmt.Sprintf("%s and start_time < %s", query, nextBindVar(&args, dateRange.End))
    99  	}
   100  
   101  	query, args, err = PaginateQuery[entities.FundingPeriodCursor](query, args, fundingPeriodOrdering, pagination)
   102  	if err != nil {
   103  		return periods, pageInfo, err
   104  	}
   105  
   106  	err = pgxscan.Select(ctx, fp.ConnectionSource, &periods, query, args...)
   107  	if err != nil {
   108  		return periods, pageInfo, err
   109  	}
   110  
   111  	periods, pageInfo = entities.PageEntities[*v2.FundingPeriodEdge](periods, pagination)
   112  
   113  	return periods, pageInfo, nil
   114  }
   115  
   116  func (fp *FundingPeriods) ListFundingPeriodDataPoints(ctx context.Context, marketID entities.MarketID, dateRange entities.DateRange,
   117  	source *entities.FundingPeriodDataPointSource, seq *uint64, pagination entities.CursorPagination,
   118  ) ([]entities.FundingPeriodDataPoint, entities.PageInfo, error) {
   119  	defer metrics.StartSQLQuery("FundingPeriodDataPoint", "ListFundingPeriodDataPoints")()
   120  	var dataPoints []entities.FundingPeriodDataPoint
   121  	var pageInfo entities.PageInfo
   122  	var args []interface{}
   123  	var err error
   124  
   125  	query := fmt.Sprintf("select * from funding_period_data_points where market_id = %s", nextBindVar(&args, marketID))
   126  
   127  	if dateRange.Start != nil {
   128  		query = fmt.Sprintf("%s and timestamp >= %s", query, nextBindVar(&args, dateRange.Start))
   129  	}
   130  	if dateRange.End != nil {
   131  		query = fmt.Sprintf("%s and timestamp < %s", query, nextBindVar(&args, dateRange.End))
   132  	}
   133  	if source != nil {
   134  		query = fmt.Sprintf("%s and data_point_type = %s", query, nextBindVar(&args, *source))
   135  	}
   136  	if seq != nil {
   137  		query = fmt.Sprintf("%s and funding_period_seq = %s", query, nextBindVar(&args, *seq))
   138  	}
   139  
   140  	query, args, err = PaginateQuery[entities.FundingPeriodDataPointCursor](query, args, fundingPeriodDataPointOrdering, pagination)
   141  	if err != nil {
   142  		return dataPoints, pageInfo, err
   143  	}
   144  
   145  	err = pgxscan.Select(ctx, fp.ConnectionSource, &dataPoints, query, args...)
   146  	if err != nil {
   147  		return dataPoints, pageInfo, err
   148  	}
   149  
   150  	dataPoints, pageInfo = entities.PageEntities[*v2.FundingPeriodDataPointEdge](dataPoints, pagination)
   151  
   152  	return dataPoints, pageInfo, nil
   153  }