code.vegaprotocol.io/vega@v0.79.0/core/liquidity/v2/snapshot_v1.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 liquidity 17 18 import ( 19 "context" 20 "time" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/core/types" 24 "code.vegaprotocol.io/vega/libs/num" 25 "code.vegaprotocol.io/vega/libs/proto" 26 "code.vegaprotocol.io/vega/logging" 27 typespb "code.vegaprotocol.io/vega/protos/vega" 28 snapshotpb "code.vegaprotocol.io/vega/protos/vega/snapshot/v1" 29 ) 30 31 type snapshotV1 struct { 32 *Engine 33 market string 34 stopped bool 35 keys []string 36 } 37 38 func (e *snapshotV1) Namespace() types.SnapshotNamespace { 39 return types.LiquiditySnapshot 40 } 41 42 func (e *snapshotV1) Keys() []string { 43 if len(e.keys) <= 0 { 44 e.keys = []string{ 45 (&types.PayloadLiquidityParameters{ 46 Parameters: &snapshotpb.LiquidityParameters{ 47 MarketId: e.market, 48 }, 49 }).Key(), 50 (&types.PayloadLiquidityPendingProvisions{ 51 PendingProvisions: &snapshotpb.LiquidityPendingProvisions{ 52 MarketId: e.market, 53 }, 54 }).Key(), 55 (&types.PayloadLiquidityProvisions{ 56 Provisions: &snapshotpb.LiquidityProvisions{ 57 MarketId: e.market, 58 }, 59 }).Key(), 60 (&types.PayloadLiquiditySupplied{ 61 LiquiditySupplied: &snapshotpb.LiquiditySupplied{ 62 MarketId: e.market, 63 }, 64 }).Key(), 65 (&types.PayloadLiquidityScores{ 66 LiquidityScores: &snapshotpb.LiquidityScores{ 67 MarketId: e.market, 68 }, 69 }).Key(), 70 } 71 } 72 73 return e.keys 74 } 75 76 func (e *snapshotV1) GetState(k string) ([]byte, []types.StateProvider, error) { 77 var ( 78 keys = e.Keys() 79 state = &snapshotpb.Payload{} 80 ) 81 82 switch k { 83 case keys[0]: 84 state.Data = &snapshotpb.Payload_LiquidityParameters{ 85 LiquidityParameters: &snapshotpb.LiquidityParameters{ 86 MarketId: e.market, 87 }, 88 } 89 case keys[1]: 90 state.Data = &snapshotpb.Payload_LiquidityPendingProvisions{ 91 LiquidityPendingProvisions: &snapshotpb.LiquidityPendingProvisions{ 92 MarketId: e.market, 93 }, 94 } 95 case keys[2]: 96 state.Data = &snapshotpb.Payload_LiquidityProvisions{ 97 LiquidityProvisions: &snapshotpb.LiquidityProvisions{ 98 MarketId: e.market, 99 }, 100 } 101 case keys[3]: 102 state.Data = &snapshotpb.Payload_LiquiditySupplied{ 103 LiquiditySupplied: &snapshotpb.LiquiditySupplied{ 104 MarketId: e.market, 105 }, 106 } 107 case keys[4]: 108 state.Data = &snapshotpb.Payload_LiquidityScores{ 109 LiquidityScores: &snapshotpb.LiquidityScores{ 110 MarketId: e.market, 111 }, 112 } 113 } 114 115 buf, err := proto.Marshal(state) 116 if err != nil { 117 return nil, nil, err 118 } 119 120 return buf, nil, nil 121 } 122 123 func (e *snapshotV1) LoadState(ctx context.Context, p *types.Payload) ([]types.StateProvider, error) { 124 if e.Namespace() != p.Data.Namespace() { 125 return nil, types.ErrInvalidSnapshotNamespace 126 } 127 128 switch pl := p.Data.(type) { 129 case *types.PayloadLiquidityProvisions: 130 if err := e.loadProvisions(ctx, pl.Provisions.GetLiquidityProvisions()); err != nil { 131 return nil, err 132 } 133 134 e.loadPerformances(pl.Provisions.GetLiquidityProvisions()) 135 return nil, nil 136 case *types.PayloadLiquidityScores: 137 return nil, e.loadScores(pl.LiquidityScores) 138 case *types.PayloadLiquiditySupplied: 139 return nil, e.loadSupplied(pl.LiquiditySupplied) 140 case *types.PayloadLiquidityPendingProvisions: 141 return nil, nil 142 case *types.PayloadLiquidityParameters: 143 return nil, nil 144 145 default: 146 return nil, types.ErrUnknownSnapshotType 147 } 148 } 149 150 func (e *snapshotV1) Stopped() bool { 151 return e.stopped 152 } 153 154 func (e *snapshotV1) Stop() { 155 e.log.Debug("market has been cleared, stopping snapshot production", logging.MarketID(e.marketID)) 156 e.stopped = true 157 } 158 159 func (e *snapshotV1) loadPerformances(provisions []*typespb.LiquidityProvision) { 160 e.slaPerformance = map[string]*slaPerformance{} 161 for _, provision := range provisions { 162 previousPenalties := restoreSliceRing( 163 []*num.Decimal{}, 164 e.slaParams.PerformanceHysteresisEpochs, 165 0, 166 ) 167 168 var startTime time.Time 169 170 e.slaPerformance[provision.PartyId] = &slaPerformance{ 171 s: 0, 172 start: startTime, 173 previousPenalties: previousPenalties, 174 } 175 } 176 } 177 178 func (e *snapshotV1) loadProvisions(ctx context.Context, provisions []*typespb.LiquidityProvision) error { 179 e.provisions = newSnapshotableProvisionsPerParty() 180 181 evts := make([]events.Event, 0, len(provisions)) 182 for _, v := range provisions { 183 provision, err := types.LiquidityProvisionFromProto(v) 184 if err != nil { 185 return err 186 } 187 e.provisions.Set(v.PartyId, provision) 188 evts = append(evts, events.NewLiquidityProvisionEvent(ctx, provision)) 189 190 for _, v := range v.Buys { 191 e.legacyOrderIDs = append(e.legacyOrderIDs, v.OrderId) 192 } 193 194 for _, v := range v.Sells { 195 e.legacyOrderIDs = append(e.legacyOrderIDs, v.OrderId) 196 } 197 } 198 199 var err error 200 e.broker.SendBatch(evts) 201 return err 202 } 203 204 func (e *snapshotV1) loadSupplied(ls *snapshotpb.LiquiditySupplied) error { 205 // Dirty hack so we can reuse the supplied engine from the liquidity engine v1, 206 // without snapshot payload namespace issue. 207 err := e.suppliedEngine.Reload(&snapshotpb.LiquiditySupplied{ 208 MarketId: ls.MarketId, 209 ConsensusReached: ls.ConsensusReached, 210 BidCache: ls.BidCache, 211 AskCache: ls.AskCache, 212 }) 213 if err != nil { 214 return err 215 } 216 217 return err 218 } 219 220 func (e *snapshotV1) loadScores(ls *snapshotpb.LiquidityScores) error { 221 var err error 222 223 e.nAvg = int64(ls.RunningAverageCounter) 224 e.feeCalculationTimeStep = defaultFeeCalculationTimeStep 225 226 scores := make(map[string]num.Decimal, len(ls.Scores)) 227 for _, p := range ls.Scores { 228 score, err := num.DecimalFromString(p.Score) 229 if err != nil { 230 return err 231 } 232 scores[p.PartyId] = score 233 } 234 235 e.avgScores = scores 236 return err 237 }