code.vegaprotocol.io/vega@v0.79.0/core/events/distressed_positions.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 events 17 18 import ( 19 "context" 20 21 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 22 ) 23 24 // DistressedPositions contains the market and parties that needed to have their orders closed in order 25 // to maintain their open positions on the market. 26 type DistressedPositions struct { 27 *Base 28 dpIDs map[string]struct{} 29 spIDs map[string]struct{} 30 31 pb eventspb.DistressedPositions 32 } 33 34 func NewDistressedPositionsEvent(ctx context.Context, marketID string, dParties, sParties []string) *DistressedPositions { 35 dk := make(map[string]struct{}, len(dParties)) 36 sk := make(map[string]struct{}, len(sParties)) 37 ret := &DistressedPositions{ 38 Base: newBase(ctx, DistressedPositionsEvent), 39 dpIDs: dk, 40 spIDs: sk, 41 pb: eventspb.DistressedPositions{ 42 MarketId: marketID, 43 DistressedParties: make([]string, 0, len(dParties)), 44 SafeParties: make([]string, 0, len(sParties)), 45 }, 46 } 47 ret.AddDistressedParties(dParties...) 48 ret.AddSafeParties(sParties...) 49 return ret 50 } 51 52 func (d *DistressedPositions) AddDistressedParties(parties ...string) { 53 // ensure parties cannot be marked as both safe and distressed 54 d.rmSafe(parties) 55 for _, p := range parties { 56 // party already registered as distressed 57 if _, ok := d.dpIDs[p]; ok { 58 continue 59 } 60 // mark party as distressed, ensure we don't mark a party as both distressed and no-longer-distressed 61 d.dpIDs[p] = struct{}{} 62 d.pb.DistressedParties = append(d.pb.DistressedParties, p) 63 } 64 } 65 66 func (d *DistressedPositions) AddSafeParties(parties ...string) { 67 // ensure these parties aren't marked as distressed 68 d.rmDistressed(parties) 69 for _, p := range parties { 70 if _, ok := d.spIDs[p]; ok { 71 continue 72 } 73 d.spIDs[p] = struct{}{} 74 d.pb.SafeParties = append(d.pb.SafeParties, p) 75 } 76 } 77 78 func (d DistressedPositions) MarketID() string { 79 return d.pb.MarketId 80 } 81 82 func (d *DistressedPositions) rmSafe(parties []string) { 83 for _, p := range parties { 84 if _, ok := d.spIDs[p]; ok { 85 delete(d.spIDs, p) 86 for i := 0; i < len(d.pb.SafeParties); i++ { 87 if d.pb.SafeParties[i] == p { 88 d.pb.SafeParties = append(d.pb.SafeParties[:i], d.pb.SafeParties[i+1:]...) 89 break 90 } 91 } 92 } 93 } 94 } 95 96 func (d *DistressedPositions) rmDistressed(parties []string) { 97 for _, p := range parties { 98 if _, ok := d.dpIDs[p]; ok { 99 delete(d.dpIDs, p) 100 for i := 0; i < len(d.pb.DistressedParties); i++ { 101 if d.pb.DistressedParties[i] == p { 102 d.pb.DistressedParties = append(d.pb.DistressedParties[:i], d.pb.DistressedParties[i+1:]...) 103 break 104 } 105 } 106 } 107 } 108 } 109 110 func (d DistressedPositions) DistressedParties() []string { 111 return d.pb.DistressedParties 112 } 113 114 func (d DistressedPositions) SafeParties() []string { 115 return d.pb.SafeParties 116 } 117 118 func (d DistressedPositions) IsMarket(marketID string) bool { 119 return d.pb.MarketId == marketID 120 } 121 122 func (d DistressedPositions) IsParty(partyID string) bool { 123 if _, ok := d.dpIDs[partyID]; ok { 124 return true 125 } 126 _, ok := d.spIDs[partyID] 127 return ok 128 } 129 130 func (d DistressedPositions) IsDistressedParty(p string) bool { 131 _, ok := d.dpIDs[p] 132 return ok 133 } 134 135 func (d DistressedPositions) IsSafeParty(p string) bool { 136 _, ok := d.spIDs[p] 137 return ok 138 } 139 140 func (d DistressedPositions) Proto() eventspb.DistressedPositions { 141 return d.pb 142 } 143 144 func (d DistressedPositions) StreamMessage() *eventspb.BusEvent { 145 busEvent := newBusEventFromBase(d.Base) 146 cpy := d.pb 147 busEvent.Event = &eventspb.BusEvent_DistressedPositions{ 148 DistressedPositions: &cpy, 149 } 150 151 return busEvent 152 } 153 154 func (d DistressedPositions) StreamMarketMessage() *eventspb.BusEvent { 155 return d.StreamMessage() 156 } 157 158 func DistressedPositionsEventFromStream(ctx context.Context, be *eventspb.BusEvent) *DistressedPositions { 159 m := be.GetDistressedPositions() 160 dk := make(map[string]struct{}, len(m.DistressedParties)) 161 for _, p := range m.DistressedParties { 162 dk[p] = struct{}{} 163 } 164 sk := make(map[string]struct{}, len(m.SafeParties)) 165 for _, p := range m.SafeParties { 166 sk[p] = struct{}{} 167 } 168 return &DistressedPositions{ 169 Base: newBaseFromBusEvent(ctx, DistressedPositionsEvent, be), 170 dpIDs: dk, 171 spIDs: sk, 172 pb: *m, 173 } 174 }