code.vegaprotocol.io/vega@v0.79.0/core/execution/update_market_state_test.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 execution_test 17 18 import ( 19 "context" 20 "encoding/hex" 21 "fmt" 22 "testing" 23 "time" 24 25 dstypes "code.vegaprotocol.io/vega/core/datasource/common" 26 "code.vegaprotocol.io/vega/core/execution" 27 "code.vegaprotocol.io/vega/core/types" 28 vgcontext "code.vegaprotocol.io/vega/libs/context" 29 "code.vegaprotocol.io/vega/libs/num" 30 vgtest "code.vegaprotocol.io/vega/libs/test" 31 paths2 "code.vegaprotocol.io/vega/paths" 32 33 "github.com/stretchr/testify/require" 34 ) 35 36 func TestVerifyUpdateMarketState(t *testing.T) { 37 now := time.Now() 38 exec := getEngine(t, paths2.New(t.TempDir()), now) 39 pubKey := &dstypes.SignerPubKey{ 40 PubKey: &dstypes.PubKey{ 41 Key: "0xDEADBEEF", 42 }, 43 } 44 mkt := newMarket("MarketID", pubKey) 45 err := exec.engine.SubmitMarket(context.Background(), mkt, "", time.Now()) 46 require.NoError(t, err) 47 48 config := &types.MarketStateUpdateConfiguration{ 49 MarketID: "wrong", 50 UpdateType: types.MarketStateUpdateTypeTerminate, 51 } 52 53 require.Equal(t, execution.ErrMarketDoesNotExist, exec.engine.VerifyUpdateMarketState(config)) 54 55 config.MarketID = mkt.ID 56 require.Equal(t, fmt.Errorf("missing settlement price for governance initiated futures market termination"), exec.engine.VerifyUpdateMarketState(config)) 57 } 58 59 func TestTerminateMarketViaGovernance(t *testing.T) { 60 ctx := vgtest.VegaContext("chainid", 100) 61 62 now := time.Now() 63 exec := getEngine(t, paths2.New(t.TempDir()), now) 64 pubKey := &dstypes.SignerPubKey{ 65 PubKey: &dstypes.PubKey{ 66 Key: "0xDEADBEEF", 67 }, 68 } 69 mkt := newMarket("MarketID", pubKey) 70 err := exec.engine.SubmitMarket(context.Background(), mkt, "", time.Now()) 71 require.NoError(t, err) 72 73 exec.engine.StartOpeningAuction(context.Background(), mkt.ID) 74 75 config := &types.MarketStateUpdateConfiguration{ 76 MarketID: mkt.ID, 77 UpdateType: types.MarketStateUpdateTypeTerminate, 78 SettlementPrice: num.NewUint(100), 79 } 80 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 81 state, err := exec.engine.GetMarketState(mkt.ID) 82 require.NoError(t, err) 83 require.Equal(t, types.MarketStateClosed, state) 84 } 85 86 func TestSuspendMarketViaGovernance(t *testing.T) { 87 ctx := vgtest.VegaContext("chainid", 100) 88 now := time.Now() 89 exec := getEngine(t, paths2.New(t.TempDir()), now) 90 pubKey := &dstypes.SignerPubKey{ 91 PubKey: &dstypes.PubKey{ 92 Key: "0xDEADBEEF", 93 }, 94 } 95 mkt := newMarket("MarketID", pubKey) 96 err := exec.engine.SubmitMarket(context.Background(), mkt, "", time.Now()) 97 require.NoError(t, err) 98 99 exec.engine.StartOpeningAuction(context.Background(), mkt.ID) 100 101 // during opening auction 102 state, err := exec.engine.GetMarketData(mkt.ID) 103 require.NoError(t, err) 104 require.Equal(t, types.MarketStateActive, state.MarketState) 105 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 106 107 config := &types.MarketStateUpdateConfiguration{ 108 MarketID: mkt.ID, 109 UpdateType: types.MarketStateUpdateTypeSuspend, 110 SettlementPrice: num.NewUint(100), 111 } 112 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 113 114 // after governance suspension 115 state, err = exec.engine.GetMarketData(mkt.ID) 116 require.NoError(t, err) 117 require.Equal(t, types.MarketStateSuspendedViaGovernance, state.MarketState) 118 require.Equal(t, types.MarketTradingModeSuspendedViaGovernance, state.MarketTradingMode) 119 120 exec.engine.OnTick(ctx, exec.timeService.GetTimeNow()) 121 122 config.UpdateType = types.MarketStateUpdateTypeResume 123 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 124 125 // after governance suspension ended - enter liquidity auction 126 state, err = exec.engine.GetMarketData(mkt.ID) 127 require.NoError(t, err) 128 require.Equal(t, types.MarketStateActive, state.MarketState) 129 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 130 131 // now suspend via governance again 132 config.UpdateType = types.MarketStateUpdateTypeSuspend 133 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 134 135 exec.engine.OnTick(ctx, exec.timeService.GetTimeNow()) 136 137 // after governance suspension 138 state, err = exec.engine.GetMarketData(mkt.ID) 139 require.NoError(t, err) 140 require.Equal(t, types.MarketStateSuspendedViaGovernance, state.MarketState) 141 // because we're in monitoring auction and the state here is taken from the auction state it is reported as monitoring auction 142 require.Equal(t, types.MarketTradingModeSuspendedViaGovernance, state.MarketTradingMode) 143 144 // release suspension should go back to liquidity auction 145 config.UpdateType = types.MarketStateUpdateTypeResume 146 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 147 148 exec.engine.OnTick(ctx, exec.timeService.GetTimeNow()) 149 150 // after governance suspension ended - enter liquidity auction 151 state, err = exec.engine.GetMarketData(mkt.ID) 152 require.NoError(t, err) 153 require.Equal(t, types.MarketStateActive, state.MarketState) 154 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 155 } 156 157 func TestSubmitOrderWhenSuspended(t *testing.T) { 158 ctx := vgtest.VegaContext("chainid", 100) 159 now := time.Now() 160 exec := getEngineWithParties(t, now, num.NewUint(1000000000), "lp", "p1", "p2", "p3", "p4") 161 pubKey := &dstypes.SignerPubKey{ 162 PubKey: &dstypes.PubKey{ 163 Key: "0xDEADBEEF", 164 }, 165 } 166 mkt := newMarket("MarketID", pubKey) 167 err := exec.engine.SubmitMarket(context.Background(), mkt, "", now) 168 require.NoError(t, err) 169 170 exec.engine.StartOpeningAuction(context.Background(), mkt.ID) 171 172 // during opening auction 173 state, err := exec.engine.GetMarketData(mkt.ID) 174 require.NoError(t, err) 175 require.Equal(t, types.MarketStateActive, state.MarketState) 176 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 177 178 config := &types.MarketStateUpdateConfiguration{ 179 MarketID: mkt.ID, 180 UpdateType: types.MarketStateUpdateTypeSuspend, 181 SettlementPrice: num.NewUint(100), 182 } 183 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 184 185 // after governance suspension 186 state, err = exec.engine.GetMarketData(mkt.ID) 187 require.NoError(t, err) 188 require.Equal(t, types.MarketStateSuspendedViaGovernance, state.MarketState) 189 require.Equal(t, types.MarketTradingModeSuspendedViaGovernance, state.MarketTradingMode) 190 191 // check we can submit an order 192 os1 := &types.OrderSubmission{ 193 MarketID: mkt.ID, 194 Price: num.NewUint(99), 195 Size: 1, 196 Side: types.SideBuy, 197 TimeInForce: types.OrderTimeInForceGTC, 198 Type: types.OrderTypeLimit, 199 Reference: "o1", 200 } 201 idgen := &stubIDGen{} 202 vgctx := vgcontext.WithTraceID(context.Background(), hex.EncodeToString([]byte("0deadbeef"))) 203 _, err = exec.engine.SubmitOrder(vgctx, os1, "p1", idgen, "o1p1") 204 require.NoError(t, err) 205 } 206 207 func TestDoubleSuspendMarketViaGovernance(t *testing.T) { 208 ctx := vgtest.VegaContext("chainid", 100) 209 now := time.Now() 210 exec := getEngine(t, paths2.New(t.TempDir()), now) 211 pubKey := &dstypes.SignerPubKey{ 212 PubKey: &dstypes.PubKey{ 213 Key: "0xDEADBEEF", 214 }, 215 } 216 mkt := newMarket("MarketID", pubKey) 217 err := exec.engine.SubmitMarket(context.Background(), mkt, "", time.Now()) 218 require.NoError(t, err) 219 220 exec.engine.StartOpeningAuction(context.Background(), mkt.ID) 221 222 // during opening auction 223 state, err := exec.engine.GetMarketData(mkt.ID) 224 require.NoError(t, err) 225 require.Equal(t, types.MarketStateActive, state.MarketState) 226 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 227 228 config := &types.MarketStateUpdateConfiguration{ 229 MarketID: mkt.ID, 230 UpdateType: types.MarketStateUpdateTypeSuspend, 231 SettlementPrice: num.NewUint(100), 232 } 233 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 234 235 // after governance suspension 236 state, err = exec.engine.GetMarketData(mkt.ID) 237 require.NoError(t, err) 238 require.Equal(t, types.MarketStateSuspendedViaGovernance, state.MarketState) 239 require.Equal(t, types.MarketTradingModeSuspendedViaGovernance, state.MarketTradingMode) 240 require.Equal(t, types.AuctionTriggerGovernanceSuspension, state.Trigger) 241 require.Equal(t, types.AuctionTriggerUnspecified, state.ExtensionTrigger) 242 243 // suspend again 244 require.Error(t, fmt.Errorf("invalid state update request. Market for suspend is already suspended"), exec.engine.UpdateMarketState(ctx, config)) 245 state, err = exec.engine.GetMarketData(mkt.ID) 246 require.NoError(t, err) 247 require.Equal(t, types.MarketStateSuspendedViaGovernance, state.MarketState) 248 require.Equal(t, types.MarketTradingModeSuspendedViaGovernance, state.MarketTradingMode) 249 require.Equal(t, types.AuctionTriggerGovernanceSuspension, state.Trigger) 250 require.Equal(t, types.AuctionTriggerUnspecified, state.ExtensionTrigger) 251 252 exec.engine.OnTick(ctx, exec.timeService.GetTimeNow()) 253 254 config.UpdateType = types.MarketStateUpdateTypeResume 255 require.NoError(t, exec.engine.UpdateMarketState(ctx, config)) 256 257 exec.engine.OnTick(ctx, exec.timeService.GetTimeNow()) 258 259 // after governance suspension ended - enter liquidity auction 260 state, err = exec.engine.GetMarketData(mkt.ID) 261 require.NoError(t, err) 262 require.Equal(t, types.MarketStateActive, state.MarketState) 263 require.Equal(t, types.MarketTradingModeContinuous, state.MarketTradingMode) 264 require.Equal(t, types.AuctionTriggerUnspecified, state.Trigger) 265 require.Equal(t, types.AuctionTriggerUnspecified, state.ExtensionTrigger) 266 require.Equal(t, int64(0), state.AuctionEnd) 267 require.Equal(t, int64(0), state.AuctionStart) 268 }