code.vegaprotocol.io/vega@v0.79.0/datanode/service/market.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 service 17 18 import ( 19 "context" 20 "sync" 21 22 "code.vegaprotocol.io/vega/datanode/entities" 23 "code.vegaprotocol.io/vega/libs/num" 24 ) 25 26 type MarketStore interface { 27 Upsert(ctx context.Context, market *entities.Market) error 28 GetByID(ctx context.Context, marketID string) (entities.Market, error) 29 GetByIDs(ctx context.Context, markets []string) ([]entities.Market, error) 30 GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Market, error) 31 GetAllPaged(ctx context.Context, marketID string, pagination entities.CursorPagination, includeSettled bool) ([]entities.Market, entities.PageInfo, error) 32 ListSuccessorMarkets(ctx context.Context, marketID string, fullHistory bool, pagination entities.CursorPagination) ([]entities.SuccessorMarket, entities.PageInfo, error) 33 GetAllFees(ctx context.Context) ([]entities.Market, error) 34 } 35 36 type Markets struct { 37 store MarketStore 38 cacheLock sync.RWMutex 39 sf map[entities.MarketID]num.Decimal 40 isSpotCache map[entities.MarketID]bool 41 } 42 43 func NewMarkets(store MarketStore) *Markets { 44 return &Markets{ 45 store: store, 46 sf: map[entities.MarketID]num.Decimal{}, 47 isSpotCache: map[entities.MarketID]bool{}, 48 } 49 } 50 51 func (m *Markets) Initialise(ctx context.Context) error { 52 return nil 53 } 54 55 func (m *Markets) GetAllFees(ctx context.Context) ([]entities.Market, error) { 56 return m.store.GetAllFees(ctx) 57 } 58 59 func (m *Markets) Upsert(ctx context.Context, market *entities.Market) error { 60 if err := m.store.Upsert(ctx, market); err != nil { 61 return err 62 } 63 m.cacheLock.Lock() 64 if market.State == entities.MarketStateSettled || market.State == entities.MarketStateRejected || market.State == entities.MarketStateCancelled { 65 // a settled, cancelled, or rejected market can be safely removed from this map. 66 delete(m.sf, market.ID) 67 delete(m.isSpotCache, market.ID) 68 } else { 69 // just in case this gets updated, or the market is new. 70 m.sf[market.ID] = num.DecimalFromFloat(10).Pow(num.DecimalFromInt64(int64(market.PositionDecimalPlaces))) 71 m.isSpotCache[market.ID] = market.TradableInstrument.Instrument.GetSpot() != nil 72 } 73 m.cacheLock.Unlock() 74 return nil 75 } 76 77 func (m *Markets) GetByID(ctx context.Context, marketID string) (entities.Market, error) { 78 return m.store.GetByID(ctx, marketID) 79 } 80 81 func (m *Markets) GetByIDs(ctx context.Context, markets []string) ([]entities.Market, error) { 82 return m.store.GetByIDs(ctx, markets) 83 } 84 85 func (m *Markets) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Market, error) { 86 return m.store.GetByTxHash(ctx, txHash) 87 } 88 89 func (m *Markets) GetMarketScalingFactor(ctx context.Context, marketID string) (num.Decimal, bool) { 90 m.cacheLock.Lock() 91 defer m.cacheLock.Unlock() 92 if pf, ok := m.sf[entities.MarketID(marketID)]; ok { 93 return pf, true 94 } 95 96 market, err := m.store.GetByID(ctx, marketID) 97 if err != nil { 98 return num.Decimal{}, false 99 } 100 101 pf := num.DecimalFromFloat(10).Pow(num.DecimalFromInt64(int64(market.PositionDecimalPlaces))) 102 return pf, true 103 } 104 105 func (m *Markets) IsSpotMarket(ctx context.Context, marketID string) bool { 106 m.cacheLock.Lock() 107 defer m.cacheLock.Unlock() 108 if is, ok := m.isSpotCache[entities.MarketID(marketID)]; ok { 109 return is 110 } 111 112 market, err := m.store.GetByID(ctx, marketID) 113 if err != nil { 114 return false 115 } 116 return market.TradableInstrument.Instrument.GetSpot() != nil 117 } 118 119 func (m *Markets) GetAllPaged(ctx context.Context, marketID string, pagination entities.CursorPagination, includeSettled bool) ([]entities.Market, entities.PageInfo, error) { 120 return m.store.GetAllPaged(ctx, marketID, pagination, includeSettled) 121 } 122 123 func (m *Markets) ListSuccessorMarkets(ctx context.Context, marketID string, childrenOnly bool, pagination entities.CursorPagination) ([]entities.SuccessorMarket, entities.PageInfo, error) { 124 return m.store.ListSuccessorMarkets(ctx, marketID, childrenOnly, pagination) 125 }