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 }