code.vegaprotocol.io/vega@v0.79.0/core/products/perpetual_snapshot.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 products 17 18 import ( 19 "context" 20 "time" 21 22 "code.vegaprotocol.io/vega/core/types" 23 "code.vegaprotocol.io/vega/libs/num" 24 "code.vegaprotocol.io/vega/logging" 25 snapshotpb "code.vegaprotocol.io/vega/protos/vega/snapshot/v1" 26 ) 27 28 func NewCachedTWAPFromSnapshot( 29 log *logging.Logger, 30 t int64, 31 auctions *auctionIntervals, 32 state *snapshotpb.TWAPData, 33 points []*snapshotpb.DataPoint, 34 ) *cachedTWAP { 35 sum, _ := num.UintFromString(state.SumProduct, 10) 36 c := &cachedTWAP{ 37 log: log, 38 periodStart: t, 39 start: state.Start, 40 end: state.End, 41 sumProduct: sum, 42 auctions: auctions, 43 } 44 c.points = make([]*dataPoint, 0, len(points)) 45 for _, v := range points { 46 price, overflow := num.UintFromString(v.Price, 10) 47 if overflow { 48 log.Panic("invalid snapshot state in external data point", logging.String("price", v.Price), logging.Bool("overflow", overflow)) 49 } 50 c.points = append(c.points, &dataPoint{price: price, t: v.Timestamp}) 51 } 52 return c 53 } 54 55 func (c *cachedTWAP) serialise() *snapshotpb.TWAPData { 56 return &snapshotpb.TWAPData{ 57 Start: c.start, 58 End: c.end, 59 SumProduct: c.sumProduct.String(), 60 } 61 } 62 63 func NewPerpetualFromSnapshot( 64 ctx context.Context, 65 log *logging.Logger, 66 p *types.Perps, 67 marketID string, 68 ts TimeService, 69 oe OracleEngine, 70 broker Broker, 71 state *snapshotpb.Perps, 72 assetDP uint32, 73 ) (*Perpetual, error) { 74 // set next trigger from the settlement cue, it'll roll forward from `initial` to the next trigger time after `now` 75 tt := p.DataSourceSpecForSettlementSchedule.Data.GetInternalTimeTriggerSpecConfiguration() 76 tt.SetNextTrigger(ts.GetTimeNow().Truncate(time.Second)) 77 78 perps, err := NewPerpetual(ctx, log, p, marketID, ts, oe, broker, assetDP) 79 if err != nil { 80 return nil, err 81 } 82 83 perps.startedAt = state.StartedAt 84 perps.seq = state.Seq 85 86 perps.auctions = &auctionIntervals{ 87 auctionStart: state.AuctionIntervals.AuctionStart, 88 auctions: state.AuctionIntervals.T, 89 total: state.AuctionIntervals.Total, 90 } 91 92 perps.externalTWAP = NewCachedTWAPFromSnapshot(log, state.StartedAt, perps.auctions, state.ExternalTwapData, state.ExternalDataPoint) 93 perps.internalTWAP = NewCachedTWAPFromSnapshot(log, state.StartedAt, perps.auctions, state.InternalTwapData, state.InternalDataPoint) 94 return perps, nil 95 } 96 97 func (p *Perpetual) Serialize() *snapshotpb.Product { 98 perps := &snapshotpb.Perps{ 99 Id: p.id, 100 Seq: p.seq, 101 StartedAt: p.startedAt, 102 ExternalDataPoint: make([]*snapshotpb.DataPoint, 0, len(p.internalTWAP.points)), 103 InternalDataPoint: make([]*snapshotpb.DataPoint, 0, len(p.externalTWAP.points)), 104 AuctionIntervals: &snapshotpb.AuctionIntervals{ 105 AuctionStart: p.auctions.auctionStart, 106 T: p.auctions.auctions, 107 Total: p.auctions.total, 108 }, 109 ExternalTwapData: p.externalTWAP.serialise(), 110 InternalTwapData: p.internalTWAP.serialise(), 111 } 112 113 for _, v := range p.externalTWAP.points { 114 perps.ExternalDataPoint = append(perps.ExternalDataPoint, &snapshotpb.DataPoint{ 115 Price: v.price.String(), 116 Timestamp: v.t, 117 }) 118 } 119 120 for _, v := range p.internalTWAP.points { 121 perps.InternalDataPoint = append(perps.InternalDataPoint, &snapshotpb.DataPoint{ 122 Price: v.price.String(), 123 Timestamp: v.t, 124 }) 125 } 126 return &snapshotpb.Product{ 127 Type: &snapshotpb.Product_Perps{ 128 Perps: perps, 129 }, 130 } 131 }