code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_update_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 TestCheckProposalSubmissionForUpdateMarket(t *testing.T) { 39 t.Run("Submitting a market change without update market fails", testUpdateMarketChangeSubmissionWithoutUpdateMarketFails) 40 t.Run("Submitting a market change without changes fails", testUpdateMarketChangeSubmissionWithoutChangesFails) 41 t.Run("Submitting a market change without decimal places succeeds", testUpdateMarketChangeSubmissionWithoutDecimalPlacesSucceeds) 42 t.Run("Submitting a update market without price monitoring succeeds", testUpdateMarketChangeSubmissionWithoutPriceMonitoringSucceeds) 43 t.Run("Submitting a update market with price monitoring succeeds", testUpdateMarketChangeSubmissionWithPriceMonitoringSucceeds) 44 t.Run("Submitting a price monitoring change without triggers succeeds", testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggersSucceeds) 45 t.Run("Submitting a price monitoring change with triggers succeeds", testUpdateMarketPriceMonitoringChangeSubmissionWithTriggersSucceeds) 46 t.Run("Submitting a price monitoring change without trigger horizon fails", testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails) 47 t.Run("Submitting a price monitoring change with trigger horizon succeeds", testUpdateMarketPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds) 48 t.Run("Submitting a price monitoring change with wrong trigger probability fails", testUpdateMarketPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails) 49 t.Run("Submitting a price monitoring change with right trigger probability succeeds", testUpdateMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds) 50 t.Run("Submitting a price monitoring change without trigger auction extension fails", testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails) 51 t.Run("Submitting a price monitoring change with trigger auction extension succeeds", testUpdateMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds) 52 t.Run("Submitting a update market without liquidity monitoring fails", testUpdateMarketChangeSubmissionWithoutLiquidityMonitoringFails) 53 t.Run("Submitting a update market with liquidity monitoring succeeds", testUpdateMarketChangeSubmissionWithLiquidityMonitoringSucceeds) 54 t.Run("Submitting a liquidity monitoring change without target stake parameters fails", testUpdateMarketLiquidityMonitoringChangeSubmissionWithoutTargetStakeParametersFails) 55 t.Run("Submitting a liquidity monitoring change with target stake parameters succeeds", testUpdateMarketLiquidityMonitoringChangeSubmissionWithTargetStakeParametersSucceeds) 56 t.Run("Submitting a liquidity monitoring change with non-positive time window fails", testUpdateMarketLiquidityMonitoringChangeSubmissionWithNonPositiveTimeWindowFails) 57 t.Run("Submitting a liquidity monitoring change with positive time window succeeds", testUpdateMarketLiquidityMonitoringChangeSubmissionWithPositiveTimeWindowSucceeds) 58 t.Run("Submitting a liquidity monitoring change with non-positive scaling factor fails", testUpdateMarketLiquidityMonitoringChangeSubmissionWithNonPositiveScalingFactorFails) 59 t.Run("Submitting a liquidity monitoring change with positive scaling factor succeeds", testUpdateMarketLiquidityMonitoringChangeSubmissionWithPositiveScalingFactorSucceeds) 60 t.Run("Submitting a market change without instrument code fails", testUpdateMarketChangeSubmissionWithoutInstrumentCodeFails) 61 t.Run("Submitting a market change without instrument name fails", testUpdateMarketChangeSubmissionWithoutInstrumentNameFails) 62 t.Run("Submitting a market change with instrument code succeeds", testUpdateMarketChangeSubmissionWithInstrumentCodeSucceeds) 63 t.Run("Submitting a market change without product fails", testUpdateMarketChangeSubmissionWithoutProductFails) 64 t.Run("Submitting a market change with product succeeds", testUpdateMarketChangeSubmissionWithProductSucceeds) 65 t.Run("Submitting a future market change without future fails", testUpdateFutureMarketChangeSubmissionWithoutFutureFails) 66 t.Run("Submitting a future market change with future succeeds", testUpdateFutureMarketChangeSubmissionWithFutureSucceeds) 67 t.Run("Submitting a future market change without quote name fails", testUpdateFutureMarketChangeSubmissionWithoutQuoteNameFails) 68 t.Run("Submitting a future market change with quote name succeeds", testUpdateFutureMarketChangeSubmissionWithQuoteNameSucceeds) 69 t.Run("Submitting a future market change without oracle spec fails", testUpdateFutureMarketChangeSubmissionWithoutOracleSpecFails) 70 t.Run("Submitting a future market change without either of the required oracle spec fails", testUpdateFutureMarketChangeSubmissionMissingSingleOracleSpecFails) 71 t.Run("Submitting a future market change without a public key fails", testUpdateFutureMarketSettlementDataChangeSubmissionWithoutPubKeysFails) 72 t.Run("Submitting a future market change with empty oracle spec fails", testUpdateFutureMarketChangeSubmissionWithEmptyOracleSpecFails) 73 t.Run("Submitting a future market change with empty oracle spec type fails", testUpdateFutureMarketChangeSubmissionWithEmptyOracleSpecTypeFails) 74 t.Run("Submitting a future market change with empty internal oracle spec type fails", testUpdateFutureMarketChangeSubmissionWithEmptyInternalOracleSpecTypeFails) 75 t.Run("Submitting a future market change with wrong pub-keys fails", testUpdateFutureMarketChangeSubmissionWithWrongPubKeysFails) 76 t.Run("Submitting a future market change with pub-keys succeeds", testUpdateFutureMarketChangeSubmissionWithPubKeysSucceeds) 77 t.Run("Submitting a future market change without filters fails", testUpdateFutureMarketChangeSubmissionWithoutFiltersFails) 78 t.Run("Submitting a future market change with filters succeeds", testUpdateFutureMarketChangeSubmissionWithFiltersSucceeds) 79 t.Run("Submitting a future market change with filter without key fails", testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyFails) 80 t.Run("Submitting a future market change with filter with key succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithKeySucceeds) 81 t.Run("Submitting a future market change with filter without key name fails", testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyNameFails) 82 t.Run("Submitting a future market change with filter with key name succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithKeyNameSucceeds) 83 t.Run("Submitting a future market change with filter without key type fails", testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyTypeFails) 84 t.Run("Submitting a future market change with filter with key type succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithKeyTypeSucceeds) 85 t.Run("Submitting a future market change with filter without condition succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionsSucceeds) 86 t.Run("Submitting a future market change with filter without condition operator fails", testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionOperatorFails) 87 t.Run("Submitting a future market change with filter with condition operator succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds) 88 t.Run("Submitting a future market change with filter without condition value fails", testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionValueFails) 89 t.Run("Submitting a future market change with filter with condition value succeeds", testUpdateFutureMarketChangeSubmissionWithFilterWithConditionValueSucceeds) 90 t.Run("Submitting a future market change without oracle spec bindings fails", testUpdateFutureMarketChangeSubmissionWithoutDataSourceSpecBindingFails) 91 t.Run("Submitting a future market change with oracle spec binding succeeds", testUpdateFutureMarketChangeSubmissionWithDataSourceSpecBindingSucceeds) 92 t.Run("Submitting a future market change without settlement data property fails", testUpdateFutureMarketChangeSubmissionWithoutSettlementDataPropertyFails) 93 t.Run("Submitting a future market change without trading termination property fails", testUpdateFutureMarketChangeSubmissionWithoutTradingTerminationPropertyFails) 94 t.Run("Submitting a future market change with a mismatch between binding property name and filter fails", testUpdateFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails) 95 t.Run("Submitting a future market change with match between binding property name and filter succeeds", testUpdateFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds) 96 t.Run("Submitting a future market change with settlement data and trading termination properties succeeds", testUpdateFutureMarketChangeSubmissionWithSettlementDataPropertySucceeds) 97 t.Run("Submitting a simple risk parameters change without simple risk parameters fails", testUpdateSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails) 98 t.Run("Submitting a simple risk parameters change with simple risk parameters succeeds", testUpdateSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds) 99 t.Run("Submitting a simple risk parameters change with min move down fails", testUpdateSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails) 100 t.Run("Submitting a simple risk parameters change with min move down succeeds", testUpdateSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds) 101 t.Run("Submitting a simple risk parameters change with max move up fails", testUpdateSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails) 102 t.Run("Submitting a simple risk parameters change with max move up succeeds", testUpdateSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds) 103 t.Run("Submitting a simple risk parameters change with wrong probability of trading fails", testUpdateSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails) 104 t.Run("Submitting a simple risk parameters change with right probability of trading succeeds", testUpdateSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds) 105 t.Run("Submitting a log normal risk parameters change without log normal risk parameters fails", testUpdateLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails) 106 t.Run("Submitting a log normal risk parameters change with log normal risk parameters succeeds", testUpdateLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds) 107 t.Run("Submitting a log normal risk parameters change with params fails", testUpdateLogNormalRiskParametersChangeSubmissionWithoutParamsFails) 108 t.Run("Submitting a log normal risk parameters change with invalid risk aversion", testUpdateLogNormalRiskParametersChangeSubmissionInvalidRiskAversion) 109 t.Run("Submitting a log normal risk parameters change with invalid tau", testUpdateLogNormalRiskParametersChangeSubmissionInvalidTau) 110 t.Run("Submitting a log normal risk parameters change with invalid mu", testUpdateLogNormalRiskParametersChangeSubmissionInvalidMu) 111 t.Run("Submitting a log normal risk parameters change with invalid sigma", testUpdateLogNormalRiskParametersChangeSubmissionInvalidSigma) 112 t.Run("Submitting a log normal risk parameters change with invalid r", testUpdateLogNormalRiskParametersChangeSubmissionInvalidR) 113 t.Run("Submitting a update market with a too long reference fails", testUpdateMarketSubmissionWithTooLongReferenceFails) 114 t.Run("Submitting a market with market ID succeeds", testUpdateMarketWithMarketIDSucceeds) 115 t.Run("Submitting a market without market ID fails", testUpdateMarketWithoutMarketIDFails) 116 t.Run("Submitting a slippage fraction change with 'banana' value fails", tesUpdateMarketChangeSubmissionWithSlippageFactorBananaFails) 117 t.Run("Submitting a slippage fraction change with a negative value fails", testUpdateMarketChangeSubmissionWithSlippageFactorNegativeFails) 118 t.Run("Submitting a slippage fraction change with a too large value fails", testUpdateMarketChangeSubmissionWithSlippageFactorTooLargeFails) 119 t.Run("Submitting a slippage fraction change with an empty string succeeds", testUpdateNewMarketChangeSubmissionWithEmptySlippageFactorPasses) 120 t.Run("Submitting a market with external data for termination without signers fails", testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingTerminationNoSignersFails) 121 t.Run("Submitting a market with internal data source to terminate with `vegaprotocol.builtin` in key name no signers succeeds", testUpdateMarketFutureMarketSubmissionWithInternalTimestampForTradingTerminationNoSignersSucceeds) 122 t.Run("Submitting a market with internal data source to terminate with invalid operator and no signers fails", testUpdateMarketFutureMarketSubmissionWithInvalidOperatorInternalSourceForTradingTerminationNoSignersFails) 123 t.Run("Submitting a market with oracle to terminate with `vegaprotocol.builtin` in key name no signers fails", testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingTerminationBuiltInKeyNoSignersFails) 124 t.Run("Submitting a market with oracle to settle with `vegaprotocol.builtin` in key name no signers fails", testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingSettlementBuiltInKeyNoSignersFails) 125 t.Run("Submitting a market with trading settlement from external source with timestamp filter succeeds", testUpdateMarketFutureSubmissionWithExternalTradingSettlementTimestampKeySucceeds) 126 t.Run("Submitting a market with external data source for termination succeeds", testUpdateMarketWithExternalTradingTerminationBuiltInKeySucceeds) 127 t.Run("Submitting a market with external data source for termination without signers fails", testUpdateMarketWithExternalTradingTerminationNoSignerFails) 128 t.Run("Submitting a market with internal data source for settlement fails", testUpdateMarketWithInternalSettlementDataFails) 129 t.Run("Submitting a market with external data source for termination with signers and external settlement data without signers fails", testUpdateMarketWithExternalSettlementDataNoSignerFails) 130 t.Run("Submitting a market with external data sources for settlement and termination with no signers fail", testUpdateMarketWithExternalSettlementDataAndTerminationNoSignerFails) 131 t.Run("Submitting a market with external data sources for settlement and termination with empty signers fail", testUpdateMarketWithExternalSettlementDataAndTerminationEmptySignerFails) 132 t.Run("Submitting a market with external data sources for settlement and termination with empty pubKey signers fail", testUpdateMarketWithExternalSettlementDataAndTerminationEmptyPubKeySignerFails) 133 t.Run("Submitting a market with external data sources for settlement and termination with empty eth address signers fail", testUpdateMarketWithExternalSettlementDataAndTerminationEmptyEthAddressSignerFails) 134 t.Run("Submitting a market with termination time trigger fails", testUpdateMarketWithTerminationWithTimeTriggerFails) 135 t.Run("Submitting a market withsettlement with time trigger fails", testUpdateMarketWithSettlementWithTimeTriggerFails) 136 t.Run("Submitting a perps market product parameters", testUpdatePerpsMarketChangeSubmissionProductParameters) 137 t.Run("Submitting a perps market with funding rate modifiers", testUpdatePerpetualMarketWithFundingRateModifiers) 138 t.Run("Submitting a market update with invalid mark price configuration ", testUpdateMarketCompositePriceConfiguration) 139 t.Run("Submitting a market update with invalid intenal composite price configuration", testUpdatePerpsMarketChangeSubmissionWithInternalCompositePriceConfig) 140 t.Run("Submitting a market update with invalid tick size fails and valid tick size succeeds", testUpdateMarketTickSize) 141 t.Run("Submitting a spot market update with invalid liquifity fee settings", testUpdateLiquidityFeeSettingsSpot) 142 t.Run("Update Log Normal with overrides", testUpdateLogNormalRiskParametersChangeSubmissionWithOverrides) 143 } 144 145 func testUpdateMarketTickSize(t *testing.T) { 146 cases := getTickSizeCases() 147 for _, tsc := range cases { 148 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 149 Terms: &vegapb.ProposalTerms{ 150 Change: &vegapb.ProposalTerms_UpdateMarket{ 151 UpdateMarket: &vegapb.UpdateMarket{ 152 Changes: &vegapb.UpdateMarketConfiguration{ 153 TickSize: tsc.tickSize, 154 }, 155 }, 156 }, 157 }, 158 }) 159 if tsc.err != nil { 160 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.tick_size"), tsc.err) 161 } else { 162 assert.Empty(t, err.Get("proposal_submission.terms.change.update_market.changes.tick_size")) 163 } 164 } 165 } 166 167 func testUpdatePerpsMarketChangeSubmissionWithInternalCompositePriceConfig(t *testing.T) { 168 cases := getCompositePriceConfigurationCases() 169 for _, c := range cases { 170 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 171 Terms: &vegapb.ProposalTerms{ 172 Change: &vegapb.ProposalTerms_UpdateMarket{ 173 UpdateMarket: &vegapb.UpdateMarket{ 174 Changes: &vegapb.UpdateMarketConfiguration{ 175 Instrument: &vegapb.UpdateInstrumentConfiguration{ 176 Product: &vegapb.UpdateInstrumentConfiguration_Perpetual{ 177 Perpetual: &vegapb.UpdatePerpetualProduct{ 178 InternalCompositePriceConfiguration: c.mpc, 179 }, 180 }, 181 }, 182 }, 183 }, 184 }, 185 }, 186 }) 187 if len(c.field) > 0 { 188 if c.err != nil { 189 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.perps.internal_composite_price_configuration."+c.field), c.err) 190 } else { 191 assert.Empty(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.perps.internal_composite_price_configuration."+c.field)) 192 } 193 } else { 194 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.perps.internal_composite_price_configuration"), c.err) 195 } 196 } 197 } 198 199 func testUpdateMarketCompositePriceConfiguration(t *testing.T) { 200 cases := getCompositePriceConfigurationCases() 201 cases = append(cases, compositePriceConfigCase{ 202 mpc: nil, 203 field: "", 204 err: commands.ErrIsRequired, 205 }) 206 207 for _, c := range cases { 208 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 209 Terms: &vegapb.ProposalTerms{ 210 Change: &vegapb.ProposalTerms_UpdateMarket{ 211 UpdateMarket: &vegapb.UpdateMarket{ 212 Changes: &vegapb.UpdateMarketConfiguration{ 213 MarkPriceConfiguration: c.mpc, 214 }, 215 }, 216 }, 217 }, 218 }) 219 if len(c.field) > 0 { 220 if c.err != nil { 221 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.mark_price_configuration."+c.field), c.err, c.field) 222 } else { 223 assert.Empty(t, err.Get("proposal_submission.terms.change.update_market.changes.mark_price_configuration."+c.field)) 224 } 225 } else { 226 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.mark_price_configuration"), c.err) 227 } 228 } 229 } 230 231 func testUpdateMarketChangeSubmissionWithoutUpdateMarketFails(t *testing.T) { 232 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 233 Terms: &protoTypes.ProposalTerms{ 234 Change: &protoTypes.ProposalTerms_UpdateMarket{}, 235 }, 236 }) 237 238 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market"), commands.ErrIsRequired) 239 } 240 241 func testUpdateMarketChangeSubmissionWithoutChangesFails(t *testing.T) { 242 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 243 Terms: &protoTypes.ProposalTerms{ 244 Change: &protoTypes.ProposalTerms_UpdateMarket{ 245 UpdateMarket: &protoTypes.UpdateMarket{}, 246 }, 247 }, 248 }) 249 250 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes"), commands.ErrIsRequired) 251 } 252 253 func testUpdateMarketChangeSubmissionWithoutDecimalPlacesSucceeds(t *testing.T) { 254 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 255 Terms: &protoTypes.ProposalTerms{ 256 Change: &protoTypes.ProposalTerms_UpdateMarket{ 257 UpdateMarket: &protoTypes.UpdateMarket{ 258 Changes: &protoTypes.UpdateMarketConfiguration{}, 259 }, 260 }, 261 }, 262 }) 263 264 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero) 265 } 266 267 func testUpdateMarketChangeSubmissionWithoutLiquidityMonitoringFails(t *testing.T) { 268 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 269 Terms: &protoTypes.ProposalTerms{ 270 Change: &protoTypes.ProposalTerms_UpdateMarket{ 271 UpdateMarket: &protoTypes.UpdateMarket{ 272 Changes: &protoTypes.UpdateMarketConfiguration{}, 273 }, 274 }, 275 }, 276 }) 277 278 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters"), commands.ErrIsRequired) 279 } 280 281 func testUpdateMarketChangeSubmissionWithLiquidityMonitoringSucceeds(t *testing.T) { 282 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 283 Terms: &protoTypes.ProposalTerms{ 284 Change: &protoTypes.ProposalTerms_UpdateMarket{ 285 UpdateMarket: &protoTypes.UpdateMarket{ 286 Changes: &protoTypes.UpdateMarketConfiguration{ 287 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{}, 288 }, 289 }, 290 }, 291 }, 292 }) 293 294 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters"), commands.ErrIsRequired) 295 } 296 297 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithoutTargetStakeParametersFails(t *testing.T) { 298 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 299 Terms: &protoTypes.ProposalTerms{ 300 Change: &protoTypes.ProposalTerms_UpdateMarket{ 301 UpdateMarket: &protoTypes.UpdateMarket{ 302 Changes: &protoTypes.UpdateMarketConfiguration{ 303 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{}, 304 }, 305 }, 306 }, 307 }, 308 }) 309 310 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters"), commands.ErrIsRequired) 311 } 312 313 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithTargetStakeParametersSucceeds(t *testing.T) { 314 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 315 Terms: &protoTypes.ProposalTerms{ 316 Change: &protoTypes.ProposalTerms_UpdateMarket{ 317 UpdateMarket: &protoTypes.UpdateMarket{ 318 Changes: &protoTypes.UpdateMarketConfiguration{ 319 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{ 320 TargetStakeParameters: &protoTypes.TargetStakeParameters{}, 321 }, 322 }, 323 }, 324 }, 325 }, 326 }) 327 328 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters"), commands.ErrIsRequired) 329 } 330 331 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithNonPositiveTimeWindowFails(t *testing.T) { 332 testCases := []struct { 333 msg string 334 value int64 335 }{ 336 { 337 msg: "with ratio of 0", 338 value: 0, 339 }, { 340 msg: "with ratio of -1", 341 value: test.RandomNegativeI64(), 342 }, 343 } 344 for _, tc := range testCases { 345 t.Run(tc.msg, func(t *testing.T) { 346 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 347 Terms: &protoTypes.ProposalTerms{ 348 Change: &protoTypes.ProposalTerms_UpdateMarket{ 349 UpdateMarket: &protoTypes.UpdateMarket{ 350 Changes: &protoTypes.UpdateMarketConfiguration{ 351 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{ 352 TargetStakeParameters: &protoTypes.TargetStakeParameters{ 353 TimeWindow: tc.value, 354 }, 355 }, 356 }, 357 }, 358 }, 359 }, 360 }) 361 362 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters.time_window"), commands.ErrMustBePositive) 363 }) 364 } 365 } 366 367 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithPositiveTimeWindowSucceeds(t *testing.T) { 368 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 369 Terms: &protoTypes.ProposalTerms{ 370 Change: &protoTypes.ProposalTerms_UpdateMarket{ 371 UpdateMarket: &protoTypes.UpdateMarket{ 372 Changes: &protoTypes.UpdateMarketConfiguration{ 373 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{ 374 TargetStakeParameters: &protoTypes.TargetStakeParameters{ 375 TimeWindow: test.RandomPositiveI64(), 376 }, 377 }, 378 }, 379 }, 380 }, 381 }, 382 }) 383 384 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters.time_window"), commands.ErrMustBePositive) 385 } 386 387 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithNonPositiveScalingFactorFails(t *testing.T) { 388 testCases := []struct { 389 msg string 390 value float64 391 }{ 392 { 393 msg: "with ratio of 0", 394 value: 0, 395 }, { 396 msg: "with ratio of -1.5", 397 value: -1.5, 398 }, 399 } 400 for _, tc := range testCases { 401 t.Run(tc.msg, func(t *testing.T) { 402 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 403 Terms: &protoTypes.ProposalTerms{ 404 Change: &protoTypes.ProposalTerms_UpdateMarket{ 405 UpdateMarket: &protoTypes.UpdateMarket{ 406 Changes: &protoTypes.UpdateMarketConfiguration{ 407 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{ 408 TargetStakeParameters: &protoTypes.TargetStakeParameters{ 409 ScalingFactor: tc.value, 410 }, 411 }, 412 }, 413 }, 414 }, 415 }, 416 }) 417 418 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive) 419 }) 420 } 421 } 422 423 func testUpdateMarketLiquidityMonitoringChangeSubmissionWithPositiveScalingFactorSucceeds(t *testing.T) { 424 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 425 Terms: &protoTypes.ProposalTerms{ 426 Change: &protoTypes.ProposalTerms_UpdateMarket{ 427 UpdateMarket: &protoTypes.UpdateMarket{ 428 Changes: &protoTypes.UpdateMarketConfiguration{ 429 LiquidityMonitoringParameters: &protoTypes.LiquidityMonitoringParameters{ 430 TargetStakeParameters: &protoTypes.TargetStakeParameters{ 431 ScalingFactor: 1.5, 432 }, 433 }, 434 }, 435 }, 436 }, 437 }, 438 }) 439 440 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.liquidity_monitoring_parameters.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive) 441 } 442 443 func testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggersSucceeds(t *testing.T) { 444 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 445 Terms: &protoTypes.ProposalTerms{ 446 Change: &protoTypes.ProposalTerms_UpdateMarket{ 447 UpdateMarket: &protoTypes.UpdateMarket{ 448 Changes: &protoTypes.UpdateMarketConfiguration{ 449 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 450 Triggers: []*protoTypes.PriceMonitoringTrigger{}, 451 }, 452 }, 453 }, 454 }, 455 }, 456 }) 457 458 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired) 459 } 460 461 func testUpdateMarketPriceMonitoringChangeSubmissionWithTriggersSucceeds(t *testing.T) { 462 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 463 Terms: &protoTypes.ProposalTerms{ 464 Change: &protoTypes.ProposalTerms_UpdateMarket{ 465 UpdateMarket: &protoTypes.UpdateMarket{ 466 Changes: &protoTypes.UpdateMarketConfiguration{ 467 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 468 Triggers: []*protoTypes.PriceMonitoringTrigger{ 469 {}, 470 {}, 471 }, 472 }, 473 }, 474 }, 475 }, 476 }, 477 }) 478 479 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired) 480 } 481 482 func testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails(t *testing.T) { 483 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 484 Terms: &protoTypes.ProposalTerms{ 485 Change: &protoTypes.ProposalTerms_UpdateMarket{ 486 UpdateMarket: &protoTypes.UpdateMarket{ 487 Changes: &protoTypes.UpdateMarketConfiguration{ 488 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 489 Triggers: []*protoTypes.PriceMonitoringTrigger{ 490 {}, 491 {}, 492 }, 493 }, 494 }, 495 }, 496 }, 497 }, 498 }) 499 500 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive) 501 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive) 502 } 503 504 func testUpdateMarketPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds(t *testing.T) { 505 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 506 Terms: &protoTypes.ProposalTerms{ 507 Change: &protoTypes.ProposalTerms_UpdateMarket{ 508 UpdateMarket: &protoTypes.UpdateMarket{ 509 Changes: &protoTypes.UpdateMarketConfiguration{ 510 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 511 Triggers: []*protoTypes.PriceMonitoringTrigger{ 512 { 513 Horizon: test.RandomPositiveI64(), 514 }, 515 { 516 Horizon: test.RandomPositiveI64(), 517 }, 518 }, 519 }, 520 }, 521 }, 522 }, 523 }, 524 }) 525 526 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive) 527 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive) 528 } 529 530 func testUpdateMarketPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails(t *testing.T) { 531 testCases := []struct { 532 msg string 533 value float64 534 }{ 535 { 536 msg: "with probability of -1", 537 value: -1, 538 }, { 539 msg: "with probability of 0", 540 value: 0, 541 }, { 542 msg: "with probability of 1", 543 value: 1, 544 }, { 545 msg: "with probability of 2", 546 value: 2, 547 }, 548 } 549 for _, tc := range testCases { 550 t.Run(tc.msg, func(t *testing.T) { 551 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 552 Terms: &protoTypes.ProposalTerms{ 553 Change: &protoTypes.ProposalTerms_UpdateMarket{ 554 UpdateMarket: &protoTypes.UpdateMarket{ 555 Changes: &protoTypes.UpdateMarketConfiguration{ 556 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 557 Triggers: []*protoTypes.PriceMonitoringTrigger{ 558 { 559 Probability: fmt.Sprintf("%f", tc.value), 560 }, 561 { 562 Probability: fmt.Sprintf("%f", tc.value), 563 }, 564 }, 565 }, 566 }, 567 }, 568 }, 569 }, 570 }) 571 572 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.probability"), 573 errors.New("should be between 0.9 (exclusive) and 1 (exclusive)")) 574 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.probability"), 575 errors.New("should be between 0.9 (exclusive) and 1 (exclusive)")) 576 }) 577 } 578 } 579 580 func testUpdateMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds(t *testing.T) { 581 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 582 Terms: &protoTypes.ProposalTerms{ 583 Change: &protoTypes.ProposalTerms_UpdateMarket{ 584 UpdateMarket: &protoTypes.UpdateMarket{ 585 Changes: &protoTypes.UpdateMarketConfiguration{ 586 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 587 Triggers: []*protoTypes.PriceMonitoringTrigger{ 588 { 589 Probability: "0.01", 590 }, 591 { 592 Probability: "0.9", 593 }, 594 }, 595 }, 596 }, 597 }, 598 }, 599 }, 600 }) 601 602 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.probability"), 603 errors.New("should be between 0 (exclusive) and 1 (exclusive)")) 604 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.probability"), 605 errors.New("should be between 0 (exclusive) and 1 (exclusive)")) 606 } 607 608 func testUpdateMarketPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails(t *testing.T) { 609 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 610 Terms: &protoTypes.ProposalTerms{ 611 Change: &protoTypes.ProposalTerms_UpdateMarket{ 612 UpdateMarket: &protoTypes.UpdateMarket{ 613 Changes: &protoTypes.UpdateMarketConfiguration{ 614 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 615 Triggers: []*protoTypes.PriceMonitoringTrigger{ 616 {}, 617 {}, 618 }, 619 }, 620 }, 621 }, 622 }, 623 }, 624 }) 625 626 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive) 627 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive) 628 } 629 630 func testUpdateMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds(t *testing.T) { 631 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 632 Terms: &protoTypes.ProposalTerms{ 633 Change: &protoTypes.ProposalTerms_UpdateMarket{ 634 UpdateMarket: &protoTypes.UpdateMarket{ 635 Changes: &protoTypes.UpdateMarketConfiguration{ 636 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{ 637 Triggers: []*protoTypes.PriceMonitoringTrigger{ 638 { 639 AuctionExtension: test.RandomPositiveI64(), 640 }, 641 { 642 AuctionExtension: test.RandomPositiveI64(), 643 }, 644 }, 645 }, 646 }, 647 }, 648 }, 649 }, 650 }) 651 652 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive) 653 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive) 654 } 655 656 func testUpdateMarketChangeSubmissionWithoutPriceMonitoringSucceeds(t *testing.T) { 657 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 658 Terms: &protoTypes.ProposalTerms{ 659 Change: &protoTypes.ProposalTerms_UpdateMarket{ 660 UpdateMarket: &protoTypes.UpdateMarket{ 661 Changes: &protoTypes.UpdateMarketConfiguration{}, 662 }, 663 }, 664 }, 665 }) 666 667 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters"), commands.ErrIsRequired) 668 } 669 670 func testUpdateMarketChangeSubmissionWithPriceMonitoringSucceeds(t *testing.T) { 671 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 672 Terms: &protoTypes.ProposalTerms{ 673 Change: &protoTypes.ProposalTerms_UpdateMarket{ 674 UpdateMarket: &protoTypes.UpdateMarket{ 675 Changes: &protoTypes.UpdateMarketConfiguration{ 676 PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{}, 677 }, 678 }, 679 }, 680 }, 681 }) 682 683 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.price_monitoring_parameters"), commands.ErrIsRequired) 684 } 685 686 func testUpdateMarketChangeSubmissionWithoutInstrumentNameFails(t *testing.T) { 687 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 688 Terms: &protoTypes.ProposalTerms{ 689 Change: &protoTypes.ProposalTerms_UpdateMarket{ 690 UpdateMarket: &protoTypes.UpdateMarket{ 691 Changes: &protoTypes.UpdateMarketConfiguration{ 692 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 693 Name: "", 694 }, 695 }, 696 }, 697 }, 698 }, 699 }) 700 701 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.name"), commands.ErrIsRequired) 702 } 703 704 func testUpdateMarketChangeSubmissionWithoutInstrumentCodeFails(t *testing.T) { 705 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 706 Terms: &protoTypes.ProposalTerms{ 707 Change: &protoTypes.ProposalTerms_UpdateMarket{ 708 UpdateMarket: &protoTypes.UpdateMarket{ 709 Changes: &protoTypes.UpdateMarketConfiguration{ 710 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 711 Code: "", 712 }, 713 }, 714 }, 715 }, 716 }, 717 }) 718 719 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.code"), commands.ErrIsRequired) 720 } 721 722 func testUpdateMarketChangeSubmissionWithInstrumentCodeSucceeds(t *testing.T) { 723 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 724 Terms: &protoTypes.ProposalTerms{ 725 Change: &protoTypes.ProposalTerms_UpdateMarket{ 726 UpdateMarket: &protoTypes.UpdateMarket{ 727 Changes: &protoTypes.UpdateMarketConfiguration{ 728 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 729 Code: "My code", 730 }, 731 }, 732 }, 733 }, 734 }, 735 }) 736 737 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.code"), commands.ErrIsRequired) 738 } 739 740 func testUpdateMarketChangeSubmissionWithoutProductFails(t *testing.T) { 741 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 742 Terms: &protoTypes.ProposalTerms{ 743 Change: &protoTypes.ProposalTerms_UpdateMarket{ 744 UpdateMarket: &protoTypes.UpdateMarket{ 745 Changes: &protoTypes.UpdateMarketConfiguration{ 746 Instrument: &protoTypes.UpdateInstrumentConfiguration{}, 747 }, 748 }, 749 }, 750 }, 751 }) 752 753 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product"), commands.ErrIsRequired) 754 } 755 756 func testUpdateMarketChangeSubmissionWithProductSucceeds(t *testing.T) { 757 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 758 Terms: &protoTypes.ProposalTerms{ 759 Change: &protoTypes.ProposalTerms_UpdateMarket{ 760 UpdateMarket: &protoTypes.UpdateMarket{ 761 Changes: &protoTypes.UpdateMarketConfiguration{ 762 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 763 Product: &protoTypes.UpdateInstrumentConfiguration_Future{}, 764 }, 765 }, 766 }, 767 }, 768 }, 769 }) 770 771 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product"), commands.ErrIsRequired) 772 } 773 774 func testUpdateFutureMarketChangeSubmissionWithoutFutureFails(t *testing.T) { 775 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 776 Terms: &protoTypes.ProposalTerms{ 777 Change: &protoTypes.ProposalTerms_UpdateMarket{ 778 UpdateMarket: &protoTypes.UpdateMarket{ 779 Changes: &protoTypes.UpdateMarketConfiguration{ 780 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 781 Product: &protoTypes.UpdateInstrumentConfiguration_Future{}, 782 }, 783 }, 784 }, 785 }, 786 }, 787 }) 788 789 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future"), commands.ErrIsRequired) 790 } 791 792 func testUpdateFutureMarketChangeSubmissionWithFutureSucceeds(t *testing.T) { 793 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 794 Terms: &protoTypes.ProposalTerms{ 795 Change: &protoTypes.ProposalTerms_UpdateMarket{ 796 UpdateMarket: &protoTypes.UpdateMarket{ 797 Changes: &protoTypes.UpdateMarketConfiguration{ 798 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 799 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 800 Future: &protoTypes.UpdateFutureProduct{}, 801 }, 802 }, 803 }, 804 }, 805 }, 806 }, 807 }) 808 809 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future"), commands.ErrIsRequired) 810 } 811 812 func testUpdateFutureMarketChangeSubmissionWithoutQuoteNameFails(t *testing.T) { 813 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 814 Terms: &protoTypes.ProposalTerms{ 815 Change: &protoTypes.ProposalTerms_UpdateMarket{ 816 UpdateMarket: &protoTypes.UpdateMarket{ 817 Changes: &protoTypes.UpdateMarketConfiguration{ 818 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 819 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 820 Future: &protoTypes.UpdateFutureProduct{ 821 QuoteName: "", 822 }, 823 }, 824 }, 825 }, 826 }, 827 }, 828 }, 829 }) 830 831 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.quote_name"), commands.ErrIsRequired) 832 } 833 834 func testUpdateFutureMarketChangeSubmissionWithQuoteNameSucceeds(t *testing.T) { 835 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 836 Terms: &protoTypes.ProposalTerms{ 837 Change: &protoTypes.ProposalTerms_UpdateMarket{ 838 UpdateMarket: &protoTypes.UpdateMarket{ 839 Changes: &protoTypes.UpdateMarketConfiguration{ 840 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 841 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 842 Future: &protoTypes.UpdateFutureProduct{ 843 QuoteName: "BTC", 844 }, 845 }, 846 }, 847 }, 848 }, 849 }, 850 }, 851 }) 852 853 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.quote_name"), commands.ErrIsRequired) 854 } 855 856 func testUpdateFutureMarketChangeSubmissionWithoutOracleSpecFails(t *testing.T) { 857 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 858 Terms: &protoTypes.ProposalTerms{ 859 Change: &protoTypes.ProposalTerms_UpdateMarket{ 860 UpdateMarket: &protoTypes.UpdateMarket{ 861 Changes: &protoTypes.UpdateMarketConfiguration{ 862 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 863 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 864 Future: &protoTypes.UpdateFutureProduct{}, 865 }, 866 }, 867 }, 868 }, 869 }, 870 }, 871 }) 872 873 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsRequired) 874 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination"), commands.ErrIsRequired) 875 } 876 877 func testUpdateFutureMarketChangeSubmissionMissingSingleOracleSpecFails(t *testing.T) { 878 testUpdateFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t, "data_source_spec_for_settlement_data") 879 testUpdateFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t, "data_source_spec_for_trading_termination") 880 } 881 882 func testUpdateFutureMarketChangeSubmissionWithoutEitherOracleSpecFails(t *testing.T, oracleSpecName string) { 883 t.Helper() 884 future := &protoTypes.UpdateFutureProduct{} 885 if oracleSpecName == "data_source_spec_for_settlement_data" { 886 future.DataSourceSpecForTradingTermination = &vegapb.DataSourceDefinition{} 887 } else { 888 future.DataSourceSpecForSettlementData = &vegapb.DataSourceDefinition{} 889 } 890 891 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 892 Terms: &protoTypes.ProposalTerms{ 893 Change: &protoTypes.ProposalTerms_UpdateMarket{ 894 UpdateMarket: &protoTypes.UpdateMarket{ 895 Changes: &protoTypes.UpdateMarketConfiguration{ 896 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 897 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 898 Future: &protoTypes.UpdateFutureProduct{}, 899 }, 900 }, 901 }, 902 }, 903 }, 904 }, 905 }) 906 907 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future."+oracleSpecName), commands.ErrIsRequired) 908 } 909 910 func testUpdateFutureMarketChangeSubmissionWithEmptyOracleSpecFails(t *testing.T) { 911 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 912 Terms: &protoTypes.ProposalTerms{ 913 Change: &protoTypes.ProposalTerms_UpdateMarket{ 914 UpdateMarket: &protoTypes.UpdateMarket{ 915 Changes: &protoTypes.UpdateMarketConfiguration{ 916 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 917 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 918 Future: &protoTypes.UpdateFutureProduct{ 919 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{}, 920 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{}, 921 }, 922 }, 923 }, 924 }, 925 }, 926 }, 927 }, 928 }) 929 930 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.source_type"), commands.ErrIsRequired) 931 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.source_type"), commands.ErrIsRequired) 932 } 933 934 func testUpdateFutureMarketChangeSubmissionWithEmptyOracleSpecTypeFails(t *testing.T) { 935 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 936 Terms: &protoTypes.ProposalTerms{ 937 Change: &protoTypes.ProposalTerms_UpdateMarket{ 938 UpdateMarket: &protoTypes.UpdateMarket{ 939 Changes: &protoTypes.UpdateMarketConfiguration{ 940 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 941 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 942 Future: &protoTypes.UpdateFutureProduct{ 943 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{ 944 SourceType: &vegapb.DataSourceDefinition_External{ 945 External: &vegapb.DataSourceDefinitionExternal{ 946 SourceType: &vegapb.DataSourceDefinitionExternal_Oracle{ 947 Oracle: nil, 948 }, 949 }, 950 }, 951 }, 952 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{ 953 SourceType: &vegapb.DataSourceDefinition_External{ 954 External: &vegapb.DataSourceDefinitionExternal{ 955 SourceType: &vegapb.DataSourceDefinitionExternal_Oracle{ 956 Oracle: nil, 957 }, 958 }, 959 }, 960 }, 961 }, 962 }, 963 }, 964 }, 965 }, 966 }, 967 }, 968 }) 969 970 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle"), commands.ErrIsRequired) 971 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle"), commands.ErrIsRequired) 972 } 973 974 func testUpdateFutureMarketChangeSubmissionWithEmptyInternalOracleSpecTypeFails(t *testing.T) { 975 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 976 Terms: &protoTypes.ProposalTerms{ 977 Change: &protoTypes.ProposalTerms_UpdateMarket{ 978 UpdateMarket: &protoTypes.UpdateMarket{ 979 Changes: &protoTypes.UpdateMarketConfiguration{ 980 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 981 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 982 Future: &protoTypes.UpdateFutureProduct{ 983 DataSourceSpecForSettlementData: &vegapb.DataSourceDefinition{ 984 SourceType: &vegapb.DataSourceDefinition_Internal{ 985 Internal: &vegapb.DataSourceDefinitionInternal{ 986 SourceType: &vegapb.DataSourceDefinitionInternal_Time{ 987 Time: nil, 988 }, 989 }, 990 }, 991 }, 992 DataSourceSpecForTradingTermination: &vegapb.DataSourceDefinition{ 993 SourceType: &vegapb.DataSourceDefinition_Internal{ 994 Internal: &vegapb.DataSourceDefinitionInternal{ 995 SourceType: &vegapb.DataSourceDefinitionInternal_Time{ 996 Time: nil, 997 }, 998 }, 999 }, 1000 }, 1001 }, 1002 }, 1003 }, 1004 }, 1005 }, 1006 }, 1007 }, 1008 }) 1009 1010 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 1011 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time"), commands.ErrIsRequired) 1012 } 1013 1014 func testUpdateFutureMarketSettlementDataChangeSubmissionWithoutPubKeysFails(t *testing.T) { 1015 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1016 Terms: &protoTypes.ProposalTerms{ 1017 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1018 UpdateMarket: &protoTypes.UpdateMarket{ 1019 Changes: &protoTypes.UpdateMarketConfiguration{ 1020 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1021 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1022 Future: &protoTypes.UpdateFutureProduct{ 1023 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1024 vegapb.DataSourceContentTypeOracle, 1025 ).SetOracleConfig( 1026 &vegapb.DataSourceDefinitionExternal_Oracle{ 1027 Oracle: &vegapb.DataSourceSpecConfiguration{ 1028 Signers: []*datapb.Signer{}, 1029 Filters: []*datapb.Filter{ 1030 { 1031 Key: &datapb.PropertyKey{ 1032 Name: "trading.terminated", 1033 Type: datapb.PropertyKey_TYPE_BOOLEAN, 1034 }, 1035 Conditions: []*datapb.Condition{}, 1036 }, 1037 }, 1038 }, 1039 }, 1040 ), 1041 }, 1042 }, 1043 }, 1044 }, 1045 }, 1046 }, 1047 }, 1048 }) 1049 1050 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 1051 } 1052 1053 func testUpdateFutureMarketChangeSubmissionWithWrongPubKeysFails(t *testing.T) { 1054 pubKeys := []*datapb.Signer{ 1055 { 1056 Signer: &datapb.Signer_PubKey{ 1057 PubKey: &datapb.PubKey{ 1058 Key: "0xDEADBEEF", 1059 }, 1060 }, 1061 }, 1062 { 1063 Signer: &datapb.Signer_PubKey{ 1064 PubKey: &datapb.PubKey{ 1065 Key: "", 1066 }, 1067 }, 1068 }, 1069 } 1070 1071 testCases := []struct { 1072 msg string 1073 value []*datapb.Signer 1074 }{ 1075 { 1076 msg: "with empty signers", 1077 value: pubKeys, 1078 }, { 1079 msg: "with blank signers", 1080 value: pubKeys, 1081 }, 1082 } 1083 1084 for _, tc := range testCases { 1085 t.Run(tc.msg, func(t *testing.T) { 1086 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1087 Terms: &protoTypes.ProposalTerms{ 1088 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1089 UpdateMarket: &protoTypes.UpdateMarket{ 1090 Changes: &protoTypes.UpdateMarketConfiguration{ 1091 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1092 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1093 Future: &protoTypes.UpdateFutureProduct{ 1094 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1095 vegapb.DataSourceContentTypeOracle, 1096 ).SetOracleConfig( 1097 &vegapb.DataSourceDefinitionExternal_Oracle{ 1098 Oracle: &vegapb.DataSourceSpecConfiguration{ 1099 Signers: tc.value, 1100 }, 1101 }, 1102 ), 1103 }, 1104 }, 1105 }, 1106 }, 1107 }, 1108 }, 1109 }, 1110 }) 1111 1112 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValid) 1113 }) 1114 } 1115 } 1116 1117 func testUpdateFutureMarketChangeSubmissionWithPubKeysSucceeds(t *testing.T) { 1118 pubKeys := []*datapb.Signer{ 1119 { 1120 Signer: &datapb.Signer_PubKey{ 1121 PubKey: &datapb.PubKey{ 1122 Key: "0xDEADBEEF", 1123 }, 1124 }, 1125 }, 1126 { 1127 Signer: &datapb.Signer_PubKey{ 1128 PubKey: &datapb.PubKey{ 1129 Key: "0xCAFEDUDE", 1130 }, 1131 }, 1132 }, 1133 } 1134 1135 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1136 Terms: &protoTypes.ProposalTerms{ 1137 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1138 UpdateMarket: &protoTypes.UpdateMarket{ 1139 Changes: &protoTypes.UpdateMarketConfiguration{ 1140 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1141 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1142 Future: &protoTypes.UpdateFutureProduct{ 1143 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1144 vegapb.DataSourceContentTypeOracle, 1145 ).SetOracleConfig( 1146 &vegapb.DataSourceDefinitionExternal_Oracle{ 1147 Oracle: &vegapb.DataSourceSpecConfiguration{ 1148 Signers: pubKeys, 1149 }, 1150 }, 1151 ), 1152 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1153 vegapb.DataSourceContentTypeOracle, 1154 ).SetOracleConfig( 1155 &vegapb.DataSourceDefinitionExternal_Oracle{ 1156 Oracle: &vegapb.DataSourceSpecConfiguration{ 1157 Signers: pubKeys, 1158 }, 1159 }, 1160 ), 1161 }, 1162 }, 1163 }, 1164 }, 1165 }, 1166 }, 1167 }, 1168 }) 1169 1170 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 1171 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 1172 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.1"), commands.ErrIsNotValid) 1173 } 1174 1175 func testUpdateFutureMarketChangeSubmissionWithoutFiltersFails(t *testing.T) { 1176 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1177 Terms: &protoTypes.ProposalTerms{ 1178 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1179 UpdateMarket: &protoTypes.UpdateMarket{ 1180 Changes: &protoTypes.UpdateMarketConfiguration{ 1181 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1182 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1183 Future: &protoTypes.UpdateFutureProduct{ 1184 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1185 vegapb.DataSourceContentTypeOracle, 1186 ).SetOracleConfig( 1187 &vegapb.DataSourceDefinitionExternal_Oracle{ 1188 Oracle: &vegapb.DataSourceSpecConfiguration{ 1189 Filters: []*datapb.Filter{}, 1190 }, 1191 }, 1192 ), 1193 }, 1194 }, 1195 }, 1196 }, 1197 }, 1198 }, 1199 }, 1200 }) 1201 1202 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters"), commands.ErrIsRequired) 1203 } 1204 1205 func testUpdateFutureMarketChangeSubmissionWithFiltersSucceeds(t *testing.T) { 1206 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1207 Terms: &protoTypes.ProposalTerms{ 1208 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1209 UpdateMarket: &protoTypes.UpdateMarket{ 1210 Changes: &protoTypes.UpdateMarketConfiguration{ 1211 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1212 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1213 Future: &protoTypes.UpdateFutureProduct{ 1214 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1215 vegapb.DataSourceContentTypeOracle, 1216 ).SetOracleConfig( 1217 &vegapb.DataSourceDefinitionExternal_Oracle{ 1218 Oracle: &vegapb.DataSourceSpecConfiguration{ 1219 Filters: []*datapb.Filter{ 1220 {}, 1221 }, 1222 }, 1223 }, 1224 ), 1225 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1226 vegapb.DataSourceContentTypeOracle, 1227 ).SetOracleConfig( 1228 &vegapb.DataSourceDefinitionExternal_Oracle{ 1229 Oracle: &vegapb.DataSourceSpecConfiguration{ 1230 Filters: []*datapb.Filter{ 1231 {}, 1232 }, 1233 }, 1234 }, 1235 ), 1236 }, 1237 }, 1238 }, 1239 }, 1240 }, 1241 }, 1242 }, 1243 }) 1244 1245 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters"), commands.ErrIsRequired) 1246 } 1247 1248 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyFails(t *testing.T) { 1249 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1250 Terms: &protoTypes.ProposalTerms{ 1251 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1252 UpdateMarket: &protoTypes.UpdateMarket{ 1253 Changes: &protoTypes.UpdateMarketConfiguration{ 1254 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1255 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1256 Future: &protoTypes.UpdateFutureProduct{ 1257 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1258 vegapb.DataSourceContentTypeOracle, 1259 ).SetOracleConfig( 1260 &vegapb.DataSourceDefinitionExternal_Oracle{ 1261 Oracle: &vegapb.DataSourceSpecConfiguration{ 1262 Filters: []*datapb.Filter{ 1263 {}, {}, 1264 }, 1265 }, 1266 }, 1267 ), 1268 }, 1269 }, 1270 }, 1271 }, 1272 }, 1273 }, 1274 }, 1275 }) 1276 1277 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key"), commands.ErrIsNotValid) 1278 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key"), commands.ErrIsNotValid) 1279 } 1280 1281 func testUpdateFutureMarketChangeSubmissionWithFilterWithKeySucceeds(t *testing.T) { 1282 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1283 Terms: &protoTypes.ProposalTerms{ 1284 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1285 UpdateMarket: &protoTypes.UpdateMarket{ 1286 Changes: &protoTypes.UpdateMarketConfiguration{ 1287 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1288 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1289 Future: &protoTypes.UpdateFutureProduct{ 1290 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1291 vegapb.DataSourceContentTypeOracle, 1292 ).SetOracleConfig( 1293 &vegapb.DataSourceDefinitionExternal_Oracle{ 1294 Oracle: &vegapb.DataSourceSpecConfiguration{ 1295 Filters: []*datapb.Filter{ 1296 { 1297 Key: &datapb.PropertyKey{}, 1298 }, { 1299 Key: &datapb.PropertyKey{}, 1300 }, 1301 }, 1302 }, 1303 }, 1304 ), 1305 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1306 vegapb.DataSourceContentTypeOracle, 1307 ).SetOracleConfig( 1308 &vegapb.DataSourceDefinitionExternal_Oracle{ 1309 Oracle: &vegapb.DataSourceSpecConfiguration{ 1310 Filters: []*datapb.Filter{ 1311 { 1312 Key: &datapb.PropertyKey{}, 1313 }, { 1314 Key: &datapb.PropertyKey{}, 1315 }, 1316 }, 1317 }, 1318 }, 1319 ), 1320 }, 1321 }, 1322 }, 1323 }, 1324 }, 1325 }, 1326 }, 1327 }) 1328 1329 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key"), commands.ErrIsNotValid) 1330 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key"), commands.ErrIsNotValid) 1331 } 1332 1333 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyNameFails(t *testing.T) { 1334 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1335 Terms: &protoTypes.ProposalTerms{ 1336 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1337 UpdateMarket: &protoTypes.UpdateMarket{ 1338 Changes: &protoTypes.UpdateMarketConfiguration{ 1339 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1340 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1341 Future: &protoTypes.UpdateFutureProduct{ 1342 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1343 vegapb.DataSourceContentTypeOracle, 1344 ).SetOracleConfig( 1345 &vegapb.DataSourceDefinitionExternal_Oracle{ 1346 Oracle: &vegapb.DataSourceSpecConfiguration{ 1347 Filters: []*datapb.Filter{ 1348 { 1349 Key: &datapb.PropertyKey{ 1350 Name: "", 1351 }, 1352 }, { 1353 Key: &datapb.PropertyKey{ 1354 Name: "", 1355 }, 1356 }, 1357 }, 1358 }, 1359 }, 1360 ), 1361 }, 1362 }, 1363 }, 1364 }, 1365 }, 1366 }, 1367 }, 1368 }) 1369 1370 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.name"), commands.ErrIsRequired) 1371 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.name"), commands.ErrIsRequired) 1372 } 1373 1374 func testUpdateFutureMarketChangeSubmissionWithFilterWithKeyNameSucceeds(t *testing.T) { 1375 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1376 Terms: &protoTypes.ProposalTerms{ 1377 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1378 UpdateMarket: &protoTypes.UpdateMarket{ 1379 Changes: &protoTypes.UpdateMarketConfiguration{ 1380 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1381 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1382 Future: &protoTypes.UpdateFutureProduct{ 1383 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1384 vegapb.DataSourceContentTypeOracle, 1385 ).SetOracleConfig( 1386 &vegapb.DataSourceDefinitionExternal_Oracle{ 1387 Oracle: &vegapb.DataSourceSpecConfiguration{ 1388 Filters: []*datapb.Filter{ 1389 { 1390 Key: &datapb.PropertyKey{ 1391 Name: "key1", 1392 }, 1393 }, { 1394 Key: &datapb.PropertyKey{ 1395 Name: "key2", 1396 }, 1397 }, 1398 }, 1399 }, 1400 }, 1401 ), 1402 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1403 vegapb.DataSourceContentTypeOracle, 1404 ).SetOracleConfig( 1405 &vegapb.DataSourceDefinitionExternal_Oracle{ 1406 Oracle: &vegapb.DataSourceSpecConfiguration{ 1407 Filters: []*datapb.Filter{ 1408 { 1409 Key: &datapb.PropertyKey{ 1410 Name: "key1", 1411 }, 1412 }, { 1413 Key: &datapb.PropertyKey{ 1414 Name: "key2", 1415 }, 1416 }, 1417 }, 1418 }, 1419 }, 1420 ), 1421 }, 1422 }, 1423 }, 1424 }, 1425 }, 1426 }, 1427 }, 1428 }) 1429 1430 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.name"), commands.ErrIsRequired) 1431 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.name"), commands.ErrIsRequired) 1432 } 1433 1434 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutKeyTypeFails(t *testing.T) { 1435 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1436 Terms: &protoTypes.ProposalTerms{ 1437 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1438 UpdateMarket: &protoTypes.UpdateMarket{ 1439 Changes: &protoTypes.UpdateMarketConfiguration{ 1440 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1441 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1442 Future: &protoTypes.UpdateFutureProduct{ 1443 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1444 vegapb.DataSourceContentTypeOracle, 1445 ).SetOracleConfig( 1446 &vegapb.DataSourceDefinitionExternal_Oracle{ 1447 Oracle: &vegapb.DataSourceSpecConfiguration{ 1448 Filters: []*datapb.Filter{ 1449 { 1450 Key: &datapb.PropertyKey{ 1451 Type: datapb.PropertyKey_TYPE_UNSPECIFIED, 1452 }, 1453 }, { 1454 Key: &datapb.PropertyKey{}, 1455 }, 1456 }, 1457 }, 1458 }, 1459 ), 1460 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 1461 vegapb.DataSourceContentTypeOracle, 1462 ).SetOracleConfig( 1463 &vegapb.DataSourceDefinitionExternal_Oracle{ 1464 Oracle: &vegapb.DataSourceSpecConfiguration{ 1465 Filters: []*datapb.Filter{ 1466 { 1467 Key: &datapb.PropertyKey{ 1468 Type: datapb.PropertyKey_TYPE_UNSPECIFIED, 1469 }, 1470 }, { 1471 Key: &datapb.PropertyKey{}, 1472 }, 1473 }, 1474 }, 1475 }, 1476 ), 1477 }, 1478 }, 1479 }, 1480 }, 1481 }, 1482 }, 1483 }, 1484 }) 1485 1486 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.key.type"), commands.ErrIsRequired) 1487 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.1.key.type"), commands.ErrIsRequired) 1488 } 1489 1490 func testUpdateFutureMarketChangeSubmissionWithFilterWithKeyTypeSucceeds(t *testing.T) { 1491 testCases := []struct { 1492 msg string 1493 value datapb.PropertyKey_Type 1494 }{ 1495 { 1496 msg: "with EMPTY", 1497 value: datapb.PropertyKey_TYPE_EMPTY, 1498 }, { 1499 msg: "with INTEGER", 1500 value: datapb.PropertyKey_TYPE_INTEGER, 1501 }, { 1502 msg: "with STRING", 1503 value: datapb.PropertyKey_TYPE_STRING, 1504 }, { 1505 msg: "with BOOLEAN", 1506 value: datapb.PropertyKey_TYPE_BOOLEAN, 1507 }, { 1508 msg: "with DECIMAL", 1509 value: datapb.PropertyKey_TYPE_DECIMAL, 1510 }, { 1511 msg: "with TIMESTAMP", 1512 value: datapb.PropertyKey_TYPE_TIMESTAMP, 1513 }, 1514 } 1515 for _, tc := range testCases { 1516 t.Run(tc.msg, func(t *testing.T) { 1517 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1518 Terms: &protoTypes.ProposalTerms{ 1519 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1520 UpdateMarket: &protoTypes.UpdateMarket{ 1521 Changes: &protoTypes.UpdateMarketConfiguration{ 1522 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1523 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1524 Future: &protoTypes.UpdateFutureProduct{ 1525 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1526 vegapb.DataSourceContentTypeOracle, 1527 ).SetOracleConfig( 1528 &vegapb.DataSourceDefinitionExternal_Oracle{ 1529 Oracle: &vegapb.DataSourceSpecConfiguration{ 1530 Filters: []*datapb.Filter{ 1531 { 1532 Key: &datapb.PropertyKey{ 1533 Type: tc.value, 1534 }, 1535 }, { 1536 Key: &datapb.PropertyKey{ 1537 Type: tc.value, 1538 }, 1539 }, 1540 }, 1541 }, 1542 }, 1543 ), 1544 }, 1545 }, 1546 }, 1547 }, 1548 }, 1549 }, 1550 }, 1551 }) 1552 1553 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.key.type"), commands.ErrIsRequired) 1554 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.1.key.type"), commands.ErrIsRequired) 1555 }) 1556 } 1557 } 1558 1559 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionsSucceeds(t *testing.T) { 1560 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1561 Terms: &protoTypes.ProposalTerms{ 1562 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1563 UpdateMarket: &protoTypes.UpdateMarket{ 1564 Changes: &protoTypes.UpdateMarketConfiguration{ 1565 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1566 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1567 Future: &protoTypes.UpdateFutureProduct{ 1568 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1569 vegapb.DataSourceContentTypeOracle, 1570 ).SetOracleConfig( 1571 &vegapb.DataSourceDefinitionExternal_Oracle{ 1572 Oracle: &vegapb.DataSourceSpecConfiguration{ 1573 Filters: []*datapb.Filter{ 1574 { 1575 Conditions: []*datapb.Condition{}, 1576 }, 1577 }, 1578 }, 1579 }, 1580 ), 1581 }, 1582 }, 1583 }, 1584 }, 1585 }, 1586 }, 1587 }, 1588 }) 1589 1590 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions"), commands.ErrIsRequired) 1591 } 1592 1593 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionOperatorFails(t *testing.T) { 1594 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1595 Terms: &protoTypes.ProposalTerms{ 1596 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1597 UpdateMarket: &protoTypes.UpdateMarket{ 1598 Changes: &protoTypes.UpdateMarketConfiguration{ 1599 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1600 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1601 Future: &protoTypes.UpdateFutureProduct{ 1602 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1603 vegapb.DataSourceContentTypeOracle, 1604 ).SetOracleConfig( 1605 &vegapb.DataSourceDefinitionExternal_Oracle{ 1606 Oracle: &vegapb.DataSourceSpecConfiguration{ 1607 Filters: []*datapb.Filter{ 1608 { 1609 Conditions: []*datapb.Condition{ 1610 { 1611 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 1612 }, 1613 {}, 1614 }, 1615 }, 1616 }, 1617 }, 1618 }, 1619 ), 1620 }, 1621 }, 1622 }, 1623 }, 1624 }, 1625 }, 1626 }, 1627 }) 1628 1629 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 1630 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.1.operator"), commands.ErrIsRequired) 1631 } 1632 1633 func testUpdateFutureMarketChangeSubmissionWithFilterWithConditionOperatorSucceeds(t *testing.T) { 1634 testCases := []struct { 1635 msg string 1636 value datapb.Condition_Operator 1637 }{ 1638 { 1639 msg: "with EQUALS", 1640 value: datapb.Condition_OPERATOR_EQUALS, 1641 }, { 1642 msg: "with GREATER_THAN", 1643 value: datapb.Condition_OPERATOR_GREATER_THAN, 1644 }, { 1645 msg: "with GREATER_THAN_OR_EQUAL", 1646 value: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 1647 }, { 1648 msg: "with LESS_THAN", 1649 value: datapb.Condition_OPERATOR_LESS_THAN, 1650 }, { 1651 msg: "with LESS_THAN_OR_EQUAL", 1652 value: datapb.Condition_OPERATOR_LESS_THAN_OR_EQUAL, 1653 }, 1654 } 1655 for _, tc := range testCases { 1656 t.Run(tc.msg, func(t *testing.T) { 1657 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1658 Terms: &protoTypes.ProposalTerms{ 1659 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1660 UpdateMarket: &protoTypes.UpdateMarket{ 1661 Changes: &protoTypes.UpdateMarketConfiguration{ 1662 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1663 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1664 Future: &protoTypes.UpdateFutureProduct{ 1665 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1666 vegapb.DataSourceContentTypeOracle, 1667 ).SetOracleConfig( 1668 &vegapb.DataSourceDefinitionExternal_Oracle{ 1669 Oracle: &vegapb.DataSourceSpecConfiguration{ 1670 Filters: []*datapb.Filter{ 1671 { 1672 Conditions: []*datapb.Condition{ 1673 { 1674 Operator: tc.value, 1675 }, 1676 { 1677 Operator: tc.value, 1678 }, 1679 }, 1680 }, 1681 }, 1682 }, 1683 }, 1684 ), 1685 }, 1686 }, 1687 }, 1688 }, 1689 }, 1690 }, 1691 }, 1692 }) 1693 1694 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.0.operator"), commands.ErrIsRequired) 1695 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.1.conditions.0.operator"), commands.ErrIsRequired) 1696 }) 1697 } 1698 } 1699 1700 func testUpdateFutureMarketChangeSubmissionWithFilterWithoutConditionValueFails(t *testing.T) { 1701 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1702 Terms: &protoTypes.ProposalTerms{ 1703 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1704 UpdateMarket: &protoTypes.UpdateMarket{ 1705 Changes: &protoTypes.UpdateMarketConfiguration{ 1706 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1707 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1708 Future: &protoTypes.UpdateFutureProduct{ 1709 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1710 vegapb.DataSourceContentTypeOracle, 1711 ).SetOracleConfig( 1712 &vegapb.DataSourceDefinitionExternal_Oracle{ 1713 Oracle: &vegapb.DataSourceSpecConfiguration{ 1714 Filters: []*datapb.Filter{ 1715 { 1716 Conditions: []*datapb.Condition{ 1717 { 1718 Value: "", 1719 }, 1720 { 1721 Value: "", 1722 }, 1723 }, 1724 }, 1725 }, 1726 }, 1727 }, 1728 ), 1729 }, 1730 }, 1731 }, 1732 }, 1733 }, 1734 }, 1735 }, 1736 }) 1737 1738 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 1739 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 1740 } 1741 1742 func testUpdateFutureMarketChangeSubmissionWithFilterWithConditionValueSucceeds(t *testing.T) { 1743 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1744 Terms: &protoTypes.ProposalTerms{ 1745 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1746 UpdateMarket: &protoTypes.UpdateMarket{ 1747 Changes: &protoTypes.UpdateMarketConfiguration{ 1748 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1749 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1750 Future: &protoTypes.UpdateFutureProduct{ 1751 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1752 vegapb.DataSourceContentTypeOracle, 1753 ).SetOracleConfig( 1754 &vegapb.DataSourceDefinitionExternal_Oracle{ 1755 Oracle: &vegapb.DataSourceSpecConfiguration{ 1756 Filters: []*datapb.Filter{ 1757 { 1758 Conditions: []*datapb.Condition{ 1759 { 1760 Value: "value 1", 1761 }, 1762 { 1763 Value: "value 2", 1764 }, 1765 }, 1766 }, 1767 }, 1768 }, 1769 }, 1770 ), 1771 }, 1772 }, 1773 }, 1774 }, 1775 }, 1776 }, 1777 }, 1778 }) 1779 1780 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.0.value"), commands.ErrIsRequired) 1781 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec.external.oracle.filters.0.conditions.1.value"), commands.ErrIsRequired) 1782 } 1783 1784 func testUpdateFutureMarketChangeSubmissionWithoutDataSourceSpecBindingFails(t *testing.T) { 1785 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1786 Terms: &protoTypes.ProposalTerms{ 1787 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1788 UpdateMarket: &protoTypes.UpdateMarket{ 1789 Changes: &protoTypes.UpdateMarketConfiguration{ 1790 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1791 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1792 Future: &protoTypes.UpdateFutureProduct{}, 1793 }, 1794 }, 1795 }, 1796 }, 1797 }, 1798 }, 1799 }) 1800 1801 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding"), commands.ErrIsRequired) 1802 } 1803 1804 func testUpdateFutureMarketChangeSubmissionWithDataSourceSpecBindingSucceeds(t *testing.T) { 1805 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1806 Terms: &protoTypes.ProposalTerms{ 1807 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1808 UpdateMarket: &protoTypes.UpdateMarket{ 1809 Changes: &protoTypes.UpdateMarketConfiguration{ 1810 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1811 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1812 Future: &protoTypes.UpdateFutureProduct{ 1813 DataSourceSpecBinding: &protoTypes.DataSourceSpecToFutureBinding{}, 1814 }, 1815 }, 1816 }, 1817 }, 1818 }, 1819 }, 1820 }, 1821 }) 1822 1823 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding"), commands.ErrIsRequired) 1824 } 1825 1826 func testUpdateFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t *testing.T, property string) { 1827 t.Helper() 1828 var binding *protoTypes.DataSourceSpecToFutureBinding 1829 if property == "settlement_data_property" { 1830 binding = &protoTypes.DataSourceSpecToFutureBinding{ 1831 SettlementDataProperty: "", 1832 } 1833 } else { 1834 binding = &protoTypes.DataSourceSpecToFutureBinding{ 1835 TradingTerminationProperty: "", 1836 } 1837 } 1838 1839 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1840 Terms: &protoTypes.ProposalTerms{ 1841 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1842 UpdateMarket: &protoTypes.UpdateMarket{ 1843 Changes: &protoTypes.UpdateMarketConfiguration{ 1844 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1845 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1846 Future: &protoTypes.UpdateFutureProduct{ 1847 DataSourceSpecBinding: binding, 1848 }, 1849 }, 1850 }, 1851 }, 1852 }, 1853 }, 1854 }, 1855 }) 1856 1857 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding."+property), commands.ErrIsRequired) 1858 } 1859 1860 func testUpdateFutureMarketChangeSubmissionWithoutTradingTerminationPropertyFails(t *testing.T) { 1861 testUpdateFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t, "trading_termination_property") 1862 } 1863 1864 func testUpdateFutureMarketChangeSubmissionWithoutSettlementDataPropertyFails(t *testing.T) { 1865 testUpdateFutureMarketChangeSubmissionMissingOracleBindingPropertyFails(t, "settlement_data_property") 1866 } 1867 1868 func testUpdateFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingSucceeds(t *testing.T) { 1869 testUpdateFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t, &protoTypes.DataSourceSpecToFutureBinding{SettlementDataProperty: "key1"}, "settlement_data_property", "key1") 1870 testUpdateFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t, &protoTypes.DataSourceSpecToFutureBinding{TradingTerminationProperty: "key2"}, "settlement_data_property", "key2") 1871 } 1872 1873 func testUpdateFutureMarketChangeSubmissionWithNoMismatchBetweenFilterAndBindingForSpecSucceeds(t *testing.T, binding *protoTypes.DataSourceSpecToFutureBinding, bindingName string, bindingKey string) { 1874 t.Helper() 1875 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1876 Terms: &protoTypes.ProposalTerms{ 1877 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1878 UpdateMarket: &protoTypes.UpdateMarket{ 1879 Changes: &protoTypes.UpdateMarketConfiguration{ 1880 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1881 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1882 Future: &protoTypes.UpdateFutureProduct{ 1883 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 1884 vegapb.DataSourceContentTypeOracle, 1885 ).SetOracleConfig( 1886 &vegapb.DataSourceDefinitionExternal_Oracle{ 1887 Oracle: &vegapb.DataSourceSpecConfiguration{ 1888 Filters: []*datapb.Filter{ 1889 { 1890 Key: &datapb.PropertyKey{ 1891 Name: bindingKey, 1892 }, 1893 }, { 1894 Key: &datapb.PropertyKey{}, 1895 }, 1896 }, 1897 }, 1898 }, 1899 ), 1900 DataSourceSpecBinding: binding, 1901 }, 1902 }, 1903 }, 1904 }, 1905 }, 1906 }, 1907 }, 1908 }) 1909 1910 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 1911 } 1912 1913 func testUpdateFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t *testing.T, binding *protoTypes.DataSourceSpecToFutureBinding, bindingName string) { 1914 t.Helper() 1915 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1916 Terms: &protoTypes.ProposalTerms{ 1917 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1918 UpdateMarket: &protoTypes.UpdateMarket{ 1919 Changes: &protoTypes.UpdateMarketConfiguration{ 1920 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1921 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1922 Future: &protoTypes.UpdateFutureProduct{ 1923 DataSourceSpecBinding: binding, 1924 }, 1925 }, 1926 }, 1927 }, 1928 }, 1929 }, 1930 }, 1931 }) 1932 1933 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding."+bindingName), commands.ErrIsMismatching) 1934 } 1935 1936 func testUpdateFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingFails(t *testing.T) { 1937 testUpdateFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t, &protoTypes.DataSourceSpecToFutureBinding{SettlementDataProperty: "My property"}, "settlement_data_property") 1938 testUpdateFutureMarketChangeSubmissionWithMismatchBetweenFilterAndBindingForSpecFails(t, &protoTypes.DataSourceSpecToFutureBinding{TradingTerminationProperty: "My property"}, "trading_termination_property") 1939 } 1940 1941 func testUpdateFutureMarketChangeSubmissionWithSettlementDataPropertySucceeds(t *testing.T) { 1942 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1943 Terms: &protoTypes.ProposalTerms{ 1944 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1945 UpdateMarket: &protoTypes.UpdateMarket{ 1946 Changes: &protoTypes.UpdateMarketConfiguration{ 1947 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 1948 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 1949 Future: &protoTypes.UpdateFutureProduct{ 1950 DataSourceSpecBinding: &protoTypes.DataSourceSpecToFutureBinding{ 1951 SettlementDataProperty: "My property", 1952 }, 1953 }, 1954 }, 1955 }, 1956 }, 1957 }, 1958 }, 1959 }, 1960 }) 1961 1962 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_binding.settlement_data_property"), commands.ErrIsRequired) 1963 } 1964 1965 func testUpdateSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails(t *testing.T) { 1966 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1967 Terms: &protoTypes.ProposalTerms{ 1968 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1969 UpdateMarket: &protoTypes.UpdateMarket{ 1970 Changes: &protoTypes.UpdateMarketConfiguration{ 1971 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{}, 1972 }, 1973 }, 1974 }, 1975 }, 1976 }) 1977 1978 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple"), commands.ErrIsRequired) 1979 } 1980 1981 func testUpdateSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds(t *testing.T) { 1982 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 1983 Terms: &protoTypes.ProposalTerms{ 1984 Change: &protoTypes.ProposalTerms_UpdateMarket{ 1985 UpdateMarket: &protoTypes.UpdateMarket{ 1986 Changes: &protoTypes.UpdateMarketConfiguration{ 1987 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 1988 Simple: &protoTypes.SimpleModelParams{}, 1989 }, 1990 }, 1991 }, 1992 }, 1993 }, 1994 }) 1995 1996 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple"), commands.ErrIsRequired) 1997 } 1998 1999 func testUpdateSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails(t *testing.T) { 2000 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2001 Terms: &protoTypes.ProposalTerms{ 2002 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2003 UpdateMarket: &protoTypes.UpdateMarket{ 2004 Changes: &protoTypes.UpdateMarketConfiguration{ 2005 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2006 Simple: &protoTypes.SimpleModelParams{ 2007 MinMoveDown: 1, 2008 }, 2009 }, 2010 }, 2011 }, 2012 }, 2013 }, 2014 }) 2015 2016 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero) 2017 } 2018 2019 func testUpdateSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds(t *testing.T) { 2020 testCases := []struct { 2021 msg string 2022 value float64 2023 }{ 2024 { 2025 msg: "with min move down of 0", 2026 value: 0, 2027 }, { 2028 msg: "with min move down of -1", 2029 value: -1, 2030 }, 2031 } 2032 for _, tc := range testCases { 2033 t.Run(tc.msg, func(t *testing.T) { 2034 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2035 Terms: &protoTypes.ProposalTerms{ 2036 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2037 UpdateMarket: &protoTypes.UpdateMarket{ 2038 Changes: &protoTypes.UpdateMarketConfiguration{ 2039 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2040 Simple: &protoTypes.SimpleModelParams{ 2041 MinMoveDown: tc.value, 2042 }, 2043 }, 2044 }, 2045 }, 2046 }, 2047 }, 2048 }) 2049 2050 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero) 2051 }) 2052 } 2053 } 2054 2055 func testUpdateSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails(t *testing.T) { 2056 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2057 Terms: &protoTypes.ProposalTerms{ 2058 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2059 UpdateMarket: &protoTypes.UpdateMarket{ 2060 Changes: &protoTypes.UpdateMarketConfiguration{ 2061 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2062 Simple: &protoTypes.SimpleModelParams{ 2063 MaxMoveUp: -1, 2064 }, 2065 }, 2066 }, 2067 }, 2068 }, 2069 }, 2070 }) 2071 2072 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero) 2073 } 2074 2075 func testUpdateSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds(t *testing.T) { 2076 testCases := []struct { 2077 msg string 2078 value float64 2079 }{ 2080 { 2081 msg: "with max move up of 0", 2082 value: 0, 2083 }, { 2084 msg: "with max move up of 1", 2085 value: 1, 2086 }, 2087 } 2088 for _, tc := range testCases { 2089 t.Run(tc.msg, func(t *testing.T) { 2090 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2091 Terms: &protoTypes.ProposalTerms{ 2092 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2093 UpdateMarket: &protoTypes.UpdateMarket{ 2094 Changes: &protoTypes.UpdateMarketConfiguration{ 2095 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2096 Simple: &protoTypes.SimpleModelParams{ 2097 MaxMoveUp: tc.value, 2098 }, 2099 }, 2100 }, 2101 }, 2102 }, 2103 }, 2104 }) 2105 2106 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero) 2107 }) 2108 } 2109 } 2110 2111 func testUpdateSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails(t *testing.T) { 2112 testCases := []struct { 2113 msg string 2114 value float64 2115 }{ 2116 { 2117 msg: "with probability of trading of -1", 2118 value: -1, 2119 }, { 2120 msg: "with probability of trading of 2", 2121 value: 2, 2122 }, 2123 } 2124 for _, tc := range testCases { 2125 t.Run(tc.msg, func(t *testing.T) { 2126 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2127 Terms: &protoTypes.ProposalTerms{ 2128 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2129 UpdateMarket: &protoTypes.UpdateMarket{ 2130 Changes: &protoTypes.UpdateMarketConfiguration{ 2131 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2132 Simple: &protoTypes.SimpleModelParams{ 2133 ProbabilityOfTrading: tc.value, 2134 }, 2135 }, 2136 }, 2137 }, 2138 }, 2139 }, 2140 }) 2141 2142 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.probability_of_trading"), 2143 errors.New("should be between 0 (inclusive) and 1 (inclusive)")) 2144 }) 2145 } 2146 } 2147 2148 func testUpdateSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds(t *testing.T) { 2149 testCases := []struct { 2150 msg string 2151 value float64 2152 }{ 2153 { 2154 msg: "with probability of trading of 0", 2155 value: 0, 2156 }, { 2157 msg: "with probability of trading of 1", 2158 value: 1, 2159 }, { 2160 msg: "with probability of trading of 0.5", 2161 value: 0.5, 2162 }, 2163 } 2164 for _, tc := range testCases { 2165 t.Run(tc.msg, func(t *testing.T) { 2166 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2167 Terms: &protoTypes.ProposalTerms{ 2168 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2169 UpdateMarket: &protoTypes.UpdateMarket{ 2170 Changes: &protoTypes.UpdateMarketConfiguration{ 2171 RiskParameters: &protoTypes.UpdateMarketConfiguration_Simple{ 2172 Simple: &protoTypes.SimpleModelParams{ 2173 ProbabilityOfTrading: tc.value, 2174 }, 2175 }, 2176 }, 2177 }, 2178 }, 2179 }, 2180 }) 2181 2182 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.simple.probability_of_trading"), 2183 errors.New("should be between 0 (inclusive) and 1 (inclusive)")) 2184 }) 2185 } 2186 } 2187 2188 func testUpdateLogNormalRiskParametersChangeSubmissionWithOverrides(t *testing.T) { 2189 cases := []struct { 2190 desc string 2191 get string 2192 override *vegapb.RiskFactorOverride 2193 err string 2194 }{ 2195 { 2196 desc: "no override is valid", 2197 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override", 2198 override: nil, 2199 err: "", 2200 }, 2201 { 2202 desc: "non nil, but with empty short", 2203 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2204 override: &vegapb.RiskFactorOverride{}, 2205 err: "is required", 2206 }, 2207 { 2208 desc: "non nil, but with bad value short", 2209 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2210 override: &vegapb.RiskFactorOverride{ 2211 Short: "asd", 2212 }, 2213 err: "is not a valid number", 2214 }, 2215 { 2216 desc: "non nil, but with negative short", 2217 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2218 override: &vegapb.RiskFactorOverride{ 2219 Short: "-1", 2220 }, 2221 err: "must be positive", 2222 }, 2223 { 2224 desc: "non nil, but with 0 short", 2225 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.short", 2226 override: &vegapb.RiskFactorOverride{ 2227 Short: "0", 2228 }, 2229 err: "must be positive", 2230 }, 2231 { 2232 desc: "non nil, but with empty long", 2233 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2234 override: &vegapb.RiskFactorOverride{ 2235 Short: "0.1", 2236 }, 2237 err: "is required", 2238 }, 2239 { 2240 desc: "non nil, but with bad value long", 2241 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2242 override: &vegapb.RiskFactorOverride{ 2243 Short: "0.1", 2244 Long: "asd", 2245 }, 2246 err: "is not a valid number", 2247 }, 2248 { 2249 desc: "non nil, but with negative long", 2250 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2251 override: &vegapb.RiskFactorOverride{ 2252 Short: "0.1", 2253 Long: "-1", 2254 }, 2255 err: "must be positive", 2256 }, 2257 { 2258 desc: "non nil, but with 0 long", 2259 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override.long", 2260 override: &vegapb.RiskFactorOverride{ 2261 Short: "0.1", 2262 Long: "0", 2263 }, 2264 err: "must be positive", 2265 }, 2266 { 2267 desc: "both valid", 2268 get: "proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_factor_override", 2269 override: &vegapb.RiskFactorOverride{ 2270 Short: "0.1", 2271 Long: "0.1", 2272 }, 2273 err: "", 2274 }, 2275 } 2276 2277 for _, c := range cases { 2278 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2279 Terms: &vegapb.ProposalTerms{ 2280 Change: &vegapb.ProposalTerms_UpdateMarket{ 2281 UpdateMarket: &vegapb.UpdateMarket{ 2282 Changes: &vegapb.UpdateMarketConfiguration{ 2283 RiskParameters: &vegapb.UpdateMarketConfiguration_LogNormal{ 2284 LogNormal: &vegapb.LogNormalRiskModel{ 2285 RiskAversionParameter: 0.1, 2286 Tau: 1, 2287 Params: &vegapb.LogNormalModelParams{ 2288 Mu: 0, 2289 Sigma: 0.1, 2290 R: 0, 2291 }, 2292 RiskFactorOverride: c.override, 2293 }, 2294 }, 2295 }, 2296 }, 2297 }, 2298 }, 2299 }) 2300 2301 if len(c.err) <= 0 { 2302 // no error 2303 assert.Len(t, err.Get(c.get), 0, c.desc) 2304 continue 2305 } 2306 2307 assert.Contains(t, err.Get(c.get), errors.New(c.err), "test: %v, err: %v", c.desc, err) 2308 } 2309 } 2310 2311 func testUpdateLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails(t *testing.T) { 2312 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2313 Terms: &protoTypes.ProposalTerms{ 2314 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2315 UpdateMarket: &protoTypes.UpdateMarket{ 2316 Changes: &protoTypes.UpdateMarketConfiguration{ 2317 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{}, 2318 }, 2319 }, 2320 }, 2321 }, 2322 }) 2323 2324 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired) 2325 } 2326 2327 func testUpdateLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds(t *testing.T) { 2328 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2329 Terms: &protoTypes.ProposalTerms{ 2330 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2331 UpdateMarket: &protoTypes.UpdateMarket{ 2332 Changes: &protoTypes.UpdateMarketConfiguration{ 2333 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2334 LogNormal: &protoTypes.LogNormalRiskModel{ 2335 RiskAversionParameter: 1, 2336 Tau: 2, 2337 Params: &protoTypes.LogNormalModelParams{ 2338 Mu: 0, 2339 Sigma: 0.1, 2340 R: 0, 2341 }, 2342 }, 2343 }, 2344 }, 2345 }, 2346 }, 2347 }, 2348 }) 2349 2350 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired) 2351 } 2352 2353 func testUpdateLogNormalRiskParametersChangeSubmissionWithoutParamsFails(t *testing.T) { 2354 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2355 Terms: &protoTypes.ProposalTerms{ 2356 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2357 UpdateMarket: &protoTypes.UpdateMarket{ 2358 Changes: &protoTypes.UpdateMarketConfiguration{ 2359 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2360 LogNormal: &protoTypes.LogNormalRiskModel{}, 2361 }, 2362 }, 2363 }, 2364 }, 2365 }, 2366 }) 2367 2368 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params"), commands.ErrIsRequired) 2369 } 2370 2371 func testUpdateLogNormalRiskParametersChangeSubmissionInvalidRiskAversion(t *testing.T) { 2372 cZero := &commandspb.ProposalSubmission{ 2373 Terms: &protoTypes.ProposalTerms{ 2374 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2375 UpdateMarket: &protoTypes.UpdateMarket{ 2376 Changes: &protoTypes.UpdateMarketConfiguration{ 2377 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2378 LogNormal: &protoTypes.LogNormalRiskModel{ 2379 RiskAversionParameter: 0, 2380 Tau: 2, 2381 Params: &protoTypes.LogNormalModelParams{ 2382 Mu: 0, 2383 Sigma: 0.1, 2384 R: 0, 2385 }, 2386 }, 2387 }, 2388 }, 2389 }, 2390 }, 2391 }, 2392 } 2393 err := checkProposalSubmission(cZero) 2394 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), commands.ErrMustBePositive) 2395 2396 cNeg := &commandspb.ProposalSubmission{ 2397 Terms: &protoTypes.ProposalTerms{ 2398 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2399 UpdateMarket: &protoTypes.UpdateMarket{ 2400 Changes: &protoTypes.UpdateMarketConfiguration{ 2401 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2402 LogNormal: &protoTypes.LogNormalRiskModel{ 2403 RiskAversionParameter: -0.1, 2404 Tau: 2, 2405 Params: &protoTypes.LogNormalModelParams{ 2406 Mu: 0, 2407 Sigma: 0.1, 2408 R: 0, 2409 }, 2410 }, 2411 }, 2412 }, 2413 }, 2414 }, 2415 }, 2416 } 2417 err = checkProposalSubmission(cNeg) 2418 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), commands.ErrMustBePositive) 2419 } 2420 2421 func testUpdateLogNormalRiskParametersChangeSubmissionInvalidTau(t *testing.T) { 2422 cZero := &commandspb.ProposalSubmission{ 2423 Terms: &protoTypes.ProposalTerms{ 2424 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2425 UpdateMarket: &protoTypes.UpdateMarket{ 2426 Changes: &protoTypes.UpdateMarketConfiguration{ 2427 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2428 LogNormal: &protoTypes.LogNormalRiskModel{ 2429 RiskAversionParameter: 0.1, 2430 Tau: 0, 2431 Params: &protoTypes.LogNormalModelParams{ 2432 Mu: 0, 2433 Sigma: 0.1, 2434 R: 0, 2435 }, 2436 }, 2437 }, 2438 }, 2439 }, 2440 }, 2441 }, 2442 } 2443 err := checkProposalSubmission(cZero) 2444 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.tau"), commands.ErrMustBePositive) 2445 2446 cNeg := &commandspb.ProposalSubmission{ 2447 Terms: &protoTypes.ProposalTerms{ 2448 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2449 UpdateMarket: &protoTypes.UpdateMarket{ 2450 Changes: &protoTypes.UpdateMarketConfiguration{ 2451 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2452 LogNormal: &protoTypes.LogNormalRiskModel{ 2453 RiskAversionParameter: 0.1, 2454 Tau: -0.2, 2455 Params: &protoTypes.LogNormalModelParams{ 2456 Mu: 0, 2457 Sigma: 0.1, 2458 R: 0, 2459 }, 2460 }, 2461 }, 2462 }, 2463 }, 2464 }, 2465 }, 2466 } 2467 err = checkProposalSubmission(cNeg) 2468 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.tau"), commands.ErrMustBePositive) 2469 } 2470 2471 func testUpdateLogNormalRiskParametersChangeSubmissionInvalidMu(t *testing.T) { 2472 cNaN := &commandspb.ProposalSubmission{ 2473 Terms: &protoTypes.ProposalTerms{ 2474 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2475 UpdateMarket: &protoTypes.UpdateMarket{ 2476 Changes: &protoTypes.UpdateMarketConfiguration{ 2477 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2478 LogNormal: &protoTypes.LogNormalRiskModel{ 2479 RiskAversionParameter: 0.1, 2480 Tau: 0.2, 2481 Params: &protoTypes.LogNormalModelParams{ 2482 Mu: math.NaN(), 2483 Sigma: 0.1, 2484 R: 0, 2485 }, 2486 }, 2487 }, 2488 }, 2489 }, 2490 }, 2491 }, 2492 } 2493 err := checkProposalSubmission(cNaN) 2494 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params.mu"), commands.ErrIsNotValidNumber) 2495 } 2496 2497 func testUpdateLogNormalRiskParametersChangeSubmissionInvalidR(t *testing.T) { 2498 cNaN := &commandspb.ProposalSubmission{ 2499 Terms: &protoTypes.ProposalTerms{ 2500 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2501 UpdateMarket: &protoTypes.UpdateMarket{ 2502 Changes: &protoTypes.UpdateMarketConfiguration{ 2503 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2504 LogNormal: &protoTypes.LogNormalRiskModel{ 2505 RiskAversionParameter: 0.1, 2506 Tau: 0.2, 2507 Params: &protoTypes.LogNormalModelParams{ 2508 Mu: 0.2, 2509 Sigma: 0.1, 2510 R: math.NaN(), 2511 }, 2512 }, 2513 }, 2514 }, 2515 }, 2516 }, 2517 }, 2518 } 2519 err := checkProposalSubmission(cNaN) 2520 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params.r"), commands.ErrIsNotValidNumber) 2521 } 2522 2523 func testUpdateLogNormalRiskParametersChangeSubmissionInvalidSigma(t *testing.T) { 2524 cNaN := &commandspb.ProposalSubmission{ 2525 Terms: &protoTypes.ProposalTerms{ 2526 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2527 UpdateMarket: &protoTypes.UpdateMarket{ 2528 Changes: &protoTypes.UpdateMarketConfiguration{ 2529 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2530 LogNormal: &protoTypes.LogNormalRiskModel{ 2531 RiskAversionParameter: 0.1, 2532 Tau: 0.2, 2533 Params: &protoTypes.LogNormalModelParams{ 2534 Mu: 0.2, 2535 Sigma: math.NaN(), 2536 R: 0, 2537 }, 2538 }, 2539 }, 2540 }, 2541 }, 2542 }, 2543 }, 2544 } 2545 err := checkProposalSubmission(cNaN) 2546 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrIsNotValidNumber) 2547 2548 cNeg := &commandspb.ProposalSubmission{ 2549 Terms: &protoTypes.ProposalTerms{ 2550 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2551 UpdateMarket: &protoTypes.UpdateMarket{ 2552 Changes: &protoTypes.UpdateMarketConfiguration{ 2553 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2554 LogNormal: &protoTypes.LogNormalRiskModel{ 2555 RiskAversionParameter: 0.1, 2556 Tau: 0.2, 2557 Params: &protoTypes.LogNormalModelParams{ 2558 Mu: 0.2, 2559 Sigma: -0.1, 2560 R: 0, 2561 }, 2562 }, 2563 }, 2564 }, 2565 }, 2566 }, 2567 }, 2568 } 2569 err = checkProposalSubmission(cNeg) 2570 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrMustBePositive) 2571 2572 c0 := &commandspb.ProposalSubmission{ 2573 Terms: &protoTypes.ProposalTerms{ 2574 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2575 UpdateMarket: &protoTypes.UpdateMarket{ 2576 Changes: &protoTypes.UpdateMarketConfiguration{ 2577 RiskParameters: &protoTypes.UpdateMarketConfiguration_LogNormal{ 2578 LogNormal: &protoTypes.LogNormalRiskModel{ 2579 RiskAversionParameter: 0.1, 2580 Tau: 0.2, 2581 Params: &protoTypes.LogNormalModelParams{ 2582 Mu: 0.2, 2583 Sigma: 0, 2584 R: 0, 2585 }, 2586 }, 2587 }, 2588 }, 2589 }, 2590 }, 2591 }, 2592 } 2593 err = checkProposalSubmission(c0) 2594 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrMustBePositive) 2595 } 2596 2597 func testUpdateMarketSubmissionWithTooLongReferenceFails(t *testing.T) { 2598 ref := make([]byte, 101) 2599 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2600 Reference: string(ref), 2601 }) 2602 assert.Contains(t, err.Get("proposal_submission.reference"), commands.ErrReferenceTooLong) 2603 } 2604 2605 func testUpdateMarketFutureMarketSubmissionWithInternalTimestampForTradingTerminationNoSignersSucceeds(t *testing.T) { 2606 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2607 Terms: &protoTypes.ProposalTerms{ 2608 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2609 UpdateMarket: &protoTypes.UpdateMarket{ 2610 Changes: &protoTypes.UpdateMarketConfiguration{ 2611 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2612 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2613 Future: &protoTypes.UpdateFutureProduct{ 2614 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 2615 vegapb.DataSourceContentTypeInternalTimeTermination, 2616 ).SetOracleConfig( 2617 &vegapb.DataSourceDefinitionExternal_Oracle{ 2618 Oracle: &vegapb.DataSourceSpecConfiguration{ 2619 Signers: []*datapb.Signer{}, 2620 Filters: []*datapb.Filter{ 2621 { 2622 Conditions: []*datapb.Condition{ 2623 { 2624 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 2625 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 2626 }, 2627 }, 2628 }, 2629 }, 2630 }, 2631 }, 2632 ), 2633 }, 2634 }, 2635 }, 2636 }, 2637 }, 2638 }, 2639 }, 2640 }) 2641 2642 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 2643 } 2644 2645 func testUpdateMarketFutureMarketSubmissionWithInvalidOperatorInternalSourceForTradingTerminationNoSignersFails(t *testing.T) { 2646 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2647 Terms: &protoTypes.ProposalTerms{ 2648 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2649 UpdateMarket: &protoTypes.UpdateMarket{ 2650 Changes: &protoTypes.UpdateMarketConfiguration{ 2651 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2652 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2653 Future: &protoTypes.UpdateFutureProduct{ 2654 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 2655 vegapb.DataSourceContentTypeInternalTimeTermination, 2656 ).SetOracleConfig( 2657 &vegapb.DataSourceDefinitionExternal_Oracle{ 2658 Oracle: &vegapb.DataSourceSpecConfiguration{ 2659 Signers: []*datapb.Signer{}, 2660 Filters: []*datapb.Filter{ 2661 { 2662 Conditions: []*datapb.Condition{ 2663 { 2664 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 2665 Value: "value 1", 2666 }, 2667 }, 2668 }, 2669 }, 2670 }, 2671 }, 2672 ), 2673 }, 2674 }, 2675 }, 2676 }, 2677 }, 2678 }, 2679 }, 2680 }) 2681 2682 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time.conditions"), commands.ErrIsRequired) 2683 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 2684 2685 err = checkProposalSubmission(&commandspb.ProposalSubmission{ 2686 Terms: &protoTypes.ProposalTerms{ 2687 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2688 UpdateMarket: &protoTypes.UpdateMarket{ 2689 Changes: &protoTypes.UpdateMarketConfiguration{ 2690 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2691 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2692 Future: &protoTypes.UpdateFutureProduct{ 2693 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 2694 vegapb.DataSourceContentTypeInternalTimeTermination, 2695 ).SetTimeTriggerConditionConfig( 2696 []*datapb.Condition{ 2697 { 2698 Operator: datapb.Condition_OPERATOR_UNSPECIFIED, 2699 Value: "value 1", 2700 }, 2701 }, 2702 ), 2703 }, 2704 }, 2705 }, 2706 }, 2707 }, 2708 }, 2709 }, 2710 }) 2711 2712 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.time.conditions.0.operator"), commands.ErrIsRequired) 2713 } 2714 2715 func testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingTerminationNoSignersFails(t *testing.T) { 2716 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2717 Terms: &protoTypes.ProposalTerms{ 2718 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2719 UpdateMarket: &protoTypes.UpdateMarket{ 2720 Changes: &protoTypes.UpdateMarketConfiguration{ 2721 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2722 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2723 Future: &protoTypes.UpdateFutureProduct{ 2724 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 2725 vegapb.DataSourceContentTypeOracle, 2726 ).SetOracleConfig( 2727 &vegapb.DataSourceDefinitionExternal_Oracle{ 2728 Oracle: &vegapb.DataSourceSpecConfiguration{ 2729 Signers: []*datapb.Signer{}, 2730 Filters: []*datapb.Filter{ 2731 { 2732 Key: &datapb.PropertyKey{ 2733 Name: "trading.terminated", 2734 Type: datapb.PropertyKey_TYPE_BOOLEAN, 2735 }, 2736 Conditions: []*datapb.Condition{}, 2737 }, 2738 }, 2739 }, 2740 }, 2741 ), 2742 }, 2743 }, 2744 }, 2745 }, 2746 }, 2747 }, 2748 }, 2749 }) 2750 2751 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 2752 } 2753 2754 func testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingTerminationBuiltInKeyNoSignersFails(t *testing.T) { 2755 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2756 Terms: &protoTypes.ProposalTerms{ 2757 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2758 UpdateMarket: &protoTypes.UpdateMarket{ 2759 Changes: &protoTypes.UpdateMarketConfiguration{ 2760 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2761 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2762 Future: &protoTypes.UpdateFutureProduct{ 2763 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 2764 vegapb.DataSourceContentTypeOracle, 2765 ).SetOracleConfig( 2766 &vegapb.DataSourceDefinitionExternal_Oracle{ 2767 Oracle: &vegapb.DataSourceSpecConfiguration{ 2768 Signers: []*datapb.Signer{}, 2769 Filters: []*datapb.Filter{ 2770 { 2771 Key: &datapb.PropertyKey{ 2772 Name: "vegaprotocol.builtin.timestamp", 2773 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 2774 }, 2775 Conditions: []*datapb.Condition{ 2776 { 2777 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 2778 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 2779 }, 2780 }, 2781 }, 2782 }, 2783 }, 2784 }, 2785 ), 2786 }, 2787 }, 2788 }, 2789 }, 2790 }, 2791 }, 2792 }, 2793 }) 2794 2795 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 2796 } 2797 2798 func testUpdateMarketFutureMarketSubmissionWithExternalSourceForTradingSettlementBuiltInKeyNoSignersFails(t *testing.T) { 2799 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2800 Terms: &protoTypes.ProposalTerms{ 2801 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2802 UpdateMarket: &protoTypes.UpdateMarket{ 2803 Changes: &protoTypes.UpdateMarketConfiguration{ 2804 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2805 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2806 Future: &protoTypes.UpdateFutureProduct{ 2807 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2808 vegapb.DataSourceContentTypeOracle, 2809 ).SetOracleConfig( 2810 &vegapb.DataSourceDefinitionExternal_Oracle{ 2811 Oracle: &vegapb.DataSourceSpecConfiguration{ 2812 Signers: []*datapb.Signer{}, 2813 Filters: []*datapb.Filter{ 2814 { 2815 Key: &datapb.PropertyKey{ 2816 Name: "vegaprotocol.builtin.timestamp", 2817 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 2818 }, 2819 Conditions: []*datapb.Condition{ 2820 { 2821 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 2822 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 2823 }, 2824 }, 2825 }, 2826 }, 2827 }, 2828 }, 2829 ), 2830 }, 2831 }, 2832 }, 2833 }, 2834 }, 2835 }, 2836 }, 2837 }) 2838 2839 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 2840 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 2841 } 2842 2843 func testUpdateMarketFutureSubmissionWithExternalTradingSettlementTimestampKeySucceeds(t *testing.T) { 2844 pubKeys := []*dstypes.Signer{ 2845 dstypes.CreateSignerFromString("0xDEADBEEF", dstypes.SignerTypePubKey), 2846 dstypes.CreateSignerFromString("", dstypes.SignerTypePubKey), 2847 } 2848 2849 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2850 Terms: &protoTypes.ProposalTerms{ 2851 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2852 UpdateMarket: &protoTypes.UpdateMarket{ 2853 Changes: &protoTypes.UpdateMarketConfiguration{ 2854 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 2855 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 2856 Future: &protoTypes.UpdateFutureProduct{ 2857 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 2858 vegapb.DataSourceContentTypeOracle, 2859 ).SetOracleConfig( 2860 &vegapb.DataSourceDefinitionExternal_Oracle{ 2861 Oracle: &vegapb.DataSourceSpecConfiguration{ 2862 Signers: dstypes.SignersIntoProto(pubKeys), 2863 Filters: []*datapb.Filter{ 2864 { 2865 Key: &datapb.PropertyKey{ 2866 Name: "price.BTC.value", 2867 Type: datapb.PropertyKey_TYPE_INTEGER, 2868 }, 2869 Conditions: []*datapb.Condition{ 2870 { 2871 Operator: datapb.Condition_OPERATOR_EQUALS, 2872 Value: "15", 2873 }, 2874 }, 2875 }, 2876 { 2877 Key: &datapb.PropertyKey{ 2878 Name: "price.BTC.timestamp", 2879 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 2880 }, 2881 Conditions: []*datapb.Condition{ 2882 { 2883 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 2884 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 2885 }, 2886 }, 2887 }, 2888 }, 2889 }, 2890 }, 2891 ), 2892 }, 2893 }, 2894 }, 2895 }, 2896 }, 2897 }, 2898 }, 2899 }) 2900 2901 assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 2902 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) 2903 } 2904 2905 func testUpdateMarketWithMarketIDSucceeds(t *testing.T) { 2906 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2907 Terms: &protoTypes.ProposalTerms{ 2908 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2909 UpdateMarket: &protoTypes.UpdateMarket{ 2910 MarketId: "12345", 2911 }, 2912 }, 2913 }, 2914 }) 2915 2916 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.market_id"), commands.ErrIsRequired) 2917 } 2918 2919 func testUpdateMarketWithoutMarketIDFails(t *testing.T) { 2920 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2921 Terms: &protoTypes.ProposalTerms{ 2922 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2923 UpdateMarket: &protoTypes.UpdateMarket{}, 2924 }, 2925 }, 2926 }) 2927 2928 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.market_id"), commands.ErrIsRequired) 2929 } 2930 2931 func tesUpdateMarketChangeSubmissionWithSlippageFactorBananaFails(t *testing.T) { 2932 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2933 Terms: &protoTypes.ProposalTerms{ 2934 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2935 UpdateMarket: &protoTypes.UpdateMarket{ 2936 Changes: &protoTypes.UpdateMarketConfiguration{ 2937 LinearSlippageFactor: "banana", 2938 }, 2939 }, 2940 }, 2941 }, 2942 }) 2943 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.linear_slippage_factor"), commands.ErrIsNotValidNumber) 2944 } 2945 2946 func testUpdateMarketChangeSubmissionWithSlippageFactorNegativeFails(t *testing.T) { 2947 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2948 Terms: &protoTypes.ProposalTerms{ 2949 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2950 UpdateMarket: &protoTypes.UpdateMarket{ 2951 Changes: &protoTypes.UpdateMarketConfiguration{ 2952 LinearSlippageFactor: "-0.1", 2953 }, 2954 }, 2955 }, 2956 }, 2957 }) 2958 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.linear_slippage_factor"), commands.ErrMustBePositiveOrZero) 2959 } 2960 2961 func testUpdateMarketChangeSubmissionWithSlippageFactorTooLargeFails(t *testing.T) { 2962 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2963 Terms: &protoTypes.ProposalTerms{ 2964 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2965 UpdateMarket: &protoTypes.UpdateMarket{ 2966 Changes: &protoTypes.UpdateMarketConfiguration{ 2967 LinearSlippageFactor: "1000000.000001", 2968 }, 2969 }, 2970 }, 2971 }, 2972 }) 2973 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.linear_slippage_factor"), commands.ErrMustBeAtMost1M) 2974 } 2975 2976 func testUpdateNewMarketChangeSubmissionWithEmptySlippageFactorPasses(t *testing.T) { 2977 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2978 Terms: &protoTypes.ProposalTerms{ 2979 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2980 UpdateMarket: &protoTypes.UpdateMarket{ 2981 Changes: &protoTypes.UpdateMarketConfiguration{}, 2982 }, 2983 }, 2984 }, 2985 }) 2986 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.linear_slippage_factor"), commands.ErrIsNotValidNumber) 2987 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.quadratic_slippage_factor"), commands.ErrIsNotValidNumber) 2988 } 2989 2990 func testUpdateMarketWithExternalTradingTerminationBuiltInKeySucceeds(t *testing.T) { 2991 pubKey := []*dstypes.Signer{ 2992 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 2993 } 2994 2995 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 2996 Terms: &protoTypes.ProposalTerms{ 2997 Change: &protoTypes.ProposalTerms_UpdateMarket{ 2998 UpdateMarket: &protoTypes.UpdateMarket{ 2999 Changes: &protoTypes.UpdateMarketConfiguration{ 3000 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3001 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3002 Future: &protoTypes.UpdateFutureProduct{ 3003 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3004 vegapb.DataSourceContentTypeOracle, 3005 ).SetOracleConfig( 3006 &vegapb.DataSourceDefinitionExternal_Oracle{ 3007 Oracle: &vegapb.DataSourceSpecConfiguration{ 3008 Signers: dstypes.SignersIntoProto(pubKey), 3009 Filters: []*datapb.Filter{ 3010 { 3011 Key: &datapb.PropertyKey{ 3012 Name: "prices.ETH.value", 3013 Type: datapb.PropertyKey_TYPE_INTEGER, 3014 }, 3015 Conditions: []*datapb.Condition{ 3016 { 3017 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3018 }, 3019 }, 3020 }, 3021 }, 3022 }, 3023 }, 3024 ), 3025 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3026 vegapb.DataSourceContentTypeOracle, 3027 ).SetOracleConfig( 3028 &vegapb.DataSourceDefinitionExternal_Oracle{ 3029 Oracle: &vegapb.DataSourceSpecConfiguration{ 3030 Signers: dstypes.SignersIntoProto(pubKey), 3031 Filters: []*datapb.Filter{ 3032 { 3033 Key: &datapb.PropertyKey{ 3034 Name: "vegaprotocol.builtin.timestamp", 3035 Type: datapb.PropertyKey_TYPE_TIMESTAMP, 3036 }, 3037 Conditions: []*datapb.Condition{ 3038 { 3039 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3040 Value: fmt.Sprintf("%d", time.Now().Add(time.Hour*24*365).UnixNano()), 3041 }, 3042 }, 3043 }, 3044 }, 3045 }, 3046 }, 3047 ), 3048 }, 3049 }, 3050 }, 3051 }, 3052 }, 3053 }, 3054 }, 3055 }) 3056 3057 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3058 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3059 } 3060 3061 func testUpdateMarketWithExternalTradingTerminationNoSignerFails(t *testing.T) { 3062 pubKey := []*dstypes.Signer{ 3063 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3064 } 3065 3066 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3067 Terms: &protoTypes.ProposalTerms{ 3068 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3069 UpdateMarket: &protoTypes.UpdateMarket{ 3070 Changes: &protoTypes.UpdateMarketConfiguration{ 3071 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3072 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3073 Future: &protoTypes.UpdateFutureProduct{ 3074 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3075 vegapb.DataSourceContentTypeOracle, 3076 ).SetOracleConfig( 3077 &vegapb.DataSourceDefinitionExternal_Oracle{ 3078 Oracle: &vegapb.DataSourceSpecConfiguration{ 3079 Signers: dstypes.SignersIntoProto(pubKey), 3080 Filters: []*datapb.Filter{ 3081 { 3082 Key: &datapb.PropertyKey{ 3083 Name: "vegaprotocol.builtin.prices.ETH.value", 3084 Type: datapb.PropertyKey_TYPE_INTEGER, 3085 }, 3086 Conditions: []*datapb.Condition{ 3087 { 3088 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3089 }, 3090 }, 3091 }, 3092 }, 3093 }, 3094 }, 3095 ), 3096 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3097 vegapb.DataSourceContentTypeOracle, 3098 ).SetOracleConfig( 3099 &vegapb.DataSourceDefinitionExternal_Oracle{ 3100 Oracle: &vegapb.DataSourceSpecConfiguration{ 3101 Filters: []*datapb.Filter{ 3102 { 3103 Key: &datapb.PropertyKey{ 3104 Name: "trading.terminated", 3105 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3106 }, 3107 Conditions: []*datapb.Condition{}, 3108 }, 3109 }, 3110 }, 3111 }, 3112 ), 3113 }, 3114 }, 3115 }, 3116 }, 3117 }, 3118 }, 3119 }, 3120 }) 3121 3122 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3123 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3124 } 3125 3126 func testUpdateMarketWithInternalSettlementDataFails(t *testing.T) { 3127 pubKey := []*dstypes.Signer{ 3128 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3129 } 3130 3131 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3132 Terms: &protoTypes.ProposalTerms{ 3133 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3134 UpdateMarket: &protoTypes.UpdateMarket{ 3135 Changes: &protoTypes.UpdateMarketConfiguration{ 3136 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3137 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3138 Future: &protoTypes.UpdateFutureProduct{ 3139 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3140 vegapb.DataSourceContentTypeInternalTimeTermination, 3141 ).SetTimeTriggerConditionConfig( 3142 []*datapb.Condition{ 3143 { 3144 // It does not matter what conditions are set here 3145 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3146 }, 3147 }, 3148 ), 3149 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3150 vegapb.DataSourceContentTypeOracle, 3151 ).SetOracleConfig( 3152 &vegapb.DataSourceDefinitionExternal_Oracle{ 3153 Oracle: &vegapb.DataSourceSpecConfiguration{ 3154 Signers: dstypes.SignersIntoProto(pubKey), 3155 Filters: []*datapb.Filter{ 3156 { 3157 Key: &datapb.PropertyKey{ 3158 Name: "trading.terminated", 3159 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3160 }, 3161 Conditions: []*datapb.Condition{}, 3162 }, 3163 }, 3164 }, 3165 }, 3166 ), 3167 }, 3168 }, 3169 }, 3170 }, 3171 }, 3172 }, 3173 }, 3174 }) 3175 3176 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data"), commands.ErrIsNotValid) 3177 } 3178 3179 func testUpdateMarketWithExternalSettlementDataNoSignerFails(t *testing.T) { 3180 pubKey := []*dstypes.Signer{ 3181 dstypes.CreateSignerFromString("bd069246503a57271375f1995c46e03db88c4e1a564077b33a9872f905650dc4", dstypes.SignerTypePubKey), 3182 } 3183 3184 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3185 Terms: &protoTypes.ProposalTerms{ 3186 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3187 UpdateMarket: &protoTypes.UpdateMarket{ 3188 Changes: &protoTypes.UpdateMarketConfiguration{ 3189 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3190 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3191 Future: &protoTypes.UpdateFutureProduct{ 3192 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3193 vegapb.DataSourceContentTypeOracle, 3194 ).SetOracleConfig( 3195 &vegapb.DataSourceDefinitionExternal_Oracle{ 3196 Oracle: &vegapb.DataSourceSpecConfiguration{ 3197 Filters: []*datapb.Filter{ 3198 { 3199 Key: &datapb.PropertyKey{ 3200 Name: "vegaprotocol.builtin.prices.ETH.value", 3201 Type: datapb.PropertyKey_TYPE_INTEGER, 3202 }, 3203 Conditions: []*datapb.Condition{ 3204 { 3205 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3206 }, 3207 }, 3208 }, 3209 }, 3210 }, 3211 }, 3212 ), 3213 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3214 vegapb.DataSourceContentTypeOracle, 3215 ).SetOracleConfig( 3216 &vegapb.DataSourceDefinitionExternal_Oracle{ 3217 Oracle: &vegapb.DataSourceSpecConfiguration{ 3218 Signers: dstypes.SignersIntoProto(pubKey), 3219 Filters: []*datapb.Filter{ 3220 { 3221 Key: &datapb.PropertyKey{ 3222 Name: "trading.terminated", 3223 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3224 }, 3225 Conditions: []*datapb.Condition{}, 3226 }, 3227 }, 3228 }, 3229 }, 3230 ), 3231 }, 3232 }, 3233 }, 3234 }, 3235 }, 3236 }, 3237 }, 3238 }) 3239 3240 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3241 assert.NotContains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3242 } 3243 3244 func testUpdateMarketWithExternalSettlementDataAndTerminationNoSignerFails(t *testing.T) { 3245 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3246 Terms: &protoTypes.ProposalTerms{ 3247 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3248 UpdateMarket: &protoTypes.UpdateMarket{ 3249 Changes: &protoTypes.UpdateMarketConfiguration{ 3250 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3251 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3252 Future: &protoTypes.UpdateFutureProduct{ 3253 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3254 vegapb.DataSourceContentTypeOracle, 3255 ).SetOracleConfig( 3256 &vegapb.DataSourceDefinitionExternal_Oracle{ 3257 Oracle: &vegapb.DataSourceSpecConfiguration{ 3258 Filters: []*datapb.Filter{ 3259 { 3260 Key: &datapb.PropertyKey{ 3261 Name: "vegaprotocol.builtin.prices.ETH.value", 3262 Type: datapb.PropertyKey_TYPE_INTEGER, 3263 }, 3264 Conditions: []*datapb.Condition{ 3265 { 3266 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3267 }, 3268 }, 3269 }, 3270 }, 3271 }, 3272 }, 3273 ), 3274 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3275 vegapb.DataSourceContentTypeOracle, 3276 ).SetOracleConfig( 3277 &vegapb.DataSourceDefinitionExternal_Oracle{ 3278 Oracle: &vegapb.DataSourceSpecConfiguration{ 3279 Filters: []*datapb.Filter{ 3280 { 3281 Key: &datapb.PropertyKey{ 3282 Name: "trading.terminated", 3283 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3284 }, 3285 Conditions: []*datapb.Condition{}, 3286 }, 3287 }, 3288 }, 3289 }, 3290 ), 3291 }, 3292 }, 3293 }, 3294 }, 3295 }, 3296 }, 3297 }, 3298 }) 3299 3300 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3301 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3302 } 3303 3304 func testUpdateMarketWithExternalSettlementDataAndTerminationEmptySignerFails(t *testing.T) { 3305 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3306 Terms: &protoTypes.ProposalTerms{ 3307 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3308 UpdateMarket: &protoTypes.UpdateMarket{ 3309 Changes: &protoTypes.UpdateMarketConfiguration{ 3310 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3311 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3312 Future: &protoTypes.UpdateFutureProduct{ 3313 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3314 vegapb.DataSourceContentTypeOracle, 3315 ).SetOracleConfig( 3316 &vegapb.DataSourceDefinitionExternal_Oracle{ 3317 Oracle: &vegapb.DataSourceSpecConfiguration{ 3318 Signers: []*datapb.Signer{}, 3319 Filters: []*datapb.Filter{ 3320 { 3321 Key: &datapb.PropertyKey{ 3322 Name: "vegaprotocol.builtin.prices.ETH.value", 3323 Type: datapb.PropertyKey_TYPE_INTEGER, 3324 }, 3325 Conditions: []*datapb.Condition{ 3326 { 3327 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3328 }, 3329 }, 3330 }, 3331 }, 3332 }, 3333 }, 3334 ), 3335 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3336 vegapb.DataSourceContentTypeOracle, 3337 ).SetOracleConfig( 3338 &vegapb.DataSourceDefinitionExternal_Oracle{ 3339 Oracle: &vegapb.DataSourceSpecConfiguration{ 3340 Signers: []*datapb.Signer{}, 3341 Filters: []*datapb.Filter{ 3342 { 3343 Key: &datapb.PropertyKey{ 3344 Name: "trading.terminated", 3345 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3346 }, 3347 Conditions: []*datapb.Condition{}, 3348 }, 3349 }, 3350 }, 3351 }, 3352 ), 3353 }, 3354 }, 3355 }, 3356 }, 3357 }, 3358 }, 3359 }, 3360 }) 3361 3362 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers"), commands.ErrIsRequired) 3363 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers"), commands.ErrIsRequired) 3364 } 3365 3366 func testUpdateMarketWithExternalSettlementDataAndTerminationEmptyPubKeySignerFails(t *testing.T) { 3367 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3368 Terms: &protoTypes.ProposalTerms{ 3369 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3370 UpdateMarket: &protoTypes.UpdateMarket{ 3371 Changes: &protoTypes.UpdateMarketConfiguration{ 3372 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3373 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3374 Future: &protoTypes.UpdateFutureProduct{ 3375 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3376 vegapb.DataSourceContentTypeOracle, 3377 ).SetOracleConfig( 3378 &vegapb.DataSourceDefinitionExternal_Oracle{ 3379 Oracle: &vegapb.DataSourceSpecConfiguration{ 3380 Signers: []*datapb.Signer{ 3381 { 3382 Signer: &datapb.Signer_PubKey{ 3383 PubKey: &datapb.PubKey{ 3384 Key: "", 3385 }, 3386 }, 3387 }, 3388 }, 3389 Filters: []*datapb.Filter{ 3390 { 3391 Key: &datapb.PropertyKey{ 3392 Name: "vegaprotocol.builtin.prices.ETH.value", 3393 Type: datapb.PropertyKey_TYPE_INTEGER, 3394 }, 3395 Conditions: []*datapb.Condition{ 3396 { 3397 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3398 }, 3399 }, 3400 }, 3401 }, 3402 }, 3403 }, 3404 ), 3405 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3406 vegapb.DataSourceContentTypeOracle, 3407 ).SetOracleConfig( 3408 &vegapb.DataSourceDefinitionExternal_Oracle{ 3409 Oracle: &vegapb.DataSourceSpecConfiguration{ 3410 Signers: []*datapb.Signer{ 3411 { 3412 Signer: &datapb.Signer_PubKey{ 3413 PubKey: &datapb.PubKey{}, 3414 }, 3415 }, 3416 }, 3417 Filters: []*datapb.Filter{ 3418 { 3419 Key: &datapb.PropertyKey{ 3420 Name: "trading.terminated", 3421 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3422 }, 3423 Conditions: []*datapb.Condition{}, 3424 }, 3425 }, 3426 }, 3427 }, 3428 ), 3429 }, 3430 }, 3431 }, 3432 }, 3433 }, 3434 }, 3435 }, 3436 }) 3437 3438 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 3439 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers.0"), commands.ErrIsNotValid) 3440 } 3441 3442 func testUpdateMarketWithExternalSettlementDataAndTerminationEmptyEthAddressSignerFails(t *testing.T) { 3443 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3444 Terms: &protoTypes.ProposalTerms{ 3445 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3446 UpdateMarket: &protoTypes.UpdateMarket{ 3447 Changes: &protoTypes.UpdateMarketConfiguration{ 3448 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3449 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3450 Future: &protoTypes.UpdateFutureProduct{ 3451 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3452 vegapb.DataSourceContentTypeOracle, 3453 ).SetOracleConfig( 3454 &vegapb.DataSourceDefinitionExternal_Oracle{ 3455 Oracle: &vegapb.DataSourceSpecConfiguration{ 3456 Signers: []*datapb.Signer{ 3457 { 3458 Signer: &datapb.Signer_EthAddress{ 3459 EthAddress: &datapb.ETHAddress{ 3460 Address: "", 3461 }, 3462 }, 3463 }, 3464 }, 3465 Filters: []*datapb.Filter{ 3466 { 3467 Key: &datapb.PropertyKey{ 3468 Name: "vegaprotocol.builtin.prices.ETH.value", 3469 Type: datapb.PropertyKey_TYPE_INTEGER, 3470 }, 3471 Conditions: []*datapb.Condition{ 3472 { 3473 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3474 }, 3475 }, 3476 }, 3477 }, 3478 }, 3479 }, 3480 ), 3481 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3482 vegapb.DataSourceContentTypeOracle, 3483 ).SetOracleConfig( 3484 &vegapb.DataSourceDefinitionExternal_Oracle{ 3485 Oracle: &vegapb.DataSourceSpecConfiguration{ 3486 Signers: []*datapb.Signer{ 3487 { 3488 Signer: &datapb.Signer_EthAddress{ 3489 EthAddress: &datapb.ETHAddress{ 3490 Address: "", 3491 }, 3492 }, 3493 }, 3494 }, 3495 Filters: []*datapb.Filter{ 3496 { 3497 Key: &datapb.PropertyKey{ 3498 Name: "trading.terminated", 3499 Type: datapb.PropertyKey_TYPE_BOOLEAN, 3500 }, 3501 Conditions: []*datapb.Condition{}, 3502 }, 3503 }, 3504 }, 3505 }, 3506 ), 3507 }, 3508 }, 3509 }, 3510 }, 3511 }, 3512 }, 3513 }, 3514 }) 3515 3516 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.external.oracle.signers.0"), commands.ErrIsNotValid) 3517 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.external.oracle.signers.0"), commands.ErrIsNotValid) 3518 } 3519 3520 func testUpdateMarketWithTerminationWithTimeTriggerFails(t *testing.T) { 3521 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3522 Terms: &protoTypes.ProposalTerms{ 3523 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3524 UpdateMarket: &protoTypes.UpdateMarket{ 3525 Changes: &protoTypes.UpdateMarketConfiguration{ 3526 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3527 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3528 Future: &protoTypes.UpdateFutureProduct{ 3529 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3530 vegapb.DataSourceContentTypeOracle, 3531 ).SetOracleConfig( 3532 &vegapb.DataSourceDefinitionExternal_Oracle{ 3533 Oracle: &vegapb.DataSourceSpecConfiguration{ 3534 Signers: []*datapb.Signer{ 3535 { 3536 Signer: &datapb.Signer_EthAddress{ 3537 EthAddress: &datapb.ETHAddress{ 3538 Address: "", 3539 }, 3540 }, 3541 }, 3542 }, 3543 Filters: []*datapb.Filter{ 3544 { 3545 Key: &datapb.PropertyKey{ 3546 Name: "vegaprotocol.builtin.prices.ETH.value", 3547 Type: datapb.PropertyKey_TYPE_INTEGER, 3548 }, 3549 Conditions: []*datapb.Condition{ 3550 { 3551 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3552 }, 3553 }, 3554 }, 3555 }, 3556 }, 3557 }, 3558 ), 3559 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3560 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 3561 ).SetTimeTriggerConditionConfig( 3562 []*datapb.Condition{ 3563 { 3564 // It does not matter what conditions are set here 3565 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3566 }, 3567 }, 3568 ), 3569 }, 3570 }, 3571 }, 3572 }, 3573 }, 3574 }, 3575 }, 3576 }) 3577 3578 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_trading_termination.internal.timetrigger"), commands.ErrIsNotValid) 3579 } 3580 3581 func testUpdateMarketWithSettlementWithTimeTriggerFails(t *testing.T) { 3582 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3583 Terms: &protoTypes.ProposalTerms{ 3584 Change: &protoTypes.ProposalTerms_UpdateMarket{ 3585 UpdateMarket: &protoTypes.UpdateMarket{ 3586 Changes: &protoTypes.UpdateMarketConfiguration{ 3587 Instrument: &protoTypes.UpdateInstrumentConfiguration{ 3588 Product: &protoTypes.UpdateInstrumentConfiguration_Future{ 3589 Future: &protoTypes.UpdateFutureProduct{ 3590 DataSourceSpecForSettlementData: vegapb.NewDataSourceDefinition( 3591 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 3592 ).SetTimeTriggerConditionConfig( 3593 []*datapb.Condition{ 3594 { 3595 // It does not matter what conditions are set here 3596 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3597 }, 3598 }, 3599 ), 3600 DataSourceSpecForTradingTermination: vegapb.NewDataSourceDefinition( 3601 vegapb.DataSourceContentTypeInternalTimeTriggerTermination, 3602 ).SetTimeTriggerConditionConfig( 3603 []*datapb.Condition{ 3604 { 3605 // It does not matter what conditions are set here 3606 Operator: datapb.Condition_OPERATOR_GREATER_THAN_OR_EQUAL, 3607 }, 3608 }, 3609 ), 3610 }, 3611 }, 3612 }, 3613 }, 3614 }, 3615 }, 3616 }, 3617 }) 3618 3619 assert.Contains(t, err.Get("proposal_submission.terms.change.update_market.changes.instrument.product.future.data_source_spec_for_settlement_data.internal.timetrigger"), commands.ErrIsNotValid) 3620 } 3621 3622 func testUpdatePerpetualMarketWithFundingRateModifiers(t *testing.T) { 3623 cases := []struct { 3624 product vegapb.UpdatePerpetualProduct 3625 err error 3626 path string 3627 desc string 3628 }{ 3629 { 3630 product: vegapb.UpdatePerpetualProduct{ 3631 FundingRateScalingFactor: ptr.From("hello"), 3632 }, 3633 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_scaling_factor", 3634 err: commands.ErrIsNotValidNumber, 3635 }, 3636 { 3637 product: vegapb.UpdatePerpetualProduct{ 3638 FundingRateScalingFactor: ptr.From("-10"), 3639 }, 3640 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_scaling_factor", 3641 err: commands.ErrMustBePositiveOrZero, 3642 }, 3643 { 3644 product: vegapb.UpdatePerpetualProduct{ 3645 FundingRateScalingFactor: ptr.From("0.1"), 3646 }, 3647 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_scaling_factor", 3648 }, 3649 { 3650 product: vegapb.UpdatePerpetualProduct{ 3651 FundingRateLowerBound: ptr.From("hello"), 3652 }, 3653 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_lower_bound", 3654 err: commands.ErrIsNotValidNumber, 3655 }, 3656 { 3657 product: vegapb.UpdatePerpetualProduct{ 3658 FundingRateLowerBound: ptr.From("-100"), 3659 }, 3660 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_lower_bound", 3661 }, 3662 { 3663 product: vegapb.UpdatePerpetualProduct{ 3664 FundingRateUpperBound: ptr.From("hello"), 3665 }, 3666 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_upper_bound", 3667 err: commands.ErrIsNotValidNumber, 3668 }, 3669 { 3670 product: vegapb.UpdatePerpetualProduct{ 3671 FundingRateUpperBound: ptr.From("100"), 3672 }, 3673 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_upper_bound", 3674 }, 3675 { 3676 product: vegapb.UpdatePerpetualProduct{ 3677 FundingRateUpperBound: ptr.From("100"), 3678 FundingRateLowerBound: ptr.From("200"), 3679 }, 3680 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.funding_rate_lower_bound", 3681 err: commands.ErrIsNotValid, 3682 }, 3683 } 3684 3685 for _, v := range cases { 3686 t.Run(v.desc, func(t *testing.T) { 3687 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3688 Terms: &vegapb.ProposalTerms{ 3689 Change: &vegapb.ProposalTerms_UpdateMarket{ 3690 UpdateMarket: &vegapb.UpdateMarket{ 3691 Changes: &vegapb.UpdateMarketConfiguration{ 3692 Instrument: &vegapb.UpdateInstrumentConfiguration{ 3693 Product: &vegapb.UpdateInstrumentConfiguration_Perpetual{ 3694 Perpetual: &v.product, 3695 }, 3696 }, 3697 }, 3698 }, 3699 }, 3700 }, 3701 }) 3702 errs := err.Get(v.path) 3703 // no errors expected 3704 if v.err == nil { 3705 assert.Len(t, errs, 0, v.desc) 3706 return 3707 } 3708 assert.Contains(t, errs, v.err, v.desc) 3709 }) 3710 } 3711 } 3712 3713 func testUpdatePerpsMarketChangeSubmissionProductParameters(t *testing.T) { 3714 cases := []struct { 3715 product vegapb.UpdatePerpetualProduct 3716 err error 3717 path string 3718 desc string 3719 }{ 3720 { 3721 product: vegapb.UpdatePerpetualProduct{ 3722 MarginFundingFactor: "", 3723 }, 3724 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.margin_funding_factor", 3725 err: commands.ErrIsRequired, 3726 desc: "margin_funding_factor is empty", 3727 }, 3728 { 3729 product: vegapb.UpdatePerpetualProduct{ 3730 MarginFundingFactor: "nope", 3731 }, 3732 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.margin_funding_factor", 3733 err: commands.ErrIsNotValidNumber, 3734 desc: "margin_funding_factor is not a valid number", 3735 }, 3736 { 3737 product: vegapb.UpdatePerpetualProduct{ 3738 MarginFundingFactor: "-10", 3739 }, 3740 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.margin_funding_factor", 3741 err: commands.ErrMustBeWithinRange01, 3742 desc: "margin_funding_factor is not within range (< 0)", 3743 }, 3744 { 3745 product: vegapb.UpdatePerpetualProduct{ 3746 MarginFundingFactor: "10", 3747 }, 3748 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.margin_funding_factor", 3749 err: commands.ErrMustBeWithinRange01, 3750 desc: "margin_funding_factor is not within range (> 1)", 3751 }, 3752 { 3753 product: vegapb.UpdatePerpetualProduct{ 3754 MarginFundingFactor: "0.5", 3755 }, 3756 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.margin_funding_factor", 3757 desc: "margin_funding_factor is valid", 3758 }, 3759 // interest_rate 3760 { 3761 product: vegapb.UpdatePerpetualProduct{ 3762 InterestRate: "", 3763 }, 3764 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3765 err: commands.ErrIsRequired, 3766 desc: "interest_rate is empty", 3767 }, 3768 { 3769 product: vegapb.UpdatePerpetualProduct{ 3770 InterestRate: "nope", 3771 }, 3772 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3773 err: commands.ErrIsNotValidNumber, 3774 desc: "interest_rate is not a valid number", 3775 }, 3776 { 3777 product: vegapb.UpdatePerpetualProduct{ 3778 InterestRate: "-10", 3779 }, 3780 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3781 err: commands.ErrMustBeWithinRange11, 3782 desc: "interest_rate is not within range (< -1)", 3783 }, 3784 { 3785 product: vegapb.UpdatePerpetualProduct{ 3786 InterestRate: "10", 3787 }, 3788 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3789 err: commands.ErrMustBeWithinRange11, 3790 desc: "interest_rate is not within range (> 1)", 3791 }, 3792 { 3793 product: vegapb.UpdatePerpetualProduct{ 3794 InterestRate: "0.5", 3795 }, 3796 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3797 desc: "interest_rate is valid", 3798 }, 3799 { 3800 product: vegapb.UpdatePerpetualProduct{ 3801 InterestRate: "-0.5", 3802 }, 3803 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.interest_rate", 3804 desc: "interest_rate is valid", 3805 }, 3806 // clamp_lower_bound 3807 { 3808 product: vegapb.UpdatePerpetualProduct{ 3809 ClampLowerBound: "", 3810 }, 3811 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3812 err: commands.ErrIsRequired, 3813 desc: "clamp_lower_bound is empty", 3814 }, 3815 { 3816 product: vegapb.UpdatePerpetualProduct{ 3817 ClampLowerBound: "nope", 3818 }, 3819 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3820 err: commands.ErrIsNotValidNumber, 3821 desc: "clamp_lower_bound is not a valid number", 3822 }, 3823 { 3824 product: vegapb.UpdatePerpetualProduct{ 3825 ClampLowerBound: "-10", 3826 }, 3827 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3828 err: commands.ErrMustBeWithinRange11, 3829 desc: "clamp_lower_bound is not within range (< -1)", 3830 }, 3831 { 3832 product: vegapb.UpdatePerpetualProduct{ 3833 ClampLowerBound: "10", 3834 }, 3835 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3836 err: commands.ErrMustBeWithinRange11, 3837 desc: "clamp_lower_bound is not within range (> 1)", 3838 }, 3839 { 3840 product: vegapb.UpdatePerpetualProduct{ 3841 ClampLowerBound: "0.5", 3842 }, 3843 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3844 desc: "clamp_lower_bound is valid", 3845 }, 3846 { 3847 product: vegapb.UpdatePerpetualProduct{ 3848 ClampLowerBound: "-0.5", 3849 }, 3850 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_lower_bound", 3851 desc: "clamp_lower_bound is valid", 3852 }, 3853 // clamp_upper_bound 3854 { 3855 product: vegapb.UpdatePerpetualProduct{ 3856 ClampUpperBound: "", 3857 }, 3858 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3859 err: commands.ErrIsRequired, 3860 desc: "clamp_upper_bound is empty", 3861 }, 3862 { 3863 product: vegapb.UpdatePerpetualProduct{ 3864 ClampUpperBound: "nope", 3865 }, 3866 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3867 err: commands.ErrIsNotValidNumber, 3868 desc: "clamp_upper_bound is not a valid number", 3869 }, 3870 { 3871 product: vegapb.UpdatePerpetualProduct{ 3872 ClampUpperBound: "-10", 3873 }, 3874 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3875 err: commands.ErrMustBeWithinRange11, 3876 desc: "clamp_upper_bound is not within range (< -1)", 3877 }, 3878 { 3879 product: vegapb.UpdatePerpetualProduct{ 3880 ClampUpperBound: "10", 3881 }, 3882 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3883 err: commands.ErrMustBeWithinRange11, 3884 desc: "clamp_upper_bound is not within range (> 1)", 3885 }, 3886 { 3887 product: vegapb.UpdatePerpetualProduct{ 3888 ClampUpperBound: "0.5", 3889 }, 3890 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3891 desc: "clamp_upper_bound is valid", 3892 }, 3893 { 3894 product: vegapb.UpdatePerpetualProduct{ 3895 ClampUpperBound: "-0.5", 3896 }, 3897 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3898 desc: "clamp_upper_bound is valid", 3899 }, 3900 // clamp lower and upper 3901 { 3902 product: vegapb.UpdatePerpetualProduct{ 3903 ClampLowerBound: "0.5", 3904 ClampUpperBound: "0.5", 3905 }, 3906 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3907 desc: "clamp_upper_bound == clamp_lower_bound is valid", 3908 }, 3909 { 3910 product: vegapb.UpdatePerpetualProduct{ 3911 ClampLowerBound: "0.4", 3912 ClampUpperBound: "0.5", 3913 }, 3914 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3915 desc: "clamp_upper_bound > clamp_lower_bound is valid", 3916 }, 3917 { 3918 product: vegapb.UpdatePerpetualProduct{ 3919 ClampLowerBound: "0.5", 3920 ClampUpperBound: "0.4", 3921 }, 3922 path: "proposal_submission.terms.change.update_market.changes.instrument.product.perps.clamp_upper_bound", 3923 err: commands.ErrMustBeGTEClampLowerBound, 3924 desc: "clamp_upper_bound < clamp_lower_bound is invalid", 3925 }, 3926 } 3927 3928 for _, v := range cases { 3929 t.Run(v.desc, func(t *testing.T) { 3930 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 3931 Terms: &vegapb.ProposalTerms{ 3932 Change: &vegapb.ProposalTerms_UpdateMarket{ 3933 UpdateMarket: &vegapb.UpdateMarket{ 3934 Changes: &vegapb.UpdateMarketConfiguration{ 3935 Instrument: &vegapb.UpdateInstrumentConfiguration{ 3936 Product: &vegapb.UpdateInstrumentConfiguration_Perpetual{ 3937 Perpetual: &v.product, 3938 }, 3939 }, 3940 }, 3941 }, 3942 }, 3943 }, 3944 }) 3945 3946 errs := err.Get(v.path) 3947 3948 // no errors expected 3949 if v.err == nil { 3950 assert.Len(t, errs, 0, v.desc) 3951 return 3952 } 3953 3954 assert.Contains(t, errs, v.err, v.desc) 3955 }) 3956 } 3957 } 3958 3959 func testUpdateLiquidityFeeSettingsSpot(t *testing.T) { 3960 cases := []struct { 3961 lfs *vega.LiquidityFeeSettings 3962 field string 3963 err error 3964 }{ 3965 { 3966 lfs: &vega.LiquidityFeeSettings{ 3967 Method: vegapb.LiquidityFeeSettings_METHOD_MARGINAL_COST, 3968 FeeConstant: ptr.From("0.1"), 3969 }, 3970 field: "method", 3971 err: commands.ErrIsNotValid, 3972 }, 3973 { 3974 lfs: &vega.LiquidityFeeSettings{ 3975 Method: vegapb.LiquidityFeeSettings_METHOD_WEIGHTED_AVERAGE, 3976 FeeConstant: ptr.From("0.1"), 3977 }, 3978 field: "method", 3979 err: commands.ErrIsNotValid, 3980 }, 3981 { 3982 lfs: &vega.LiquidityFeeSettings{ 3983 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 3984 FeeConstant: nil, 3985 }, 3986 field: "fee_constant", 3987 err: commands.ErrIsRequired, 3988 }, 3989 { 3990 lfs: &vega.LiquidityFeeSettings{ 3991 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 3992 FeeConstant: ptr.From("hello"), 3993 }, 3994 field: "fee_constant", 3995 err: commands.ErrIsNotValidNumber, 3996 }, 3997 { 3998 lfs: &vega.LiquidityFeeSettings{ 3999 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 4000 FeeConstant: ptr.From("-0.1"), // (0042-LIQF-072) 4001 }, 4002 field: "fee_constant", 4003 err: commands.ErrMustBePositiveOrZero, 4004 }, 4005 { 4006 lfs: &vega.LiquidityFeeSettings{ 4007 Method: vegapb.LiquidityFeeSettings_METHOD_CONSTANT, 4008 FeeConstant: ptr.From("1.1"), // (0042-LIQF-072) 4009 }, 4010 field: "fee_constant", 4011 err: commands.ErrMustBeWithinRange01, 4012 }, 4013 { 4014 lfs: &vega.LiquidityFeeSettings{ 4015 Method: vegapb.LiquidityFeeSettings_METHOD_UNSPECIFIED, 4016 }, 4017 field: "method", 4018 err: commands.ErrIsRequired, 4019 }, 4020 { 4021 lfs: &vega.LiquidityFeeSettings{ 4022 Method: vegapb.LiquidityFeeSettings_Method(int32(100)), 4023 }, 4024 field: "method", 4025 err: commands.ErrIsNotValid, 4026 }, 4027 } 4028 4029 for _, c := range cases { 4030 err := checkProposalSubmission(&commandspb.ProposalSubmission{ 4031 Terms: &vegapb.ProposalTerms{ 4032 Change: &vegapb.ProposalTerms_UpdateSpotMarket{ 4033 UpdateSpotMarket: &vegapb.UpdateSpotMarket{ 4034 Changes: &vegapb.UpdateSpotMarketConfiguration{ 4035 Instrument: &vegapb.UpdateSpotInstrumentConfiguration{}, 4036 LiquidityFeeSettings: c.lfs, 4037 }, 4038 }, 4039 }, 4040 }, 4041 }) 4042 assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.liquidity_fee_settings."+c.field), c.err) 4043 } 4044 }