code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_new_market_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 commands_test 17 18 import ( 19 "errors" 20 "fmt" 21 "math" 22 "testing" 23 "time" 24 25 "code.vegaprotocol.io/vega/commands" 26 dstypes "code.vegaprotocol.io/vega/core/datasource/common" 27 "code.vegaprotocol.io/vega/libs/ptr" 28 "code.vegaprotocol.io/vega/libs/test" 29 "code.vegaprotocol.io/vega/protos/vega" 30 protoTypes "code.vegaprotocol.io/vega/protos/vega" 31 vegapb "code.vegaprotocol.io/vega/protos/vega" 32 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 33 datapb "code.vegaprotocol.io/vega/protos/vega/data/v1" 34 35 "github.com/stretchr/testify/assert" 36 ) 37 38 func TestCheckProposalSubmissionForNewMarket(t *testing.T) { 39 t.Run("Submitting a market change without new market fails", testNewMarketChangeSubmissionWithoutNewMarketFails) 40 t.Run("Submitting a market change without changes fails", testNewMarketChangeSubmissionWithoutChangesFails) 41 t.Run("Submitting a market change without too many pm trigger fails", testNewMarketChangeSubmissionWithTooManyPMTriggersFails) 42 t.Run("Submitting a market change without decimal places succeeds", testNewMarketChangeSubmissionWithoutDecimalPlacesSucceeds) 43 t.Run("Submitting a market change with decimal places equal to 0 succeeds", testNewMarketChangeSubmissionWithDecimalPlacesEqualTo0Succeeds) 44 t.Run("Submitting a market change with decimal places above or equal to 150 fails", testNewMarketChangeSubmissionWithDecimalPlacesAboveOrEqualTo150Fails) 45 t.Run("Submitting a market change with decimal places below 150 succeeds", testNewMarketChangeSubmissionWithDecimalPlacesBelow150Succeeds) 46 t.Run("Submitting a market change without decimal places succeeds", testNewMarketChangeSubmissionWithoutDecimalPlacesSucceeds) 47 t.Run("Submitting a market change with position decimal places equal to 0 succeeds", testNewMarketChangeSubmissionWithPositionDecimalPlacesEqualTo0Succeeds) 48 t.Run("Submitting a market change with position decimal places above or equal to 6 fails", testNewMarketChangeSubmissionWithPositionDecimalPlacesAboveOrEqualTo7Fails) 49 t.Run("Submitting a market change with position decimal places below 6 succeeds", testNewMarketChangeSubmissionWithPositionDecimalPlacesBelow7Succeeds) 50 t.Run("Submitting a market change with slippage factor 'banana' fails", testNewMarketChangeSubmissionWithSlippageFactorBananaFails) 51 t.Run("Submitting a market change with negative slippage factor fails", testNewMarketChangeSubmissionWithSlippageFactorNegativeFails) 52 t.Run("Submitting a market change with empty max slippage factor succeeds", testNewMarketChangeSubmissionWithEmptySlippageFactorPasses) 53 t.Run("Submitting a market change with too large slippage factor fails", testNewMarketChangeSubmissionWithSlippageFactorTooLargeFails) 54 t.Run("Submitting a new capped market with max price succeeds", testNewCappedMarketWithMaxPriceSucceeds) 55 t.Run("Submitting a new capped market without max price fails", testNewCappedMarketWithoutMaxPriceFails) 56 57 t.Run("Submitting a new market without price monitoring succeeds", testNewMarketChangeSubmissionWithoutPriceMonitoringSucceeds) 58 t.Run("Submitting a new market with price monitoring succeeds", testNewMarketChangeSubmissionWithPriceMonitoringSucceeds) 59 t.Run("Submitting a price monitoring change without triggers succeeds", testPriceMonitoringChangeSubmissionWithoutTriggersSucceeds) 60 t.Run("Submitting a price monitoring change with triggers succeeds", testPriceMonitoringChangeSubmissionWithTriggersSucceeds) 61 t.Run("Submitting a price monitoring change without trigger horizon fails", testPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails) 62 t.Run("Submitting a price monitoring change with trigger horizon succeeds", testPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds) 63 t.Run("Submitting a price monitoring change with wrong trigger probability fails", testPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails) 64 t.Run("Submitting a price monitoring change with right trigger probability succeeds", testPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds) 65 t.Run("Submitting a price monitoring change without trigger auction extension fails", testPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails) 66 t.Run("Submitting a price monitoring change with trigger auction extension succeeds", testPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds) 67 t.Run("Submitting a new market without liquidity monitoring fails", testNewMarketChangeSubmissionWithoutLiquidityMonitoringFails) 68 t.Run("Submitting a new market with liquidity monitoring succeeds", testNewMarketChangeSubmissionWithLiquidityMonitoringSucceeds) 69 t.Run("Submitting a liquidity monitoring change without target stake parameters fails", testLiquidityMonitoringChangeSubmissionWithoutTargetStakeParametersFails) 70 t.Run("Submitting a liquidity monitoring change with target stake parameters succeeds", testLiquidityMonitoringChangeSubmissionWithTargetStakeParametersSucceeds) 71 t.Run("Submitting a liquidity monitoring change with non-positive time window fails", testLiquidityMonitoringChangeSubmissionWithNonPositiveTimeWindowFails) 72 t.Run("Submitting a liquidity monitoring change with positive time window succeeds", testLiquidityMonitoringChangeSubmissionWithPositiveTimeWindowSucceeds) 73 t.Run("Submitting a liquidity monitoring change with non-positive scaling factor fails", testLiquidityMonitoringChangeSubmissionWithNonPositiveScalingFactorFails) 74 t.Run("Submitting a liquidity monitoring change with positive scaling factor succeeds", testLiquidityMonitoringChangeSubmissionWithPositiveScalingFactorSucceeds) 75 t.Run("Submitting a market change without instrument name fails", testNewMarketChangeSubmissionWithoutInstrumentNameFails) 76 t.Run("Submitting a market change with instrument name succeeds", testNewMarketChangeSubmissionWithInstrumentNameSucceeds) 77 t.Run("Submitting a market change without instrument code fails", testNewMarketChangeSubmissionWithoutInstrumentCodeFails) 78 t.Run("Submitting a market change with instrument code succeeds", testNewMarketChangeSubmissionWithInstrumentCodeSucceeds) 79 t.Run("Submitting a market change without product fails", testNewMarketChangeSubmissionWithoutProductFails) 80 t.Run("Submitting a market change with product succeeds", testNewMarketChangeSubmissionWithProductSucceeds) 81 t.Run("Submitting a future market change without future fails", testNewFutureMarketChangeSubmissionWithoutFutureFails) 82 t.Run("Submitting a future market change with future succeeds", testNewFutureMarketChangeSubmissionWithFutureSucceeds) 83 t.Run("Submitting a future market change without settlement asset fails", testNewFutureMarketChangeSubmissionWithoutSettlementAssetFails) 84 t.Run("Submitting a future market change with settlement asset succeeds", testNewFutureMarketChangeSubmissionWithSettlementAssetSucceeds) 85 t.Run("Submitting a future market change without quote name fails", testNewFutureMarketChangeSubmissionWithoutQuoteNameFails) 86 t.Run("Submitting a future market change with quote name succeeds", testNewFutureMarketChangeSubmissionWithQuoteNameSucceeds) 87 t.Run("Submitting a future market change without oracle spec fails", testNewFutureMarketChangeSubmissionWithoutOracleSpecFails) 88 t.Run("Submitting a future market change without either of the required oracle spec fails", testNewFutureMarketChangeSubmissionMissingSingleOracleSpecFails) 89 t.Run("Submitting a future market change with empty oracle spec fails", testNewFutureMarketChangeSubmissionWithEmptyOracleSpecFails) 90 t.Run("Submitting a future market change with empty oracle spec type fails", testNewFutureMarketChangeSubmissionWithEmptyOracleSpecTypeFails) 91 t.Run("Submitting a future market change with empty internal spec type fails", testNewFutureMarketChangeSubmissionWithEmptyInternalSpecTypeFails) 92 t.Run("Submitting a future market change with wrong pub-keys fails", testNewFutureMarketChangeSubmissionWithWrongPubKeysFails) 93 t.Run("Submitting a future market change with bad pubkey or address fails", testNewFutureMarketChangeSubmissionWithBadPubKeysOrderAddressFail) 94 t.Run("Submitting a future market change with good pubkey or address succeed", testNewFutureMarketChangeSubmissionWithGoodPubKeysOrderAddressSucceed) 95 t.Run("Submitting a future market change without filters fails", testNewFutureMarketChangeSubmissionWithoutFiltersFails) 96 t.Run("Submitting a future market change with filters succeeds", testNewFutureMarketChangeSubmissionWithFiltersSucceeds) 97 t.Run("Submitting a future market change with filter without key fails", testNewFutureMarketChangeSubmissionWithFilterWithoutKeyFails) 98 t.Run("Submitting a future market change with filter with key succeeds", testNewFutureMarketChangeSubmissionWithFilterWithKeySucceeds) 99 t.Run("Submitting a future market change with filter without key name fails", testNewFutureMarketChangeSubmissionWithFilterWithoutKeyNameFails) 100 t.Run("Submitting a future market change with filter with key name succeeds", testNewFutureMarketChangeSubmissionWithFilterWithKeyNameSucceeds) 101 t.Run("Submitting a future market change with filter without key type fails", testNewFutureMarketChangeSubmissionWithFilterWithoutKeyTypeFails) 102 t.Run("Submitting a future market change with filter with key type succeeds", testNewFutureMarketChangeSubmissionWithFilterWithKeyTypeSucceeds) 103 t.Run("Submitting a future market change with filter without condition succeeds", testNewFutureMarketChangeSubmissionWithFilterWithoutConditionsSucceeds) 104 t.Run("Submitting a future market change with filter without condition operator fails", testNewFutureMarketChangeSubmissionWithFilterWithoutConditionOperatorFails) 105 t.Run("Submitting a future market change with filter with condition operator succeeds", testNewFutureMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds) 106 t.Run("Submitting a future market change with filter without condition value fails", testNewFutureMarketChangeSubmissionWithFilterWithoutConditionValueFails) 107 t.Run("Submitting a future market change with filter with condition value succeeds", testNewFutureMarketChangeSubmissionWithFilterWithConditionValueSucceeds) 108 t.Run("Submitting a future market change without oracle spec bindings fails", testNewFutureMarketChangeSubmissionWithoutDataSourceSpecBindingFails) 109 t.Run("Submitting a future market change with oracle spec binding succeeds", testNewFutureMarketChangeSubmissionWithDataSourceSpecBindingSucceeds) 110 t.Run("Submitting a future market change without settlement data property fails", testNewFutureMarketChangeSubmissionWithoutSettlementDataPropertyFails) 111 t.Run("Submitting a future market change without pub-keys fails", testNewFutureMarketChangeSubmissionWithoutPubKeysFails) 112 t.Run("Submitting a future market change without trading termination property fails", testNewFutureMarketChangeSubmissionWithoutTradingTerminationPropertyFails) 113 t.Run("Submitting a future market change with a mismatch between binding property name and filter fails", testNewFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails) 114 t.Run("Submitting a future market change with match between binding property name and filter succeeds", testNewFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds) 115 t.Run("Submitting a future market change with settlement data and trading termination properties succeeds", testNewFutureMarketChangeSubmissionWithSettlementDataPropertySucceeds) 116 t.Run("Submitting a simple risk parameters change without simple risk parameters fails", testNewSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails) 117 t.Run("Submitting a simple risk parameters change with simple risk parameters succeeds", testNewSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds) 118 t.Run("Submitting a simple risk parameters change with min move down fails", testNewSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails) 119 t.Run("Submitting a simple risk parameters change with min move down succeeds", testNewSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds) 120 t.Run("Submitting a simple risk parameters change with max move up succeeds", testNewSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds) 121 t.Run("Submitting a simple risk parameters change with wrong probability of trading fails", testNewSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails) 122 t.Run("Submitting a simple risk parameters change with right probability of trading succeeds", testNewSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds) 123 t.Run("Submitting a log normal risk parameters change without log normal risk parameters fails", testNewLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails) 124 t.Run("Submitting a log normal risk parameters change with log normal risk parameters succeeds", testNewLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds) 125 t.Run("Submitting a log normal risk parameters change with params fails", testNewLogNormalRiskParametersChangeSubmissionWithoutParamsFails) 126 t.Run("Submitting a log normal risk parameters change with invalid risk aversion", testNewLogNormalRiskParametersChangeSubmissionInvalidRiskAversion) 127 t.Run("Submitting a log normal risk parameters change with invalid tau", testNewLogNormalRiskParametersChangeSubmissionInvalidTau) 128 t.Run("Submitting a log normal risk parameters change with invalid mu", testNewLogNormalRiskParametersChangeSubmissionInvalidMu) 129 t.Run("Submitting a log normal risk parameters change with invalid sigma", testNewLogNormalRiskParametersChangeSubmissionInvalidSigma) 130 t.Run("Submitting a log normal risk parameters change with invalid r", testNewLogNormalRiskParametersChangeSubmissionInvalidR) 131 t.Run("Submitting a new market with a too long reference fails", testNewMarketSubmissionWithTooLongReferenceFails) 132 t.Run("Submitting a future market with internal time for trade termination succeeds", testFutureMarketSubmissionWithInternalTimestampForTradingTerminationSucceeds) 133 t.Run("Submitting a future market with trade termination from external oracle with no public key fails", testFutureMarketSubmissionWithExternalTradingTerminationNoPublicKeyFails) 134 t.Run("Submitting a future market with trading termination from internal source with no public keys succeeds", testFutureMarketSubmissionWithInternalTradingTerminationSucceeds) 135 t.Run("Submitting a future market with trading termination from internal source with invalid operator fails", testFutureMarketSubmissionWithInternalTradingInvalidOperatorTerminationFails) 136 t.Run("Submitting a future market with trading termination from external source with `vegaprotocol.builtin` key and no public keys fails", testFutureMarketSubmissionWithExternalTradingTerminationBuiltInKeyNoPublicKeyFails) 137 t.Run("Submitting a future market with trading settlement from external source with `vegaprotocol.builtin` key and no public keys fails", testFutureMarketSubmissionWithExternalTradingSettlementBuiltInKeyNoPublicKeyFails) 138 t.Run("Submitting a future market with trading settlement from external source with one timestamp filter succeeds", testFutureMarketSubmissionWithExternalTradingSettlementTimestampKeySucceeds) 139 t.Run("Submitting a future market with trade termination from oracle with no public key fails", testFutureMarketSubmissionWithExternalTradingTerminationNoPublicKeyFails) 140 t.Run("Submitting a future market with invalid oracle condition or type", testFutureMarketSubmissionWithInvalidOracleConditionOrType) 141 t.Run("Submitting a future market with external data source for termination succeeds", testFutureMarketSubmissionWithExternalTradingTerminationBuiltInKeySucceeds) 142 t.Run("Submitting a future market with external data source for termination without signers fails", testFutureMarketSubmissionWithExternalTradingTerminationNoSignerFails) 143 t.Run("Submitting a future market with external data source for termination with signers and external settlement data without signers fails", testFutureMarketSubmissionWithExternalSettlementDataNoSignerFails) 144 t.Run("Submitting a future market with internal data for settlement fails", testFutureMarketSubmissionWithInternalSettlementDataFails) 145 t.Run("Submitting a future market with external data sources for settlement and termination with empty signers fail", testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptySignerFails) 146 t.Run("Submitting a future market with external data sources for settlement and termination with empty pubKey signer fail", testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptyPubKeySignerFails) 147 t.Run("Submitting a future market with external data sources for settlement and termination with empty eth address signer fail", testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptyEthAddressSignerFails) 148 t.Run("Submitting a future market with external data sources for settlement and termination with no signers fail", testFutureMarketSubmissionWithExternalSettlementDataAndTerminationNoSignerFails) 149 t.Run("Submitting a future market with internal time trigger termination data fails", testFutureMarketSubmissionWithInternalTimeTriggerTerminationDataFails) 150 t.Run("Submitting a future market with internal time trigger settlement data fails", testFutureMarketSubmissionWithInternalTimeTriggerSettlementDataFails) 151 t.Run("Submitting a future market with valid liquidation strategy succeeds", testFutureMarketSubmissionWithValidLiquidationStrategySucceeds) 152 t.Run("Submitting a future market with invalid liquidation strategy fails", testFutureMarketSubmissionWithInvalidLiquidationStrategyFails) 153 154 t.Run("Submitting a perps market change without perps fails", testNewPerpsMarketChangeSubmissionWithoutPerpsFails) 155 t.Run("Submitting a perps market change with perps succeeds", testNewPerpsMarketChangeSubmissionWithPerpsSucceeds) 156 t.Run("Submitting a perps market change without settlement asset fails", testNewPerpsMarketChangeSubmissionWithoutSettlementAssetFails) 157 t.Run("Submitting a perps market change with settlement asset succeeds", testNewPerpsMarketChangeSubmissionWithSettlementAssetSucceeds) 158 t.Run("Submitting a perps market change without quote name fails", testNewPerpsMarketChangeSubmissionWithoutQuoteNameFails) 159 t.Run("Submitting a perps market change with quote name succeeds", testNewPerpsMarketChangeSubmissionWithQuoteNameSucceeds) 160 t.Run("Submitting a perps market change without oracle spec fails", testNewPerpsMarketChangeSubmissionWithoutOracleSpecFails) 161 t.Run("Submitting a perps market change with oracle spec succeeds", testNewPerpsMarketChangeSubmissionWithOracleSpecSucceeds) 162 t.Run("Submitting a perps market change without filters fails", testNewPerpsMarketChangeSubmissionWithoutFiltersFails) 163 t.Run("Submitting a perps market change with filters succeeds", testNewPerpsMarketChangeSubmissionWithFiltersSucceeds) 164 t.Run("Submitting a perps market change with filter without key fails", testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyFails) 165 t.Run("Submitting a perps market change with filter with key succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithKeySucceeds) 166 t.Run("Submitting a perps market change with filter without key name fails", testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyNameFails) 167 t.Run("Submitting a perps market change with filter with key name succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithKeyNameSucceeds) 168 t.Run("Submitting a perps market change with filter without key type fails", testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyTypeFails) 169 t.Run("Submitting a perps market change with filter with key type succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithKeyTypeSucceeds) 170 t.Run("Submitting a perps market change with filter without condition succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionsSucceeds) 171 t.Run("Submitting a perps market change with filter without condition operator fails", testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionOperatorFails) 172 t.Run("Submitting a perps market change with filter with condition operator succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds) 173 t.Run("Submitting a perps market change with filter without condition value fails", testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionValueFails) 174 t.Run("Submitting a perps market change with filter with condition value succeeds", testNewPerpsMarketChangeSubmissionWithFilterWithConditionValueSucceeds) 175 t.Run("Submitting a perps market change without oracle spec bindings fails", testNewPerpsMarketChangeSubmissionWithoutDataSourceSpecBindingFails) 176 t.Run("Submitting a perps market change with oracle spec binding succeeds", testNewPerpsMarketChangeSubmissionWithDataSourceSpecBindingSucceeds) 177 t.Run("Submitting a perps market with funding rate modifiers", testNewPerpsMarketWithFundingRateModifiers) 178 t.Run("Submitting a perps market change with a mismatch between binding property name and filter fails", testNewPerpsMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails) 179 t.Run("Submitting a perps market change with match between binding property name and filter succeeds", testNewPerpsMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds) 180 t.Run("Submitting a perps market change with settlement data and trading termination properties succeeds", testNewPerpsMarketChangeSubmissionWithSettlementDataPropertySucceeds) 181 t.Run("Submitting a perps market change with intenal composite price config", testNewPerpsMarketChangeSubmissionWithInternalCompositePriceConfig) 182 t.Run("Submitting a new market with invalid SLA price range fails", testNewMarketChangeSubmissionWithInvalidLpRangeFails) 183 t.Run("Submitting a new market with valid SLA price range succeeds", testNewMarketChangeSubmissionWithValidLpRangeSucceeds) 184 t.Run("Submitting a new market with invalid min time fraction fails", testNewMarketChangeSubmissionWithInvalidMinTimeFractionFails) 185 t.Run("Submitting a new market with valid min time fraction succeeds", testNewMarketChangeSubmissionWithValidMinTimeFractionSucceeds) 186 t.Run("Submitting a new market with invalid competition factor fails", testNewMarketChangeSubmissionWithInvalidCompetitionFactorFails) 187 t.Run("Submitting a new market with valid competition factor succeeds", testNewMarketChangeSubmissionWithValidCompetitionFactorSucceeds) 188 t.Run("Submitting a new market with invalid hysteresis epochs fails", testNewMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails) 189 t.Run("Submitting a new market with valid hysteresis epochs succeeds", testNewMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds) 190 t.Run("Submitting a new market with invalid liquidity fee settings", testLiquidityFeeSettings) 191 t.Run("Submitting a new spot market with invalid liquidity fee settings", testLiquidityFeeSettingsSpot) 192 t.Run("Submitting a new market with invalid mark price configuration ", testCompositePriceConfiguration) 193 t.Run("Submitting a new market with invalid tick size fails and with valid tick size succeeds", testNewMarketTickSize) 194 195 t.Run("Log Normal risk factor overrides", testNewLogNormalRiskParametersChangeSubmissionWithOverrides) 196 } 197 198 type tickSizeCase struct { 199 tickSize string 200 err error 201 } 202 203 func getTickSizeCases() []tickSizeCase { 204 return []tickSizeCase{ 205 {tickSize: "", err: commands.ErrIsRequired}, 206 {tickSize: "banana", err: commands.ErrNotAValidInteger}, 207 {tickSize: "-1", err: commands.ErrMustBePositive}, 208 {tickSize: "0", err: commands.ErrMustBePositive}, 209 {tickSize: "1", err: nil}, 210 {tickSize: "123", err: nil}, 211 } 212 } 213 214 func testNewMarketTickSize(t *testing.T) { 215 cases := getTickSizeCases() 216 for _, tsc := range cases { 217 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 218 Terms: &vegapb.ProposalTerms{ 219 Change: &vegapb.ProposalTerms_NewMarket{ 220 NewMarket: &vegapb.NewMarket{ 221 Changes: &vegapb.NewMarketConfiguration{ 222 TickSize: tsc.tickSize, 223 }, 224 }, 225 }, 226 }, 227 }) 228 if tsc.err != nil { 229 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.tick_size"), tsc.err) 230 } else { 231 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.tick_size")) 232 } 233 } 234 } 235 236 func testNewMarketChangeSubmissionWithoutNewMarketFails(t *testing.T) { 237 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 238 Terms: &vegapb.ProposalTerms{ 239 Change: &vegapb.ProposalTerms_NewMarket{}, 240 }, 241 }) 242 243 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market"), commands.ErrIsRequired) 244 } 245 246 func testNewMarketChangeSubmissionWithoutChangesFails(t *testing.T) { 247 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 248 Terms: &vegapb.ProposalTerms{ 249 Change: &vegapb.ProposalTerms_NewMarket{ 250 NewMarket: &vegapb.NewMarket{}, 251 }, 252 }, 253 }) 254 255 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes"), commands.ErrIsRequired) 256 } 257 258 func testNewMarketChangeSubmissionWithoutDecimalPlacesSucceeds(t *testing.T) { 259 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 260 Terms: &vegapb.ProposalTerms{ 261 Change: &vegapb.ProposalTerms_NewMarket{ 262 NewMarket: &vegapb.NewMarket{ 263 Changes: &vegapb.NewMarketConfiguration{}, 264 }, 265 }, 266 }, 267 }) 268 269 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero) 270 } 271 272 func testNewMarketChangeSubmissionWithDecimalPlacesEqualTo0Succeeds(t *testing.T) { 273 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 274 Terms: &vegapb.ProposalTerms{ 275 Change: &vegapb.ProposalTerms_NewMarket{ 276 NewMarket: &vegapb.NewMarket{ 277 Changes: &vegapb.NewMarketConfiguration{ 278 DecimalPlaces: 0, 279 }, 280 }, 281 }, 282 }, 283 }) 284 285 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero) 286 } 287 288 func testNewMarketChangeSubmissionWithDecimalPlacesAboveOrEqualTo150Fails(t *testing.T) { 289 testCases := []struct { 290 msg string 291 value uint64 292 }{ 293 { 294 msg: "equal to 150", 295 value: 150, 296 }, { 297 msg: "above 150", 298 value: 1000, 299 }, 300 } 301 for _, tc := range testCases { 302 t.Run(tc.msg, func(t *testing.T) { 303 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 304 Terms: &vegapb.ProposalTerms{ 305 Change: &vegapb.ProposalTerms_NewMarket{ 306 NewMarket: &vegapb.NewMarket{ 307 Changes: &vegapb.NewMarketConfiguration{ 308 DecimalPlaces: tc.value, 309 }, 310 }, 311 }, 312 }, 313 }) 314 315 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.decimal_places"), commands.ErrMustBeLessThan150) 316 }) 317 } 318 } 319 320 func testNewMarketChangeSubmissionWithDecimalPlacesBelow150Succeeds(t *testing.T) { 321 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 322 Terms: &vegapb.ProposalTerms{ 323 Change: &vegapb.ProposalTerms_NewMarket{ 324 NewMarket: &vegapb.NewMarket{ 325 Changes: &vegapb.NewMarketConfiguration{ 326 DecimalPlaces: test.RandomPositiveU64Before(150), 327 }, 328 }, 329 }, 330 }, 331 }) 332 333 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.decimal_places"), commands.ErrMustBePositive) 334 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.decimal_places"), commands.ErrMustBeLessThan150) 335 } 336 337 func testNewMarketChangeSubmissionWithPositionDecimalPlacesEqualTo0Succeeds(t *testing.T) { 338 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 339 Terms: &vegapb.ProposalTerms{ 340 Change: &vegapb.ProposalTerms_NewMarket{ 341 NewMarket: &vegapb.NewMarket{ 342 Changes: &vegapb.NewMarketConfiguration{ 343 PositionDecimalPlaces: 0, 344 }, 345 }, 346 }, 347 }, 348 }) 349 350 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.position_decimal_places"), commands.ErrMustBePositiveOrZero) 351 } 352 353 func testNewMarketChangeSubmissionWithPositionDecimalPlacesAboveOrEqualTo7Fails(t *testing.T) { 354 testCases := []struct { 355 msg string 356 value int64 357 }{ 358 { 359 msg: "equal to 7", 360 value: 7, 361 }, 362 { 363 msg: "greater than 7", 364 value: 8, 365 }, 366 { 367 msg: "equal to -7", 368 value: -7, 369 }, 370 { 371 msg: "less than -7", 372 value: -8, 373 }, 374 } 375 for _, tc := range testCases { 376 t.Run(tc.msg, func(t *testing.T) { 377 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 378 Terms: &vegapb.ProposalTerms{ 379 Change: &vegapb.ProposalTerms_NewMarket{ 380 NewMarket: &vegapb.NewMarket{ 381 Changes: &vegapb.NewMarketConfiguration{ 382 PositionDecimalPlaces: tc.value, 383 }, 384 }, 385 }, 386 }, 387 }) 388 389 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.position_decimal_places"), commands.ErrMustBeWithinRange7) 390 }) 391 } 392 } 393 394 func testNewMarketChangeSubmissionWithPositionDecimalPlacesBelow7Succeeds(t *testing.T) { 395 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 396 Terms: &vegapb.ProposalTerms{ 397 Change: &vegapb.ProposalTerms_NewMarket{ 398 NewMarket: &vegapb.NewMarket{ 399 Changes: &vegapb.NewMarketConfiguration{ 400 PositionDecimalPlaces: test.RandomPositiveI64Before(7), 401 }, 402 }, 403 }, 404 }, 405 }) 406 407 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.position_decimal_places"), commands.ErrMustBeWithinRange7) 408 } 409 410 func testNewMarketChangeSubmissionWithSlippageFactorBananaFails(t *testing.T) { 411 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 412 Terms: &vegapb.ProposalTerms{ 413 Change: &vegapb.ProposalTerms_NewMarket{ 414 NewMarket: &vegapb.NewMarket{ 415 Changes: &vegapb.NewMarketConfiguration{ 416 LinearSlippageFactor: "banana", 417 }, 418 }, 419 }, 420 }, 421 }) 422 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.linear_slippage_factor"), commands.ErrIsNotValidNumber) 423 } 424 425 func testNewMarketChangeSubmissionWithSlippageFactorNegativeFails(t *testing.T) { 426 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 427 Terms: &vegapb.ProposalTerms{ 428 Change: &vegapb.ProposalTerms_NewMarket{ 429 NewMarket: &vegapb.NewMarket{ 430 Changes: &vegapb.NewMarketConfiguration{ 431 LinearSlippageFactor: "-0.1", 432 }, 433 }, 434 }, 435 }, 436 }) 437 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.linear_slippage_factor"), commands.ErrMustBePositiveOrZero) 438 } 439 440 func testNewMarketChangeSubmissionWithSlippageFactorTooLargeFails(t *testing.T) { 441 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 442 Terms: &vegapb.ProposalTerms{ 443 Change: &vegapb.ProposalTerms_NewMarket{ 444 NewMarket: &vegapb.NewMarket{ 445 Changes: &vegapb.NewMarketConfiguration{ 446 LinearSlippageFactor: "1000000.000001", 447 }, 448 }, 449 }, 450 }, 451 }) 452 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.linear_slippage_factor"), commands.ErrMustBeAtMost1M) 453 } 454 455 func testNewMarketChangeSubmissionWithEmptySlippageFactorPasses(t *testing.T) { 456 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 457 Terms: &vegapb.ProposalTerms{ 458 Change: &vegapb.ProposalTerms_NewMarket{ 459 NewMarket: &vegapb.NewMarket{ 460 Changes: &vegapb.NewMarketConfiguration{}, 461 }, 462 }, 463 }, 464 }) 465 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.linear_slippage_factor"), commands.ErrIsNotValidNumber) 466 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.quadratic_slippage_factor"), commands.ErrIsNotValidNumber) 467 } 468 469 func testNewMarketChangeSubmissionWithoutLiquidityMonitoringFails(t *testing.T) { 470 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 471 Terms: &vegapb.ProposalTerms{ 472 Change: &vegapb.ProposalTerms_NewMarket{ 473 NewMarket: &vegapb.NewMarket{ 474 Changes: &vegapb.NewMarketConfiguration{}, 475 }, 476 }, 477 }, 478 }) 479 480 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters"), commands.ErrIsRequired) 481 } 482 483 func testNewMarketChangeSubmissionWithLiquidityMonitoringSucceeds(t *testing.T) { 484 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 485 Terms: &vegapb.ProposalTerms{ 486 Change: &vegapb.ProposalTerms_NewMarket{ 487 NewMarket: &vegapb.NewMarket{ 488 Changes: &vegapb.NewMarketConfiguration{ 489 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{}, 490 }, 491 }, 492 }, 493 }, 494 }) 495 496 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters"), commands.ErrIsRequired) 497 } 498 499 func testLiquidityMonitoringChangeSubmissionWithoutTargetStakeParametersFails(t *testing.T) { 500 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 501 Terms: &vegapb.ProposalTerms{ 502 Change: &vegapb.ProposalTerms_NewMarket{ 503 NewMarket: &vegapb.NewMarket{ 504 Changes: &vegapb.NewMarketConfiguration{ 505 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{}, 506 }, 507 }, 508 }, 509 }, 510 }) 511 512 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters"), commands.ErrIsRequired) 513 } 514 515 func testLiquidityMonitoringChangeSubmissionWithTargetStakeParametersSucceeds(t *testing.T) { 516 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 517 Terms: &vegapb.ProposalTerms{ 518 Change: &vegapb.ProposalTerms_NewMarket{ 519 NewMarket: &vegapb.NewMarket{ 520 Changes: &vegapb.NewMarketConfiguration{ 521 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{ 522 TargetStakeParameters: &vegapb.TargetStakeParameters{}, 523 }, 524 }, 525 }, 526 }, 527 }, 528 }) 529 530 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters"), commands.ErrIsRequired) 531 } 532 533 func testLiquidityMonitoringChangeSubmissionWithNonPositiveTimeWindowFails(t *testing.T) { 534 testCases := []struct { 535 msg string 536 value int64 537 }{ 538 { 539 msg: "with ratio of 0", 540 value: 0, 541 }, { 542 msg: "with ratio of -1", 543 value: test.RandomNegativeI64(), 544 }, 545 } 546 for _, tc := range testCases { 547 t.Run(tc.msg, func(t *testing.T) { 548 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 549 Terms: &vegapb.ProposalTerms{ 550 Change: &vegapb.ProposalTerms_NewMarket{ 551 NewMarket: &vegapb.NewMarket{ 552 Changes: &vegapb.NewMarketConfiguration{ 553 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{ 554 TargetStakeParameters: &vegapb.TargetStakeParameters{ 555 TimeWindow: tc.value, 556 }, 557 }, 558 }, 559 }, 560 }, 561 }, 562 }) 563 564 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters.time_window"), commands.ErrMustBePositive) 565 }) 566 } 567 } 568 569 func testLiquidityMonitoringChangeSubmissionWithPositiveTimeWindowSucceeds(t *testing.T) { 570 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 571 Terms: &vegapb.ProposalTerms{ 572 Change: &vegapb.ProposalTerms_NewMarket{ 573 NewMarket: &vegapb.NewMarket{ 574 Changes: &vegapb.NewMarketConfiguration{ 575 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{ 576 TargetStakeParameters: &vegapb.TargetStakeParameters{ 577 TimeWindow: test.RandomPositiveI64(), 578 }, 579 }, 580 }, 581 }, 582 }, 583 }, 584 }) 585 586 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters.time_window"), commands.ErrMustBePositive) 587 } 588 589 func testLiquidityMonitoringChangeSubmissionWithNonPositiveScalingFactorFails(t *testing.T) { 590 testCases := []struct { 591 msg string 592 value float64 593 }{ 594 { 595 msg: "with ratio of 0", 596 value: 0, 597 }, { 598 msg: "with ratio of -1.5", 599 value: -1.5, 600 }, 601 } 602 for _, tc := range testCases { 603 t.Run(tc.msg, func(t *testing.T) { 604 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 605 Terms: &vegapb.ProposalTerms{ 606 Change: &vegapb.ProposalTerms_NewMarket{ 607 NewMarket: &vegapb.NewMarket{ 608 Changes: &vegapb.NewMarketConfiguration{ 609 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{ 610 TargetStakeParameters: &vegapb.TargetStakeParameters{ 611 ScalingFactor: tc.value, 612 }, 613 }, 614 }, 615 }, 616 }, 617 }, 618 }) 619 620 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive) 621 }) 622 } 623 } 624 625 func testLiquidityMonitoringChangeSubmissionWithPositiveScalingFactorSucceeds(t *testing.T) { 626 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 627 Terms: &vegapb.ProposalTerms{ 628 Change: &vegapb.ProposalTerms_NewMarket{ 629 NewMarket: &vegapb.NewMarket{ 630 Changes: &vegapb.NewMarketConfiguration{ 631 LiquidityMonitoringParameters: &vegapb.LiquidityMonitoringParameters{ 632 TargetStakeParameters: &vegapb.TargetStakeParameters{ 633 ScalingFactor: 1.5, 634 }, 635 }, 636 }, 637 }, 638 }, 639 }, 640 }) 641 642 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_monitoring_parameters.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive) 643 } 644 645 func testPriceMonitoringChangeSubmissionWithoutTriggersSucceeds(t *testing.T) { 646 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 647 Terms: &vegapb.ProposalTerms{ 648 Change: &vegapb.ProposalTerms_NewMarket{ 649 NewMarket: &vegapb.NewMarket{ 650 Changes: &vegapb.NewMarketConfiguration{ 651 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 652 Triggers: []*vegapb.PriceMonitoringTrigger{}, 653 }, 654 }, 655 }, 656 }, 657 }, 658 }) 659 660 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired) 661 } 662 663 func testPriceMonitoringChangeSubmissionWithTriggersSucceeds(t *testing.T) { 664 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 665 Terms: &vegapb.ProposalTerms{ 666 Change: &vegapb.ProposalTerms_NewMarket{ 667 NewMarket: &vegapb.NewMarket{ 668 Changes: &vegapb.NewMarketConfiguration{ 669 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 670 Triggers: []*vegapb.PriceMonitoringTrigger{ 671 {}, 672 {}, 673 }, 674 }, 675 }, 676 }, 677 }, 678 }, 679 }) 680 681 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired) 682 } 683 684 func testNewMarketChangeSubmissionWithTooManyPMTriggersFails(t *testing.T) { 685 triggers := []*vegapb.PriceMonitoringTrigger{} 686 for i := 0; i <= 100; i++ { 687 triggers = append(triggers, &vegapb.PriceMonitoringTrigger{}) 688 } 689 690 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 691 Terms: &vegapb.ProposalTerms{ 692 Change: &vegapb.ProposalTerms_NewMarket{ 693 NewMarket: &vegapb.NewMarket{ 694 Changes: &vegapb.NewMarketConfiguration{ 695 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 696 Triggers: triggers, 697 }, 698 }, 699 }, 700 }, 701 }, 702 }) 703 704 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers"), errors.New("maximum 100 triggers allowed")) 705 } 706 707 func testPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails(t *testing.T) { 708 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 709 Terms: &vegapb.ProposalTerms{ 710 Change: &vegapb.ProposalTerms_NewMarket{ 711 NewMarket: &vegapb.NewMarket{ 712 Changes: &vegapb.NewMarketConfiguration{ 713 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 714 Triggers: []*vegapb.PriceMonitoringTrigger{ 715 {}, 716 {}, 717 }, 718 }, 719 }, 720 }, 721 }, 722 }, 723 }) 724 725 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive) 726 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive) 727 } 728 729 func testPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds(t *testing.T) { 730 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 731 Terms: &vegapb.ProposalTerms{ 732 Change: &vegapb.ProposalTerms_NewMarket{ 733 NewMarket: &vegapb.NewMarket{ 734 Changes: &vegapb.NewMarketConfiguration{ 735 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 736 Triggers: []*vegapb.PriceMonitoringTrigger{ 737 { 738 Horizon: test.RandomPositiveI64(), 739 }, 740 { 741 Horizon: test.RandomPositiveI64(), 742 }, 743 }, 744 }, 745 }, 746 }, 747 }, 748 }, 749 }) 750 751 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive) 752 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive) 753 } 754 755 func testPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails(t *testing.T) { 756 testCases := []struct { 757 msg string 758 value float64 759 }{ 760 { 761 msg: "with probability of -1", 762 value: -1, 763 }, { 764 msg: "with probability of 0", 765 value: 0, 766 }, { 767 msg: "with probability of 1", 768 value: 1, 769 }, { 770 msg: "with probability of 2", 771 value: 2, 772 }, 773 } 774 for _, tc := range testCases { 775 t.Run(tc.msg, func(t *testing.T) { 776 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 777 Terms: &vegapb.ProposalTerms{ 778 Change: &vegapb.ProposalTerms_NewMarket{ 779 NewMarket: &vegapb.NewMarket{ 780 Changes: &vegapb.NewMarketConfiguration{ 781 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 782 Triggers: []*vegapb.PriceMonitoringTrigger{ 783 { 784 Probability: fmt.Sprintf("%f", tc.value), 785 }, 786 { 787 Probability: fmt.Sprintf("%f", tc.value), 788 }, 789 }, 790 }, 791 }, 792 }, 793 }, 794 }, 795 }) 796 797 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.probability"), 798 errors.New("should be between 0.9 (exclusive) and 1 (exclusive)")) 799 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.probability"), 800 errors.New("should be between 0.9 (exclusive) and 1 (exclusive)")) 801 }) 802 } 803 } 804 805 func testPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds(t *testing.T) { 806 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 807 Terms: &vegapb.ProposalTerms{ 808 Change: &vegapb.ProposalTerms_NewMarket{ 809 NewMarket: &vegapb.NewMarket{ 810 Changes: &vegapb.NewMarketConfiguration{ 811 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 812 Triggers: []*vegapb.PriceMonitoringTrigger{ 813 { 814 Probability: "0.01", 815 }, 816 { 817 Probability: "0.9", 818 }, 819 }, 820 }, 821 }, 822 }, 823 }, 824 }, 825 }) 826 827 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.probability"), 828 errors.New("should be between 0 (exclusive) and 1 (exclusive)")) 829 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.probability"), 830 errors.New("should be between 0 (exclusive) and 1 (exclusive)")) 831 } 832 833 func testPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails(t *testing.T) { 834 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 835 Terms: &vegapb.ProposalTerms{ 836 Change: &vegapb.ProposalTerms_NewMarket{ 837 NewMarket: &vegapb.NewMarket{ 838 Changes: &vegapb.NewMarketConfiguration{ 839 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 840 Triggers: []*vegapb.PriceMonitoringTrigger{ 841 {}, 842 {}, 843 }, 844 }, 845 }, 846 }, 847 }, 848 }, 849 }) 850 851 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive) 852 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive) 853 } 854 855 func testPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds(t *testing.T) { 856 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 857 Terms: &vegapb.ProposalTerms{ 858 Change: &vegapb.ProposalTerms_NewMarket{ 859 NewMarket: &vegapb.NewMarket{ 860 Changes: &vegapb.NewMarketConfiguration{ 861 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{ 862 Triggers: []*vegapb.PriceMonitoringTrigger{ 863 { 864 AuctionExtension: test.RandomPositiveI64(), 865 }, 866 { 867 AuctionExtension: test.RandomPositiveI64(), 868 }, 869 }, 870 }, 871 }, 872 }, 873 }, 874 }, 875 }) 876 877 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive) 878 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive) 879 } 880 881 func testNewCappedMarketWithMaxPriceSucceeds(t *testing.T) { 882 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 883 Terms: &vegapb.ProposalTerms{ 884 Change: &vegapb.ProposalTerms_NewMarket{ 885 NewMarket: &vegapb.NewMarket{ 886 Changes: &vegapb.NewMarketConfiguration{ 887 Instrument: &vegapb.InstrumentConfiguration{ 888 Product: &vegapb.InstrumentConfiguration_Future{ 889 Future: &vegapb.FutureProduct{ 890 Cap: &vegapb.FutureCap{ 891 MaxPrice: "100", 892 }, 893 }, 894 }, 895 }, 896 TickSize: "10", // ensure tick size is fine, too 897 }, 898 }, 899 }, 900 }, 901 }) 902 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMustBePositive) 903 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrIsRequired) 904 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMaxPriceMustRespectTickSize) 905 } 906 907 func testNewCappedMarketWithoutMaxPriceFails(t *testing.T) { 908 fCap := &vegapb.FutureCap{ 909 MaxPrice: "", 910 } 911 nmConf := &vegapb.NewMarketConfiguration{ 912 Instrument: &vegapb.InstrumentConfiguration{ 913 Product: &vegapb.InstrumentConfiguration_Future{ 914 Future: &vegapb.FutureProduct{ 915 Cap: fCap, 916 }, 917 }, 918 }, 919 } 920 cmd := &commandspb.ProposalSubmission{ 921 Terms: &vegapb.ProposalTerms{ 922 Change: &vegapb.ProposalTerms_NewMarket{ 923 NewMarket: &vegapb.NewMarket{ 924 Changes: nmConf, 925 }, 926 }, 927 }, 928 } 929 // submit with empty string: 930 err := checkProposalSubmission(cmd) 931 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrIsRequired) 932 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMaxPriceMustRespectTickSize) 933 fCap.MaxPrice = "foobar" // invalid input 934 err = checkProposalSubmission(cmd) 935 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMustBePositive) 936 // submit with invalid value relative to tick size 937 fCap.MaxPrice = "123" 938 nmConf.TickSize = "10" 939 err = checkProposalSubmission(cmd) 940 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMaxPriceMustRespectTickSize) 941 942 // submit with no max price but other fields set (0019-MCAL-170) 943 fCap.MaxPrice = "" 944 fCap.BinarySettlement = ptr.From(true) 945 fCap.FullyCollateralised = nil 946 err = checkProposalSubmission(cmd) 947 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrIsRequired) 948 949 // submit with no max price but other fields set (0019-MCAL-171) 950 fCap.MaxPrice = "" 951 fCap.BinarySettlement = nil 952 fCap.FullyCollateralised = ptr.From(true) 953 err = checkProposalSubmission(cmd) 954 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrIsRequired) 955 956 // max cap of zero is rejected 957 fCap.MaxPrice = "0" 958 fCap.BinarySettlement = nil 959 fCap.FullyCollateralised = ptr.From(true) 960 err = checkProposalSubmission(cmd) 961 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.cap.max_price"), commands.ErrMustBePositive) 962 } 963 964 func testNewMarketChangeSubmissionWithoutPriceMonitoringSucceeds(t *testing.T) { 965 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 966 Terms: &vegapb.ProposalTerms{ 967 Change: &vegapb.ProposalTerms_NewMarket{ 968 NewMarket: &vegapb.NewMarket{ 969 Changes: &vegapb.NewMarketConfiguration{}, 970 }, 971 }, 972 }, 973 }) 974 975 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters"), commands.ErrIsRequired) 976 } 977 978 func testNewMarketChangeSubmissionWithPriceMonitoringSucceeds(t *testing.T) { 979 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 980 Terms: &vegapb.ProposalTerms{ 981 Change: &vegapb.ProposalTerms_NewMarket{ 982 NewMarket: &vegapb.NewMarket{ 983 Changes: &vegapb.NewMarketConfiguration{ 984 PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{}, 985 }, 986 }, 987 }, 988 }, 989 }) 990 991 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters"), commands.ErrIsRequired) 992 } 993 994 func testNewMarketChangeSubmissionWithoutInstrumentNameFails(t *testing.T) { 995 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 996 Terms: &vegapb.ProposalTerms{ 997 Change: &vegapb.ProposalTerms_NewMarket{ 998 NewMarket: &vegapb.NewMarket{ 999 Changes: &vegapb.NewMarketConfiguration{ 1000 Instrument: &vegapb.InstrumentConfiguration{ 1001 Name: "", 1002 }, 1003 }, 1004 }, 1005 }, 1006 }, 1007 }) 1008 1009 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.name"), commands.ErrIsRequired) 1010 } 1011 1012 func testNewMarketChangeSubmissionWithInstrumentNameSucceeds(t *testing.T) { 1013 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1014 Terms: &vegapb.ProposalTerms{ 1015 Change: &vegapb.ProposalTerms_NewMarket{ 1016 NewMarket: &vegapb.NewMarket{ 1017 Changes: &vegapb.NewMarketConfiguration{ 1018 Instrument: &vegapb.InstrumentConfiguration{ 1019 Name: "My name", 1020 }, 1021 }, 1022 }, 1023 }, 1024 }, 1025 }) 1026 1027 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.name"), commands.ErrIsRequired) 1028 } 1029 1030 func testNewMarketChangeSubmissionWithoutInstrumentCodeFails(t *testing.T) { 1031 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1032 Terms: &vegapb.ProposalTerms{ 1033 Change: &vegapb.ProposalTerms_NewMarket{ 1034 NewMarket: &vegapb.NewMarket{ 1035 Changes: &vegapb.NewMarketConfiguration{ 1036 Instrument: &vegapb.InstrumentConfiguration{ 1037 Code: "", 1038 }, 1039 }, 1040 }, 1041 }, 1042 }, 1043 }) 1044 1045 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.code"), commands.ErrIsRequired) 1046 } 1047 1048 func testNewMarketChangeSubmissionWithInstrumentCodeSucceeds(t *testing.T) { 1049 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1050 Terms: &vegapb.ProposalTerms{ 1051 Change: &vegapb.ProposalTerms_NewMarket{ 1052 NewMarket: &vegapb.NewMarket{ 1053 Changes: &vegapb.NewMarketConfiguration{ 1054 Instrument: &vegapb.InstrumentConfiguration{ 1055 Code: "My code", 1056 }, 1057 }, 1058 }, 1059 }, 1060 }, 1061 }) 1062 1063 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.code"), commands.ErrIsRequired) 1064 } 1065 1066 func testNewMarketChangeSubmissionWithoutProductFails(t *testing.T) { 1067 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1068 Terms: &vegapb.ProposalTerms{ 1069 Change: &vegapb.ProposalTerms_NewMarket{ 1070 NewMarket: &vegapb.NewMarket{ 1071 Changes: &vegapb.NewMarketConfiguration{ 1072 Instrument: &vegapb.InstrumentConfiguration{}, 1073 }, 1074 }, 1075 }, 1076 }, 1077 }) 1078 1079 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product"), commands.ErrIsRequired) 1080 } 1081 1082 func testNewMarketChangeSubmissionWithProductSucceeds(t *testing.T) { 1083 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1084 Terms: &vegapb.ProposalTerms{ 1085 Change: &vegapb.ProposalTerms_NewMarket{ 1086 NewMarket: &vegapb.NewMarket{ 1087 Changes: &vegapb.NewMarketConfiguration{ 1088 Instrument: &vegapb.InstrumentConfiguration{ 1089 Product: &vegapb.InstrumentConfiguration_Future{}, 1090 }, 1091 }, 1092 }, 1093 }, 1094 }, 1095 }) 1096 1097 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product"), commands.ErrIsRequired) 1098 } 1099 1100 func testNewFutureMarketChangeSubmissionWithoutFutureFails(t *testing.T) { 1101 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1102 Terms: &vegapb.ProposalTerms{ 1103 Change: &vegapb.ProposalTerms_NewMarket{ 1104 NewMarket: &vegapb.NewMarket{ 1105 Changes: &vegapb.NewMarketConfiguration{ 1106 Instrument: &vegapb.InstrumentConfiguration{ 1107 Product: &vegapb.InstrumentConfiguration_Future{}, 1108 }, 1109 }, 1110 }, 1111 }, 1112 }, 1113 }) 1114 1115 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future"), commands.ErrIsRequired) 1116 } 1117 1118 func testNewFutureMarketChangeSubmissionWithFutureSucceeds(t *testing.T) { 1119 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1120 Terms: &vegapb.ProposalTerms{ 1121 Change: &vegapb.ProposalTerms_NewMarket{ 1122 NewMarket: &vegapb.NewMarket{ 1123 Changes: &vegapb.NewMarketConfiguration{ 1124 Instrument: &vegapb.InstrumentConfiguration{ 1125 Product: &vegapb.InstrumentConfiguration_Future{ 1126 Future: &vegapb.FutureProduct{}, 1127 }, 1128 }, 1129 }, 1130 }, 1131 }, 1132 }, 1133 }) 1134 1135 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future"), commands.ErrIsRequired) 1136 } 1137 1138 func testNewFutureMarketChangeSubmissionWithoutSettlementAssetFails(t *testing.T) { 1139 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1140 Terms: &vegapb.ProposalTerms{ 1141 Change: &vegapb.ProposalTerms_NewMarket{ 1142 NewMarket: &vegapb.NewMarket{ 1143 Changes: &vegapb.NewMarketConfiguration{ 1144 Instrument: &vegapb.InstrumentConfiguration{ 1145 Product: &vegapb.InstrumentConfiguration_Future{ 1146 Future: &vegapb.FutureProduct{ 1147 SettlementAsset: "", 1148 }, 1149 }, 1150 }, 1151 }, 1152 }, 1153 }, 1154 }, 1155 }) 1156 1157 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.settlement_asset"), commands.ErrIsRequired) 1158 } 1159 1160 func testNewFutureMarketChangeSubmissionWithSettlementAssetSucceeds(t *testing.T) { 1161 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1162 Terms: &vegapb.ProposalTerms{ 1163 Change: &vegapb.ProposalTerms_NewMarket{ 1164 NewMarket: &vegapb.NewMarket{ 1165 Changes: &vegapb.NewMarketConfiguration{ 1166 Instrument: &vegapb.InstrumentConfiguration{ 1167 Product: &vegapb.InstrumentConfiguration_Future{ 1168 Future: &vegapb.FutureProduct{ 1169 SettlementAsset: "BTC", 1170 }, 1171 }, 1172 }, 1173 }, 1174 }, 1175 }, 1176 }, 1177 }) 1178 1179 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.settlement_asset"), commands.ErrIsRequired) 1180 } 1181 1182 func testNewFutureMarketChangeSubmissionWithoutQuoteNameFails(t *testing.T) { 1183 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1184 Terms: &vegapb.ProposalTerms{ 1185 Change: &vegapb.ProposalTerms_NewMarket{ 1186 NewMarket: &vegapb.NewMarket{ 1187 Changes: &vegapb.NewMarketConfiguration{ 1188 Instrument: &vegapb.InstrumentConfiguration{ 1189 Product: &vegapb.InstrumentConfiguration_Future{ 1190 Future: &vegapb.FutureProduct{ 1191 QuoteName: "", 1192 }, 1193 }, 1194 }, 1195 }, 1196 }, 1197 }, 1198 }, 1199 }) 1200 1201 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.quote_name"), commands.ErrIsRequired) 1202 } 1203 1204 func testNewFutureMarketChangeSubmissionWithQuoteNameSucceeds(t *testing.T) { 1205 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1206 Terms: &vegapb.ProposalTerms{ 1207 Change: &vegapb.ProposalTerms_NewMarket{ 1208 NewMarket: &vegapb.NewMarket{ 1209 Changes: &vegapb.NewMarketConfiguration{ 1210 Instrument: &vegapb.InstrumentConfiguration{ 1211 Product: &vegapb.InstrumentConfiguration_Future{ 1212 Future: &vegapb.FutureProduct{ 1213 QuoteName: "BTC", 1214 }, 1215 }, 1216 }, 1217 }, 1218 }, 1219 }, 1220 }, 1221 }) 1222 1223 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.quote_name"), commands.ErrIsRequired) 1224 } 1225 1226 func testNewFutureMarketChangeSubmissionWithoutOracleSpecFails(t *testing.T) { 1227 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1228 Terms: &vegapb.ProposalTerms{ 1229 Change: &vegapb.ProposalTerms_NewMarket{ 1230 NewMarket: &vegapb.NewMarket{ 1231 Changes: &vegapb.NewMarketConfiguration{ 1232 Instrument: &vegapb.InstrumentConfiguration{ 1233 Product: &vegapb.InstrumentConfiguration_Future{ 1234 Future: &vegapb.FutureProduct{}, 1235 }, 1236 }, 1237 }, 1238 }, 1239 }, 1240 }, 1241 }) 1242 1243 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsRequired) 1244 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination"), commands.ErrIsRequired) 1245 } 1246 1247 func testNewFutureMarketChangeSubmissionMissingSingleOracleSpecFails(t *testing.T) { 1248 testNewFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t, "data_source_spec_for_settlement_data") 1249 testNewFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t, "data_source_spec_for_trading_termination") 1250 } 1251 1252 func testNewFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t *testing.T, oracleSpecName string) { 1253 t.Helper() 1254 future := &vegapb.FutureProduct{} 1255 if oracleSpecName == "data_source_spec_for_settlement_data" { 1256 future.DataSourceSpecForTradingTermination = &vegapb.DataSourceDefinition{} 1257 } else { 1258 future.DataSourceSpecForSettlementData = &vegapb.DataSourceDefinition{} 1259 } 1260 1261 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1262 Terms: &vegapb.ProposalTerms{ 1263 Change: &vegapb.ProposalTerms_NewMarket{ 1264 NewMarket: &vegapb.NewMarket{ 1265 Changes: &vegapb.NewMarketConfiguration{ 1266 Instrument: &vegapb.InstrumentConfiguration{ 1267 Product: &vegapb.InstrumentConfiguration_Future{ 1268 Future: &vegapb.FutureProduct{}, 1269 }, 1270 }, 1271 }, 1272 }, 1273 }, 1274 }, 1275 }) 1276 1277 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future."+oracleSpecName), commands.ErrIsRequired) 1278 } 1279 1280 func testNewFutureMarketChangeSubmissionWithEmptyOracleSpecFails(t *testing.T) { 1281 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1282 Terms: &vegapb.ProposalTerms{ 1283 Change: &vegapb.ProposalTerms_NewMarket{ 1284 NewMarket: &vegapb.NewMarket{ 1285 Changes: &vegapb.NewMarketConfiguration{ 1286 Instrument: &vegapb.InstrumentConfiguration{ 1287 Product: &vegapb.InstrumentConfiguration_Future{ 1288 Future: &vegapb.FutureProduct{ 1289 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{}, 1290 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{}, 1291 }, 1292 }, 1293 }, 1294 }, 1295 }, 1296 }, 1297 }, 1298 }) 1299 1300 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.source_type"), commands.ErrIsRequired) 1301 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.source_type"), commands.ErrIsRequired) 1302 } 1303 1304 func testNewFutureMarketChangeSubmissionWithEmptyOracleSpecTypeFails(t *testing.T) { 1305 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1306 Terms: &vegapb.ProposalTerms{ 1307 Change: &vegapb.ProposalTerms_NewMarket{ 1308 NewMarket: &vegapb.NewMarket{ 1309 Changes: &vegapb.NewMarketConfiguration{ 1310 Instrument: &vegapb.InstrumentConfiguration{ 1311 Product: &vegapb.InstrumentConfiguration_Future{ 1312 Future: &vegapb.FutureProduct{ 1313 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{ 1314 SourceType: &vegapb.DataSourceDefinition_External{ 1315 External: &vegapb.DataSourceDefinitionExternal{ 1316 SourceType: &vegapb.DataSourceDefinitionExternal_Oracle{ 1317 Oracle: nil, 1318 }, 1319 }, 1320 }, 1321 }, 1322 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{ 1323 SourceType: &vegapb.DataSourceDefinition_External{ 1324 External: &vegapb.DataSourceDefinitionExternal{ 1325 SourceType: &vegapb.DataSourceDefinitionExternal_Oracle{ 1326 Oracle: nil, 1327 }, 1328 }, 1329 }, 1330 }, 1331 }, 1332 }, 1333 }, 1334 }, 1335 }, 1336 }, 1337 }, 1338 }) 1339 1340 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle"), commands.ErrIsRequired) 1341 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle"), commands.ErrIsRequired) 1342 } 1343 1344 func testNewFutureMarketChangeSubmissionWithEmptyInternalSpecTypeFails(t *testing.T) { 1345 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1346 Terms: &vegapb.ProposalTerms{ 1347 Change: &vegapb.ProposalTerms_NewMarket{ 1348 NewMarket: &vegapb.NewMarket{ 1349 Changes: &vegapb.NewMarketConfiguration{ 1350 Instrument: &vegapb.InstrumentConfiguration{ 1351 Product: &vegapb.InstrumentConfiguration_Future{ 1352 Future: &vegapb.FutureProduct{ 1353 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{ 1354 SourceType: &vegapb.DataSourceDefinition_Internal{ 1355 Internal: &vegapb.DataSourceDefinitionInternal{ 1356 SourceType: &vegapb.DataSourceDefinitionInternal_Time{ 1357 Time: nil, 1358 }, 1359 }, 1360 }, 1361 }, 1362 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{ 1363 SourceType: &vegapb.DataSourceDefinition_Internal{ 1364 Internal: &vegapb.DataSourceDefinitionInternal{ 1365 SourceType: &vegapb.DataSourceDefinitionInternal_Time{ 1366 Time: nil, 1367 }, 1368 }, 1369 }, 1370 }, 1371 }, 1372 }, 1373 }, 1374 }, 1375 }, 1376 }, 1377 }, 1378 }) 1379 1380 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 1381 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time"), commands.ErrIsRequired) 1382 } 1383 1384 func testNewFutureMarketChangeSubmissionWithoutPubKeysFails(t *testing.T) { 1385 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1386 Terms: &vegapb.ProposalTerms{ 1387 Change: &vegapb.ProposalTerms_NewMarket{ 1388 NewMarket: &vegapb.NewMarket{ 1389 Changes: &vegapb.NewMarketConfiguration{ 1390 Instrument: &vegapb.InstrumentConfiguration{ 1391 Product: &vegapb.InstrumentConfiguration_Future{ 1392 Future: &vegapb.FutureProduct{ 1393 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition(vegapb.DataSourceContentTypeOracle), 1394 }, 1395 }, 1396 }, 1397 }, 1398 }, 1399 }, 1400 }, 1401 }) 1402 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 1403 } 1404 1405 func testNewFutureMarketChangeSubmissionWithWrongPubKeysFails(t *testing.T) { 1406 pubKeys := []*dstypes.Signer{ 1407 dstypes.CreateSignerFromString("0xDEADBEEF", dstypes.SignerTypePubKey), 1408 dstypes.CreateSignerFromString("", dstypes.SignerTypePubKey), 1409 } 1410 1411 testCases := []struct { 1412 msg string 1413 value []*datapb.Signer 1414 }{ 1415 { 1416 msg: "with empty signers", 1417 value: dstypes.SignersIntoProto(pubKeys), 1418 }, { 1419 msg: "with blank signers", 1420 value: dstypes.SignersIntoProto(pubKeys), 1421 }, 1422 } 1423 for _, tc := range testCases { 1424 t.Run(tc.msg, func(t *testing.T) { 1425 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1426 Terms: &vegapb.ProposalTerms{ 1427 Change: &vegapb.ProposalTerms_NewMarket{ 1428 NewMarket: &vegapb.NewMarket{ 1429 Changes: &vegapb.NewMarketConfiguration{ 1430 Instrument: &vegapb.InstrumentConfiguration{ 1431 Product: &vegapb.InstrumentConfiguration_Future{ 1432 Future: &vegapb.FutureProduct{ 1433 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1434 vegapb.DataSourceContentTypeOracle, 1435 ).SetOracleConfig( 1436 &vegapb.DataSourceDefinitionExternal_Oracle{ 1437 Oracle: &vegapb.DataSourceSpecConfiguration{ 1438 Signers: tc.value, 1439 }, 1440 }, 1441 ), 1442 }, 1443 }, 1444 }, 1445 }, 1446 }, 1447 }, 1448 }, 1449 }) 1450 1451 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValid) 1452 }) 1453 } 1454 } 1455 1456 func testNewFutureMarketChangeSubmissionWithBadPubKeysOrderAddressFail(t *testing.T) { 1457 pubKeys := []*dstypes.Signer{ 1458 dstypes.CreateSignerFromString("0xDEADBEEF", dstypes.SignerTypePubKey), 1459 dstypes.CreateSignerFromString("0xCAFEDUDE", dstypes.SignerTypePubKey), 1460 dstypes.CreateSignerFromString("0xCAFEDUDE", dstypes.SignerTypeEthAddress), 1461 dstypes.CreateSignerFromString("36393436346533356263623865386132393030636130663837616361663235326435306366326162326663373336393438343561313662376338613064633666", dstypes.SignerTypePubKey), 1462 } 1463 1464 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1465 Terms: &vegapb.ProposalTerms{ 1466 Change: &vegapb.ProposalTerms_NewMarket{ 1467 NewMarket: &vegapb.NewMarket{ 1468 Changes: &vegapb.NewMarketConfiguration{ 1469 Instrument: &vegapb.InstrumentConfiguration{ 1470 Product: &vegapb.InstrumentConfiguration_Future{ 1471 Future: &vegapb.FutureProduct{ 1472 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1473 vegapb.DataSourceContentTypeOracle, 1474 ).SetOracleConfig( 1475 &vegapb.DataSourceDefinitionExternal_Oracle{ 1476 Oracle: &vegapb.DataSourceSpecConfiguration{ 1477 Signers: dstypes.SignersIntoProto(pubKeys), 1478 }, 1479 }, 1480 ), 1481 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1482 vegapb.DataSourceContentTypeOracle, 1483 ).SetOracleConfig( 1484 &vegapb.DataSourceDefinitionExternal_Oracle{ 1485 Oracle: &vegapb.DataSourceSpecConfiguration{ 1486 Signers: dstypes.SignersIntoProto(pubKeys), 1487 }, 1488 }, 1489 ), 1490 }, 1491 }, 1492 }, 1493 }, 1494 }, 1495 }, 1496 }, 1497 }) 1498 1499 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 1500 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 1501 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValid) 1502 1503 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.3"), commands.ErrIsNotValidVegaPubkey) 1504 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.2"), commands.ErrIsNotValidEthereumAddress) 1505 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValidVegaPubkey) 1506 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValidVegaPubkey) 1507 } 1508 1509 func testNewFutureMarketChangeSubmissionWithGoodPubKeysOrderAddressSucceed(t *testing.T) { 1510 pubKeys := []*dstypes.Signer{ 1511 dstypes.CreateSignerFromString("0x8565a19c49bcD6Fa7b6EB0221a50606F9c9cC683", dstypes.SignerTypeEthAddress), 1512 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 1513 } 1514 1515 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1516 Terms: &vegapb.ProposalTerms{ 1517 Change: &vegapb.ProposalTerms_NewMarket{ 1518 NewMarket: &vegapb.NewMarket{ 1519 Changes: &vegapb.NewMarketConfiguration{ 1520 Instrument: &vegapb.InstrumentConfiguration{ 1521 Product: &vegapb.InstrumentConfiguration_Future{ 1522 Future: &vegapb.FutureProduct{ 1523 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1524 vegapb.DataSourceContentTypeOracle, 1525 ).SetOracleConfig( 1526 &vegapb.DataSourceDefinitionExternal_Oracle{ 1527 Oracle: &vegapb.DataSourceSpecConfiguration{ 1528 Signers: dstypes.SignersIntoProto(pubKeys), 1529 }, 1530 }, 1531 ), 1532 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1533 vegapb.DataSourceContentTypeOracle, 1534 ).SetOracleConfig( 1535 &vegapb.DataSourceDefinitionExternal_Oracle{ 1536 Oracle: &vegapb.DataSourceSpecConfiguration{ 1537 Signers: dstypes.SignersIntoProto(pubKeys), 1538 }, 1539 }, 1540 ), 1541 }, 1542 }, 1543 }, 1544 }, 1545 }, 1546 }, 1547 }, 1548 }) 1549 1550 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 1551 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 1552 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValid) 1553 1554 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValidEthereumAddress) 1555 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValidVegaPubkey) 1556 } 1557 1558 func testNewFutureMarketChangeSubmissionWithoutFiltersFails(t *testing.T) { 1559 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1560 Terms: &vegapb.ProposalTerms{ 1561 Change: &vegapb.ProposalTerms_NewMarket{ 1562 NewMarket: &vegapb.NewMarket{ 1563 Changes: &vegapb.NewMarketConfiguration{ 1564 Instrument: &vegapb.InstrumentConfiguration{ 1565 Product: &vegapb.InstrumentConfiguration_Future{ 1566 Future: &vegapb.FutureProduct{ 1567 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1568 vegapb.DataSourceContentTypeOracle, 1569 ), 1570 }, 1571 }, 1572 }, 1573 }, 1574 }, 1575 }, 1576 }, 1577 }) 1578 1579 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters"), commands.ErrIsRequired) 1580 } 1581 1582 func testNewFutureMarketChangeSubmissionWithFiltersSucceeds(t *testing.T) { 1583 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1584 Terms: &vegapb.ProposalTerms{ 1585 Change: &vegapb.ProposalTerms_NewMarket{ 1586 NewMarket: &vegapb.NewMarket{ 1587 Changes: &vegapb.NewMarketConfiguration{ 1588 Instrument: &vegapb.InstrumentConfiguration{ 1589 Product: &vegapb.InstrumentConfiguration_Future{ 1590 Future: &vegapb.FutureProduct{ 1591 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1592 vegapb.DataSourceContentTypeOracle, 1593 ).SetOracleConfig( 1594 &vegapb.DataSourceDefinitionExternal_Oracle{ 1595 Oracle: &vegapb.DataSourceSpecConfiguration{ 1596 Filters: []*datapb.Filter{ 1597 {}, 1598 }, 1599 }, 1600 }, 1601 ), 1602 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1603 vegapb.DataSourceContentTypeOracle, 1604 ).SetOracleConfig( 1605 &vegapb.DataSourceDefinitionExternal_Oracle{ 1606 Oracle: &vegapb.DataSourceSpecConfiguration{ 1607 Filters: []*datapb.Filter{ 1608 {}, 1609 }, 1610 }, 1611 }, 1612 ), 1613 }, 1614 }, 1615 }, 1616 }, 1617 }, 1618 }, 1619 }, 1620 }) 1621 1622 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters"), commands.ErrIsRequired) 1623 } 1624 1625 func testNewFutureMarketChangeSubmissionWithFilterWithoutKeyFails(t *testing.T) { 1626 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1627 Terms: &vegapb.ProposalTerms{ 1628 Change: &vegapb.ProposalTerms_NewMarket{ 1629 NewMarket: &vegapb.NewMarket{ 1630 Changes: &vegapb.NewMarketConfiguration{ 1631 Instrument: &vegapb.InstrumentConfiguration{ 1632 Product: &vegapb.InstrumentConfiguration_Future{ 1633 Future: &vegapb.FutureProduct{ 1634 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1635 vegapb.DataSourceContentTypeOracle, 1636 ).SetOracleConfig( 1637 &vegapb.DataSourceDefinitionExternal_Oracle{ 1638 Oracle: &vegapb.DataSourceSpecConfiguration{ 1639 Filters: []*datapb.Filter{ 1640 {}, {}, 1641 }, 1642 }, 1643 }, 1644 ), 1645 }, 1646 }, 1647 }, 1648 }, 1649 }, 1650 }, 1651 }, 1652 }) 1653 1654 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key"), commands.ErrIsNotValid) 1655 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key"), commands.ErrIsNotValid) 1656 } 1657 1658 func testNewFutureMarketChangeSubmissionWithFilterWithKeySucceeds(t *testing.T) { 1659 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1660 Terms: &vegapb.ProposalTerms{ 1661 Change: &vegapb.ProposalTerms_NewMarket{ 1662 NewMarket: &vegapb.NewMarket{ 1663 Changes: &vegapb.NewMarketConfiguration{ 1664 Instrument: &vegapb.InstrumentConfiguration{ 1665 Product: &vegapb.InstrumentConfiguration_Future{ 1666 Future: &vegapb.FutureProduct{ 1667 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1668 vegapb.DataSourceContentTypeOracle, 1669 ).SetOracleConfig( 1670 &vegapb.DataSourceDefinitionExternal_Oracle{ 1671 Oracle: &vegapb.DataSourceSpecConfiguration{ 1672 Filters: []*datapb.Filter{ 1673 { 1674 Key: &datapb.PropertyKey{}, 1675 }, { 1676 Key: &datapb.PropertyKey{}, 1677 }, 1678 }, 1679 }, 1680 }, 1681 ), 1682 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1683 vegapb.DataSourceContentTypeOracle, 1684 ).SetOracleConfig( 1685 &vegapb.DataSourceDefinitionExternal_Oracle{ 1686 Oracle: &vegapb.DataSourceSpecConfiguration{ 1687 Filters: []*datapb.Filter{ 1688 { 1689 Key: &datapb.PropertyKey{}, 1690 }, { 1691 Key: &datapb.PropertyKey{}, 1692 }, 1693 }, 1694 }, 1695 }, 1696 ), 1697 }, 1698 }, 1699 }, 1700 }, 1701 }, 1702 }, 1703 }, 1704 }) 1705 1706 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key"), commands.ErrIsNotValid) 1707 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key"), commands.ErrIsNotValid) 1708 } 1709 1710 func testNewFutureMarketChangeSubmissionWithFilterWithoutKeyNameFails(t *testing.T) { 1711 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1712 Terms: &vegapb.ProposalTerms{ 1713 Change: &vegapb.ProposalTerms_NewMarket{ 1714 NewMarket: &vegapb.NewMarket{ 1715 Changes: &vegapb.NewMarketConfiguration{ 1716 Instrument: &vegapb.InstrumentConfiguration{ 1717 Product: &vegapb.InstrumentConfiguration_Future{ 1718 Future: &vegapb.FutureProduct{ 1719 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1720 vegapb.DataSourceContentTypeOracle, 1721 ).SetOracleConfig( 1722 &vegapb.DataSourceDefinitionExternal_Oracle{ 1723 Oracle: &vegapb.DataSourceSpecConfiguration{ 1724 Filters: []*datapb.Filter{ 1725 { 1726 Key: &datapb.PropertyKey{ 1727 Name: "", 1728 }, 1729 }, { 1730 Key: &datapb.PropertyKey{ 1731 Name: "", 1732 }, 1733 }, 1734 }, 1735 }, 1736 }, 1737 ), 1738 }, 1739 }, 1740 }, 1741 }, 1742 }, 1743 }, 1744 }, 1745 }) 1746 1747 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.name"), commands.ErrIsRequired) 1748 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.name"), commands.ErrIsRequired) 1749 } 1750 1751 func testNewFutureMarketChangeSubmissionWithFilterWithKeyNameSucceeds(t *testing.T) { 1752 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1753 Terms: &vegapb.ProposalTerms{ 1754 Change: &vegapb.ProposalTerms_NewMarket{ 1755 NewMarket: &vegapb.NewMarket{ 1756 Changes: &vegapb.NewMarketConfiguration{ 1757 Instrument: &vegapb.InstrumentConfiguration{ 1758 Product: &vegapb.InstrumentConfiguration_Future{ 1759 Future: &vegapb.FutureProduct{ 1760 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1761 vegapb.DataSourceContentTypeOracle, 1762 ).SetOracleConfig( 1763 &vegapb.DataSourceDefinitionExternal_Oracle{ 1764 Oracle: &vegapb.DataSourceSpecConfiguration{ 1765 Filters: []*datapb.Filter{ 1766 { 1767 Key: &datapb.PropertyKey{ 1768 Name: "key1", 1769 }, 1770 }, { 1771 Key: &datapb.PropertyKey{ 1772 Name: "key2", 1773 }, 1774 }, 1775 }, 1776 }, 1777 }, 1778 ), 1779 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1780 vegapb.DataSourceContentTypeOracle, 1781 ).SetOracleConfig( 1782 &vegapb.DataSourceDefinitionExternal_Oracle{ 1783 Oracle: &vegapb.DataSourceSpecConfiguration{ 1784 Filters: []*datapb.Filter{ 1785 { 1786 Key: &datapb.PropertyKey{ 1787 Name: "key1", 1788 }, 1789 }, { 1790 Key: &datapb.PropertyKey{ 1791 Name: "key2", 1792 }, 1793 }, 1794 }, 1795 }, 1796 }, 1797 ), 1798 }, 1799 }, 1800 }, 1801 }, 1802 }, 1803 }, 1804 }, 1805 }) 1806 1807 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.name"), commands.ErrIsRequired) 1808 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.name"), commands.ErrIsRequired) 1809 } 1810 1811 func testNewFutureMarketChangeSubmissionWithFilterWithoutKeyTypeFails(t *testing.T) { 1812 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1813 Terms: &vegapb.ProposalTerms{ 1814 Change: &vegapb.ProposalTerms_NewMarket{ 1815 NewMarket: &vegapb.NewMarket{ 1816 Changes: &vegapb.NewMarketConfiguration{ 1817 Instrument: &vegapb.InstrumentConfiguration{ 1818 Product: &vegapb.InstrumentConfiguration_Future{ 1819 Future: &vegapb.FutureProduct{ 1820 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1821 vegapb.DataSourceContentTypeOracle, 1822 ).SetOracleConfig( 1823 &vegapb.DataSourceDefinitionExternal_Oracle{ 1824 Oracle: &vegapb.DataSourceSpecConfiguration{ 1825 Filters: []*datapb.Filter{ 1826 { 1827 Key: &datapb.PropertyKey{ 1828 Type: datapb.PropertyKey_TYPE_UNSPECIFIED, 1829 }, 1830 }, { 1831 Key: &datapb.PropertyKey{}, 1832 }, 1833 }, 1834 }, 1835 }, 1836 ), 1837 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1838 vegapb.DataSourceContentTypeOracle, 1839 ).SetOracleConfig( 1840 &vegapb.DataSourceDefinitionExternal_Oracle{ 1841 Oracle: &vegapb.DataSourceSpecConfiguration{ 1842 Filters: []*datapb.Filter{ 1843 { 1844 Key: &datapb.PropertyKey{ 1845 Type: datapb.PropertyKey_TYPE_UNSPECIFIED, 1846 }, 1847 }, { 1848 Key: &datapb.PropertyKey{}, 1849 }, 1850 }, 1851 }, 1852 }, 1853 ), 1854 }, 1855 }, 1856 }, 1857 }, 1858 }, 1859 }, 1860 }, 1861 }) 1862 1863 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.type"), commands.ErrIsRequired) 1864 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.type"), commands.ErrIsRequired) 1865 } 1866 1867 func testNewFutureMarketChangeSubmissionWithFilterWithKeyTypeSucceeds(t *testing.T) { 1868 testCases := []struct { 1869 msg string 1870 value datapb.PropertyKey_Type 1871 }{ 1872 { 1873 msg: "with EMPTY", 1874 value: datapb.PropertyKey_TYPE_EMPTY, 1875 }, { 1876 msg: "with INTEGER", 1877 value: datapb.PropertyKey_TYPE_INTEGER, 1878 }, { 1879 msg: "with STRING", 1880 value: datapb.PropertyKey_TYPE_STRING, 1881 }, { 1882 msg: "with BOOLEAN", 1883 value: datapb.PropertyKey_TYPE_BOOLEAN, 1884 }, { 1885 msg: "with DECIMAL", 1886 value: datapb.PropertyKey_TYPE_DECIMAL, 1887 }, { 1888 msg: "with TIMESTAMP", 1889 value: datapb.PropertyKey_TYPE_TIMESTAMP, 1890 }, 1891 } 1892 for _, tc := range testCases { 1893 t.Run(tc.msg, func(t *testing.T) { 1894 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1895 Terms: &vegapb.ProposalTerms{ 1896 Change: &vegapb.ProposalTerms_NewMarket{ 1897 NewMarket: &vegapb.NewMarket{ 1898 Changes: &vegapb.NewMarketConfiguration{ 1899 Instrument: &vegapb.InstrumentConfiguration{ 1900 Product: &vegapb.InstrumentConfiguration_Future{ 1901 Future: &vegapb.FutureProduct{ 1902 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1903 vegapb.DataSourceContentTypeOracle, 1904 ).SetOracleConfig( 1905 &vegapb.DataSourceDefinitionExternal_Oracle{ 1906 Oracle: &vegapb.DataSourceSpecConfiguration{ 1907 Filters: []*datapb.Filter{ 1908 { 1909 Key: &datapb.PropertyKey{ 1910 Type: tc.value, 1911 }, 1912 }, { 1913 Key: &datapb.PropertyKey{ 1914 Type: tc.value, 1915 }, 1916 }, 1917 }, 1918 }, 1919 }, 1920 ), 1921 }, 1922 }, 1923 }, 1924 }, 1925 }, 1926 }, 1927 }, 1928 }) 1929 1930 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.key.type"), commands.ErrIsRequired) 1931 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.1.key.type"), commands.ErrIsRequired) 1932 }) 1933 } 1934 } 1935 1936 func testNewFutureMarketChangeSubmissionWithFilterWithoutConditionsSucceeds(t *testing.T) { 1937 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1938 Terms: &vegapb.ProposalTerms{ 1939 Change: &vegapb.ProposalTerms_NewMarket{ 1940 NewMarket: &vegapb.NewMarket{ 1941 Changes: &vegapb.NewMarketConfiguration{ 1942 Instrument: &vegapb.InstrumentConfiguration{ 1943 Product: &vegapb.InstrumentConfiguration_Future{ 1944 Future: &vegapb.FutureProduct{ 1945 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1946 vegapb.DataSourceContentTypeOracle, 1947 ).SetOracleConfig( 1948 &vegapb.DataSourceDefinitionExternal_Oracle{ 1949 Oracle: &vegapb.DataSourceSpecConfiguration{ 1950 Filters: []*datapb.Filter{ 1951 { 1952 Conditions: []*datapb.Condition{}, 1953 }, 1954 }, 1955 }, 1956 }, 1957 ), 1958 }, 1959 }, 1960 }, 1961 }, 1962 }, 1963 }, 1964 }, 1965 }) 1966 1967 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions"), commands.ErrIsRequired) 1968 } 1969 1970 func testNewFutureMarketChangeSubmissionWithFilterWithoutConditionOperatorFails(t *testing.T) { 1971 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1972 Terms: &vegapb.ProposalTerms{ 1973 Change: &vegapb.ProposalTerms_NewMarket{ 1974 NewMarket: &vegapb.NewMarket{ 1975 Changes: &vegapb.NewMarketConfiguration{ 1976 Instrument: &vegapb.InstrumentConfiguration{ 1977 Product: &vegapb.InstrumentConfiguration_Future{ 1978 Future: &vegapb.FutureProduct{ 1979 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1980 vegapb.DataSourceContentTypeOracle, 1981 ).SetOracleConfig( 1982 &vegapb.DataSourceDefinitionExternal_Oracle{ 1983 Oracle: &vegapb.DataSourceSpecConfiguration{ 1984 Filters: []*datapb.Filter{ 1985 { 1986 Conditions: []*datapb.Condition{ 1987 { 1988 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 1989 }, 1990 {}, 1991 }, 1992 }, 1993 }, 1994 }, 1995 }, 1996 ), 1997 }, 1998 }, 1999 }, 2000 }, 2001 }, 2002 }, 2003 }, 2004 }) 2005 2006 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 2007 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.1.operator"), commands.ErrIsRequired) 2008 } 2009 2010 func testNewFutureMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds(t *testing.T) { 2011 testCases := []struct { 2012 msg string 2013 value datapb.Condition_Operator 2014 }{ 2015 { 2016 msg: "with EQUALS", 2017 value: datapb.Condition_OPERATOR_EQUALS, 2018 }, { 2019 msg: "with GREATER_THAN", 2020 value: datapb.Condition_OPERATOR_GREATER_THAN, 2021 }, { 2022 msg: "with GREATER_THAN_OR_EQUAL", 2023 value: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 2024 }, { 2025 msg: "with LESS_THAN", 2026 value: datapb.Condition_OPERATOR_LESS_THAN, 2027 }, { 2028 msg: "with LESS_THAN_OR_EQUAL", 2029 value: datapb.Condition_OPERATOR_LESS_THAN_OR_EQUAL, 2030 }, 2031 } 2032 for _, tc := range testCases { 2033 t.Run(tc.msg, func(t *testing.T) { 2034 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2035 Terms: &vegapb.ProposalTerms{ 2036 Change: &vegapb.ProposalTerms_NewMarket{ 2037 NewMarket: &vegapb.NewMarket{ 2038 Changes: &vegapb.NewMarketConfiguration{ 2039 Instrument: &vegapb.InstrumentConfiguration{ 2040 Product: &vegapb.InstrumentConfiguration_Future{ 2041 Future: &vegapb.FutureProduct{ 2042 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2043 vegapb.DataSourceContentTypeOracle, 2044 ).SetOracleConfig( 2045 &vegapb.DataSourceDefinitionExternal_Oracle{ 2046 Oracle: &vegapb.DataSourceSpecConfiguration{ 2047 Filters: []*datapb.Filter{ 2048 { 2049 Conditions: []*datapb.Condition{ 2050 { 2051 Operator: tc.value, 2052 }, 2053 { 2054 Operator: tc.value, 2055 }, 2056 }, 2057 }, 2058 }, 2059 }, 2060 }, 2061 ), 2062 }, 2063 }, 2064 }, 2065 }, 2066 }, 2067 }, 2068 }, 2069 }) 2070 2071 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 2072 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.1.conditions.0.operator"), commands.ErrIsRequired) 2073 }) 2074 } 2075 } 2076 2077 func testNewFutureMarketChangeSubmissionWithFilterWithoutConditionValueFails(t *testing.T) { 2078 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2079 Terms: &vegapb.ProposalTerms{ 2080 Change: &vegapb.ProposalTerms_NewMarket{ 2081 NewMarket: &vegapb.NewMarket{ 2082 Changes: &vegapb.NewMarketConfiguration{ 2083 Instrument: &vegapb.InstrumentConfiguration{ 2084 Product: &vegapb.InstrumentConfiguration_Future{ 2085 Future: &vegapb.FutureProduct{ 2086 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2087 vegapb.DataSourceContentTypeOracle, 2088 ).SetOracleConfig( 2089 &vegapb.DataSourceDefinitionExternal_Oracle{ 2090 Oracle: &vegapb.DataSourceSpecConfiguration{ 2091 Filters: []*datapb.Filter{ 2092 { 2093 Conditions: []*datapb.Condition{ 2094 { 2095 Value: "", 2096 }, 2097 { 2098 Value: "", 2099 }, 2100 }, 2101 }, 2102 }, 2103 }, 2104 }, 2105 ), 2106 }, 2107 }, 2108 }, 2109 }, 2110 }, 2111 }, 2112 }, 2113 }) 2114 2115 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 2116 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 2117 } 2118 2119 func testNewFutureMarketChangeSubmissionWithFilterWithConditionValueSucceeds(t *testing.T) { 2120 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2121 Terms: &vegapb.ProposalTerms{ 2122 Change: &vegapb.ProposalTerms_NewMarket{ 2123 NewMarket: &vegapb.NewMarket{ 2124 Changes: &vegapb.NewMarketConfiguration{ 2125 Instrument: &vegapb.InstrumentConfiguration{ 2126 Product: &vegapb.InstrumentConfiguration_Future{ 2127 Future: &vegapb.FutureProduct{ 2128 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2129 vegapb.DataSourceContentTypeOracle, 2130 ).SetOracleConfig( 2131 &vegapb.DataSourceDefinitionExternal_Oracle{ 2132 Oracle: &vegapb.DataSourceSpecConfiguration{ 2133 Filters: []*datapb.Filter{ 2134 { 2135 Conditions: []*datapb.Condition{ 2136 { 2137 Value: "value 1", 2138 }, 2139 { 2140 Value: "value 2", 2141 }, 2142 }, 2143 }, 2144 }, 2145 }, 2146 }, 2147 ), 2148 }, 2149 }, 2150 }, 2151 }, 2152 }, 2153 }, 2154 }, 2155 }) 2156 2157 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 2158 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 2159 } 2160 2161 func testNewFutureMarketChangeSubmissionWithoutDataSourceSpecBindingFails(t *testing.T) { 2162 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2163 Terms: &vegapb.ProposalTerms{ 2164 Change: &vegapb.ProposalTerms_NewMarket{ 2165 NewMarket: &vegapb.NewMarket{ 2166 Changes: &vegapb.NewMarketConfiguration{ 2167 Instrument: &vegapb.InstrumentConfiguration{ 2168 Product: &vegapb.InstrumentConfiguration_Future{ 2169 Future: &vegapb.FutureProduct{}, 2170 }, 2171 }, 2172 }, 2173 }, 2174 }, 2175 }, 2176 }) 2177 2178 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding"), commands.ErrIsRequired) 2179 } 2180 2181 func testNewFutureMarketChangeSubmissionWithDataSourceSpecBindingSucceeds(t *testing.T) { 2182 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2183 Terms: &vegapb.ProposalTerms{ 2184 Change: &vegapb.ProposalTerms_NewMarket{ 2185 NewMarket: &vegapb.NewMarket{ 2186 Changes: &vegapb.NewMarketConfiguration{ 2187 Instrument: &vegapb.InstrumentConfiguration{ 2188 Product: &vegapb.InstrumentConfiguration_Future{ 2189 Future: &vegapb.FutureProduct{ 2190 DataSourceSpecBinding: &vegapb.DataSourceSpecToFutureBinding{}, 2191 }, 2192 }, 2193 }, 2194 }, 2195 }, 2196 }, 2197 }, 2198 }) 2199 2200 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding"), commands.ErrIsRequired) 2201 } 2202 2203 func testNewFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t *testing.T, property string) { 2204 t.Helper() 2205 var binding *vegapb.DataSourceSpecToFutureBinding 2206 if property == "settlement_data_property" { 2207 binding = &vegapb.DataSourceSpecToFutureBinding{ 2208 SettlementDataProperty: "", 2209 } 2210 } else { 2211 binding = &vegapb.DataSourceSpecToFutureBinding{ 2212 TradingTerminationProperty: "", 2213 } 2214 } 2215 2216 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2217 Terms: &vegapb.ProposalTerms{ 2218 Change: &vegapb.ProposalTerms_NewMarket{ 2219 NewMarket: &vegapb.NewMarket{ 2220 Changes: &vegapb.NewMarketConfiguration{ 2221 Instrument: &vegapb.InstrumentConfiguration{ 2222 Product: &vegapb.InstrumentConfiguration_Future{ 2223 Future: &vegapb.FutureProduct{ 2224 DataSourceSpecBinding: binding, 2225 }, 2226 }, 2227 }, 2228 }, 2229 }, 2230 }, 2231 }, 2232 }) 2233 2234 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding."+property), commands.ErrIsRequired) 2235 } 2236 2237 func testNewFutureMarketChangeSubmissionWithoutTradingTerminationPropertyFails(t *testing.T) { 2238 testNewFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t, "trading_termination_property") 2239 } 2240 2241 func testNewFutureMarketChangeSubmissionWithoutSettlementDataPropertyFails(t *testing.T) { 2242 testNewFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t, "settlement_data_property") 2243 } 2244 2245 func testNewFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds(t *testing.T) { 2246 testNewFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t, &vegapb.DataSourceSpecToFutureBinding{SettlementDataProperty: "key1"}, "settlement_data_property", "key1") 2247 testNewFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t, &vegapb.DataSourceSpecToFutureBinding{TradingTerminationProperty: "key2"}, "settlement_data_property", "key2") 2248 } 2249 2250 func testNewFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t *testing.T, binding *vegapb.DataSourceSpecToFutureBinding, bindingName string, bindingKey string) { 2251 t.Helper() 2252 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2253 Terms: &vegapb.ProposalTerms{ 2254 Change: &vegapb.ProposalTerms_NewMarket{ 2255 NewMarket: &vegapb.NewMarket{ 2256 Changes: &vegapb.NewMarketConfiguration{ 2257 Instrument: &vegapb.InstrumentConfiguration{ 2258 Product: &vegapb.InstrumentConfiguration_Future{ 2259 Future: &vegapb.FutureProduct{ 2260 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2261 vegapb.DataSourceContentTypeOracle, 2262 ).SetOracleConfig( 2263 &vegapb.DataSourceDefinitionExternal_Oracle{ 2264 Oracle: &vegapb.DataSourceSpecConfiguration{ 2265 Filters: []*datapb.Filter{ 2266 { 2267 Key: &datapb.PropertyKey{ 2268 Name: bindingKey, 2269 }, 2270 }, { 2271 Key: &datapb.PropertyKey{}, 2272 }, 2273 }, 2274 }, 2275 }, 2276 ), 2277 DataSourceSpecBinding: binding, 2278 }, 2279 }, 2280 }, 2281 }, 2282 }, 2283 }, 2284 }, 2285 }) 2286 2287 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 2288 } 2289 2290 func testNewFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t *testing.T, binding *vegapb.DataSourceSpecToFutureBinding, bindingName string) { 2291 t.Helper() 2292 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2293 Terms: &vegapb.ProposalTerms{ 2294 Change: &vegapb.ProposalTerms_NewMarket{ 2295 NewMarket: &vegapb.NewMarket{ 2296 Changes: &vegapb.NewMarketConfiguration{ 2297 Instrument: &vegapb.InstrumentConfiguration{ 2298 Product: &vegapb.InstrumentConfiguration_Future{ 2299 Future: &vegapb.FutureProduct{ 2300 DataSourceSpecBinding: binding, 2301 }, 2302 }, 2303 }, 2304 }, 2305 }, 2306 }, 2307 }, 2308 }) 2309 2310 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 2311 } 2312 2313 func testNewFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails(t *testing.T) { 2314 testNewFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t, &vegapb.DataSourceSpecToFutureBinding{SettlementDataProperty: "My property"}, "settlement_data_property") 2315 testNewFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t, &vegapb.DataSourceSpecToFutureBinding{TradingTerminationProperty: "My property"}, "trading_termination_property") 2316 } 2317 2318 func testNewFutureMarketChangeSubmissionWithSettlementDataPropertySucceeds(t *testing.T) { 2319 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2320 Terms: &vegapb.ProposalTerms{ 2321 Change: &vegapb.ProposalTerms_NewMarket{ 2322 NewMarket: &vegapb.NewMarket{ 2323 Changes: &vegapb.NewMarketConfiguration{ 2324 Instrument: &vegapb.InstrumentConfiguration{ 2325 Product: &vegapb.InstrumentConfiguration_Future{ 2326 Future: &vegapb.FutureProduct{ 2327 DataSourceSpecBinding: &vegapb.DataSourceSpecToFutureBinding{ 2328 SettlementDataProperty: "My property", 2329 }, 2330 }, 2331 }, 2332 }, 2333 }, 2334 }, 2335 }, 2336 }, 2337 }) 2338 2339 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_binding.settlement_data_property"), commands.ErrIsRequired) 2340 } 2341 2342 func testNewSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails(t *testing.T) { 2343 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2344 Terms: &vegapb.ProposalTerms{ 2345 Change: &vegapb.ProposalTerms_NewMarket{ 2346 NewMarket: &vegapb.NewMarket{ 2347 Changes: &vegapb.NewMarketConfiguration{ 2348 RiskParameters: &vegapb.NewMarketConfiguration_Simple{}, 2349 }, 2350 }, 2351 }, 2352 }, 2353 }) 2354 2355 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple"), commands.ErrIsRequired) 2356 } 2357 2358 func testNewSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds(t *testing.T) { 2359 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2360 Terms: &vegapb.ProposalTerms{ 2361 Change: &vegapb.ProposalTerms_NewMarket{ 2362 NewMarket: &vegapb.NewMarket{ 2363 Changes: &vegapb.NewMarketConfiguration{ 2364 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2365 Simple: &vegapb.SimpleModelParams{}, 2366 }, 2367 }, 2368 }, 2369 }, 2370 }, 2371 }) 2372 2373 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple"), commands.ErrIsRequired) 2374 } 2375 2376 func testNewSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails(t *testing.T) { 2377 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2378 Terms: &vegapb.ProposalTerms{ 2379 Change: &vegapb.ProposalTerms_NewMarket{ 2380 NewMarket: &vegapb.NewMarket{ 2381 Changes: &vegapb.NewMarketConfiguration{ 2382 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2383 Simple: &vegapb.SimpleModelParams{ 2384 MinMoveDown: 1, 2385 }, 2386 }, 2387 }, 2388 }, 2389 }, 2390 }, 2391 }) 2392 2393 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero) 2394 } 2395 2396 func testNewSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds(t *testing.T) { 2397 testCases := []struct { 2398 msg string 2399 value float64 2400 }{ 2401 { 2402 msg: "with min move down of 0", 2403 value: 0, 2404 }, { 2405 msg: "with min move down of -1", 2406 value: -1, 2407 }, 2408 } 2409 for _, tc := range testCases { 2410 t.Run(tc.msg, func(t *testing.T) { 2411 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2412 Terms: &vegapb.ProposalTerms{ 2413 Change: &vegapb.ProposalTerms_NewMarket{ 2414 NewMarket: &vegapb.NewMarket{ 2415 Changes: &vegapb.NewMarketConfiguration{ 2416 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2417 Simple: &vegapb.SimpleModelParams{ 2418 MinMoveDown: tc.value, 2419 }, 2420 }, 2421 }, 2422 }, 2423 }, 2424 }, 2425 }) 2426 2427 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero) 2428 }) 2429 } 2430 } 2431 2432 func testNewSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds(t *testing.T) { 2433 testCases := []struct { 2434 msg string 2435 value float64 2436 }{ 2437 { 2438 msg: "with max move up of 0", 2439 value: 0, 2440 }, { 2441 msg: "with max move up of 1", 2442 value: 1, 2443 }, 2444 } 2445 for _, tc := range testCases { 2446 t.Run(tc.msg, func(t *testing.T) { 2447 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2448 Terms: &vegapb.ProposalTerms{ 2449 Change: &vegapb.ProposalTerms_NewMarket{ 2450 NewMarket: &vegapb.NewMarket{ 2451 Changes: &vegapb.NewMarketConfiguration{ 2452 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2453 Simple: &vegapb.SimpleModelParams{ 2454 MaxMoveUp: tc.value, 2455 }, 2456 }, 2457 }, 2458 }, 2459 }, 2460 }, 2461 }) 2462 2463 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero) 2464 }) 2465 } 2466 } 2467 2468 func testNewSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails(t *testing.T) { 2469 testCases := []struct { 2470 msg string 2471 value float64 2472 }{ 2473 { 2474 msg: "with probability of trading of -1", 2475 value: -1, 2476 }, { 2477 msg: "with probability of trading of 2", 2478 value: 2, 2479 }, 2480 } 2481 for _, tc := range testCases { 2482 t.Run(tc.msg, func(t *testing.T) { 2483 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2484 Terms: &vegapb.ProposalTerms{ 2485 Change: &vegapb.ProposalTerms_NewMarket{ 2486 NewMarket: &vegapb.NewMarket{ 2487 Changes: &vegapb.NewMarketConfiguration{ 2488 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2489 Simple: &vegapb.SimpleModelParams{ 2490 ProbabilityOfTrading: tc.value, 2491 }, 2492 }, 2493 }, 2494 }, 2495 }, 2496 }, 2497 }) 2498 2499 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.probability_of_trading"), 2500 errors.New("should be between 0 (inclusive) and 1 (inclusive)")) 2501 }) 2502 } 2503 } 2504 2505 func testNewSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds(t *testing.T) { 2506 testCases := []struct { 2507 msg string 2508 value float64 2509 }{ 2510 { 2511 msg: "with probability of trading of 0", 2512 value: 0, 2513 }, { 2514 msg: "with probability of trading of 1", 2515 value: 1, 2516 }, { 2517 msg: "with probability of trading of 0.5", 2518 value: 0.5, 2519 }, 2520 } 2521 for _, tc := range testCases { 2522 t.Run(tc.msg, func(t *testing.T) { 2523 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2524 Terms: &vegapb.ProposalTerms{ 2525 Change: &vegapb.ProposalTerms_NewMarket{ 2526 NewMarket: &vegapb.NewMarket{ 2527 Changes: &vegapb.NewMarketConfiguration{ 2528 RiskParameters: &vegapb.NewMarketConfiguration_Simple{ 2529 Simple: &vegapb.SimpleModelParams{ 2530 ProbabilityOfTrading: tc.value, 2531 }, 2532 }, 2533 }, 2534 }, 2535 }, 2536 }, 2537 }) 2538 2539 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.probability_of_trading"), 2540 errors.New("should be between 0 (inclusive) and 1 (inclusive)")) 2541 }) 2542 } 2543 } 2544 2545 func testNewLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails(t *testing.T) { 2546 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2547 Terms: &vegapb.ProposalTerms{ 2548 Change: &vegapb.ProposalTerms_NewMarket{ 2549 NewMarket: &vegapb.NewMarket{ 2550 Changes: &vegapb.NewMarketConfiguration{ 2551 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{}, 2552 }, 2553 }, 2554 }, 2555 }, 2556 }) 2557 2558 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired) 2559 } 2560 2561 func testNewLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds(t *testing.T) { 2562 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2563 Terms: &vegapb.ProposalTerms{ 2564 Change: &vegapb.ProposalTerms_NewMarket{ 2565 NewMarket: &vegapb.NewMarket{ 2566 Changes: &vegapb.NewMarketConfiguration{ 2567 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2568 LogNormal: &vegapb.LogNormalRiskModel{ 2569 RiskAversionParameter: 1, 2570 Tau: 2, 2571 Params: &vegapb.LogNormalModelParams{ 2572 Mu: 0, 2573 Sigma: 0.1, 2574 R: 0, 2575 }, 2576 }, 2577 }, 2578 }, 2579 }, 2580 }, 2581 }, 2582 }) 2583 2584 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired) 2585 } 2586 2587 func testNewLogNormalRiskParametersChangeSubmissionWithOverrides(t *testing.T) { 2588 cases := []struct { 2589 desc string 2590 get string 2591 override *vegapb.RiskFactorOverride 2592 err string 2593 }{ 2594 { 2595 desc: "no override is valid", 2596 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override", 2597 override: nil, 2598 err: "", 2599 }, 2600 { 2601 desc: "non nil, but with empty short", 2602 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2603 override: &vegapb.RiskFactorOverride{}, 2604 err: "is required", 2605 }, 2606 { 2607 desc: "non nil, but with bad value short", 2608 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2609 override: &vegapb.RiskFactorOverride{ 2610 Short: "asd", 2611 }, 2612 err: "is not a valid number", 2613 }, 2614 { 2615 desc: "non nil, but with negative short", 2616 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2617 override: &vegapb.RiskFactorOverride{ 2618 Short: "-1", 2619 }, 2620 err: "must be positive", 2621 }, 2622 { 2623 desc: "non nil, but with 0 short", 2624 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2625 override: &vegapb.RiskFactorOverride{ 2626 Short: "0", 2627 }, 2628 err: "must be positive", 2629 }, 2630 { 2631 desc: "non nil, but with empty long", 2632 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2633 override: &vegapb.RiskFactorOverride{ 2634 Short: "0.1", 2635 }, 2636 err: "is required", 2637 }, 2638 { 2639 desc: "non nil, but with bad value long", 2640 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2641 override: &vegapb.RiskFactorOverride{ 2642 Short: "0.1", 2643 Long: "asd", 2644 }, 2645 err: "is not a valid number", 2646 }, 2647 { 2648 desc: "non nil, but with negative long", 2649 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2650 override: &vegapb.RiskFactorOverride{ 2651 Short: "0.1", 2652 Long: "-1", 2653 }, 2654 err: "must be positive", 2655 }, 2656 { 2657 desc: "non nil, but with 0 long", 2658 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2659 override: &vegapb.RiskFactorOverride{ 2660 Short: "0.1", 2661 Long: "0", 2662 }, 2663 err: "must be positive", 2664 }, 2665 { 2666 desc: "both valid", 2667 get: "proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_factor_override", 2668 override: &vegapb.RiskFactorOverride{ 2669 Short: "0.1", 2670 Long: "0.1", 2671 }, 2672 err: "", 2673 }, 2674 } 2675 2676 for _, c := range cases { 2677 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2678 Terms: &vegapb.ProposalTerms{ 2679 Change: &vegapb.ProposalTerms_NewMarket{ 2680 NewMarket: &vegapb.NewMarket{ 2681 Changes: &vegapb.NewMarketConfiguration{ 2682 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2683 LogNormal: &vegapb.LogNormalRiskModel{ 2684 RiskAversionParameter: 0.1, 2685 Tau: 1, 2686 Params: &vegapb.LogNormalModelParams{ 2687 Mu: 0, 2688 Sigma: 0.1, 2689 R: 0, 2690 }, 2691 RiskFactorOverride: c.override, 2692 }, 2693 }, 2694 }, 2695 }, 2696 }, 2697 }, 2698 }) 2699 2700 if len(c.err) <= 0 { 2701 // no error 2702 assert.Len(t, err.Get(c.get), 0, c.desc) 2703 continue 2704 } 2705 2706 assert.Contains(t, err.Get(c.get), errors.New(c.err), "test: %v, err: %v", c.desc, err) 2707 } 2708 } 2709 2710 func testNewLogNormalRiskParametersChangeSubmissionWithoutParamsFails(t *testing.T) { 2711 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2712 Terms: &vegapb.ProposalTerms{ 2713 Change: &vegapb.ProposalTerms_NewMarket{ 2714 NewMarket: &vegapb.NewMarket{ 2715 Changes: &vegapb.NewMarketConfiguration{ 2716 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2717 LogNormal: &vegapb.LogNormalRiskModel{}, 2718 }, 2719 }, 2720 }, 2721 }, 2722 }, 2723 }) 2724 2725 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params"), commands.ErrIsRequired) 2726 } 2727 2728 func testNewLogNormalRiskParametersChangeSubmissionInvalidRiskAversion(t *testing.T) { 2729 cTooSmall := &commandspb.ProposalSubmission{ 2730 Terms: &vegapb.ProposalTerms{ 2731 Change: &vegapb.ProposalTerms_NewMarket{ 2732 NewMarket: &vegapb.NewMarket{ 2733 Changes: &vegapb.NewMarketConfiguration{ 2734 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2735 LogNormal: &vegapb.LogNormalRiskModel{ 2736 RiskAversionParameter: 5e-9, 2737 Tau: 1.0, 2738 Params: &vegapb.LogNormalModelParams{ 2739 Mu: 0.0, 2740 Sigma: 0.1, 2741 R: 0, 2742 }, 2743 }, 2744 }, 2745 }, 2746 }, 2747 }, 2748 }, 2749 } 2750 err := checkProposalSubmission(cTooSmall) 2751 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]")) 2752 2753 cNeg := &commandspb.ProposalSubmission{ 2754 Terms: &vegapb.ProposalTerms{ 2755 Change: &vegapb.ProposalTerms_NewMarket{ 2756 NewMarket: &vegapb.NewMarket{ 2757 Changes: &vegapb.NewMarketConfiguration{ 2758 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2759 LogNormal: &vegapb.LogNormalRiskModel{ 2760 RiskAversionParameter: 1e-9, 2761 Tau: 2, 2762 Params: &vegapb.LogNormalModelParams{ 2763 Mu: 0, 2764 Sigma: 0.1, 2765 R: 0, 2766 }, 2767 }, 2768 }, 2769 }, 2770 }, 2771 }, 2772 }, 2773 } 2774 err = checkProposalSubmission(cNeg) 2775 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]")) 2776 2777 cTooBig := &commandspb.ProposalSubmission{ 2778 Terms: &vegapb.ProposalTerms{ 2779 Change: &vegapb.ProposalTerms_NewMarket{ 2780 NewMarket: &vegapb.NewMarket{ 2781 Changes: &vegapb.NewMarketConfiguration{ 2782 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2783 LogNormal: &vegapb.LogNormalRiskModel{ 2784 RiskAversionParameter: 0.1 + 1e-8, 2785 Tau: 2, 2786 Params: &vegapb.LogNormalModelParams{ 2787 Mu: 0, 2788 Sigma: 0.1, 2789 R: 0, 2790 }, 2791 }, 2792 }, 2793 }, 2794 }, 2795 }, 2796 }, 2797 } 2798 err = checkProposalSubmission(cTooBig) 2799 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]")) 2800 2801 cJustAboutRight1 := &commandspb.ProposalSubmission{ 2802 Terms: &vegapb.ProposalTerms{ 2803 Change: &vegapb.ProposalTerms_NewMarket{ 2804 NewMarket: &vegapb.NewMarket{ 2805 Changes: &vegapb.NewMarketConfiguration{ 2806 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2807 LogNormal: &vegapb.LogNormalRiskModel{ 2808 RiskAversionParameter: 1e-8, 2809 Tau: 2, 2810 Params: &vegapb.LogNormalModelParams{ 2811 Mu: 0, 2812 Sigma: 0.1, 2813 R: 0, 2814 }, 2815 }, 2816 }, 2817 }, 2818 }, 2819 }, 2820 }, 2821 } 2822 err = checkProposalSubmission(cJustAboutRight1) 2823 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 1)")) 2824 2825 cJustAboutRight2 := &commandspb.ProposalSubmission{ 2826 Terms: &vegapb.ProposalTerms{ 2827 Change: &vegapb.ProposalTerms_NewMarket{ 2828 NewMarket: &vegapb.NewMarket{ 2829 Changes: &vegapb.NewMarketConfiguration{ 2830 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2831 LogNormal: &vegapb.LogNormalRiskModel{ 2832 RiskAversionParameter: 1 - 1e-12, 2833 Tau: 2, 2834 Params: &vegapb.LogNormalModelParams{ 2835 Mu: 0, 2836 Sigma: 0.1, 2837 R: 0, 2838 }, 2839 }, 2840 }, 2841 }, 2842 }, 2843 }, 2844 }, 2845 } 2846 err = checkProposalSubmission(cJustAboutRight2) 2847 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 1)")) 2848 } 2849 2850 func testNewLogNormalRiskParametersChangeSubmissionInvalidTau(t *testing.T) { 2851 cZero := &commandspb.ProposalSubmission{ 2852 Terms: &vegapb.ProposalTerms{ 2853 Change: &vegapb.ProposalTerms_NewMarket{ 2854 NewMarket: &vegapb.NewMarket{ 2855 Changes: &vegapb.NewMarketConfiguration{ 2856 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2857 LogNormal: &vegapb.LogNormalRiskModel{ 2858 RiskAversionParameter: 0.1, 2859 Tau: 0, 2860 Params: &vegapb.LogNormalModelParams{ 2861 Mu: 0, 2862 Sigma: 0.1, 2863 R: 0, 2864 }, 2865 }, 2866 }, 2867 }, 2868 }, 2869 }, 2870 }, 2871 } 2872 err := checkProposalSubmission(cZero) 2873 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]")) 2874 2875 cNeg := &commandspb.ProposalSubmission{ 2876 Terms: &vegapb.ProposalTerms{ 2877 Change: &vegapb.ProposalTerms_NewMarket{ 2878 NewMarket: &vegapb.NewMarket{ 2879 Changes: &vegapb.NewMarketConfiguration{ 2880 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2881 LogNormal: &vegapb.LogNormalRiskModel{ 2882 RiskAversionParameter: 0.1, 2883 Tau: 1e-9, 2884 Params: &vegapb.LogNormalModelParams{ 2885 Mu: 0, 2886 Sigma: 0.1, 2887 R: 0, 2888 }, 2889 }, 2890 }, 2891 }, 2892 }, 2893 }, 2894 }, 2895 } 2896 err = checkProposalSubmission(cNeg) 2897 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]")) 2898 2899 cTooLarge := &commandspb.ProposalSubmission{ 2900 Terms: &vegapb.ProposalTerms{ 2901 Change: &vegapb.ProposalTerms_NewMarket{ 2902 NewMarket: &vegapb.NewMarket{ 2903 Changes: &vegapb.NewMarketConfiguration{ 2904 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2905 LogNormal: &vegapb.LogNormalRiskModel{ 2906 RiskAversionParameter: 0.1, 2907 Tau: 1 + 1e-12, 2908 Params: &vegapb.LogNormalModelParams{ 2909 Mu: 0, 2910 Sigma: 0.1, 2911 R: 0, 2912 }, 2913 }, 2914 }, 2915 }, 2916 }, 2917 }, 2918 }, 2919 } 2920 err = checkProposalSubmission(cTooLarge) 2921 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]")) 2922 2923 cJustAboutRight1 := &commandspb.ProposalSubmission{ 2924 Terms: &vegapb.ProposalTerms{ 2925 Change: &vegapb.ProposalTerms_NewMarket{ 2926 NewMarket: &vegapb.NewMarket{ 2927 Changes: &vegapb.NewMarketConfiguration{ 2928 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2929 LogNormal: &vegapb.LogNormalRiskModel{ 2930 RiskAversionParameter: 0.1, 2931 Tau: 1e-12, 2932 Params: &vegapb.LogNormalModelParams{ 2933 Mu: 0, 2934 Sigma: 0.1, 2935 R: 0, 2936 }, 2937 }, 2938 }, 2939 }, 2940 }, 2941 }, 2942 }, 2943 } 2944 err = checkProposalSubmission(cJustAboutRight1) 2945 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between (0, 1]")) 2946 2947 cJustAboutRight2 := &commandspb.ProposalSubmission{ 2948 Terms: &vegapb.ProposalTerms{ 2949 Change: &vegapb.ProposalTerms_NewMarket{ 2950 NewMarket: &vegapb.NewMarket{ 2951 Changes: &vegapb.NewMarketConfiguration{ 2952 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2953 LogNormal: &vegapb.LogNormalRiskModel{ 2954 RiskAversionParameter: 0.1, 2955 Tau: 1, 2956 Params: &vegapb.LogNormalModelParams{ 2957 Mu: 0, 2958 Sigma: 0.1, 2959 R: 0, 2960 }, 2961 }, 2962 }, 2963 }, 2964 }, 2965 }, 2966 }, 2967 } 2968 err = checkProposalSubmission(cJustAboutRight2) 2969 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between (0, 1]")) 2970 } 2971 2972 func testNewLogNormalRiskParametersChangeSubmissionInvalidMu(t *testing.T) { 2973 cNaN := &commandspb.ProposalSubmission{ 2974 Terms: &vegapb.ProposalTerms{ 2975 Change: &vegapb.ProposalTerms_NewMarket{ 2976 NewMarket: &vegapb.NewMarket{ 2977 Changes: &vegapb.NewMarketConfiguration{ 2978 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 2979 LogNormal: &vegapb.LogNormalRiskModel{ 2980 RiskAversionParameter: 0.1, 2981 Tau: 0.2, 2982 Params: &vegapb.LogNormalModelParams{ 2983 Mu: math.NaN(), 2984 Sigma: 0.1, 2985 R: 0, 2986 }, 2987 }, 2988 }, 2989 }, 2990 }, 2991 }, 2992 }, 2993 } 2994 err := checkProposalSubmission(cNaN) 2995 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.mu"), commands.ErrIsNotValidNumber) 2996 2997 cTooSmall := &commandspb.ProposalSubmission{ 2998 Terms: &vegapb.ProposalTerms{ 2999 Change: &vegapb.ProposalTerms_NewMarket{ 3000 NewMarket: &vegapb.NewMarket{ 3001 Changes: &vegapb.NewMarketConfiguration{ 3002 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3003 LogNormal: &vegapb.LogNormalRiskModel{ 3004 RiskAversionParameter: 0.1, 3005 Tau: 0.2, 3006 Params: &vegapb.LogNormalModelParams{ 3007 Mu: -1e-6 - 1e-12, 3008 Sigma: 0.1, 3009 R: 0, 3010 }, 3011 }, 3012 }, 3013 }, 3014 }, 3015 }, 3016 }, 3017 } 3018 err = checkProposalSubmission(cTooSmall) 3019 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-1e-6,1e-6]")) 3020 3021 cTooLarge := &commandspb.ProposalSubmission{ 3022 Terms: &vegapb.ProposalTerms{ 3023 Change: &vegapb.ProposalTerms_NewMarket{ 3024 NewMarket: &vegapb.NewMarket{ 3025 Changes: &vegapb.NewMarketConfiguration{ 3026 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3027 LogNormal: &vegapb.LogNormalRiskModel{ 3028 RiskAversionParameter: 0.1, 3029 Tau: 0.2, 3030 Params: &vegapb.LogNormalModelParams{ 3031 Mu: 1e-6 + 1e-12, 3032 Sigma: 0.1, 3033 R: 0, 3034 }, 3035 }, 3036 }, 3037 }, 3038 }, 3039 }, 3040 }, 3041 } 3042 err = checkProposalSubmission(cTooLarge) 3043 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-1e-6,1e-6]")) 3044 3045 cJustAboutRight1 := &commandspb.ProposalSubmission{ 3046 Terms: &vegapb.ProposalTerms{ 3047 Change: &vegapb.ProposalTerms_NewMarket{ 3048 NewMarket: &vegapb.NewMarket{ 3049 Changes: &vegapb.NewMarketConfiguration{ 3050 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3051 LogNormal: &vegapb.LogNormalRiskModel{ 3052 RiskAversionParameter: 0.1, 3053 Tau: 0.2, 3054 Params: &vegapb.LogNormalModelParams{ 3055 Mu: -20, 3056 Sigma: 0.1, 3057 R: 0, 3058 }, 3059 }, 3060 }, 3061 }, 3062 }, 3063 }, 3064 }, 3065 } 3066 err = checkProposalSubmission(cJustAboutRight1) 3067 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-20,20]")) 3068 3069 cJustAboutRight2 := &commandspb.ProposalSubmission{ 3070 Terms: &vegapb.ProposalTerms{ 3071 Change: &vegapb.ProposalTerms_NewMarket{ 3072 NewMarket: &vegapb.NewMarket{ 3073 Changes: &vegapb.NewMarketConfiguration{ 3074 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3075 LogNormal: &vegapb.LogNormalRiskModel{ 3076 RiskAversionParameter: 0.1, 3077 Tau: 0.2, 3078 Params: &vegapb.LogNormalModelParams{ 3079 Mu: 20, 3080 Sigma: 0.1, 3081 R: 0, 3082 }, 3083 }, 3084 }, 3085 }, 3086 }, 3087 }, 3088 }, 3089 } 3090 err = checkProposalSubmission(cJustAboutRight2) 3091 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-20,20]")) 3092 } 3093 3094 func testNewLogNormalRiskParametersChangeSubmissionInvalidR(t *testing.T) { 3095 cNaN := &commandspb.ProposalSubmission{ 3096 Terms: &vegapb.ProposalTerms{ 3097 Change: &vegapb.ProposalTerms_NewMarket{ 3098 NewMarket: &vegapb.NewMarket{ 3099 Changes: &vegapb.NewMarketConfiguration{ 3100 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3101 LogNormal: &vegapb.LogNormalRiskModel{ 3102 RiskAversionParameter: 0.1, 3103 Tau: 0.2, 3104 Params: &vegapb.LogNormalModelParams{ 3105 Mu: 0.0, 3106 Sigma: 0.1, 3107 R: math.NaN(), 3108 }, 3109 }, 3110 }, 3111 }, 3112 }, 3113 }, 3114 }, 3115 } 3116 err := checkProposalSubmission(cNaN) 3117 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.r"), commands.ErrIsNotValidNumber) 3118 3119 cTooSmall := &commandspb.ProposalSubmission{ 3120 Terms: &vegapb.ProposalTerms{ 3121 Change: &vegapb.ProposalTerms_NewMarket{ 3122 NewMarket: &vegapb.NewMarket{ 3123 Changes: &vegapb.NewMarketConfiguration{ 3124 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3125 LogNormal: &vegapb.LogNormalRiskModel{ 3126 RiskAversionParameter: 0.1, 3127 Tau: 0.2, 3128 Params: &vegapb.LogNormalModelParams{ 3129 Mu: 0.0, 3130 Sigma: 0.1, 3131 R: -1 - 1e-12, 3132 }, 3133 }, 3134 }, 3135 }, 3136 }, 3137 }, 3138 }, 3139 } 3140 err = checkProposalSubmission(cTooSmall) 3141 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-1,1]")) 3142 3143 cTooLarge := &commandspb.ProposalSubmission{ 3144 Terms: &vegapb.ProposalTerms{ 3145 Change: &vegapb.ProposalTerms_NewMarket{ 3146 NewMarket: &vegapb.NewMarket{ 3147 Changes: &vegapb.NewMarketConfiguration{ 3148 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3149 LogNormal: &vegapb.LogNormalRiskModel{ 3150 RiskAversionParameter: 0.1, 3151 Tau: 0.2, 3152 Params: &vegapb.LogNormalModelParams{ 3153 Mu: 0.0, 3154 Sigma: 0.1, 3155 R: 1 + 1e-12, 3156 }, 3157 }, 3158 }, 3159 }, 3160 }, 3161 }, 3162 }, 3163 } 3164 err = checkProposalSubmission(cTooLarge) 3165 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-1,1]")) 3166 3167 cJustAboutRight1 := &commandspb.ProposalSubmission{ 3168 Terms: &vegapb.ProposalTerms{ 3169 Change: &vegapb.ProposalTerms_NewMarket{ 3170 NewMarket: &vegapb.NewMarket{ 3171 Changes: &vegapb.NewMarketConfiguration{ 3172 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3173 LogNormal: &vegapb.LogNormalRiskModel{ 3174 RiskAversionParameter: 0.1, 3175 Tau: 0.2, 3176 Params: &vegapb.LogNormalModelParams{ 3177 Mu: 0.0, 3178 Sigma: 0.1, 3179 R: -20, 3180 }, 3181 }, 3182 }, 3183 }, 3184 }, 3185 }, 3186 }, 3187 } 3188 err = checkProposalSubmission(cJustAboutRight1) 3189 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-20,20]")) 3190 3191 cJustAboutRight2 := &commandspb.ProposalSubmission{ 3192 Terms: &vegapb.ProposalTerms{ 3193 Change: &vegapb.ProposalTerms_NewMarket{ 3194 NewMarket: &vegapb.NewMarket{ 3195 Changes: &vegapb.NewMarketConfiguration{ 3196 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3197 LogNormal: &vegapb.LogNormalRiskModel{ 3198 RiskAversionParameter: 0.1, 3199 Tau: 0.2, 3200 Params: &vegapb.LogNormalModelParams{ 3201 Mu: 0.0, 3202 Sigma: 0.1, 3203 R: 20, 3204 }, 3205 }, 3206 }, 3207 }, 3208 }, 3209 }, 3210 }, 3211 } 3212 err = checkProposalSubmission(cJustAboutRight2) 3213 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-20,20]")) 3214 } 3215 3216 func testNewLogNormalRiskParametersChangeSubmissionInvalidSigma(t *testing.T) { 3217 cNaN := &commandspb.ProposalSubmission{ 3218 Terms: &vegapb.ProposalTerms{ 3219 Change: &vegapb.ProposalTerms_NewMarket{ 3220 NewMarket: &vegapb.NewMarket{ 3221 Changes: &vegapb.NewMarketConfiguration{ 3222 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3223 LogNormal: &vegapb.LogNormalRiskModel{ 3224 RiskAversionParameter: 0.1, 3225 Tau: 0.2, 3226 Params: &vegapb.LogNormalModelParams{ 3227 Mu: 0.0, 3228 Sigma: math.NaN(), 3229 R: 0, 3230 }, 3231 }, 3232 }, 3233 }, 3234 }, 3235 }, 3236 }, 3237 } 3238 err := checkProposalSubmission(cNaN) 3239 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrIsNotValidNumber) 3240 3241 cNeg := &commandspb.ProposalSubmission{ 3242 Terms: &vegapb.ProposalTerms{ 3243 Change: &vegapb.ProposalTerms_NewMarket{ 3244 NewMarket: &vegapb.NewMarket{ 3245 Changes: &vegapb.NewMarketConfiguration{ 3246 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3247 LogNormal: &vegapb.LogNormalRiskModel{ 3248 RiskAversionParameter: 0.1, 3249 Tau: 0.2, 3250 Params: &vegapb.LogNormalModelParams{ 3251 Mu: 0.0, 3252 Sigma: 1e-4, 3253 R: 0, 3254 }, 3255 }, 3256 }, 3257 }, 3258 }, 3259 }, 3260 }, 3261 } 3262 err = checkProposalSubmission(cNeg) 3263 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]")) 3264 3265 cTooSmall := &commandspb.ProposalSubmission{ 3266 Terms: &vegapb.ProposalTerms{ 3267 Change: &vegapb.ProposalTerms_NewMarket{ 3268 NewMarket: &vegapb.NewMarket{ 3269 Changes: &vegapb.NewMarketConfiguration{ 3270 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3271 LogNormal: &vegapb.LogNormalRiskModel{ 3272 RiskAversionParameter: 0.1, 3273 Tau: 0.2, 3274 Params: &vegapb.LogNormalModelParams{ 3275 Mu: 0.0, 3276 Sigma: 1e-3 - 1e-12, 3277 R: 0, 3278 }, 3279 }, 3280 }, 3281 }, 3282 }, 3283 }, 3284 }, 3285 } 3286 err = checkProposalSubmission(cTooSmall) 3287 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]")) 3288 3289 cTooLarge := &commandspb.ProposalSubmission{ 3290 Terms: &vegapb.ProposalTerms{ 3291 Change: &vegapb.ProposalTerms_NewMarket{ 3292 NewMarket: &vegapb.NewMarket{ 3293 Changes: &vegapb.NewMarketConfiguration{ 3294 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3295 LogNormal: &vegapb.LogNormalRiskModel{ 3296 RiskAversionParameter: 0.1, 3297 Tau: 0.2, 3298 Params: &vegapb.LogNormalModelParams{ 3299 Mu: 0.0, 3300 Sigma: 50 + 1e-12, 3301 R: 0, 3302 }, 3303 }, 3304 }, 3305 }, 3306 }, 3307 }, 3308 }, 3309 } 3310 err = checkProposalSubmission(cTooLarge) 3311 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]")) 3312 3313 cJustAboutRight1 := &commandspb.ProposalSubmission{ 3314 Terms: &vegapb.ProposalTerms{ 3315 Change: &vegapb.ProposalTerms_NewMarket{ 3316 NewMarket: &vegapb.NewMarket{ 3317 Changes: &vegapb.NewMarketConfiguration{ 3318 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3319 LogNormal: &vegapb.LogNormalRiskModel{ 3320 RiskAversionParameter: 0.1, 3321 Tau: 0.2, 3322 Params: &vegapb.LogNormalModelParams{ 3323 Mu: 0.0, 3324 Sigma: 1e-4, 3325 R: 0, 3326 }, 3327 }, 3328 }, 3329 }, 3330 }, 3331 }, 3332 }, 3333 } 3334 err = checkProposalSubmission(cJustAboutRight1) 3335 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-4,100]")) 3336 3337 cJustAboutRight2 := &commandspb.ProposalSubmission{ 3338 Terms: &vegapb.ProposalTerms{ 3339 Change: &vegapb.ProposalTerms_NewMarket{ 3340 NewMarket: &vegapb.NewMarket{ 3341 Changes: &vegapb.NewMarketConfiguration{ 3342 RiskParameters: &vegapb.NewMarketConfiguration_LogNormal{ 3343 LogNormal: &vegapb.LogNormalRiskModel{ 3344 RiskAversionParameter: 0.1, 3345 Tau: 0.2, 3346 Params: &vegapb.LogNormalModelParams{ 3347 Mu: 0.0, 3348 Sigma: 50, 3349 R: 0, 3350 }, 3351 }, 3352 }, 3353 }, 3354 }, 3355 }, 3356 }, 3357 } 3358 err = checkProposalSubmission(cJustAboutRight2) 3359 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-4,100]")) 3360 } 3361 3362 func testNewMarketSubmissionWithTooLongReferenceFails(t *testing.T) { 3363 ref := make([]byte, 101) 3364 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3365 Reference: string(ref), 3366 }) 3367 assert.Contains(t, err.Get("proposal_submission.reference"), commands.ErrReferenceTooLong) 3368 } 3369 3370 func testFutureMarketSubmissionWithInternalTimestampForTradingTerminationSucceeds(t *testing.T) { 3371 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3372 Terms: &vegapb.ProposalTerms{ 3373 Change: &vegapb.ProposalTerms_NewMarket{ 3374 NewMarket: &vegapb.NewMarket{ 3375 Changes: &vegapb.NewMarketConfiguration{ 3376 Instrument: &vegapb.InstrumentConfiguration{ 3377 Product: &vegapb.InstrumentConfiguration_Future{ 3378 Future: &vegapb.FutureProduct{ 3379 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{ 3380 SourceType: &vegapb.DataSourceDefinition_Internal{ 3381 Internal: &vegapb.DataSourceDefinitionInternal{ 3382 SourceType: &vegapb.DataSourceDefinitionInternal_Time{ 3383 Time: &vegapb.DataSourceSpecConfigurationTime{ 3384 Conditions: []*datapb.Condition{ 3385 { 3386 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3387 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3388 }, 3389 }, 3390 }, 3391 }, 3392 }, 3393 }, 3394 }, 3395 }, 3396 }, 3397 }, 3398 }, 3399 }, 3400 }, 3401 }, 3402 }) 3403 3404 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3405 } 3406 3407 func testFutureMarketSubmissionWithInvalidOracleConditionOrType(t *testing.T) { 3408 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3409 Terms: &vegapb.ProposalTerms{ 3410 Change: &vegapb.ProposalTerms_NewMarket{ 3411 NewMarket: &vegapb.NewMarket{ 3412 Changes: &vegapb.NewMarketConfiguration{ 3413 Instrument: &vegapb.InstrumentConfiguration{ 3414 Product: &vegapb.InstrumentConfiguration_Future{ 3415 Future: &vegapb.FutureProduct{ 3416 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3417 vegapb.DataSourceContentTypeOracle, 3418 ).SetOracleConfig( 3419 &vegapb.DataSourceDefinitionExternal_Oracle{ 3420 Oracle: &vegapb.DataSourceSpecConfiguration{ 3421 Signers: []*datapb.Signer{}, 3422 Filters: []*datapb.Filter{ 3423 { 3424 Key: &datapb.PropertyKey{ 3425 Name: "trading.terminated", 3426 Type: datapb.PropertyKey_Type(10000), 3427 }, 3428 Conditions: []*datapb.Condition{ 3429 { 3430 Operator: datapb.Condition_Operator(10000), 3431 }, 3432 }, 3433 }, 3434 }, 3435 }, 3436 }, 3437 ), 3438 }, 3439 }, 3440 }, 3441 }, 3442 }, 3443 }, 3444 }, 3445 }) 3446 3447 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.filters.0.conditions.0.operator"), commands.ErrIsNotValid) 3448 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.filters.0.key.type"), commands.ErrIsNotValid) 3449 } 3450 3451 func testFutureMarketSubmissionWithExternalTradingTerminationNoPublicKeyFails(t *testing.T) { 3452 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3453 Terms: &vegapb.ProposalTerms{ 3454 Change: &vegapb.ProposalTerms_NewMarket{ 3455 NewMarket: &vegapb.NewMarket{ 3456 Changes: &vegapb.NewMarketConfiguration{ 3457 Instrument: &vegapb.InstrumentConfiguration{ 3458 Product: &vegapb.InstrumentConfiguration_Future{ 3459 Future: &vegapb.FutureProduct{ 3460 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3461 vegapb.DataSourceContentTypeOracle, 3462 ).SetOracleConfig( 3463 &vegapb.DataSourceDefinitionExternal_Oracle{ 3464 Oracle: &vegapb.DataSourceSpecConfiguration{ 3465 Signers: []*datapb.Signer{}, 3466 Filters: []*datapb.Filter{ 3467 { 3468 Key: &datapb.PropertyKey{ 3469 Name: "trading.terminated", 3470 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3471 }, 3472 Conditions: []*datapb.Condition{}, 3473 }, 3474 }, 3475 }, 3476 }, 3477 ), 3478 }, 3479 }, 3480 }, 3481 }, 3482 }, 3483 }, 3484 }, 3485 }) 3486 3487 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3488 } 3489 3490 func testFutureMarketSubmissionWithInternalTradingTerminationSucceeds(t *testing.T) { 3491 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3492 Terms: &vegapb.ProposalTerms{ 3493 Change: &vegapb.ProposalTerms_NewMarket{ 3494 NewMarket: &vegapb.NewMarket{ 3495 Changes: &vegapb.NewMarketConfiguration{ 3496 Instrument: &vegapb.InstrumentConfiguration{ 3497 Product: &vegapb.InstrumentConfiguration_Future{ 3498 Future: &vegapb.FutureProduct{ 3499 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3500 vegapb.DataSourceContentTypeInternalTimeTermination, 3501 ).SetOracleConfig( 3502 &vegapb.DataSourceDefinitionExternal_Oracle{ 3503 Oracle: &vegapb.DataSourceSpecConfiguration{ 3504 Signers: []*datapb.Signer{}, 3505 Filters: []*datapb.Filter{ 3506 { 3507 Conditions: []*datapb.Condition{ 3508 { 3509 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3510 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3511 }, 3512 }, 3513 }, 3514 }, 3515 }, 3516 }, 3517 ), 3518 }, 3519 }, 3520 }, 3521 }, 3522 }, 3523 }, 3524 }, 3525 }) 3526 3527 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3528 } 3529 3530 func testFutureMarketSubmissionWithInternalTradingInvalidOperatorTerminationFails(t *testing.T) { 3531 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3532 Terms: &vegapb.ProposalTerms{ 3533 Change: &vegapb.ProposalTerms_NewMarket{ 3534 NewMarket: &vegapb.NewMarket{ 3535 Changes: &vegapb.NewMarketConfiguration{ 3536 Instrument: &vegapb.InstrumentConfiguration{ 3537 Product: &vegapb.InstrumentConfiguration_Future{ 3538 Future: &vegapb.FutureProduct{ 3539 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3540 vegapb.DataSourceContentTypeInternalTimeTermination, 3541 ).SetOracleConfig( 3542 &vegapb.DataSourceDefinitionExternal_Oracle{ 3543 Oracle: &vegapb.DataSourceSpecConfiguration{ 3544 Signers: []*datapb.Signer{}, 3545 Filters: []*datapb.Filter{ 3546 { 3547 Conditions: []*datapb.Condition{ 3548 { 3549 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 3550 Value: "value 1", 3551 }, 3552 }, 3553 }, 3554 }, 3555 }, 3556 }, 3557 ), 3558 }, 3559 }, 3560 }, 3561 }, 3562 }, 3563 }, 3564 }, 3565 }) 3566 3567 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time.conditions"), commands.ErrIsRequired) 3568 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsRequired) 3569 3570 err = checkProposalSubmission(&commandspb.ProposalSubmission{ 3571 Terms: &vegapb.ProposalTerms{ 3572 Change: &vegapb.ProposalTerms_NewMarket{ 3573 NewMarket: &vegapb.NewMarket{ 3574 Changes: &vegapb.NewMarketConfiguration{ 3575 Instrument: &vegapb.InstrumentConfiguration{ 3576 Product: &vegapb.InstrumentConfiguration_Future{ 3577 Future: &vegapb.FutureProduct{ 3578 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3579 vegapb.DataSourceContentTypeInternalTimeTermination, 3580 ).SetTimeTriggerConditionConfig( 3581 []*datapb.Condition{ 3582 { 3583 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 3584 Value: "value 1", 3585 }, 3586 }, 3587 ), 3588 }, 3589 }, 3590 }, 3591 }, 3592 }, 3593 }, 3594 }, 3595 }) 3596 3597 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time.conditions.0.operator"), commands.ErrIsRequired) 3598 } 3599 3600 func testFutureMarketSubmissionWithExternalTradingTerminationBuiltInKeyNoPublicKeyFails(t *testing.T) { 3601 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3602 Terms: &vegapb.ProposalTerms{ 3603 Change: &vegapb.ProposalTerms_NewMarket{ 3604 NewMarket: &vegapb.NewMarket{ 3605 Changes: &vegapb.NewMarketConfiguration{ 3606 Instrument: &vegapb.InstrumentConfiguration{ 3607 Product: &vegapb.InstrumentConfiguration_Future{ 3608 Future: &vegapb.FutureProduct{ 3609 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3610 vegapb.DataSourceContentTypeOracle, 3611 ).SetOracleConfig( 3612 &vegapb.DataSourceDefinitionExternal_Oracle{ 3613 Oracle: &vegapb.DataSourceSpecConfiguration{ 3614 Signers: []*datapb.Signer{}, 3615 Filters: []*datapb.Filter{ 3616 { 3617 Key: &datapb.PropertyKey{ 3618 Name: "vegaprotocol.builtin.timestamp", 3619 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 3620 }, 3621 Conditions: []*datapb.Condition{ 3622 { 3623 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3624 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3625 }, 3626 }, 3627 }, 3628 }, 3629 }, 3630 }, 3631 ), 3632 }, 3633 }, 3634 }, 3635 }, 3636 }, 3637 }, 3638 }, 3639 }) 3640 3641 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3642 } 3643 3644 func testFutureMarketSubmissionWithExternalTradingSettlementBuiltInKeyNoPublicKeyFails(t *testing.T) { 3645 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3646 Terms: &vegapb.ProposalTerms{ 3647 Change: &vegapb.ProposalTerms_NewMarket{ 3648 NewMarket: &vegapb.NewMarket{ 3649 Changes: &vegapb.NewMarketConfiguration{ 3650 Instrument: &vegapb.InstrumentConfiguration{ 3651 Product: &vegapb.InstrumentConfiguration_Future{ 3652 Future: &vegapb.FutureProduct{ 3653 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3654 vegapb.DataSourceContentTypeOracle, 3655 ).SetOracleConfig( 3656 &vegapb.DataSourceDefinitionExternal_Oracle{ 3657 Oracle: &vegapb.DataSourceSpecConfiguration{ 3658 Signers: []*datapb.Signer{}, 3659 Filters: []*datapb.Filter{ 3660 { 3661 Key: &datapb.PropertyKey{ 3662 Name: "vegaprotocol.builtin.timestamp", 3663 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 3664 }, 3665 Conditions: []*datapb.Condition{ 3666 { 3667 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3668 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3669 }, 3670 }, 3671 }, 3672 }, 3673 }, 3674 }, 3675 ), 3676 }, 3677 }, 3678 }, 3679 }, 3680 }, 3681 }, 3682 }, 3683 }) 3684 3685 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 3686 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3687 } 3688 3689 func testFutureMarketSubmissionWithExternalTradingSettlementTimestampKeySucceeds(t *testing.T) { 3690 pubKeys := []*dstypes.Signer{ 3691 dstypes.CreateSignerFromString("0xDEADBEEF", dstypes.SignerTypePubKey), 3692 dstypes.CreateSignerFromString("", dstypes.SignerTypePubKey), 3693 } 3694 3695 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3696 Terms: &vegapb.ProposalTerms{ 3697 Change: &vegapb.ProposalTerms_NewMarket{ 3698 NewMarket: &vegapb.NewMarket{ 3699 Changes: &vegapb.NewMarketConfiguration{ 3700 Instrument: &vegapb.InstrumentConfiguration{ 3701 Product: &vegapb.InstrumentConfiguration_Future{ 3702 Future: &vegapb.FutureProduct{ 3703 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3704 vegapb.DataSourceContentTypeOracle, 3705 ).SetOracleConfig( 3706 &vegapb.DataSourceDefinitionExternal_Oracle{ 3707 Oracle: &vegapb.DataSourceSpecConfiguration{ 3708 Signers: dstypes.SignersIntoProto(pubKeys), 3709 Filters: []*datapb.Filter{ 3710 { 3711 Key: &datapb.PropertyKey{ 3712 Name: "price.BTC.value", 3713 Type: datapb.PropertyKey_TYPE_INTEGER, 3714 }, 3715 Conditions: []*datapb.Condition{ 3716 { 3717 Operator: datapb.Condition_OPERATOR_EQUALS, 3718 Value: "15", 3719 }, 3720 }, 3721 }, 3722 { 3723 Key: &datapb.PropertyKey{ 3724 Name: "price.BTC.timestamp", 3725 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 3726 }, 3727 Conditions: []*datapb.Condition{ 3728 { 3729 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3730 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3731 }, 3732 }, 3733 }, 3734 }, 3735 }, 3736 }, 3737 ), 3738 }, 3739 }, 3740 }, 3741 }, 3742 }, 3743 }, 3744 }, 3745 }) 3746 3747 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 3748 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3749 } 3750 3751 func testFutureMarketSubmissionWithExternalTradingTerminationBuiltInKeySucceeds(t *testing.T) { 3752 pubKey := []*dstypes.Signer{ 3753 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3754 } 3755 3756 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3757 Terms: &vegapb.ProposalTerms{ 3758 Change: &vegapb.ProposalTerms_NewMarket{ 3759 NewMarket: &vegapb.NewMarket{ 3760 Changes: &vegapb.NewMarketConfiguration{ 3761 Instrument: &vegapb.InstrumentConfiguration{ 3762 Product: &vegapb.InstrumentConfiguration_Future{ 3763 Future: &vegapb.FutureProduct{ 3764 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3765 vegapb.DataSourceContentTypeOracle, 3766 ).SetOracleConfig( 3767 &vegapb.DataSourceDefinitionExternal_Oracle{ 3768 Oracle: &vegapb.DataSourceSpecConfiguration{ 3769 Signers: dstypes.SignersIntoProto(pubKey), 3770 Filters: []*datapb.Filter{ 3771 { 3772 Key: &datapb.PropertyKey{ 3773 Name: "prices.ETH.value", 3774 Type: datapb.PropertyKey_TYPE_INTEGER, 3775 }, 3776 Conditions: []*datapb.Condition{ 3777 { 3778 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3779 }, 3780 }, 3781 }, 3782 }, 3783 }, 3784 }, 3785 ), 3786 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3787 vegapb.DataSourceContentTypeOracle, 3788 ).SetOracleConfig( 3789 &vegapb.DataSourceDefinitionExternal_Oracle{ 3790 Oracle: &vegapb.DataSourceSpecConfiguration{ 3791 Signers: dstypes.SignersIntoProto(pubKey), 3792 Filters: []*datapb.Filter{ 3793 { 3794 Key: &datapb.PropertyKey{ 3795 Name: "vegaprotocol.builtin.timestamp", 3796 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 3797 }, 3798 Conditions: []*datapb.Condition{ 3799 { 3800 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3801 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3802 }, 3803 }, 3804 }, 3805 }, 3806 }, 3807 }, 3808 ), 3809 }, 3810 }, 3811 }, 3812 }, 3813 }, 3814 }, 3815 }, 3816 }) 3817 3818 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3819 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3820 } 3821 3822 func testFutureMarketSubmissionWithExternalTradingTerminationNoSignerFails(t *testing.T) { 3823 pubKey := []*dstypes.Signer{ 3824 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3825 } 3826 3827 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3828 Terms: &vegapb.ProposalTerms{ 3829 Change: &vegapb.ProposalTerms_NewMarket{ 3830 NewMarket: &vegapb.NewMarket{ 3831 Changes: &vegapb.NewMarketConfiguration{ 3832 Instrument: &vegapb.InstrumentConfiguration{ 3833 Product: &vegapb.InstrumentConfiguration_Future{ 3834 Future: &vegapb.FutureProduct{ 3835 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3836 vegapb.DataSourceContentTypeOracle, 3837 ).SetOracleConfig( 3838 &vegapb.DataSourceDefinitionExternal_Oracle{ 3839 Oracle: &vegapb.DataSourceSpecConfiguration{ 3840 Signers: dstypes.SignersIntoProto(pubKey), 3841 Filters: []*datapb.Filter{ 3842 { 3843 Key: &datapb.PropertyKey{ 3844 Name: "vegaprotocol.builtin.prices.ETH.value", 3845 Type: datapb.PropertyKey_TYPE_INTEGER, 3846 }, 3847 Conditions: []*datapb.Condition{ 3848 { 3849 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3850 }, 3851 }, 3852 }, 3853 }, 3854 }, 3855 }, 3856 ), 3857 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3858 vegapb.DataSourceContentTypeOracle, 3859 ).SetOracleConfig( 3860 &vegapb.DataSourceDefinitionExternal_Oracle{ 3861 Oracle: &vegapb.DataSourceSpecConfiguration{ 3862 Filters: []*datapb.Filter{ 3863 { 3864 Key: &datapb.PropertyKey{ 3865 Name: "trading.terminated", 3866 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3867 }, 3868 Conditions: []*datapb.Condition{}, 3869 }, 3870 }, 3871 }, 3872 }, 3873 ), 3874 }, 3875 }, 3876 }, 3877 }, 3878 }, 3879 }, 3880 }, 3881 }) 3882 3883 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3884 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3885 } 3886 3887 func testFutureMarketSubmissionWithExternalSettlementDataNoSignerFails(t *testing.T) { 3888 pubKey := []*dstypes.Signer{ 3889 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3890 } 3891 3892 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3893 Terms: &vegapb.ProposalTerms{ 3894 Change: &vegapb.ProposalTerms_NewMarket{ 3895 NewMarket: &vegapb.NewMarket{ 3896 Changes: &vegapb.NewMarketConfiguration{ 3897 Instrument: &vegapb.InstrumentConfiguration{ 3898 Product: &vegapb.InstrumentConfiguration_Future{ 3899 Future: &vegapb.FutureProduct{ 3900 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3901 vegapb.DataSourceContentTypeOracle, 3902 ).SetOracleConfig( 3903 &vegapb.DataSourceDefinitionExternal_Oracle{ 3904 Oracle: &vegapb.DataSourceSpecConfiguration{ 3905 Filters: []*datapb.Filter{ 3906 { 3907 Key: &datapb.PropertyKey{ 3908 Name: "vegaprotocol.builtin.prices.ETH.value", 3909 Type: datapb.PropertyKey_TYPE_INTEGER, 3910 }, 3911 Conditions: []*datapb.Condition{ 3912 { 3913 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3914 }, 3915 }, 3916 }, 3917 }, 3918 }, 3919 }, 3920 ), 3921 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3922 vegapb.DataSourceContentTypeOracle, 3923 ).SetOracleConfig( 3924 &vegapb.DataSourceDefinitionExternal_Oracle{ 3925 Oracle: &vegapb.DataSourceSpecConfiguration{ 3926 Signers: dstypes.SignersIntoProto(pubKey), 3927 Filters: []*datapb.Filter{ 3928 { 3929 Key: &datapb.PropertyKey{ 3930 Name: "trading.terminated", 3931 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3932 }, 3933 Conditions: []*datapb.Condition{}, 3934 }, 3935 }, 3936 }, 3937 }, 3938 ), 3939 }, 3940 }, 3941 }, 3942 }, 3943 }, 3944 }, 3945 }, 3946 }) 3947 3948 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3949 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3950 } 3951 3952 func testFutureMarketSubmissionWithInternalSettlementDataFails(t *testing.T) { 3953 pubKey := []*dstypes.Signer{ 3954 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3955 } 3956 3957 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3958 Terms: &vegapb.ProposalTerms{ 3959 Change: &vegapb.ProposalTerms_NewMarket{ 3960 NewMarket: &vegapb.NewMarket{ 3961 Changes: &vegapb.NewMarketConfiguration{ 3962 Instrument: &vegapb.InstrumentConfiguration{ 3963 Product: &vegapb.InstrumentConfiguration_Future{ 3964 Future: &vegapb.FutureProduct{ 3965 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3966 vegapb.DataSourceContentTypeInternalTimeTermination, 3967 ).SetTimeTriggerConditionConfig( 3968 []*datapb.Condition{ 3969 { 3970 // It does not matter what conditions are set here 3971 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3972 }, 3973 }, 3974 ), 3975 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3976 vegapb.DataSourceContentTypeOracle, 3977 ).SetOracleConfig( 3978 &vegapb.DataSourceDefinitionExternal_Oracle{ 3979 Oracle: &vegapb.DataSourceSpecConfiguration{ 3980 Signers: dstypes.SignersIntoProto(pubKey), 3981 Filters: []*datapb.Filter{ 3982 { 3983 Key: &datapb.PropertyKey{ 3984 Name: "trading.terminated", 3985 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3986 }, 3987 Conditions: []*datapb.Condition{}, 3988 }, 3989 }, 3990 }, 3991 }, 3992 ), 3993 }, 3994 }, 3995 }, 3996 }, 3997 }, 3998 }, 3999 }, 4000 }) 4001 4002 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 4003 } 4004 4005 func testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptySignerFails(t *testing.T) { 4006 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4007 Terms: &vegapb.ProposalTerms{ 4008 Change: &vegapb.ProposalTerms_NewMarket{ 4009 NewMarket: &vegapb.NewMarket{ 4010 Changes: &vegapb.NewMarketConfiguration{ 4011 Instrument: &vegapb.InstrumentConfiguration{ 4012 Product: &vegapb.InstrumentConfiguration_Future{ 4013 Future: &vegapb.FutureProduct{ 4014 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4015 vegapb.DataSourceContentTypeOracle, 4016 ).SetOracleConfig( 4017 &vegapb.DataSourceDefinitionExternal_Oracle{ 4018 Oracle: &vegapb.DataSourceSpecConfiguration{ 4019 Signers: []*datapb.Signer{}, 4020 Filters: []*datapb.Filter{ 4021 { 4022 Key: &datapb.PropertyKey{ 4023 Name: "vegaprotocol.builtin.prices.ETH.value", 4024 Type: datapb.PropertyKey_TYPE_INTEGER, 4025 }, 4026 Conditions: []*datapb.Condition{ 4027 { 4028 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 4029 }, 4030 }, 4031 }, 4032 }, 4033 }, 4034 }, 4035 ), 4036 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 4037 vegapb.DataSourceContentTypeOracle, 4038 ).SetOracleConfig( 4039 &vegapb.DataSourceDefinitionExternal_Oracle{ 4040 Oracle: &vegapb.DataSourceSpecConfiguration{ 4041 Signers: []*datapb.Signer{}, 4042 Filters: []*datapb.Filter{ 4043 { 4044 Key: &datapb.PropertyKey{ 4045 Name: "trading.terminated", 4046 Type: datapb.PropertyKey_TYPE_BOOLEAN, 4047 }, 4048 Conditions: []*datapb.Condition{}, 4049 }, 4050 }, 4051 }, 4052 }, 4053 ), 4054 }, 4055 }, 4056 }, 4057 }, 4058 }, 4059 }, 4060 }, 4061 }) 4062 4063 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 4064 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 4065 } 4066 4067 func testFutureMarketSubmissionWithExternalSettlementDataAndTerminationNoSignerFails(t *testing.T) { 4068 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4069 Terms: &vegapb.ProposalTerms{ 4070 Change: &vegapb.ProposalTerms_NewMarket{ 4071 NewMarket: &vegapb.NewMarket{ 4072 Changes: &vegapb.NewMarketConfiguration{ 4073 Instrument: &vegapb.InstrumentConfiguration{ 4074 Product: &vegapb.InstrumentConfiguration_Future{ 4075 Future: &vegapb.FutureProduct{ 4076 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4077 vegapb.DataSourceContentTypeOracle, 4078 ).SetOracleConfig( 4079 &vegapb.DataSourceDefinitionExternal_Oracle{ 4080 Oracle: &vegapb.DataSourceSpecConfiguration{ 4081 Filters: []*datapb.Filter{ 4082 { 4083 Key: &datapb.PropertyKey{ 4084 Name: "vegaprotocol.builtin.prices.ETH.value", 4085 Type: datapb.PropertyKey_TYPE_INTEGER, 4086 }, 4087 Conditions: []*datapb.Condition{ 4088 { 4089 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 4090 }, 4091 }, 4092 }, 4093 }, 4094 }, 4095 }, 4096 ), 4097 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 4098 vegapb.DataSourceContentTypeOracle, 4099 ).SetOracleConfig( 4100 &vegapb.DataSourceDefinitionExternal_Oracle{ 4101 Oracle: &vegapb.DataSourceSpecConfiguration{ 4102 Filters: []*datapb.Filter{ 4103 { 4104 Key: &datapb.PropertyKey{ 4105 Name: "trading.terminated", 4106 Type: datapb.PropertyKey_TYPE_BOOLEAN, 4107 }, 4108 Conditions: []*datapb.Condition{}, 4109 }, 4110 }, 4111 }, 4112 }, 4113 ), 4114 }, 4115 }, 4116 }, 4117 }, 4118 }, 4119 }, 4120 }, 4121 }) 4122 4123 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 4124 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 4125 } 4126 4127 func testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptyPubKeySignerFails(t *testing.T) { 4128 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4129 Terms: &vegapb.ProposalTerms{ 4130 Change: &vegapb.ProposalTerms_NewMarket{ 4131 NewMarket: &vegapb.NewMarket{ 4132 Changes: &vegapb.NewMarketConfiguration{ 4133 Instrument: &vegapb.InstrumentConfiguration{ 4134 Product: &vegapb.InstrumentConfiguration_Future{ 4135 Future: &vegapb.FutureProduct{ 4136 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4137 vegapb.DataSourceContentTypeOracle, 4138 ).SetOracleConfig( 4139 &vegapb.DataSourceDefinitionExternal_Oracle{ 4140 Oracle: &vegapb.DataSourceSpecConfiguration{ 4141 Signers: []*datapb.Signer{ 4142 { 4143 Signer: &datapb.Signer_PubKey{ 4144 PubKey: &datapb.PubKey{ 4145 Key: "", 4146 }, 4147 }, 4148 }, 4149 }, 4150 Filters: []*datapb.Filter{ 4151 { 4152 Key: &datapb.PropertyKey{ 4153 Name: "vegaprotocol.builtin.prices.ETH.value", 4154 Type: datapb.PropertyKey_TYPE_INTEGER, 4155 }, 4156 Conditions: []*datapb.Condition{ 4157 { 4158 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 4159 }, 4160 }, 4161 }, 4162 }, 4163 }, 4164 }, 4165 ), 4166 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 4167 vegapb.DataSourceContentTypeOracle, 4168 ).SetOracleConfig( 4169 &vegapb.DataSourceDefinitionExternal_Oracle{ 4170 Oracle: &vegapb.DataSourceSpecConfiguration{ 4171 Signers: []*datapb.Signer{ 4172 { 4173 Signer: &datapb.Signer_PubKey{ 4174 PubKey: &datapb.PubKey{}, 4175 }, 4176 }, 4177 }, 4178 Filters: []*datapb.Filter{ 4179 { 4180 Key: &datapb.PropertyKey{ 4181 Name: "trading.terminated", 4182 Type: datapb.PropertyKey_TYPE_BOOLEAN, 4183 }, 4184 Conditions: []*datapb.Condition{}, 4185 }, 4186 }, 4187 }, 4188 }, 4189 ), 4190 }, 4191 }, 4192 }, 4193 }, 4194 }, 4195 }, 4196 }, 4197 }) 4198 4199 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 4200 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers.0"), commands.ErrIsNotValid) 4201 } 4202 4203 func testFutureMarketSubmissionWithExternalSettlementDataAndTerminationEmptyEthAddressSignerFails(t *testing.T) { 4204 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4205 Terms: &vegapb.ProposalTerms{ 4206 Change: &vegapb.ProposalTerms_NewMarket{ 4207 NewMarket: &vegapb.NewMarket{ 4208 Changes: &vegapb.NewMarketConfiguration{ 4209 Instrument: &vegapb.InstrumentConfiguration{ 4210 Product: &vegapb.InstrumentConfiguration_Future{ 4211 Future: &vegapb.FutureProduct{ 4212 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4213 vegapb.DataSourceContentTypeOracle, 4214 ).SetOracleConfig( 4215 &vegapb.DataSourceDefinitionExternal_Oracle{ 4216 Oracle: &vegapb.DataSourceSpecConfiguration{ 4217 Signers: []*datapb.Signer{ 4218 { 4219 Signer: &datapb.Signer_EthAddress{ 4220 EthAddress: &datapb.ETHAddress{ 4221 Address: "", 4222 }, 4223 }, 4224 }, 4225 }, 4226 Filters: []*datapb.Filter{ 4227 { 4228 Key: &datapb.PropertyKey{ 4229 Name: "vegaprotocol.builtin.prices.ETH.value", 4230 Type: datapb.PropertyKey_TYPE_INTEGER, 4231 }, 4232 Conditions: []*datapb.Condition{ 4233 { 4234 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 4235 }, 4236 }, 4237 }, 4238 }, 4239 }, 4240 }, 4241 ), 4242 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 4243 vegapb.DataSourceContentTypeOracle, 4244 ).SetOracleConfig( 4245 &vegapb.DataSourceDefinitionExternal_Oracle{ 4246 Oracle: &vegapb.DataSourceSpecConfiguration{ 4247 Signers: []*datapb.Signer{ 4248 { 4249 Signer: &datapb.Signer_EthAddress{ 4250 EthAddress: &datapb.ETHAddress{}, 4251 }, 4252 }, 4253 }, 4254 Filters: []*datapb.Filter{ 4255 { 4256 Key: &datapb.PropertyKey{ 4257 Name: "trading.terminated", 4258 Type: datapb.PropertyKey_TYPE_BOOLEAN, 4259 }, 4260 Conditions: []*datapb.Condition{}, 4261 }, 4262 }, 4263 }, 4264 }, 4265 ), 4266 }, 4267 }, 4268 }, 4269 }, 4270 }, 4271 }, 4272 }, 4273 }) 4274 4275 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 4276 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers.0"), commands.ErrIsNotValid) 4277 } 4278 4279 func testNewPerpsMarketChangeSubmissionWithoutPerpsFails(t *testing.T) { 4280 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4281 Terms: &vegapb.ProposalTerms{ 4282 Change: &vegapb.ProposalTerms_NewMarket{ 4283 NewMarket: &vegapb.NewMarket{ 4284 Changes: &vegapb.NewMarketConfiguration{ 4285 Instrument: &vegapb.InstrumentConfiguration{ 4286 Product: &vegapb.InstrumentConfiguration_Perpetual{}, 4287 }, 4288 }, 4289 }, 4290 }, 4291 }, 4292 }) 4293 4294 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps"), commands.ErrIsRequired) 4295 } 4296 4297 func testNewPerpsMarketChangeSubmissionWithPerpsSucceeds(t *testing.T) { 4298 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4299 Terms: &vegapb.ProposalTerms{ 4300 Change: &vegapb.ProposalTerms_NewMarket{ 4301 NewMarket: &vegapb.NewMarket{ 4302 Changes: &vegapb.NewMarketConfiguration{ 4303 Instrument: &vegapb.InstrumentConfiguration{ 4304 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4305 Perpetual: &vegapb.PerpetualProduct{}, 4306 }, 4307 }, 4308 }, 4309 }, 4310 }, 4311 }, 4312 }) 4313 4314 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps"), commands.ErrIsRequired) 4315 } 4316 4317 func testNewPerpsMarketChangeSubmissionWithoutSettlementAssetFails(t *testing.T) { 4318 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4319 Terms: &vegapb.ProposalTerms{ 4320 Change: &vegapb.ProposalTerms_NewMarket{ 4321 NewMarket: &vegapb.NewMarket{ 4322 Changes: &vegapb.NewMarketConfiguration{ 4323 Instrument: &vegapb.InstrumentConfiguration{ 4324 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4325 Perpetual: &vegapb.PerpetualProduct{ 4326 SettlementAsset: "", 4327 }, 4328 }, 4329 }, 4330 }, 4331 }, 4332 }, 4333 }, 4334 }) 4335 4336 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.settlement_asset"), commands.ErrIsRequired) 4337 } 4338 4339 func testNewPerpsMarketChangeSubmissionWithSettlementAssetSucceeds(t *testing.T) { 4340 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4341 Terms: &vegapb.ProposalTerms{ 4342 Change: &vegapb.ProposalTerms_NewMarket{ 4343 NewMarket: &vegapb.NewMarket{ 4344 Changes: &vegapb.NewMarketConfiguration{ 4345 Instrument: &vegapb.InstrumentConfiguration{ 4346 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4347 Perpetual: &vegapb.PerpetualProduct{ 4348 SettlementAsset: "BTC", 4349 }, 4350 }, 4351 }, 4352 }, 4353 }, 4354 }, 4355 }, 4356 }) 4357 4358 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.settlement_asset"), commands.ErrIsRequired) 4359 } 4360 4361 func testNewPerpsMarketChangeSubmissionWithoutQuoteNameFails(t *testing.T) { 4362 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4363 Terms: &vegapb.ProposalTerms{ 4364 Change: &vegapb.ProposalTerms_NewMarket{ 4365 NewMarket: &vegapb.NewMarket{ 4366 Changes: &vegapb.NewMarketConfiguration{ 4367 Instrument: &vegapb.InstrumentConfiguration{ 4368 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4369 Perpetual: &vegapb.PerpetualProduct{ 4370 QuoteName: "", 4371 }, 4372 }, 4373 }, 4374 }, 4375 }, 4376 }, 4377 }, 4378 }) 4379 4380 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.quote_name"), commands.ErrIsRequired) 4381 } 4382 4383 func testNewPerpsMarketChangeSubmissionWithQuoteNameSucceeds(t *testing.T) { 4384 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4385 Terms: &vegapb.ProposalTerms{ 4386 Change: &vegapb.ProposalTerms_NewMarket{ 4387 NewMarket: &vegapb.NewMarket{ 4388 Changes: &vegapb.NewMarketConfiguration{ 4389 Instrument: &vegapb.InstrumentConfiguration{ 4390 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4391 Perpetual: &vegapb.PerpetualProduct{ 4392 QuoteName: "BTC", 4393 }, 4394 }, 4395 }, 4396 }, 4397 }, 4398 }, 4399 }, 4400 }) 4401 4402 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.quote_name"), commands.ErrIsRequired) 4403 } 4404 4405 func testNewPerpsMarketChangeSubmissionWithoutOracleSpecFails(t *testing.T) { 4406 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4407 Terms: &vegapb.ProposalTerms{ 4408 Change: &vegapb.ProposalTerms_NewMarket{ 4409 NewMarket: &vegapb.NewMarket{ 4410 Changes: &vegapb.NewMarketConfiguration{ 4411 Instrument: &vegapb.InstrumentConfiguration{ 4412 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4413 Perpetual: &vegapb.PerpetualProduct{}, 4414 }, 4415 }, 4416 }, 4417 }, 4418 }, 4419 }, 4420 }) 4421 4422 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data"), commands.ErrIsRequired) 4423 } 4424 4425 func testNewPerpsMarketChangeSubmissionWithOracleSpecSucceeds(t *testing.T) { 4426 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4427 Terms: &vegapb.ProposalTerms{ 4428 Change: &vegapb.ProposalTerms_NewMarket{ 4429 NewMarket: &vegapb.NewMarket{ 4430 Changes: &vegapb.NewMarketConfiguration{ 4431 Instrument: &vegapb.InstrumentConfiguration{ 4432 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4433 Perpetual: &vegapb.PerpetualProduct{ 4434 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{}, 4435 }, 4436 }, 4437 }, 4438 }, 4439 }, 4440 }, 4441 }, 4442 }) 4443 4444 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data"), commands.ErrIsRequired) 4445 } 4446 4447 func testNewPerpsMarketChangeSubmissionWithoutFiltersFails(t *testing.T) { 4448 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4449 Terms: &vegapb.ProposalTerms{ 4450 Change: &vegapb.ProposalTerms_NewMarket{ 4451 NewMarket: &vegapb.NewMarket{ 4452 Changes: &vegapb.NewMarketConfiguration{ 4453 Instrument: &vegapb.InstrumentConfiguration{ 4454 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4455 Perpetual: &vegapb.PerpetualProduct{ 4456 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4457 vegapb.DataSourceContentTypeEthOracle, 4458 ), 4459 }, 4460 }, 4461 }, 4462 }, 4463 }, 4464 }, 4465 }, 4466 }) 4467 4468 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters"), commands.ErrIsRequired) 4469 } 4470 4471 func testNewPerpsMarketChangeSubmissionWithFiltersSucceeds(t *testing.T) { 4472 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4473 Terms: &vegapb.ProposalTerms{ 4474 Change: &vegapb.ProposalTerms_NewMarket{ 4475 NewMarket: &vegapb.NewMarket{ 4476 Changes: &vegapb.NewMarketConfiguration{ 4477 Instrument: &vegapb.InstrumentConfiguration{ 4478 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4479 Perpetual: &vegapb.PerpetualProduct{ 4480 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4481 vegapb.DataSourceContentTypeEthOracle, 4482 ).SetOracleConfig( 4483 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4484 EthOracle: &vegapb.EthCallSpec{ 4485 Filters: []*datapb.Filter{ 4486 {}, 4487 }, 4488 }, 4489 }, 4490 ), 4491 }, 4492 }, 4493 }, 4494 }, 4495 }, 4496 }, 4497 }, 4498 }) 4499 4500 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters"), commands.ErrIsRequired) 4501 } 4502 4503 func testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyFails(t *testing.T) { 4504 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4505 Terms: &vegapb.ProposalTerms{ 4506 Change: &vegapb.ProposalTerms_NewMarket{ 4507 NewMarket: &vegapb.NewMarket{ 4508 Changes: &vegapb.NewMarketConfiguration{ 4509 Instrument: &vegapb.InstrumentConfiguration{ 4510 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4511 Perpetual: &vegapb.PerpetualProduct{ 4512 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4513 vegapb.DataSourceContentTypeEthOracle, 4514 ).SetOracleConfig( 4515 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4516 EthOracle: &vegapb.EthCallSpec{ 4517 Filters: []*datapb.Filter{ 4518 {}, {}, 4519 }, 4520 }, 4521 }, 4522 ), 4523 }, 4524 }, 4525 }, 4526 }, 4527 }, 4528 }, 4529 }, 4530 }) 4531 4532 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.key"), commands.ErrIsNotValid) 4533 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.1.key"), commands.ErrIsNotValid) 4534 } 4535 4536 func testNewPerpsMarketChangeSubmissionWithFilterWithKeySucceeds(t *testing.T) { 4537 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4538 Terms: &vegapb.ProposalTerms{ 4539 Change: &vegapb.ProposalTerms_NewMarket{ 4540 NewMarket: &vegapb.NewMarket{ 4541 Changes: &vegapb.NewMarketConfiguration{ 4542 Instrument: &vegapb.InstrumentConfiguration{ 4543 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4544 Perpetual: &vegapb.PerpetualProduct{ 4545 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4546 vegapb.DataSourceContentTypeEthOracle, 4547 ).SetOracleConfig( 4548 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4549 EthOracle: &vegapb.EthCallSpec{ 4550 Filters: []*datapb.Filter{ 4551 { 4552 Key: &datapb.PropertyKey{}, 4553 }, { 4554 Key: &datapb.PropertyKey{}, 4555 }, 4556 }, 4557 }, 4558 }, 4559 ), 4560 }, 4561 }, 4562 }, 4563 }, 4564 }, 4565 }, 4566 }, 4567 }) 4568 4569 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.key"), commands.ErrIsNotValid) 4570 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.1.key"), commands.ErrIsNotValid) 4571 } 4572 4573 func testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyNameFails(t *testing.T) { 4574 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4575 Terms: &vegapb.ProposalTerms{ 4576 Change: &vegapb.ProposalTerms_NewMarket{ 4577 NewMarket: &vegapb.NewMarket{ 4578 Changes: &vegapb.NewMarketConfiguration{ 4579 Instrument: &vegapb.InstrumentConfiguration{ 4580 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4581 Perpetual: &vegapb.PerpetualProduct{ 4582 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4583 vegapb.DataSourceContentTypeEthOracle, 4584 ).SetOracleConfig( 4585 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4586 EthOracle: &vegapb.EthCallSpec{ 4587 Filters: []*datapb.Filter{ 4588 { 4589 Key: &datapb.PropertyKey{ 4590 Name: "", 4591 }, 4592 }, { 4593 Key: &datapb.PropertyKey{ 4594 Name: "", 4595 }, 4596 }, 4597 }, 4598 }, 4599 }, 4600 ), 4601 }, 4602 }, 4603 }, 4604 }, 4605 }, 4606 }, 4607 }, 4608 }) 4609 4610 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.key.name"), commands.ErrIsRequired) 4611 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.1.key.name"), commands.ErrIsRequired) 4612 } 4613 4614 func testNewPerpsMarketChangeSubmissionWithFilterWithKeyNameSucceeds(t *testing.T) { 4615 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4616 Terms: &vegapb.ProposalTerms{ 4617 Change: &vegapb.ProposalTerms_NewMarket{ 4618 NewMarket: &vegapb.NewMarket{ 4619 Changes: &vegapb.NewMarketConfiguration{ 4620 Instrument: &vegapb.InstrumentConfiguration{ 4621 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4622 Perpetual: &vegapb.PerpetualProduct{ 4623 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4624 vegapb.DataSourceContentTypeEthOracle, 4625 ).SetOracleConfig( 4626 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4627 EthOracle: &vegapb.EthCallSpec{ 4628 Filters: []*datapb.Filter{ 4629 { 4630 Key: &datapb.PropertyKey{ 4631 Name: "key1", 4632 }, 4633 }, { 4634 Key: &datapb.PropertyKey{ 4635 Name: "key2", 4636 }, 4637 }, 4638 }, 4639 }, 4640 }, 4641 ), 4642 }, 4643 }, 4644 }, 4645 }, 4646 }, 4647 }, 4648 }, 4649 }) 4650 4651 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.key.name"), commands.ErrIsRequired) 4652 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.1.key.name"), commands.ErrIsRequired) 4653 } 4654 4655 func testNewPerpsMarketChangeSubmissionWithFilterWithoutKeyTypeFails(t *testing.T) { 4656 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4657 Terms: &vegapb.ProposalTerms{ 4658 Change: &vegapb.ProposalTerms_NewMarket{ 4659 NewMarket: &vegapb.NewMarket{ 4660 Changes: &vegapb.NewMarketConfiguration{ 4661 Instrument: &vegapb.InstrumentConfiguration{ 4662 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4663 Perpetual: &vegapb.PerpetualProduct{ 4664 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4665 vegapb.DataSourceContentTypeEthOracle, 4666 ).SetOracleConfig( 4667 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4668 EthOracle: &vegapb.EthCallSpec{ 4669 Filters: []*datapb.Filter{ 4670 { 4671 Key: &datapb.PropertyKey{ 4672 Type: datapb.PropertyKey_TYPE_UNSPECIFIED, 4673 }, 4674 }, { 4675 Key: &datapb.PropertyKey{}, 4676 }, 4677 }, 4678 }, 4679 }, 4680 ), 4681 }, 4682 }, 4683 }, 4684 }, 4685 }, 4686 }, 4687 }, 4688 }) 4689 4690 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.key.type"), commands.ErrIsRequired) 4691 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.1.key.type"), commands.ErrIsRequired) 4692 } 4693 4694 func testNewPerpsMarketChangeSubmissionWithFilterWithKeyTypeSucceeds(t *testing.T) { 4695 testCases := []struct { 4696 msg string 4697 value datapb.PropertyKey_Type 4698 }{ 4699 { 4700 msg: "with EMPTY", 4701 value: datapb.PropertyKey_TYPE_EMPTY, 4702 }, { 4703 msg: "with INTEGER", 4704 value: datapb.PropertyKey_TYPE_INTEGER, 4705 }, { 4706 msg: "with STRING", 4707 value: datapb.PropertyKey_TYPE_STRING, 4708 }, { 4709 msg: "with BOOLEAN", 4710 value: datapb.PropertyKey_TYPE_BOOLEAN, 4711 }, { 4712 msg: "with DECIMAL", 4713 value: datapb.PropertyKey_TYPE_DECIMAL, 4714 }, { 4715 msg: "with TIMESTAMP", 4716 value: datapb.PropertyKey_TYPE_TIMESTAMP, 4717 }, 4718 } 4719 for _, tc := range testCases { 4720 t.Run(tc.msg, func(t *testing.T) { 4721 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4722 Terms: &vegapb.ProposalTerms{ 4723 Change: &vegapb.ProposalTerms_NewMarket{ 4724 NewMarket: &vegapb.NewMarket{ 4725 Changes: &vegapb.NewMarketConfiguration{ 4726 Instrument: &vegapb.InstrumentConfiguration{ 4727 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4728 Perpetual: &vegapb.PerpetualProduct{ 4729 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4730 vegapb.DataSourceContentTypeEthOracle, 4731 ).SetOracleConfig( 4732 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4733 EthOracle: &vegapb.EthCallSpec{ 4734 Filters: []*datapb.Filter{ 4735 { 4736 Key: &datapb.PropertyKey{ 4737 Type: tc.value, 4738 }, 4739 }, { 4740 Key: &datapb.PropertyKey{ 4741 Type: tc.value, 4742 }, 4743 }, 4744 }, 4745 }, 4746 }, 4747 ), 4748 }, 4749 }, 4750 }, 4751 }, 4752 }, 4753 }, 4754 }, 4755 }) 4756 4757 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.0.key.type"), commands.ErrIsRequired) 4758 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.1.key.type"), commands.ErrIsRequired) 4759 }) 4760 } 4761 } 4762 4763 func testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionsSucceeds(t *testing.T) { 4764 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4765 Terms: &vegapb.ProposalTerms{ 4766 Change: &vegapb.ProposalTerms_NewMarket{ 4767 NewMarket: &vegapb.NewMarket{ 4768 Changes: &vegapb.NewMarketConfiguration{ 4769 Instrument: &vegapb.InstrumentConfiguration{ 4770 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4771 Perpetual: &vegapb.PerpetualProduct{ 4772 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4773 vegapb.DataSourceContentTypeEthOracle, 4774 ).SetOracleConfig( 4775 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4776 EthOracle: &vegapb.EthCallSpec{ 4777 Filters: []*datapb.Filter{ 4778 { 4779 Conditions: []*datapb.Condition{}, 4780 }, 4781 }, 4782 }, 4783 }, 4784 ), 4785 }, 4786 }, 4787 }, 4788 }, 4789 }, 4790 }, 4791 }, 4792 }) 4793 4794 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.0.conditions"), commands.ErrIsRequired) 4795 } 4796 4797 func testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionOperatorFails(t *testing.T) { 4798 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4799 Terms: &vegapb.ProposalTerms{ 4800 Change: &vegapb.ProposalTerms_NewMarket{ 4801 NewMarket: &vegapb.NewMarket{ 4802 Changes: &vegapb.NewMarketConfiguration{ 4803 Instrument: &vegapb.InstrumentConfiguration{ 4804 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4805 Perpetual: &vegapb.PerpetualProduct{ 4806 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4807 vegapb.DataSourceContentTypeEthOracle, 4808 ).SetOracleConfig( 4809 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4810 EthOracle: &vegapb.EthCallSpec{ 4811 Filters: []*datapb.Filter{ 4812 { 4813 Conditions: []*datapb.Condition{ 4814 { 4815 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 4816 }, 4817 {}, 4818 }, 4819 }, 4820 }, 4821 }, 4822 }, 4823 ), 4824 }, 4825 }, 4826 }, 4827 }, 4828 }, 4829 }, 4830 }, 4831 }) 4832 4833 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 4834 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.conditions.1.operator"), commands.ErrIsRequired) 4835 } 4836 4837 func testNewPerpsMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds(t *testing.T) { 4838 testCases := []struct { 4839 msg string 4840 value datapb.Condition_Operator 4841 }{ 4842 { 4843 msg: "with EQUALS", 4844 value: datapb.Condition_OPERATOR_EQUALS, 4845 }, { 4846 msg: "with GREATER_THAN", 4847 value: datapb.Condition_OPERATOR_GREATER_THAN, 4848 }, { 4849 msg: "with GREATER_THAN_OR_EQUAL", 4850 value: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 4851 }, { 4852 msg: "with LESS_THAN", 4853 value: datapb.Condition_OPERATOR_LESS_THAN, 4854 }, { 4855 msg: "with LESS_THAN_OR_EQUAL", 4856 value: datapb.Condition_OPERATOR_LESS_THAN_OR_EQUAL, 4857 }, 4858 } 4859 for _, tc := range testCases { 4860 t.Run(tc.msg, func(t *testing.T) { 4861 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4862 Terms: &vegapb.ProposalTerms{ 4863 Change: &vegapb.ProposalTerms_NewMarket{ 4864 NewMarket: &vegapb.NewMarket{ 4865 Changes: &vegapb.NewMarketConfiguration{ 4866 Instrument: &vegapb.InstrumentConfiguration{ 4867 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4868 Perpetual: &vegapb.PerpetualProduct{ 4869 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4870 vegapb.DataSourceContentTypeEthOracle, 4871 ).SetOracleConfig( 4872 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4873 EthOracle: &vegapb.EthCallSpec{ 4874 Filters: []*datapb.Filter{ 4875 { 4876 Conditions: []*datapb.Condition{ 4877 { 4878 Operator: tc.value, 4879 }, 4880 { 4881 Operator: tc.value, 4882 }, 4883 }, 4884 }, 4885 }, 4886 }, 4887 }, 4888 ), 4889 }, 4890 }, 4891 }, 4892 }, 4893 }, 4894 }, 4895 }, 4896 }) 4897 4898 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 4899 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.1.conditions.0.operator"), commands.ErrIsRequired) 4900 }) 4901 } 4902 } 4903 4904 func testNewPerpsMarketChangeSubmissionWithFilterWithoutConditionValueFails(t *testing.T) { 4905 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4906 Terms: &vegapb.ProposalTerms{ 4907 Change: &vegapb.ProposalTerms_NewMarket{ 4908 NewMarket: &vegapb.NewMarket{ 4909 Changes: &vegapb.NewMarketConfiguration{ 4910 Instrument: &vegapb.InstrumentConfiguration{ 4911 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4912 Perpetual: &vegapb.PerpetualProduct{ 4913 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4914 vegapb.DataSourceContentTypeEthOracle, 4915 ).SetOracleConfig( 4916 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4917 EthOracle: &vegapb.EthCallSpec{ 4918 Filters: []*datapb.Filter{ 4919 { 4920 Conditions: []*datapb.Condition{ 4921 { 4922 Value: "", 4923 }, 4924 { 4925 Value: "", 4926 }, 4927 }, 4928 }, 4929 }, 4930 }, 4931 }, 4932 ), 4933 }, 4934 }, 4935 }, 4936 }, 4937 }, 4938 }, 4939 }, 4940 }) 4941 4942 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 4943 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_data.external.ethoracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 4944 } 4945 4946 func testNewPerpsMarketChangeSubmissionWithFilterWithConditionValueSucceeds(t *testing.T) { 4947 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4948 Terms: &vegapb.ProposalTerms{ 4949 Change: &vegapb.ProposalTerms_NewMarket{ 4950 NewMarket: &vegapb.NewMarket{ 4951 Changes: &vegapb.NewMarketConfiguration{ 4952 Instrument: &vegapb.InstrumentConfiguration{ 4953 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4954 Perpetual: &vegapb.PerpetualProduct{ 4955 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 4956 vegapb.DataSourceContentTypeEthOracle, 4957 ).SetOracleConfig( 4958 &vegapb.DataSourceDefinitionExternal_EthOracle{ 4959 EthOracle: &vegapb.EthCallSpec{ 4960 Filters: []*datapb.Filter{ 4961 { 4962 Conditions: []*datapb.Condition{ 4963 { 4964 Value: "value 1", 4965 }, 4966 { 4967 Value: "value 2", 4968 }, 4969 }, 4970 }, 4971 }, 4972 }, 4973 }, 4974 ), 4975 }, 4976 }, 4977 }, 4978 }, 4979 }, 4980 }, 4981 }, 4982 }) 4983 4984 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 4985 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec.external.ethoracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 4986 } 4987 4988 func testNewPerpsMarketChangeSubmissionWithoutDataSourceSpecBindingFails(t *testing.T) { 4989 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4990 Terms: &vegapb.ProposalTerms{ 4991 Change: &vegapb.ProposalTerms_NewMarket{ 4992 NewMarket: &vegapb.NewMarket{ 4993 Changes: &vegapb.NewMarketConfiguration{ 4994 Instrument: &vegapb.InstrumentConfiguration{ 4995 Product: &vegapb.InstrumentConfiguration_Perpetual{ 4996 Perpetual: &vegapb.PerpetualProduct{}, 4997 }, 4998 }, 4999 }, 5000 }, 5001 }, 5002 }, 5003 }) 5004 5005 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_binding"), commands.ErrIsRequired) 5006 } 5007 5008 func testNewPerpsMarketChangeSubmissionWithDataSourceSpecBindingSucceeds(t *testing.T) { 5009 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5010 Terms: &vegapb.ProposalTerms{ 5011 Change: &vegapb.ProposalTerms_NewMarket{ 5012 NewMarket: &vegapb.NewMarket{ 5013 Changes: &vegapb.NewMarketConfiguration{ 5014 Instrument: &vegapb.InstrumentConfiguration{ 5015 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5016 Perpetual: &vegapb.PerpetualProduct{ 5017 DataSourceSpecBinding: &vegapb.DataSourceSpecToPerpetualBinding{}, 5018 }, 5019 }, 5020 }, 5021 }, 5022 }, 5023 }, 5024 }, 5025 }) 5026 5027 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_binding"), commands.ErrIsRequired) 5028 } 5029 5030 func testNewPerpsMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds(t *testing.T) { 5031 testNewPerpsMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t, &vegapb.DataSourceSpecToPerpetualBinding{SettlementDataProperty: "key1"}, "settlement_data_property", "key1") 5032 } 5033 5034 func testNewPerpsMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t *testing.T, binding *vegapb.DataSourceSpecToPerpetualBinding, bindingName string, bindingKey string) { 5035 t.Helper() 5036 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5037 Terms: &vegapb.ProposalTerms{ 5038 Change: &vegapb.ProposalTerms_NewMarket{ 5039 NewMarket: &vegapb.NewMarket{ 5040 Changes: &vegapb.NewMarketConfiguration{ 5041 Instrument: &vegapb.InstrumentConfiguration{ 5042 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5043 Perpetual: &vegapb.PerpetualProduct{ 5044 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 5045 vegapb.DataSourceContentTypeEthOracle, 5046 ).SetOracleConfig( 5047 &vegapb.DataSourceDefinitionExternal_EthOracle{ 5048 EthOracle: &vegapb.EthCallSpec{ 5049 Filters: []*datapb.Filter{ 5050 { 5051 Key: &datapb.PropertyKey{ 5052 Name: bindingKey, 5053 }, 5054 }, { 5055 Key: &datapb.PropertyKey{}, 5056 }, 5057 }, 5058 }, 5059 }, 5060 ), 5061 DataSourceSpecBinding: binding, 5062 }, 5063 }, 5064 }, 5065 }, 5066 }, 5067 }, 5068 }, 5069 }) 5070 5071 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 5072 } 5073 5074 func testNewPerpsMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t *testing.T, binding *vegapb.DataSourceSpecToPerpetualBinding, bindingName string) { 5075 t.Helper() 5076 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5077 Terms: &vegapb.ProposalTerms{ 5078 Change: &vegapb.ProposalTerms_NewMarket{ 5079 NewMarket: &vegapb.NewMarket{ 5080 Changes: &vegapb.NewMarketConfiguration{ 5081 Instrument: &vegapb.InstrumentConfiguration{ 5082 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5083 Perpetual: &vegapb.PerpetualProduct{ 5084 DataSourceSpecBinding: binding, 5085 }, 5086 }, 5087 }, 5088 }, 5089 }, 5090 }, 5091 }, 5092 }) 5093 5094 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 5095 } 5096 5097 func testNewPerpsMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails(t *testing.T) { 5098 testNewPerpsMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t, &vegapb.DataSourceSpecToPerpetualBinding{SettlementDataProperty: "My property"}, "settlement_data_property") 5099 } 5100 5101 func testNewPerpsMarketChangeSubmissionWithSettlementDataPropertySucceeds(t *testing.T) { 5102 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5103 Terms: &vegapb.ProposalTerms{ 5104 Change: &vegapb.ProposalTerms_NewMarket{ 5105 NewMarket: &vegapb.NewMarket{ 5106 Changes: &vegapb.NewMarketConfiguration{ 5107 Instrument: &vegapb.InstrumentConfiguration{ 5108 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5109 Perpetual: &vegapb.PerpetualProduct{ 5110 DataSourceSpecBinding: &vegapb.DataSourceSpecToPerpetualBinding{ 5111 SettlementDataProperty: "My property", 5112 }, 5113 }, 5114 }, 5115 }, 5116 }, 5117 }, 5118 }, 5119 }, 5120 }) 5121 5122 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_binding.settlement_data_property"), commands.ErrIsRequired) 5123 } 5124 5125 func testNewPerpsMarketChangeSubmissionWithInternalCompositePriceConfig(t *testing.T) { 5126 cases := getCompositePriceConfigurationCases() 5127 for _, c := range cases { 5128 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5129 Terms: &vegapb.ProposalTerms{ 5130 Change: &vegapb.ProposalTerms_NewMarket{ 5131 NewMarket: &vegapb.NewMarket{ 5132 Changes: &vegapb.NewMarketConfiguration{ 5133 Instrument: &vegapb.InstrumentConfiguration{ 5134 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5135 Perpetual: &vegapb.PerpetualProduct{ 5136 DataSourceSpecBinding: &vegapb.DataSourceSpecToPerpetualBinding{ 5137 SettlementDataProperty: "My property", 5138 }, 5139 InternalCompositePriceConfiguration: c.mpc, 5140 }, 5141 }, 5142 }, 5143 }, 5144 }, 5145 }, 5146 }, 5147 }) 5148 if len(c.field) > 0 { 5149 if c.err != nil { 5150 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.internal_composite_price_configuration."+c.field), c.err) 5151 } else { 5152 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.internal_composite_price_configuration."+c.field)) 5153 } 5154 } else { 5155 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.perps.internal_composite_price_configuration"), c.err) 5156 } 5157 } 5158 } 5159 5160 func TestNewPerpsMarketChangeSubmissionProductParameters(t *testing.T) { 5161 cases := []struct { 5162 product vegapb.PerpetualProduct 5163 err error 5164 path string 5165 desc string 5166 }{ 5167 // margin_funding_factor 5168 { 5169 product: vegapb.PerpetualProduct{ 5170 MarginFundingFactor: "", 5171 }, 5172 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.margin_funding_factor", 5173 err: commands.ErrIsRequired, 5174 desc: "margin_funding_factor is empty", 5175 }, 5176 { 5177 product: vegapb.PerpetualProduct{ 5178 MarginFundingFactor: "nope", 5179 }, 5180 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.margin_funding_factor", 5181 err: commands.ErrIsNotValidNumber, 5182 desc: "margin_funding_factor is not a valid number", 5183 }, 5184 { 5185 product: vegapb.PerpetualProduct{ 5186 MarginFundingFactor: "-10", 5187 }, 5188 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.margin_funding_factor", 5189 err: commands.ErrMustBeWithinRange01, 5190 desc: "margin_funding_factor is not within range (< 0)", 5191 }, 5192 { 5193 product: vegapb.PerpetualProduct{ 5194 MarginFundingFactor: "10", 5195 }, 5196 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.margin_funding_factor", 5197 err: commands.ErrMustBeWithinRange01, 5198 desc: "margin_funding_factor is not within range (> 1)", 5199 }, 5200 { 5201 product: vegapb.PerpetualProduct{ 5202 MarginFundingFactor: "0.5", 5203 }, 5204 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.margin_funding_factor", 5205 desc: "margin_funding_factor is valid", 5206 }, 5207 // interest_rate 5208 { 5209 product: vegapb.PerpetualProduct{ 5210 InterestRate: "", 5211 }, 5212 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5213 err: commands.ErrIsRequired, 5214 desc: "interest_rate is empty", 5215 }, 5216 { 5217 product: vegapb.PerpetualProduct{ 5218 InterestRate: "nope", 5219 }, 5220 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5221 err: commands.ErrIsNotValidNumber, 5222 desc: "interest_rate is not a valid number", 5223 }, 5224 { 5225 product: vegapb.PerpetualProduct{ 5226 InterestRate: "-10", 5227 }, 5228 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5229 err: commands.ErrMustBeWithinRange11, 5230 desc: "interest_rate is not within range (< -1)", 5231 }, 5232 { 5233 product: vegapb.PerpetualProduct{ 5234 InterestRate: "10", 5235 }, 5236 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5237 err: commands.ErrMustBeWithinRange11, 5238 desc: "interest_rate is not within range (> 1)", 5239 }, 5240 { 5241 product: vegapb.PerpetualProduct{ 5242 InterestRate: "0.5", 5243 }, 5244 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5245 desc: "interest_rate is valid", 5246 }, 5247 { 5248 product: vegapb.PerpetualProduct{ 5249 InterestRate: "-0.5", 5250 }, 5251 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.interest_rate", 5252 desc: "interest_rate is valid", 5253 }, 5254 // clamp_lower_bound (0053-PERP-042) 5255 { 5256 product: vegapb.PerpetualProduct{ 5257 ClampLowerBound: "", 5258 }, 5259 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5260 err: commands.ErrIsRequired, 5261 desc: "clamp_lower_bound is empty", 5262 }, 5263 { 5264 product: vegapb.PerpetualProduct{ 5265 ClampLowerBound: "nope", 5266 }, 5267 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5268 err: commands.ErrIsNotValidNumber, 5269 desc: "clamp_lower_bound is not a valid number", 5270 }, 5271 { 5272 product: vegapb.PerpetualProduct{ 5273 ClampLowerBound: "-10", 5274 }, 5275 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5276 err: commands.ErrMustBeWithinRange11, 5277 desc: "clamp_lower_bound is not within range (< -1)", 5278 }, 5279 { 5280 product: vegapb.PerpetualProduct{ 5281 ClampLowerBound: "10", 5282 }, 5283 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5284 err: commands.ErrMustBeWithinRange11, 5285 desc: "clamp_lower_bound is not within range (> 1)", 5286 }, 5287 { 5288 product: vegapb.PerpetualProduct{ 5289 ClampLowerBound: "0.5", 5290 }, 5291 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5292 desc: "clamp_lower_bound is valid", 5293 }, 5294 { 5295 product: vegapb.PerpetualProduct{ 5296 ClampLowerBound: "-0.5", 5297 }, 5298 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_lower_bound", 5299 desc: "clamp_lower_bound is valid", 5300 }, 5301 // clamp_upper_bound (0053-PERP-042) 5302 { 5303 product: vegapb.PerpetualProduct{ 5304 ClampUpperBound: "", 5305 }, 5306 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5307 err: commands.ErrIsRequired, 5308 desc: "clamp_upper_bound is empty", 5309 }, 5310 { 5311 product: vegapb.PerpetualProduct{ 5312 ClampUpperBound: "nope", 5313 }, 5314 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5315 err: commands.ErrIsNotValidNumber, 5316 desc: "clamp_upper_bound is not a valid number", 5317 }, 5318 { 5319 product: vegapb.PerpetualProduct{ 5320 ClampUpperBound: "-10", 5321 }, 5322 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5323 err: commands.ErrMustBeWithinRange11, 5324 desc: "clamp_upper_bound is not within range (< -1)", 5325 }, 5326 { 5327 product: vegapb.PerpetualProduct{ 5328 ClampUpperBound: "10", 5329 }, 5330 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5331 err: commands.ErrMustBeWithinRange11, 5332 desc: "clamp_upper_bound is not within range (> 1)", 5333 }, 5334 { 5335 product: vegapb.PerpetualProduct{ 5336 ClampUpperBound: "0.5", 5337 }, 5338 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5339 desc: "clamp_upper_bound is valid", 5340 }, 5341 { 5342 product: vegapb.PerpetualProduct{ 5343 ClampUpperBound: "-0.5", 5344 }, 5345 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5346 desc: "clamp_upper_bound is valid", 5347 }, 5348 // clamp lower and upper (0053-PERP-042) 5349 { 5350 product: vegapb.PerpetualProduct{ 5351 ClampLowerBound: "0.5", 5352 ClampUpperBound: "0.5", 5353 }, 5354 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5355 desc: "clamp_upper_bound == clamp_lower_bound is valid", 5356 }, 5357 { 5358 product: vegapb.PerpetualProduct{ 5359 ClampLowerBound: "0.4", 5360 ClampUpperBound: "0.5", 5361 }, 5362 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5363 desc: "clamp_upper_bound > clamp_lower_bound is valid", 5364 }, 5365 { 5366 product: vegapb.PerpetualProduct{ 5367 ClampLowerBound: "0.5", 5368 ClampUpperBound: "0.4", 5369 }, 5370 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.clamp_upper_bound", 5371 err: commands.ErrMustBeGTEClampLowerBound, 5372 desc: "clamp_upper_bound < clamp_lower_bound is invalid", 5373 }, 5374 } 5375 5376 for _, v := range cases { 5377 t.Run(v.desc, func(t *testing.T) { 5378 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5379 Terms: &vegapb.ProposalTerms{ 5380 Change: &vegapb.ProposalTerms_NewMarket{ 5381 NewMarket: &vegapb.NewMarket{ 5382 Changes: &vegapb.NewMarketConfiguration{ 5383 Instrument: &vegapb.InstrumentConfiguration{ 5384 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5385 Perpetual: &v.product, 5386 }, 5387 }, 5388 }, 5389 }, 5390 }, 5391 }, 5392 }) 5393 5394 errs := err.Get(v.path) 5395 5396 // no errors expected 5397 if v.err == nil { 5398 assert.Len(t, errs, 0, v.desc) 5399 return 5400 } 5401 5402 assert.Contains(t, errs, v.err, v.desc) 5403 }) 5404 } 5405 } 5406 5407 func testNewPerpsMarketWithFundingRateModifiers(t *testing.T) { 5408 cases := []struct { 5409 product vegapb.PerpetualProduct 5410 err error 5411 path string 5412 desc string 5413 }{ 5414 { 5415 product: vegapb.PerpetualProduct{ 5416 FundingRateScalingFactor: ptr.From("hello"), 5417 }, 5418 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_scaling_factor", 5419 err: commands.ErrIsNotValidNumber, 5420 }, 5421 { 5422 product: vegapb.PerpetualProduct{ 5423 FundingRateScalingFactor: ptr.From("-10"), 5424 }, 5425 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_scaling_factor", 5426 err: commands.ErrMustBePositiveOrZero, 5427 }, 5428 { 5429 product: vegapb.PerpetualProduct{ 5430 FundingRateScalingFactor: ptr.From("0.1"), 5431 }, 5432 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_scaling_factor", 5433 }, 5434 { 5435 product: vegapb.PerpetualProduct{ 5436 FundingRateLowerBound: ptr.From("hello"), 5437 }, 5438 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_lower_bound", 5439 err: commands.ErrIsNotValidNumber, 5440 }, 5441 { 5442 product: vegapb.PerpetualProduct{ 5443 FundingRateLowerBound: ptr.From("-100"), 5444 }, 5445 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_lower_bound", 5446 }, 5447 { 5448 product: vegapb.PerpetualProduct{ 5449 FundingRateUpperBound: ptr.From("hello"), 5450 }, 5451 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_upper_bound", 5452 err: commands.ErrIsNotValidNumber, 5453 }, 5454 { 5455 product: vegapb.PerpetualProduct{ 5456 FundingRateUpperBound: ptr.From("100"), 5457 }, 5458 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_upper_bound", 5459 }, 5460 { 5461 product: vegapb.PerpetualProduct{ 5462 FundingRateUpperBound: ptr.From("100"), 5463 FundingRateLowerBound: ptr.From("200"), 5464 }, 5465 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.funding_rate_lower_bound", 5466 err: commands.ErrIsNotValid, 5467 }, 5468 } 5469 5470 for _, v := range cases { 5471 t.Run(v.desc, func(t *testing.T) { 5472 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5473 Terms: &vegapb.ProposalTerms{ 5474 Change: &vegapb.ProposalTerms_NewMarket{ 5475 NewMarket: &vegapb.NewMarket{ 5476 Changes: &vegapb.NewMarketConfiguration{ 5477 Instrument: &vegapb.InstrumentConfiguration{ 5478 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5479 Perpetual: &v.product, 5480 }, 5481 }, 5482 }, 5483 }, 5484 }, 5485 }, 5486 }) 5487 errs := err.Get(v.path) 5488 5489 // no errors expected 5490 if v.err == nil { 5491 assert.Len(t, errs, 0, v.desc) 5492 return 5493 } 5494 assert.Contains(t, errs, v.err, v.desc) 5495 }) 5496 } 5497 } 5498 5499 func TestNewPerpsMarketChangeSubmissionSettlementSchedule(t *testing.T) { 5500 cases := []struct { 5501 product vegapb.PerpetualProduct 5502 err error 5503 path string 5504 desc string 5505 }{ 5506 { 5507 product: vegapb.PerpetualProduct{ 5508 DataSourceSpecForSettlementSchedule: &vegapb.DataSourceDefinition{ 5509 SourceType: &vegapb.DataSourceDefinition_Internal{ 5510 Internal: &vega.DataSourceDefinitionInternal{ 5511 SourceType: &vegapb.DataSourceDefinitionInternal_TimeTrigger{ 5512 TimeTrigger: &vegapb.DataSourceSpecConfigurationTimeTrigger{ 5513 Triggers: []*datapb.InternalTimeTrigger{ 5514 { 5515 Initial: nil, 5516 Every: 0, 5517 }, 5518 }, 5519 }, 5520 }, 5521 }, 5522 }, 5523 }, 5524 }, 5525 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_schedule.internal.timetrigger.triggers.0.every", 5526 err: commands.ErrIsNotValid, 5527 desc: "not a valid every", 5528 }, 5529 { 5530 product: vegapb.PerpetualProduct{ 5531 DataSourceSpecForSettlementSchedule: &vegapb.DataSourceDefinition{ 5532 SourceType: &vegapb.DataSourceDefinition_Internal{ 5533 Internal: &vega.DataSourceDefinitionInternal{ 5534 SourceType: &vegapb.DataSourceDefinitionInternal_TimeTrigger{ 5535 TimeTrigger: &vegapb.DataSourceSpecConfigurationTimeTrigger{ 5536 Triggers: []*datapb.InternalTimeTrigger{ 5537 { 5538 Initial: nil, 5539 Every: -1, 5540 }, 5541 }, 5542 }, 5543 }, 5544 }, 5545 }, 5546 }, 5547 }, 5548 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_schedule.internal.timetrigger.triggers.0.every", 5549 err: commands.ErrIsNotValid, 5550 desc: "not a valid every", 5551 }, 5552 { 5553 product: vegapb.PerpetualProduct{ 5554 DataSourceSpecForSettlementSchedule: &vegapb.DataSourceDefinition{ 5555 SourceType: &vegapb.DataSourceDefinition_Internal{ 5556 Internal: &vega.DataSourceDefinitionInternal{ 5557 SourceType: &vegapb.DataSourceDefinitionInternal_TimeTrigger{ 5558 TimeTrigger: &vegapb.DataSourceSpecConfigurationTimeTrigger{ 5559 Triggers: []*datapb.InternalTimeTrigger{ 5560 { 5561 Initial: ptr.From(int64(-1)), 5562 Every: 100, 5563 }, 5564 }, 5565 }, 5566 }, 5567 }, 5568 }, 5569 }, 5570 }, 5571 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_schedule.internal.timetrigger.triggers.0.initial", 5572 err: commands.ErrIsNotValid, 5573 desc: "not a valid every", 5574 }, 5575 { 5576 product: vegapb.PerpetualProduct{ 5577 DataSourceSpecForSettlementSchedule: &vegapb.DataSourceDefinition{ 5578 SourceType: &vegapb.DataSourceDefinition_Internal{ 5579 Internal: &vega.DataSourceDefinitionInternal{ 5580 SourceType: &vegapb.DataSourceDefinitionInternal_TimeTrigger{ 5581 TimeTrigger: &vegapb.DataSourceSpecConfigurationTimeTrigger{ 5582 Triggers: []*datapb.InternalTimeTrigger{ 5583 { 5584 Initial: nil, 5585 Every: 100, 5586 }, 5587 }, 5588 }, 5589 }, 5590 }, 5591 }, 5592 }, 5593 }, 5594 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_schedule.internal.timetrigger", 5595 desc: "valid with initial nil", 5596 }, 5597 { 5598 product: vegapb.PerpetualProduct{ 5599 DataSourceSpecForSettlementSchedule: &vegapb.DataSourceDefinition{ 5600 SourceType: &vegapb.DataSourceDefinition_Internal{ 5601 Internal: &vega.DataSourceDefinitionInternal{ 5602 SourceType: &vegapb.DataSourceDefinitionInternal_TimeTrigger{ 5603 TimeTrigger: &vegapb.DataSourceSpecConfigurationTimeTrigger{ 5604 Triggers: []*datapb.InternalTimeTrigger{ 5605 { 5606 Initial: ptr.From(int64(100)), 5607 Every: 100, 5608 }, 5609 }, 5610 }, 5611 }, 5612 }, 5613 }, 5614 }, 5615 }, 5616 path: "proposal_submission.terms.change.new_market.changes.instrument.product.perps.data_source_spec_for_settlement_schedule.internal.timetrigger", 5617 desc: "valid", 5618 }, 5619 } 5620 5621 for _, v := range cases { 5622 t.Run(v.desc, func(t *testing.T) { 5623 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5624 Terms: &vegapb.ProposalTerms{ 5625 Change: &vegapb.ProposalTerms_NewMarket{ 5626 NewMarket: &vegapb.NewMarket{ 5627 Changes: &vegapb.NewMarketConfiguration{ 5628 Instrument: &vegapb.InstrumentConfiguration{ 5629 Product: &vegapb.InstrumentConfiguration_Perpetual{ 5630 Perpetual: &v.product, 5631 }, 5632 }, 5633 }, 5634 }, 5635 }, 5636 }, 5637 }) 5638 5639 errs := err.Get(v.path) 5640 5641 // no errors expected 5642 if v.err == nil { 5643 assert.Len(t, errs, 0, v.desc) 5644 return 5645 } 5646 5647 assert.Contains(t, errs, v.err, v.desc) 5648 }) 5649 } 5650 } 5651 5652 func testFutureMarketSubmissionWithInternalTimeTriggerTerminationDataFails(t *testing.T) { 5653 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5654 Terms: &vegapb.ProposalTerms{ 5655 Change: &vegapb.ProposalTerms_NewMarket{ 5656 NewMarket: &vegapb.NewMarket{ 5657 Changes: &vegapb.NewMarketConfiguration{ 5658 Instrument: &vegapb.InstrumentConfiguration{ 5659 Product: &vegapb.InstrumentConfiguration_Future{ 5660 Future: &vegapb.FutureProduct{ 5661 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 5662 vegapb.DataSourceContentTypeOracle, 5663 ).SetOracleConfig( 5664 &vegapb.DataSourceDefinitionExternal_Oracle{ 5665 Oracle: &vegapb.DataSourceSpecConfiguration{ 5666 Signers: []*datapb.Signer{ 5667 { 5668 Signer: &datapb.Signer_EthAddress{ 5669 EthAddress: &datapb.ETHAddress{ 5670 Address: "", 5671 }, 5672 }, 5673 }, 5674 }, 5675 Filters: []*datapb.Filter{ 5676 { 5677 Key: &datapb.PropertyKey{ 5678 Name: "vegaprotocol.builtin.prices.ETH.value", 5679 Type: datapb.PropertyKey_TYPE_INTEGER, 5680 }, 5681 Conditions: []*datapb.Condition{ 5682 { 5683 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 5684 }, 5685 }, 5686 }, 5687 }, 5688 }, 5689 }, 5690 ), 5691 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 5692 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 5693 ).SetTimeTriggerConditionConfig( 5694 []*datapb.Condition{ 5695 { 5696 // It does not matter what conditions are set here 5697 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 5698 }, 5699 }, 5700 ), 5701 }, 5702 }, 5703 }, 5704 }, 5705 }, 5706 }, 5707 }, 5708 }) 5709 5710 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.timetrigger"), commands.ErrIsNotValid) 5711 } 5712 5713 func testFutureMarketSubmissionWithInternalTimeTriggerSettlementDataFails(t *testing.T) { 5714 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5715 Terms: &vegapb.ProposalTerms{ 5716 Change: &vegapb.ProposalTerms_NewMarket{ 5717 NewMarket: &vegapb.NewMarket{ 5718 Changes: &vegapb.NewMarketConfiguration{ 5719 Instrument: &vegapb.InstrumentConfiguration{ 5720 Product: &vegapb.InstrumentConfiguration_Future{ 5721 Future: &vegapb.FutureProduct{ 5722 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 5723 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 5724 ).SetTimeTriggerConditionConfig( 5725 []*datapb.Condition{ 5726 { 5727 // It does not matter what conditions are set here 5728 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 5729 }, 5730 }, 5731 ), 5732 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 5733 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 5734 ).SetTimeTriggerConditionConfig( 5735 []*datapb.Condition{ 5736 { 5737 // It does not matter what conditions are set here 5738 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 5739 }, 5740 }, 5741 ), 5742 }, 5743 }, 5744 }, 5745 }, 5746 }, 5747 }, 5748 }, 5749 }) 5750 5751 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data.internal.timetrigger"), commands.ErrIsNotValid) 5752 } 5753 5754 func TestNewMarketChangeSubmissionWithInvalidLpRangeFails(t *testing.T) { 5755 priceRanges := []string{"banana", "-1", "0", "101"} 5756 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20} 5757 5758 for i, v := range priceRanges { 5759 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5760 Terms: &protoTypes.ProposalTerms{ 5761 Change: &protoTypes.ProposalTerms_NewMarket{ 5762 NewMarket: &protoTypes.NewMarket{ 5763 Changes: &protoTypes.NewMarketConfiguration{ 5764 Instrument: &protoTypes.InstrumentConfiguration{ 5765 Product: &protoTypes.InstrumentConfiguration_Future{}, 5766 }, 5767 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5768 PriceRange: v, 5769 }, 5770 }, 5771 }, 5772 }, 5773 }, 5774 }) 5775 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.price_range"), errors[i]) 5776 } 5777 } 5778 5779 func TestNewMarketChangeSubmissionWithInvalidMinTimeFractionFails(t *testing.T) { 5780 minTimeFraction := []string{"banana", "-1", "-1.1", "1.1", "100"} 5781 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01} 5782 5783 for i, v := range minTimeFraction { 5784 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5785 Terms: &protoTypes.ProposalTerms{ 5786 Change: &protoTypes.ProposalTerms_NewMarket{ 5787 NewMarket: &protoTypes.NewMarket{ 5788 Changes: &protoTypes.NewMarketConfiguration{ 5789 Instrument: &protoTypes.InstrumentConfiguration{ 5790 Product: &protoTypes.InstrumentConfiguration_Future{}, 5791 }, 5792 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5793 CommitmentMinTimeFraction: v, 5794 }, 5795 }, 5796 }, 5797 }, 5798 }, 5799 }) 5800 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.commitment_min_time_fraction"), errors[i]) 5801 } 5802 } 5803 5804 func TestNewMarketChangeSubmissionWithValidMinTimeFractionSucceeds(t *testing.T) { 5805 minTimeFraction := []string{"0", "0.1", "0.99", "1"} 5806 5807 for _, v := range minTimeFraction { 5808 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5809 Terms: &protoTypes.ProposalTerms{ 5810 Change: &protoTypes.ProposalTerms_NewMarket{ 5811 NewMarket: &protoTypes.NewMarket{ 5812 Changes: &protoTypes.NewMarketConfiguration{ 5813 Instrument: &protoTypes.InstrumentConfiguration{ 5814 Product: &protoTypes.InstrumentConfiguration_Future{}, 5815 }, 5816 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5817 CommitmentMinTimeFraction: v, 5818 }, 5819 }, 5820 }, 5821 }, 5822 }, 5823 }) 5824 5825 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01} 5826 for _, e := range errors { 5827 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.commitment_min_time_fraction"), e) 5828 } 5829 } 5830 } 5831 5832 func TestNewMarketChangeSubmissionWithInvalidCompetitionFactorFails(t *testing.T) { 5833 competitionFactors := []string{"banana", "-1", "-1.1", "1.1", "100"} 5834 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01} 5835 5836 for i, v := range competitionFactors { 5837 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5838 Terms: &protoTypes.ProposalTerms{ 5839 Change: &protoTypes.ProposalTerms_NewMarket{ 5840 NewMarket: &protoTypes.NewMarket{ 5841 Changes: &protoTypes.NewMarketConfiguration{ 5842 Instrument: &protoTypes.InstrumentConfiguration{ 5843 Product: &protoTypes.InstrumentConfiguration_Future{}, 5844 }, 5845 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5846 SlaCompetitionFactor: v, 5847 }, 5848 }, 5849 }, 5850 }, 5851 }, 5852 }) 5853 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.sla_competition_factor"), errors[i]) 5854 } 5855 } 5856 5857 func TestNewMarketChangeSubmissionWithValidCompetitionFactorSucceeds(t *testing.T) { 5858 minTimeFraction := []string{"0", "0.1", "0.99", "1"} 5859 5860 for _, v := range minTimeFraction { 5861 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5862 Terms: &protoTypes.ProposalTerms{ 5863 Change: &protoTypes.ProposalTerms_NewMarket{ 5864 NewMarket: &protoTypes.NewMarket{ 5865 Changes: &protoTypes.NewMarketConfiguration{ 5866 Instrument: &protoTypes.InstrumentConfiguration{ 5867 Product: &protoTypes.InstrumentConfiguration_Future{}, 5868 }, 5869 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5870 SlaCompetitionFactor: v, 5871 }, 5872 }, 5873 }, 5874 }, 5875 }, 5876 }) 5877 5878 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01} 5879 for _, e := range errors { 5880 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.sla_competition_factor"), e) 5881 } 5882 } 5883 } 5884 5885 func TestNewMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails(t *testing.T) { 5886 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5887 Terms: &protoTypes.ProposalTerms{ 5888 Change: &protoTypes.ProposalTerms_NewMarket{ 5889 NewMarket: &protoTypes.NewMarket{ 5890 Changes: &protoTypes.NewMarketConfiguration{ 5891 Instrument: &protoTypes.InstrumentConfiguration{ 5892 Product: &protoTypes.InstrumentConfiguration_Future{}, 5893 }, 5894 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5895 PerformanceHysteresisEpochs: 367, 5896 }, 5897 }, 5898 }, 5899 }, 5900 }, 5901 }) 5902 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBeLessThen366) 5903 } 5904 5905 func TestNewMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds(t *testing.T) { 5906 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5907 Terms: &protoTypes.ProposalTerms{ 5908 Change: &protoTypes.ProposalTerms_NewMarket{ 5909 NewMarket: &protoTypes.NewMarket{ 5910 Changes: &protoTypes.NewMarketConfiguration{ 5911 Instrument: &protoTypes.InstrumentConfiguration{ 5912 Product: &protoTypes.InstrumentConfiguration_Future{}, 5913 }, 5914 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5915 PerformanceHysteresisEpochs: 1, 5916 }, 5917 }, 5918 }, 5919 }, 5920 }, 5921 }) 5922 5923 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBePositive) 5924 } 5925 5926 func testNewMarketChangeSubmissionWithInvalidLpRangeFails(t *testing.T) { 5927 priceRanges := []string{"banana", "-1", "0", "101"} 5928 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20} 5929 5930 for i, v := range priceRanges { 5931 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5932 Terms: &protoTypes.ProposalTerms{ 5933 Change: &protoTypes.ProposalTerms_NewMarket{ 5934 NewMarket: &protoTypes.NewMarket{ 5935 Changes: &protoTypes.NewMarketConfiguration{ 5936 Instrument: &protoTypes.InstrumentConfiguration{ 5937 Product: &protoTypes.InstrumentConfiguration_Future{}, 5938 }, 5939 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5940 PriceRange: v, 5941 }, 5942 }, 5943 }, 5944 }, 5945 }, 5946 }) 5947 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.price_range"), errors[i]) 5948 } 5949 } 5950 5951 func testNewMarketChangeSubmissionWithValidLpRangeSucceeds(t *testing.T) { 5952 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5953 Terms: &protoTypes.ProposalTerms{ 5954 Change: &protoTypes.ProposalTerms_NewMarket{ 5955 NewMarket: &protoTypes.NewMarket{ 5956 Changes: &protoTypes.NewMarketConfiguration{ 5957 Instrument: &protoTypes.InstrumentConfiguration{ 5958 Product: &protoTypes.InstrumentConfiguration_Future{}, 5959 }, 5960 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5961 PriceRange: "50", 5962 }, 5963 }, 5964 }, 5965 }, 5966 }, 5967 }) 5968 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBePositive, commands.ErrMustBePositive, commands.ErrMustBeAtMost100} 5969 for _, e := range errors { 5970 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.price_range"), e) 5971 } 5972 } 5973 5974 func testNewMarketChangeSubmissionWithInvalidMinTimeFractionFails(t *testing.T) { 5975 minTimeFraction := []string{"banana", "-1", "-1.1", "1.1", "100"} 5976 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01} 5977 5978 for i, v := range minTimeFraction { 5979 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 5980 Terms: &protoTypes.ProposalTerms{ 5981 Change: &protoTypes.ProposalTerms_NewMarket{ 5982 NewMarket: &protoTypes.NewMarket{ 5983 Changes: &protoTypes.NewMarketConfiguration{ 5984 Instrument: &protoTypes.InstrumentConfiguration{ 5985 Product: &protoTypes.InstrumentConfiguration_Future{}, 5986 }, 5987 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 5988 CommitmentMinTimeFraction: v, 5989 }, 5990 }, 5991 }, 5992 }, 5993 }, 5994 }) 5995 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.commitment_min_time_fraction"), errors[i]) 5996 } 5997 } 5998 5999 func testNewMarketChangeSubmissionWithValidMinTimeFractionSucceeds(t *testing.T) { 6000 minTimeFraction := []string{"0", "0.1", "0.99", "1"} 6001 6002 for _, v := range minTimeFraction { 6003 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6004 Terms: &protoTypes.ProposalTerms{ 6005 Change: &protoTypes.ProposalTerms_NewMarket{ 6006 NewMarket: &protoTypes.NewMarket{ 6007 Changes: &protoTypes.NewMarketConfiguration{ 6008 Instrument: &protoTypes.InstrumentConfiguration{ 6009 Product: &protoTypes.InstrumentConfiguration_Future{}, 6010 }, 6011 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 6012 CommitmentMinTimeFraction: v, 6013 }, 6014 }, 6015 }, 6016 }, 6017 }, 6018 }) 6019 6020 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01} 6021 for _, e := range errors { 6022 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.commitment_min_time_fraction"), e) 6023 } 6024 } 6025 } 6026 6027 func testNewMarketChangeSubmissionWithInvalidCompetitionFactorFails(t *testing.T) { 6028 competitionFactors := []string{"banana", "-1", "-1.1", "1.1", "100"} 6029 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01} 6030 6031 for i, v := range competitionFactors { 6032 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6033 Terms: &protoTypes.ProposalTerms{ 6034 Change: &protoTypes.ProposalTerms_NewMarket{ 6035 NewMarket: &protoTypes.NewMarket{ 6036 Changes: &protoTypes.NewMarketConfiguration{ 6037 Instrument: &protoTypes.InstrumentConfiguration{ 6038 Product: &protoTypes.InstrumentConfiguration_Future{}, 6039 }, 6040 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 6041 SlaCompetitionFactor: v, 6042 }, 6043 }, 6044 }, 6045 }, 6046 }, 6047 }) 6048 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.sla_competition_factor"), errors[i]) 6049 } 6050 } 6051 6052 func testNewMarketChangeSubmissionWithValidCompetitionFactorSucceeds(t *testing.T) { 6053 minTimeFraction := []string{"0", "0.1", "0.99", "1"} 6054 6055 for _, v := range minTimeFraction { 6056 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6057 Terms: &protoTypes.ProposalTerms{ 6058 Change: &protoTypes.ProposalTerms_NewMarket{ 6059 NewMarket: &protoTypes.NewMarket{ 6060 Changes: &protoTypes.NewMarketConfiguration{ 6061 Instrument: &protoTypes.InstrumentConfiguration{ 6062 Product: &protoTypes.InstrumentConfiguration_Future{}, 6063 }, 6064 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 6065 SlaCompetitionFactor: v, 6066 }, 6067 }, 6068 }, 6069 }, 6070 }, 6071 }) 6072 6073 errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01} 6074 for _, e := range errors { 6075 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.sla_competition_factor"), e) 6076 } 6077 } 6078 } 6079 6080 func testNewMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails(t *testing.T) { 6081 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6082 Terms: &protoTypes.ProposalTerms{ 6083 Change: &protoTypes.ProposalTerms_NewMarket{ 6084 NewMarket: &protoTypes.NewMarket{ 6085 Changes: &protoTypes.NewMarketConfiguration{ 6086 Instrument: &protoTypes.InstrumentConfiguration{ 6087 Product: &protoTypes.InstrumentConfiguration_Future{}, 6088 }, 6089 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 6090 PerformanceHysteresisEpochs: 367, 6091 }, 6092 }, 6093 }, 6094 }, 6095 }, 6096 }) 6097 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBeLessThen366) 6098 } 6099 6100 func testNewMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds(t *testing.T) { 6101 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6102 Terms: &protoTypes.ProposalTerms{ 6103 Change: &protoTypes.ProposalTerms_NewMarket{ 6104 NewMarket: &protoTypes.NewMarket{ 6105 Changes: &protoTypes.NewMarketConfiguration{ 6106 Instrument: &protoTypes.InstrumentConfiguration{ 6107 Product: &protoTypes.InstrumentConfiguration_Future{}, 6108 }, 6109 LiquiditySlaParameters: &protoTypes.LiquiditySLAParameters{ 6110 PerformanceHysteresisEpochs: 1, 6111 }, 6112 }, 6113 }, 6114 }, 6115 }, 6116 }) 6117 6118 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBePositive) 6119 } 6120 6121 func testLiquidityFeeSettings(t *testing.T) { 6122 cases := []struct { 6123 lfs *vega.LiquidityFeeSettings 6124 field string 6125 err error 6126 }{ 6127 { 6128 lfs: &vega.LiquidityFeeSettings{ 6129 Method: vegapb.LiquidityFeeSettings_METHOD_MARGINAL_COST, 6130 FeeConstant: ptr.From("0.1"), 6131 }, 6132 field: "method", 6133 err: commands.ErrIsNotValid, 6134 }, 6135 { 6136 lfs: &vega.LiquidityFeeSettings{ 6137 Method: vegapb.LiquidityFeeSettings_METHOD_WEIGHTED_AVERAGE, 6138 FeeConstant: ptr.From("0.1"), 6139 }, 6140 field: "method", 6141 err: commands.ErrIsNotValid, 6142 }, 6143 { 6144 lfs: &vega.LiquidityFeeSettings{ 6145 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6146 FeeConstant: nil, 6147 }, 6148 field: "fee_constant", 6149 err: commands.ErrIsRequired, 6150 }, 6151 { 6152 lfs: &vega.LiquidityFeeSettings{ 6153 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6154 FeeConstant: ptr.From("hello"), 6155 }, 6156 field: "fee_constant", 6157 err: commands.ErrIsNotValidNumber, 6158 }, 6159 { 6160 lfs: &vega.LiquidityFeeSettings{ 6161 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6162 FeeConstant: ptr.From("-0.1"), // (0042-LIQF-060) 6163 }, 6164 field: "fee_constant", 6165 err: commands.ErrMustBePositiveOrZero, 6166 }, 6167 { 6168 lfs: &vega.LiquidityFeeSettings{ 6169 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6170 FeeConstant: ptr.From("1.1"), // (0042-LIQF-060) 6171 }, 6172 field: "fee_constant", 6173 err: commands.ErrMustBeWithinRange01, 6174 }, 6175 { 6176 lfs: &vega.LiquidityFeeSettings{ 6177 Method: vegapb.LiquidityFeeSettings_METHOD_UNSPECIFIED, 6178 }, 6179 field: "method", 6180 err: commands.ErrIsRequired, 6181 }, 6182 { 6183 lfs: &vega.LiquidityFeeSettings{ 6184 Method: vegapb.LiquidityFeeSettings_Method(int32(100)), 6185 }, 6186 field: "method", 6187 err: commands.ErrIsNotValid, 6188 }, 6189 } 6190 6191 for _, c := range cases { 6192 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6193 Terms: &vegapb.ProposalTerms{ 6194 Change: &vegapb.ProposalTerms_NewMarket{ 6195 NewMarket: &vegapb.NewMarket{ 6196 Changes: &vegapb.NewMarketConfiguration{ 6197 Instrument: &vegapb.InstrumentConfiguration{ 6198 Product: &vegapb.InstrumentConfiguration_Perpetual{ 6199 Perpetual: &vegapb.PerpetualProduct{}, 6200 }, 6201 }, 6202 LiquidityFeeSettings: c.lfs, 6203 }, 6204 }, 6205 }, 6206 }, 6207 }) 6208 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidity_fee_settings."+c.field), c.err) 6209 } 6210 } 6211 6212 func testLiquidityFeeSettingsSpot(t *testing.T) { 6213 cases := []struct { 6214 lfs *vega.LiquidityFeeSettings 6215 field string 6216 err error 6217 }{ 6218 { 6219 lfs: &vega.LiquidityFeeSettings{ 6220 Method: vegapb.LiquidityFeeSettings_METHOD_MARGINAL_COST, 6221 FeeConstant: ptr.From("0.1"), 6222 }, 6223 field: "method", 6224 err: commands.ErrIsNotValid, 6225 }, 6226 { 6227 lfs: &vega.LiquidityFeeSettings{ 6228 Method: vegapb.LiquidityFeeSettings_METHOD_WEIGHTED_AVERAGE, 6229 FeeConstant: ptr.From("0.1"), 6230 }, 6231 field: "method", 6232 err: commands.ErrIsNotValid, 6233 }, 6234 { 6235 lfs: &vega.LiquidityFeeSettings{ 6236 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6237 FeeConstant: nil, 6238 }, 6239 field: "fee_constant", 6240 err: commands.ErrIsRequired, 6241 }, 6242 { 6243 lfs: &vega.LiquidityFeeSettings{ 6244 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6245 FeeConstant: ptr.From("hello"), 6246 }, 6247 field: "fee_constant", 6248 err: commands.ErrIsNotValidNumber, 6249 }, 6250 { 6251 lfs: &vega.LiquidityFeeSettings{ 6252 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6253 FeeConstant: ptr.From("-0.1"), // (0042-LIQF-072) 6254 }, 6255 field: "fee_constant", 6256 err: commands.ErrMustBePositiveOrZero, 6257 }, 6258 { 6259 lfs: &vega.LiquidityFeeSettings{ 6260 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 6261 FeeConstant: ptr.From("1.1"), // (0042-LIQF-072) 6262 }, 6263 field: "fee_constant", 6264 err: commands.ErrMustBeWithinRange01, 6265 }, 6266 { 6267 lfs: &vega.LiquidityFeeSettings{ 6268 Method: vegapb.LiquidityFeeSettings_METHOD_UNSPECIFIED, 6269 }, 6270 field: "method", 6271 err: commands.ErrIsRequired, 6272 }, 6273 { 6274 lfs: &vega.LiquidityFeeSettings{ 6275 Method: vegapb.LiquidityFeeSettings_Method(int32(100)), 6276 }, 6277 field: "method", 6278 err: commands.ErrIsNotValid, 6279 }, 6280 } 6281 6282 for _, c := range cases { 6283 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6284 Terms: &vegapb.ProposalTerms{ 6285 Change: &vegapb.ProposalTerms_NewSpotMarket{ 6286 NewSpotMarket: &vegapb.NewSpotMarket{ 6287 Changes: &vegapb.NewSpotMarketConfiguration{ 6288 Instrument: &vegapb.InstrumentConfiguration{ 6289 Product: &vegapb.InstrumentConfiguration_Spot{ 6290 Spot: &vegapb.SpotProduct{}, 6291 }, 6292 }, 6293 LiquidityFeeSettings: c.lfs, 6294 }, 6295 }, 6296 }, 6297 }, 6298 }) 6299 assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.liquidity_fee_settings."+c.field), c.err) 6300 } 6301 } 6302 6303 func testFutureMarketSubmissionWithValidLiquidationStrategySucceeds(t *testing.T) { 6304 pubKey := []*dstypes.Signer{ 6305 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 6306 } 6307 6308 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6309 Terms: &vegapb.ProposalTerms{ 6310 Change: &vegapb.ProposalTerms_NewMarket{ 6311 NewMarket: &vegapb.NewMarket{ 6312 Changes: &vegapb.NewMarketConfiguration{ 6313 Instrument: &vegapb.InstrumentConfiguration{ 6314 Product: &vegapb.InstrumentConfiguration_Future{ 6315 Future: &vegapb.FutureProduct{ 6316 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 6317 vegapb.DataSourceContentTypeOracle, 6318 ).SetOracleConfig( 6319 &vegapb.DataSourceDefinitionExternal_Oracle{ 6320 Oracle: &vegapb.DataSourceSpecConfiguration{ 6321 Signers: dstypes.SignersIntoProto(pubKey), 6322 Filters: []*datapb.Filter{ 6323 { 6324 Key: &datapb.PropertyKey{ 6325 Name: "prices.ETH.value", 6326 Type: datapb.PropertyKey_TYPE_INTEGER, 6327 }, 6328 Conditions: []*datapb.Condition{ 6329 { 6330 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 6331 }, 6332 }, 6333 }, 6334 }, 6335 }, 6336 }, 6337 ), 6338 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 6339 vegapb.DataSourceContentTypeOracle, 6340 ).SetOracleConfig( 6341 &vegapb.DataSourceDefinitionExternal_Oracle{ 6342 Oracle: &vegapb.DataSourceSpecConfiguration{ 6343 Signers: dstypes.SignersIntoProto(pubKey), 6344 Filters: []*datapb.Filter{ 6345 { 6346 Key: &datapb.PropertyKey{ 6347 Name: "vegaprotocol.builtin.timestamp", 6348 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 6349 }, 6350 Conditions: []*datapb.Condition{ 6351 { 6352 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 6353 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 6354 }, 6355 }, 6356 }, 6357 }, 6358 }, 6359 }, 6360 ), 6361 }, 6362 }, 6363 }, 6364 LiquidationStrategy: &vegapb.LiquidationStrategy{ 6365 DisposalTimeStep: 20, 6366 DisposalFraction: "0.05", 6367 FullDisposalSize: 20, 6368 MaxFractionConsumed: "0.01", 6369 DisposalSlippageRange: "0.1", 6370 }, 6371 }, 6372 }, 6373 }, 6374 }, 6375 }) 6376 6377 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_fraction")) 6378 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidation_strategy.max_fraction_consumed")) 6379 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_time_step")) 6380 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_slippage_range")) 6381 } 6382 6383 type compositePriceConfigCase struct { 6384 mpc *vega.CompositePriceConfiguration 6385 field string 6386 err error 6387 } 6388 6389 func getCompositePriceConfigurationCases() []compositePriceConfigCase { 6390 cases := []compositePriceConfigCase{ 6391 { 6392 mpc: &vega.CompositePriceConfiguration{}, 6393 field: "composite_price_type", 6394 err: commands.ErrIsRequired, 6395 }, 6396 { 6397 mpc: &vega.CompositePriceConfiguration{ 6398 CompositePriceType: 0, 6399 }, 6400 field: "composite_price_type", 6401 err: commands.ErrIsRequired, 6402 }, 6403 { 6404 mpc: &vega.CompositePriceConfiguration{ 6405 CompositePriceType: 4, 6406 }, 6407 field: "composite_price_type", 6408 err: commands.ErrIsNotValid, 6409 }, 6410 { 6411 mpc: &vega.CompositePriceConfiguration{ 6412 CompositePriceType: 2, 6413 DecayWeight: "", 6414 }, 6415 field: "decay_weight", 6416 err: commands.ErrIsRequired, 6417 }, 6418 { 6419 mpc: &vega.CompositePriceConfiguration{ 6420 CompositePriceType: 2, 6421 DecayWeight: "banana", 6422 }, 6423 field: "decay_weight", 6424 err: commands.ErrIsNotValidNumber, 6425 }, 6426 { 6427 mpc: &vega.CompositePriceConfiguration{ 6428 CompositePriceType: 2, 6429 DecayWeight: "-1", 6430 }, 6431 field: "decay_weight", 6432 err: commands.ErrMustBeWithinRange01, 6433 }, 6434 { 6435 mpc: &vega.CompositePriceConfiguration{ 6436 CompositePriceType: 2, 6437 DecayWeight: "1.1", 6438 }, 6439 field: "decay_weight", 6440 err: commands.ErrMustBeWithinRange01, 6441 }, 6442 { 6443 mpc: &vega.CompositePriceConfiguration{ 6444 CompositePriceType: 3, 6445 DecayWeight: "", 6446 }, 6447 field: "decay_weight", 6448 err: nil, 6449 }, 6450 { 6451 mpc: &vega.CompositePriceConfiguration{ 6452 CompositePriceType: 2, 6453 DecayPower: 4, 6454 }, 6455 field: "decay_power", 6456 err: fmt.Errorf("must be in {1, 2, 3}"), 6457 }, 6458 { 6459 mpc: &vega.CompositePriceConfiguration{ 6460 CompositePriceType: 2, 6461 DecayPower: 0, 6462 }, 6463 field: "decay_power", 6464 err: fmt.Errorf("must be in {1, 2, 3}"), 6465 }, 6466 { 6467 mpc: &vega.CompositePriceConfiguration{ 6468 CompositePriceType: 3, 6469 DecayPower: 0, 6470 }, 6471 field: "decay_power", 6472 err: nil, 6473 }, 6474 { 6475 mpc: &vega.CompositePriceConfiguration{ 6476 CompositePriceType: 2, 6477 CashAmount: "", 6478 }, 6479 field: "cash_amount", 6480 err: commands.ErrIsRequired, 6481 }, 6482 { 6483 mpc: &vega.CompositePriceConfiguration{ 6484 CompositePriceType: 2, 6485 CashAmount: "banana", 6486 }, 6487 field: "cash_amount", 6488 err: commands.ErrIsNotValidNumber, 6489 }, 6490 { 6491 mpc: &vega.CompositePriceConfiguration{ 6492 CompositePriceType: 2, 6493 CashAmount: "-1", 6494 }, 6495 field: "cash_amount", 6496 err: commands.ErrIsNotValidNumber, 6497 }, 6498 { 6499 mpc: &vega.CompositePriceConfiguration{ 6500 CompositePriceType: 2, 6501 CashAmount: "1.2", 6502 }, 6503 field: "cash_amount", 6504 err: commands.ErrIsNotValidNumber, 6505 }, 6506 { 6507 mpc: &vega.CompositePriceConfiguration{ 6508 CompositePriceType: 3, 6509 CashAmount: "", 6510 }, 6511 field: "cash_amount", 6512 err: nil, 6513 }, 6514 { 6515 mpc: &vega.CompositePriceConfiguration{ 6516 SourceWeights: []string{"1", "2", "3"}, 6517 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_MEDIAN, 6518 }, 6519 field: "source_weights", 6520 err: fmt.Errorf("must be empty if composite price type is not weighted"), 6521 }, 6522 { 6523 mpc: &vega.CompositePriceConfiguration{ 6524 SourceWeights: []string{"1", "2", "3"}, 6525 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_LAST_TRADE, 6526 }, 6527 field: "source_weights", 6528 err: fmt.Errorf("must be empty if composite price type is not weighted"), 6529 }, 6530 { 6531 mpc: &vega.CompositePriceConfiguration{ 6532 SourceWeights: []string{"", "", ""}, 6533 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6534 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6535 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6536 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6537 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6538 }, 6539 }, 6540 field: "source_weights", 6541 err: fmt.Errorf("must be defined for all price sources"), 6542 }, 6543 { 6544 mpc: &vega.CompositePriceConfiguration{ 6545 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6546 SourceStalenessTolerance: []string{"1", "2", "3", "4", "5"}, 6547 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6548 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6549 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6550 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6551 }, 6552 }, 6553 field: "source_staleness_tolerance", 6554 err: fmt.Errorf("must included staleness information for all price sources"), 6555 }, 6556 { 6557 mpc: &vega.CompositePriceConfiguration{ 6558 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6559 SourceStalenessTolerance: []string{"1", "2", "3", "4", "5", "6", "7"}, 6560 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6561 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6562 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6563 }, 6564 }, 6565 field: "source_staleness_tolerance", 6566 err: fmt.Errorf("must included staleness information for all price sources"), 6567 }, 6568 { 6569 mpc: &vega.CompositePriceConfiguration{ 6570 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_MEDIAN, 6571 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6572 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6573 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6574 }, 6575 }, 6576 field: "source_staleness_tolerance", 6577 err: fmt.Errorf("must included staleness information for all price sources"), 6578 }, 6579 { 6580 mpc: &vega.CompositePriceConfiguration{ 6581 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6582 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6583 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6584 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6585 }, 6586 }, 6587 field: "source_staleness_tolerance", 6588 err: fmt.Errorf("must included staleness information for all price sources"), 6589 }, 6590 { 6591 mpc: &vega.CompositePriceConfiguration{ 6592 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6593 SourceStalenessTolerance: []string{"1s", "2s", "3s"}, 6594 SourceWeights: []string{"1", "2", "3"}, 6595 }, 6596 field: "source_staleness_tolerance", 6597 err: nil, 6598 }, 6599 { 6600 mpc: &vega.CompositePriceConfiguration{ 6601 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_MEDIAN, 6602 SourceStalenessTolerance: []string{"1s", "2s", "3s"}, 6603 }, 6604 field: "source_staleness_tolerance", 6605 err: nil, 6606 }, 6607 { 6608 mpc: &vega.CompositePriceConfiguration{ 6609 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6610 SourceStalenessTolerance: []string{"1s", "2s", "3s"}, 6611 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6612 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6613 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6614 }, 6615 }, 6616 field: "source_staleness_tolerance", 6617 err: fmt.Errorf("must included staleness information for all price sources"), 6618 }, 6619 { 6620 mpc: &vega.CompositePriceConfiguration{ 6621 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_MEDIAN, 6622 SourceStalenessTolerance: []string{"1s", "2s", "3s"}, 6623 DataSourcesSpec: []*protoTypes.DataSourceDefinition{ 6624 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6625 {SourceType: &vegapb.DataSourceDefinition_External{}}, 6626 }, 6627 }, 6628 field: "source_staleness_tolerance", 6629 err: fmt.Errorf("must included staleness information for all price sources"), 6630 }, 6631 { 6632 mpc: &vega.CompositePriceConfiguration{ 6633 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_LAST_TRADE, 6634 SourceStalenessTolerance: nil, 6635 }, 6636 field: "source_staleness_tolerance", 6637 err: nil, 6638 }, 6639 { 6640 mpc: &vega.CompositePriceConfiguration{ 6641 SourceWeights: []string{"", "", "", ""}, 6642 SourceStalenessTolerance: []string{"", "", "", "", ""}, 6643 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6644 }, 6645 field: "source_staleness_tolerance", 6646 err: fmt.Errorf("must have the same length as source_weights"), 6647 }, 6648 { 6649 mpc: &vega.CompositePriceConfiguration{ 6650 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_WEIGHTED, 6651 SourceWeights: []string{"0", "0", "0", "0"}, 6652 }, 6653 field: "source_weights", 6654 err: fmt.Errorf("must have at least one none zero weight"), 6655 }, 6656 { 6657 mpc: &vega.CompositePriceConfiguration{ 6658 CompositePriceType: protoTypes.CompositePriceType_COMPOSITE_PRICE_TYPE_MEDIAN, 6659 SourceWeights: []string{"0", "0", "0", "0"}, 6660 }, 6661 field: "source_weights", 6662 err: fmt.Errorf("must be empty if composite price type is not weighted"), 6663 }, 6664 { 6665 mpc: &vega.CompositePriceConfiguration{ 6666 SourceWeights: []string{"", "banana", "-1", ""}, 6667 }, 6668 field: "source_weights.0", 6669 err: commands.ErrIsNotValidNumber, 6670 }, 6671 { 6672 mpc: &vega.CompositePriceConfiguration{ 6673 SourceWeights: []string{"", "banana", "-1", ""}, 6674 }, 6675 field: "source_weights.1", 6676 err: commands.ErrIsNotValidNumber, 6677 }, 6678 { 6679 mpc: &vega.CompositePriceConfiguration{ 6680 SourceWeights: []string{"", "banana", "-1", ""}, 6681 }, 6682 field: "source_weights.2", 6683 err: commands.ErrMustBePositiveOrZero, 6684 }, 6685 { 6686 mpc: &vega.CompositePriceConfiguration{ 6687 SourceStalenessTolerance: []string{"", "banana", "-1", ""}, 6688 }, 6689 field: "source_staleness_tolerance.0", 6690 err: fmt.Errorf("must be a valid duration"), 6691 }, 6692 { 6693 mpc: &vega.CompositePriceConfiguration{ 6694 SourceStalenessTolerance: []string{"", "banana", "-1", ""}, 6695 }, 6696 field: "source_staleness_tolerance.1", 6697 err: fmt.Errorf("must be a valid duration"), 6698 }, 6699 } 6700 return cases 6701 } 6702 6703 func testCompositePriceConfiguration(t *testing.T) { 6704 cases := getCompositePriceConfigurationCases() 6705 cases = append(cases, compositePriceConfigCase{ 6706 mpc: nil, 6707 field: "", 6708 err: commands.ErrIsRequired, 6709 }) 6710 6711 for _, c := range cases { 6712 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 6713 Terms: &vegapb.ProposalTerms{ 6714 Change: &vegapb.ProposalTerms_NewMarket{ 6715 NewMarket: &vegapb.NewMarket{ 6716 Changes: &vegapb.NewMarketConfiguration{ 6717 Instrument: &vegapb.InstrumentConfiguration{ 6718 Product: &vegapb.InstrumentConfiguration_Perpetual{ 6719 Perpetual: &vegapb.PerpetualProduct{}, 6720 }, 6721 }, 6722 MarkPriceConfiguration: c.mpc, 6723 }, 6724 }, 6725 }, 6726 }, 6727 }) 6728 if len(c.field) > 0 { 6729 if c.err != nil { 6730 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.mark_price_configuration."+c.field), c.err) 6731 } else { 6732 assert.Empty(t, err.Get("proposal_submission.terms.change.new_market.changes.mark_price_configuration."+c.field)) 6733 } 6734 } else { 6735 assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.mark_price_configuration"), c.err) 6736 } 6737 } 6738 } 6739 6740 func testFutureMarketSubmissionWithInvalidLiquidationStrategyFails(t *testing.T) { 6741 pubKey := []*dstypes.Signer{ 6742 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 6743 } 6744 6745 submission := &commandspb.ProposalSubmission{ 6746 Terms: &vegapb.ProposalTerms{ 6747 Change: &vegapb.ProposalTerms_NewMarket{ 6748 NewMarket: &vegapb.NewMarket{ 6749 Changes: &vegapb.NewMarketConfiguration{ 6750 Instrument: &vegapb.InstrumentConfiguration{ 6751 Product: &vegapb.InstrumentConfiguration_Future{ 6752 Future: &vegapb.FutureProduct{ 6753 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 6754 vegapb.DataSourceContentTypeOracle, 6755 ).SetOracleConfig( 6756 &vegapb.DataSourceDefinitionExternal_Oracle{ 6757 Oracle: &vegapb.DataSourceSpecConfiguration{ 6758 Signers: dstypes.SignersIntoProto(pubKey), 6759 Filters: []*datapb.Filter{ 6760 { 6761 Key: &datapb.PropertyKey{ 6762 Name: "prices.ETH.value", 6763 Type: datapb.PropertyKey_TYPE_INTEGER, 6764 }, 6765 Conditions: []*datapb.Condition{ 6766 { 6767 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 6768 }, 6769 }, 6770 }, 6771 }, 6772 }, 6773 }, 6774 ), 6775 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 6776 vegapb.DataSourceContentTypeOracle, 6777 ).SetOracleConfig( 6778 &vegapb.DataSourceDefinitionExternal_Oracle{ 6779 Oracle: &vegapb.DataSourceSpecConfiguration{ 6780 Signers: dstypes.SignersIntoProto(pubKey), 6781 Filters: []*datapb.Filter{ 6782 { 6783 Key: &datapb.PropertyKey{ 6784 Name: "vegaprotocol.builtin.timestamp", 6785 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 6786 }, 6787 Conditions: []*datapb.Condition{ 6788 { 6789 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 6790 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 6791 }, 6792 }, 6793 }, 6794 }, 6795 }, 6796 }, 6797 ), 6798 }, 6799 }, 6800 }, 6801 LiquidationStrategy: &vegapb.LiquidationStrategy{ 6802 DisposalTimeStep: 20, 6803 DisposalFraction: "0.05", 6804 FullDisposalSize: 20, 6805 MaxFractionConsumed: "0.01", 6806 DisposalSlippageRange: "0.1", 6807 }, 6808 }, 6809 }, 6810 }, 6811 }, 6812 } 6813 6814 data := map[string]struct { 6815 ls *vegapb.LiquidationStrategy 6816 err error 6817 }{ 6818 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_fraction": { 6819 ls: &vegapb.LiquidationStrategy{ 6820 DisposalTimeStep: 20, 6821 DisposalFraction: "123", 6822 FullDisposalSize: 20, 6823 MaxFractionConsumed: "0.01", 6824 DisposalSlippageRange: "0.1", 6825 }, 6826 err: commands.ErrMustBeBetween01, 6827 }, 6828 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.max_fraction_consumed": { 6829 ls: &vegapb.LiquidationStrategy{ 6830 DisposalTimeStep: 20, 6831 DisposalFraction: "0.1", 6832 FullDisposalSize: 20, 6833 MaxFractionConsumed: "-0.1", 6834 DisposalSlippageRange: "100", // large values are fine 6835 }, 6836 err: commands.ErrMustBeBetween01, 6837 }, 6838 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_time_step": { 6839 ls: &vegapb.LiquidationStrategy{ 6840 DisposalTimeStep: 0, 6841 DisposalFraction: "0.1", 6842 FullDisposalSize: 20, 6843 MaxFractionConsumed: "0.1", 6844 DisposalSlippageRange: "0.5", 6845 }, 6846 err: commands.ErrMustBePositive, 6847 }, 6848 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_slippage_range": { 6849 ls: &vegapb.LiquidationStrategy{ 6850 DisposalTimeStep: 5, 6851 DisposalFraction: "0.1", 6852 FullDisposalSize: 20, 6853 MaxFractionConsumed: "0.1", 6854 DisposalSlippageRange: "-0.5", 6855 }, 6856 err: commands.ErrMustBePositive, 6857 }, 6858 } 6859 checks := []string{ 6860 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_fraction", 6861 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.max_fraction_consumed", 6862 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_time_step", 6863 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_slippage_range", 6864 } 6865 for ec, exp := range data { 6866 nm := submission.Terms.GetNewMarket() 6867 nm.Changes.LiquidationStrategy = exp.ls 6868 submission.Terms.Change = &vegapb.ProposalTerms_NewMarket{ 6869 NewMarket: nm, 6870 } 6871 err := checkProposalSubmission(submission) 6872 for _, k := range checks { 6873 if k != ec { 6874 assert.Empty(t, err.Get(k)) 6875 } else { 6876 assert.Contains(t, err.Get(k), exp.err) 6877 } 6878 } 6879 } 6880 // pretty much the same as above, only this time set the disposal fraction to a negative value 6881 // and max fraction consumed to a large positive 6882 // finally set the disposal time step to a large int value, this changes the error 6883 data = map[string]struct { 6884 ls *vegapb.LiquidationStrategy 6885 err error 6886 }{ 6887 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_fraction": { 6888 ls: &vegapb.LiquidationStrategy{ 6889 DisposalTimeStep: 20, 6890 DisposalFraction: "-2", 6891 FullDisposalSize: 20, 6892 MaxFractionConsumed: "0.01", 6893 DisposalSlippageRange: "0.5", 6894 }, 6895 err: commands.ErrMustBeBetween01, 6896 }, 6897 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.max_fraction_consumed": { 6898 ls: &vegapb.LiquidationStrategy{ 6899 DisposalTimeStep: 20, 6900 DisposalFraction: "0.1", 6901 FullDisposalSize: 20, 6902 MaxFractionConsumed: "2", 6903 DisposalSlippageRange: "0.5", 6904 }, 6905 err: commands.ErrMustBeBetween01, 6906 }, 6907 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_time_step": { 6908 ls: &vegapb.LiquidationStrategy{ 6909 DisposalTimeStep: 3601, 6910 DisposalFraction: "0.1", 6911 FullDisposalSize: 20, 6912 MaxFractionConsumed: "0.1", 6913 DisposalSlippageRange: "0.5", 6914 }, 6915 err: commands.ErrMustBeAtMost3600, 6916 }, 6917 "proposal_submission.terms.change.new_market.changes.liquidation_strategy.disposal_slippage_range": { 6918 ls: &vegapb.LiquidationStrategy{ 6919 DisposalTimeStep: 5, 6920 DisposalFraction: "0.1", 6921 FullDisposalSize: 20, 6922 MaxFractionConsumed: "0.1", 6923 DisposalSlippageRange: "0", // zero or missing values fail, too 6924 }, 6925 err: commands.ErrMustBePositive, 6926 }, 6927 } 6928 for ec, exp := range data { 6929 nm := submission.Terms.GetNewMarket() 6930 nm.Changes.LiquidationStrategy = exp.ls 6931 submission.Terms.Change = &vegapb.ProposalTerms_NewMarket{ 6932 NewMarket: nm, 6933 } 6934 err := checkProposalSubmission(submission) 6935 for _, k := range checks { 6936 if k != ec { 6937 assert.Empty(t, err.Get(k)) 6938 } else { 6939 assert.Contains(t, err.Get(k), exp.err) 6940 } 6941 } 6942 } 6943 }