diff --git a/protocol/app/app.go b/protocol/app/app.go index 8bf9853bb9..6fcdb7bfda 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -876,7 +876,6 @@ func New( appCodec, keys[pricesmoduletypes.StoreKey], indexPriceCache, - pricesmoduletypes.NewMarketToSmoothedPrices(pricesmoduletypes.SmoothedPriceTrackingBlockHistoryLength), timeProvider, app.IndexerEventManager, // set the governance and delaymsg module accounts as the authority for conducting upgrades diff --git a/protocol/app/prepare/prepare_proposal_test.go b/protocol/app/prepare/prepare_proposal_test.go index 32a70446bd..19536bc5af 100644 --- a/protocol/app/prepare/prepare_proposal_test.go +++ b/protocol/app/prepare/prepare_proposal_test.go @@ -360,7 +360,7 @@ func TestPrepareProposalHandler(t *testing.T) { mockClobKeeper.On("GetOperations", mock.Anything, mock.Anything). Return(tc.clobResp) - ctx, _, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, _, _, _, _ := keepertest.PricesKeepers(t) handler := prepare.PrepareProposalHandler( mockTxConfig, @@ -440,7 +440,7 @@ func TestPrepareProposalHandler_OtherTxs(t *testing.T) { mockBridgeKeeper.On("GetAcknowledgeBridges", mock.Anything, mock.Anything). Return(constants.MsgAcknowledgeBridges_Ids0_1_Height0) - ctx, _, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, _, _, _, _ := keepertest.PricesKeepers(t) handler := prepare.PrepareProposalHandler( encodingCfg.TxConfig, diff --git a/protocol/app/process/expected_keepers.go b/protocol/app/process/expected_keepers.go index 9787c1d176..757be839ac 100644 --- a/protocol/app/process/expected_keepers.go +++ b/protocol/app/process/expected_keepers.go @@ -19,11 +19,6 @@ type ProcessPricesKeeper interface { marketPriceUpdates *pricestypes.MsgUpdateMarketPrices, performNonDeterministicValidation bool, ) error - - UpdateSmoothedPrices( - ctx sdk.Context, - linearInterpolateFunc func(v0 uint64, v1 uint64, ppm uint32) (uint64, error), - ) error } // ProcessClobKeeper defines the expected clob keeper used for `ProcessProposal`. diff --git a/protocol/app/process/full_node_process_proposal_test.go b/protocol/app/process/full_node_process_proposal_test.go index 412ce147f0..e0d0104882 100644 --- a/protocol/app/process/full_node_process_proposal_test.go +++ b/protocol/app/process/full_node_process_proposal_test.go @@ -73,7 +73,7 @@ func TestFullNodeProcessProposalHandler(t *testing.T) { // Setup. _, bridgeKeeper, _, _, _, _, _ := keepertest.BridgeKeepers(t) - ctx, pricesKeeper, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, pricesKeeper) indexPriceCache.UpdatePrices(constants.AtTimeTSingleExchangePriceUpdate) diff --git a/protocol/app/process/market_prices_test.go b/protocol/app/process/market_prices_test.go index c770bf1710..a77bf9c188 100644 --- a/protocol/app/process/market_prices_test.go +++ b/protocol/app/process/market_prices_test.go @@ -65,7 +65,7 @@ func TestDecodeUpdateMarketPricesTx(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, k, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, k, _, _, _ := keepertest.PricesKeepers(t) pricesTxDecoder := process.NewDefaultUpdateMarketPriceTxDecoder(k, encodingCfg.TxConfig.TxDecoder()) umpt, err := pricesTxDecoder.DecodeUpdateMarketPricesTx(ctx, [][]byte{tc.txBytes}) if tc.expectedErr != nil { @@ -120,7 +120,7 @@ func TestUpdateMarketPricesTx_Validate(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, k) indexPriceCache.UpdatePrices(tc.indexPrices) @@ -162,7 +162,7 @@ func TestUpdateMarketPricesTx_GetMsg(t *testing.T) { t.Run(name, func(t *testing.T) { var msg sdk.Msg if tc.txBytes != nil { - ctx, k, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, k, _, _, _ := keepertest.PricesKeepers(t) // Decode. pricesTxDecoder := process.NewDefaultUpdateMarketPriceTxDecoder(k, constants.TestEncodingCfg.TxConfig.TxDecoder()) diff --git a/protocol/app/process/process_proposal.go b/protocol/app/process/process_proposal.go index f5cba1e661..f69af84151 100644 --- a/protocol/app/process/process_proposal.go +++ b/protocol/app/process/process_proposal.go @@ -3,7 +3,6 @@ package process import ( "time" - "github.com/dydxprotocol/v4-chain/protocol/lib" error_lib "github.com/dydxprotocol/v4-chain/protocol/lib/error" "github.com/dydxprotocol/v4-chain/protocol/lib/log" @@ -65,14 +64,6 @@ func ProcessProposalHandler( log.Module, ModuleName, ) - // Perform the update of smoothed prices here to ensure that smoothed prices are updated even if a block is later - // rejected by consensus. We want smoothed prices to be updated on fixed cadence, and we are piggybacking on - // consensus round to do so. - if err := pricesKeeper.UpdateSmoothedPrices(ctx, lib.Uint64LinearInterpolate); err != nil { - recordErrorMetricsWithLabel(metrics.UpdateSmoothedPrices) - error_lib.LogErrorWithOptionalContext(ctx, "UpdateSmoothedPrices failed", err) - } - txs, err := DecodeProcessProposalTxs(ctx, txConfig.TxDecoder(), req, bridgeKeeper, pricesTxDecoder) if err != nil { error_lib.LogErrorWithOptionalContext(ctx, "DecodeProcessProposalTxs failed", err) diff --git a/protocol/app/process/process_proposal_test.go b/protocol/app/process/process_proposal_test.go index 68774c494b..cccf4cee36 100644 --- a/protocol/app/process/process_proposal_test.go +++ b/protocol/app/process/process_proposal_test.go @@ -258,7 +258,7 @@ func TestProcessProposalHandler_Error(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, pricesKeeper, _, indexPriceCache, marketToSmoothedPrices, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, pricesKeeper) indexPriceCache.UpdatePrices(constants.AtTimeTSingleExchangePriceUpdate) @@ -295,11 +295,6 @@ func TestProcessProposalHandler_Error(t *testing.T) { // Validate. require.Equal(t, tc.expectedResponse, *resp) - require.Equal( - t, - marketToSmoothedPrices.GetSmoothedPricesForTest(), - constants.AtTimeTSingleExchangeSmoothedPrices, - ) }) } } diff --git a/protocol/app/process/transactions_test.go b/protocol/app/process/transactions_test.go index 640f7fc506..62a93bc627 100644 --- a/protocol/app/process/transactions_test.go +++ b/protocol/app/process/transactions_test.go @@ -108,7 +108,7 @@ func TestDecodeProcessProposalTxs_Error(t *testing.T) { t.Run(name, func(t *testing.T) { // Setup. _, bridgeKeeper, _, _, _, _, _ := keepertest.BridgeKeepers(t) - ctx, pricesKeeper, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, _, _ := keepertest.PricesKeepers(t) // Run. _, err := process.DecodeProcessProposalTxs( @@ -188,7 +188,7 @@ func TestDecodeProcessProposalTxs_Valid(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, pricesKeeper, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, _, _ := keepertest.PricesKeepers(t) _, bridgeKeeper, _, _, _, _, _ := keepertest.BridgeKeepers(t) // Run. @@ -318,7 +318,7 @@ func TestProcessProposalTxs_Validate_Error(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, pricesKeeper, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, pricesKeeper) indexPriceCache.UpdatePrices(constants.AtTimeTSingleExchangePriceUpdate) @@ -425,7 +425,7 @@ func TestProcessProposalTxs_Validate_Valid(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, pricesKeeper, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, pricesKeeper) indexPriceCache.UpdatePrices(constants.AtTimeTSingleExchangePriceUpdate) diff --git a/protocol/lib/metrics/constants.go b/protocol/lib/metrics/constants.go index f1d25fc3bd..2c04b963d1 100644 --- a/protocol/lib/metrics/constants.go +++ b/protocol/lib/metrics/constants.go @@ -255,26 +255,22 @@ const ( BlockTimeMs = "block_time_ms" // Prices. - CreateOracleMarket = "create_oracle_market" - CurrentMarketPrices = "current_market_prices" - GetValidMarketPriceUpdates = "get_valid_market_price_updates" - IndexPriceDoesNotExist = "index_price_does_not_exist" - IndexPriceIsZero = "index_price_is_zero" - IndexPriceNotAccurate = "index_price_not_accurate" - IndexPriceNotAvailForAccuracyCheck = "index_price_not_available_for_accuracy_check" - LastPriceUpdateForMarketBlock = "last_price_update_for_market_block" - MissingPriceUpdates = "missing_price_updates" - NumMarketPricesToUpdate = "num_market_prices_to_update" - PriceChangeRate = "price_change_rate" - ProposedPriceChangesPriceUpdateDecision = "proposed_price_changes_price_update_decision" - ProposedPriceCrossesOraclePrice = "proposed_price_crosses_oracle_price" - ProposedPriceDoesNotMeetMinPriceChange = "proposed_price_does_not_meet_min_price_change" - RecentSmoothedPriceDoesNotMeetMinPriceChange = "recent_smoothed_price_doesnt_meet_min_price_change" - RecentSmoothedPriceCrossesOraclePrice = "recent_smoothed_price_crosses_old_price" - StatefulPriceUpdateValidation = "stateful_price_update_validation" - UpdateMarketParam = "update_market_param" - UpdateMarketPrices = "update_market_prices" - UpdateSmoothedPrices = "update_smoothed_prices" + CreateOracleMarket = "create_oracle_market" + CurrentMarketPrices = "current_market_prices" + GetValidMarketPriceUpdates = "get_valid_market_price_updates" + IndexPriceDoesNotExist = "index_price_does_not_exist" + IndexPriceIsZero = "index_price_is_zero" + IndexPriceNotAccurate = "index_price_not_accurate" + IndexPriceNotAvailForAccuracyCheck = "index_price_not_available_for_accuracy_check" + LastPriceUpdateForMarketBlock = "last_price_update_for_market_block" + MissingPriceUpdates = "missing_price_updates" + NumMarketPricesToUpdate = "num_market_prices_to_update" + PriceChangeRate = "price_change_rate" + ProposedPriceChangesPriceUpdateDecision = "proposed_price_changes_price_update_decision" + ProposedPriceDoesNotMeetMinPriceChange = "proposed_price_does_not_meet_min_price_change" + StatefulPriceUpdateValidation = "stateful_price_update_validation" + UpdateMarketParam = "update_market_param" + UpdateMarketPrices = "update_market_prices" // Sending. Account = "account" diff --git a/protocol/mocks/PricesKeeper.go b/protocol/mocks/PricesKeeper.go index b23f130fe7..0fef8f39bb 100644 --- a/protocol/mocks/PricesKeeper.go +++ b/protocol/mocks/PricesKeeper.go @@ -399,24 +399,6 @@ func (_m *PricesKeeper) UpdateMarketPrices(ctx types.Context, updates []*pricest return r0 } -// UpdateSmoothedPrices provides a mock function with given fields: ctx, linearInterpolateFunc -func (_m *PricesKeeper) UpdateSmoothedPrices(ctx types.Context, linearInterpolateFunc func(uint64, uint64, uint32) (uint64, error)) error { - ret := _m.Called(ctx, linearInterpolateFunc) - - if len(ret) == 0 { - panic("no return value specified for UpdateSmoothedPrices") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, func(uint64, uint64, uint32) (uint64, error)) error); ok { - r0 = rf(ctx, linearInterpolateFunc) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // NewPricesKeeper creates a new instance of PricesKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewPricesKeeper(t interface { diff --git a/protocol/testutil/keeper/assets.go b/protocol/testutil/keeper/assets.go index 6e1afcba5d..7b159f4f2d 100644 --- a/protocol/testutil/keeper/assets.go +++ b/protocol/testutil/keeper/assets.go @@ -56,7 +56,7 @@ func AssetsKeepers( transientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - pricesKeeper, _, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) + pricesKeeper, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) accountKeeper, _ = createAccountKeeper(stateStore, db, cdc, registry) bankKeeper, _ = createBankKeeper(stateStore, db, cdc, accountKeeper) keeper, storeKey = createAssetsKeeper(stateStore, db, cdc, pricesKeeper, transientStoreKey, msgSenderEnabled) diff --git a/protocol/testutil/keeper/clob.go b/protocol/testutil/keeper/clob.go index 5f1f7f72a9..024dc962f6 100644 --- a/protocol/testutil/keeper/clob.go +++ b/protocol/testutil/keeper/clob.go @@ -79,7 +79,7 @@ func NewClobKeepersTestContextWithUninitializedMemStore( indexerEventsTransientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - ks.PricesKeeper, _, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, indexerEventsTransientStoreKey) + ks.PricesKeeper, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, indexerEventsTransientStoreKey) // Mock time provider response for market creation. mockTimeProvider.On("Now").Return(constants.TimeT) epochsKeeper, _ := createEpochsKeeper(stateStore, db, cdc) diff --git a/protocol/testutil/keeper/perpetuals.go b/protocol/testutil/keeper/perpetuals.go index ca22d289c1..6417ef3362 100644 --- a/protocol/testutil/keeper/perpetuals.go +++ b/protocol/testutil/keeper/perpetuals.go @@ -63,7 +63,7 @@ func PerpetualsKeepersWithClobHelpers( transientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - pc.PricesKeeper, _, pc.IndexPriceCache, _, pc.MockTimeProvider = createPricesKeeper( + pc.PricesKeeper, _, pc.IndexPriceCache, pc.MockTimeProvider = createPricesKeeper( stateStore, db, cdc, diff --git a/protocol/testutil/keeper/prices.go b/protocol/testutil/keeper/prices.go index 3d774099ee..d44604676d 100644 --- a/protocol/testutil/keeper/prices.go +++ b/protocol/testutil/keeper/prices.go @@ -31,7 +31,6 @@ func PricesKeepers( keeper *keeper.Keeper, storeKey storetypes.StoreKey, indexPriceCache *pricefeedserver_types.MarketToExchangePrices, - marketToSmoothedPrices types.MarketToSmoothedPrices, mockTimeProvider *mocks.TimeProvider, ) { ctx = initKeepers(t, func( @@ -42,13 +41,13 @@ func PricesKeepers( transientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - keeper, storeKey, indexPriceCache, marketToSmoothedPrices, mockTimeProvider = + keeper, storeKey, indexPriceCache, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) return []GenesisInitializer{keeper} }) - return ctx, keeper, storeKey, indexPriceCache, marketToSmoothedPrices, mockTimeProvider + return ctx, keeper, storeKey, indexPriceCache, mockTimeProvider } func createPricesKeeper( @@ -60,7 +59,6 @@ func createPricesKeeper( *keeper.Keeper, storetypes.StoreKey, *pricefeedserver_types.MarketToExchangePrices, - types.MarketToSmoothedPrices, *mocks.TimeProvider, ) { storeKey := storetypes.NewKVStoreKey(types.StoreKey) @@ -69,8 +67,6 @@ func createPricesKeeper( indexPriceCache := pricefeedserver_types.NewMarketToExchangePrices(pricefeed_types.MaxPriceAge) - marketToSmoothedPrices := types.NewMarketToSmoothedPrices(types.SmoothedPriceTrackingBlockHistoryLength) - mockTimeProvider := &mocks.TimeProvider{} mockMsgSender := &mocks.IndexerMessageSender{} @@ -84,7 +80,6 @@ func createPricesKeeper( cdc, storeKey, indexPriceCache, - marketToSmoothedPrices, mockTimeProvider, mockIndexerEventsManager, []string{ @@ -93,7 +88,7 @@ func createPricesKeeper( }, ) - return k, storeKey, indexPriceCache, marketToSmoothedPrices, mockTimeProvider + return k, storeKey, indexPriceCache, mockTimeProvider } // CreateTestMarkets creates a standard set of test markets for testing. diff --git a/protocol/testutil/keeper/rewards.go b/protocol/testutil/keeper/rewards.go index bb63a4ecd5..c467e278f4 100644 --- a/protocol/testutil/keeper/rewards.go +++ b/protocol/testutil/keeper/rewards.go @@ -42,7 +42,7 @@ func RewardsKeepers( transientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - pricesKeeper, _, _, _, _ = createPricesKeeper(stateStore, db, cdc, transientStoreKey) + pricesKeeper, _, _, _ = createPricesKeeper(stateStore, db, cdc, transientStoreKey) // Mock time provider response for market creation. epochsKeeper, _ := createEpochsKeeper(stateStore, db, cdc) assetsKeeper, _ = createAssetsKeeper( diff --git a/protocol/testutil/keeper/sending.go b/protocol/testutil/keeper/sending.go index 93cd6c429f..6fd275bc66 100644 --- a/protocol/testutil/keeper/sending.go +++ b/protocol/testutil/keeper/sending.go @@ -57,7 +57,7 @@ func SendingKeepersWithSubaccountsKeeper(t testing.TB, saKeeper types.Subaccount // Define necessary keepers here for unit tests epochsKeeper, _ := createEpochsKeeper(stateStore, db, cdc) blockTimeKeeper, _ := createBlockTimeKeeper(stateStore, db, cdc) - ks.PricesKeeper, _, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) + ks.PricesKeeper, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) ks.PerpetualsKeeper, _ = createPerpetualsKeeper( stateStore, db, diff --git a/protocol/testutil/keeper/subaccounts.go b/protocol/testutil/keeper/subaccounts.go index ee3c8ec666..07b33984b0 100644 --- a/protocol/testutil/keeper/subaccounts.go +++ b/protocol/testutil/keeper/subaccounts.go @@ -52,7 +52,7 @@ func SubaccountsKeepers( transientStoreKey storetypes.StoreKey, ) []GenesisInitializer { // Define necessary keepers here for unit tests - pricesKeeper, _, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) + pricesKeeper, _, _, mockTimeProvider = createPricesKeeper(stateStore, db, cdc, transientStoreKey) epochsKeeper, _ := createEpochsKeeper(stateStore, db, cdc) perpetualsKeeper, _ = createPerpetualsKeeper(stateStore, db, cdc, pricesKeeper, epochsKeeper, transientStoreKey) assetsKeeper, _ = createAssetsKeeper(stateStore, db, cdc, pricesKeeper, transientStoreKey, msgSenderEnabled) diff --git a/protocol/x/prices/genesis_test.go b/protocol/x/prices/genesis_test.go index aef348f7db..3d76af63ac 100644 --- a/protocol/x/prices/genesis_test.go +++ b/protocol/x/prices/genesis_test.go @@ -33,7 +33,7 @@ func TestExportGenesis(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, k, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) prices.InitGenesis(ctx, *k, *tc.genesisState) @@ -50,7 +50,7 @@ func TestExportGenesis(t *testing.T) { } func TestExportGenesis_WithMutation(t *testing.T) { - ctx, k, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) prices.InitGenesis(ctx, *k, *types.DefaultGenesis()) @@ -94,7 +94,7 @@ func invalidGenesis() types.GenesisState { } func TestInitGenesis_Panics(t *testing.T) { - ctx, k, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) // Verify InitGenesis panics when given an invalid genesis state. @@ -104,7 +104,7 @@ func TestInitGenesis_Panics(t *testing.T) { } func TestInitGenesisEmitsMarketUpdates(t *testing.T) { - ctx, k, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) prices.InitGenesis(ctx, *k, constants.Prices_DefaultGenesisState) diff --git a/protocol/x/prices/keeper/grpc_query_market_test.go b/protocol/x/prices/keeper/grpc_query_market_test.go index d32772495a..959cd646e0 100644 --- a/protocol/x/prices/keeper/grpc_query_market_test.go +++ b/protocol/x/prices/keeper/grpc_query_market_test.go @@ -15,7 +15,7 @@ import ( ) func TestMarketPriceQuerySingle(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgs := keepertest.CreateNMarkets(t, ctx, keeper, 2) for _, tc := range []struct { @@ -66,7 +66,7 @@ func TestMarketPriceQuerySingle(t *testing.T) { } func TestMarketPriceQueryPaginated(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgs := keepertest.CreateNMarkets(t, ctx, keeper, 5) prices := make([]types.MarketPrice, len(msgs)) @@ -126,7 +126,7 @@ func TestMarketPriceQueryPaginated(t *testing.T) { } func TestMarketParamQuerySingle(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgs := keepertest.CreateNMarkets(t, ctx, keeper, 2) for _, tc := range []struct { @@ -177,7 +177,7 @@ func TestMarketParamQuerySingle(t *testing.T) { } func TestMarketParamQueryPaginated(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgs := keepertest.CreateNMarkets(t, ctx, keeper, 5) params := make([]types.MarketParam, len(msgs)) diff --git a/protocol/x/prices/keeper/keeper.go b/protocol/x/prices/keeper/keeper.go index 0673574ff0..96a95c74ce 100644 --- a/protocol/x/prices/keeper/keeper.go +++ b/protocol/x/prices/keeper/keeper.go @@ -17,14 +17,13 @@ import ( type ( Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - indexPriceCache *pricefeedtypes.MarketToExchangePrices - marketToSmoothedPrices types.MarketToSmoothedPrices - timeProvider libtime.TimeProvider - indexerEventManager indexer_manager.IndexerEventManager - marketToCreatedAt map[uint32]time.Time - authorities map[string]struct{} + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + indexPriceCache *pricefeedtypes.MarketToExchangePrices + timeProvider libtime.TimeProvider + indexerEventManager indexer_manager.IndexerEventManager + marketToCreatedAt map[uint32]time.Time + authorities map[string]struct{} } ) @@ -34,20 +33,18 @@ func NewKeeper( cdc codec.BinaryCodec, storeKey storetypes.StoreKey, indexPriceCache *pricefeedtypes.MarketToExchangePrices, - marketToSmoothedPrices types.MarketToSmoothedPrices, timeProvider libtime.TimeProvider, indexerEventManager indexer_manager.IndexerEventManager, authorities []string, ) *Keeper { return &Keeper{ - cdc: cdc, - storeKey: storeKey, - indexPriceCache: indexPriceCache, - marketToSmoothedPrices: marketToSmoothedPrices, - timeProvider: timeProvider, - indexerEventManager: indexerEventManager, - marketToCreatedAt: map[uint32]time.Time{}, - authorities: lib.UniqueSliceToSet(authorities), + cdc: cdc, + storeKey: storeKey, + indexPriceCache: indexPriceCache, + timeProvider: timeProvider, + indexerEventManager: indexerEventManager, + marketToCreatedAt: map[uint32]time.Time{}, + authorities: lib.UniqueSliceToSet(authorities), } } diff --git a/protocol/x/prices/keeper/keeper_test.go b/protocol/x/prices/keeper/keeper_test.go index 5eaeb54de4..a97d761df8 100644 --- a/protocol/x/prices/keeper/keeper_test.go +++ b/protocol/x/prices/keeper/keeper_test.go @@ -8,7 +8,7 @@ import ( ) func TestLogger(t *testing.T) { - ctx, keeper, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, keeper, _, _, _ := keepertest.PricesKeepers(t) logger := keeper.Logger(ctx) require.NotNil(t, logger) } diff --git a/protocol/x/prices/keeper/market_param_test.go b/protocol/x/prices/keeper/market_param_test.go index 5fc479086a..2c1ce910b1 100644 --- a/protocol/x/prices/keeper/market_param_test.go +++ b/protocol/x/prices/keeper/market_param_test.go @@ -15,7 +15,7 @@ import ( ) func TestModifyMarketParam(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) ctx = ctx.WithTxBytes(constants.TestTxBytes) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) @@ -123,7 +123,7 @@ func TestModifyMarketParam_Errors(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, keeper, _, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) mockTimeKeeper.On("Now").Return(constants.TimeT) ctx = ctx.WithTxBytes(constants.TestTxBytes) keepertest.CreateNMarkets(t, ctx, keeper, 2) @@ -143,7 +143,7 @@ func TestModifyMarketParam_Errors(t *testing.T) { } func TestGetMarketParam(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) for _, item := range items { @@ -158,13 +158,13 @@ func TestGetMarketParam(t *testing.T) { } func TestGetMarketParam_NotFound(t *testing.T) { - ctx, keeper, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, keeper, _, _, _ := keepertest.PricesKeepers(t) _, exists := keeper.GetMarketParam(ctx, uint32(0)) require.False(t, exists) } func TestGetAllMarketParams(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) params := make([]types.MarketParam, len(items)) diff --git a/protocol/x/prices/keeper/market_price_test.go b/protocol/x/prices/keeper/market_price_test.go index b9e3c458e5..35b720c59f 100644 --- a/protocol/x/prices/keeper/market_price_test.go +++ b/protocol/x/prices/keeper/market_price_test.go @@ -25,7 +25,7 @@ func createNMarketPriceUpdates( } func TestUpdateMarketPrices(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) ctx = ctx.WithTxBytes(constants.TestTxBytes) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) @@ -60,7 +60,7 @@ func TestUpdateMarketPrices(t *testing.T) { } func TestUpdateMarketPrices_NotFound(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) ctx = ctx.WithTxBytes(constants.TestTxBytes) priceUpdates := createNMarketPriceUpdates(10) @@ -89,7 +89,7 @@ func TestUpdateMarketPrices_NotFound(t *testing.T) { } func TestGetMarketPrice(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) for _, item := range items { @@ -104,13 +104,13 @@ func TestGetMarketPrice(t *testing.T) { } func TestGetMarketPrice_NotFound(t *testing.T) { - ctx, keeper, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, keeper, _, _, _ := keepertest.PricesKeepers(t) _, err := keeper.GetMarketPrice(ctx, uint32(0)) require.EqualError(t, err, "0: Market price does not exist") } func TestGetAllMarketPrices(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) prices := make([]types.MarketPrice, len(items)) @@ -126,7 +126,7 @@ func TestGetAllMarketPrices(t *testing.T) { } func TestGetMarketIdToValidIndexPrice(t *testing.T) { - ctx, keeper, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) // Now() is used by `GetMarketIdToValidIndexPrice` internally compare with the cutoff time // of each price. mockTimeProvider.On("Now").Return(constants.TimeT) diff --git a/protocol/x/prices/keeper/market_test.go b/protocol/x/prices/keeper/market_test.go index 970cfd9a85..35872d4091 100644 --- a/protocol/x/prices/keeper/market_test.go +++ b/protocol/x/prices/keeper/market_test.go @@ -14,7 +14,7 @@ import ( ) func TestCreateMarket(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) ctx = ctx.WithTxBytes(constants.TestTxBytes) @@ -88,7 +88,7 @@ func TestMarketIsRecentlyAvailable(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) // Create market with TimeT creation timestamp. mockTimeProvider.On("Now").Return(constants.TimeT).Once() @@ -187,7 +187,7 @@ func TestCreateMarket_Errors(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, keeper, _, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) ctx = ctx.WithTxBytes(constants.TestTxBytes) mockTimeKeeper.On("Now").Return(constants.TimeT) @@ -236,7 +236,7 @@ func TestCreateMarket_Errors(t *testing.T) { } func TestGetAllMarketParamPrices(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) items := keepertest.CreateNMarkets(t, ctx, keeper, 10) diff --git a/protocol/x/prices/keeper/msg_server_create_oracle_market_test.go b/protocol/x/prices/keeper/msg_server_create_oracle_market_test.go index b9b15738cc..ed9bd80919 100644 --- a/protocol/x/prices/keeper/msg_server_create_oracle_market_test.go +++ b/protocol/x/prices/keeper/msg_server_create_oracle_market_test.go @@ -90,7 +90,7 @@ func TestCreateOracleMarket(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - ctx, pricesKeeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgServer := keeper.NewMsgServerImpl(pricesKeeper) tc.setup(t, ctx, pricesKeeper) diff --git a/protocol/x/prices/keeper/msg_server_update_market_param_test.go b/protocol/x/prices/keeper/msg_server_update_market_param_test.go index 3d26be1a7e..fb2613f082 100644 --- a/protocol/x/prices/keeper/msg_server_update_market_param_test.go +++ b/protocol/x/prices/keeper/msg_server_update_market_param_test.go @@ -143,7 +143,7 @@ func TestUpdateMarketParam(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - ctx, pricesKeeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, pricesKeeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgServer := keeper.NewMsgServerImpl(pricesKeeper) initialMarketParam, err := pricesKeeper.CreateMarket(ctx, testMarketParam, testMarketPrice) diff --git a/protocol/x/prices/keeper/msg_server_update_market_prices_test.go b/protocol/x/prices/keeper/msg_server_update_market_prices_test.go index ebbf453d33..01cf2aabc1 100644 --- a/protocol/x/prices/keeper/msg_server_update_market_prices_test.go +++ b/protocol/x/prices/keeper/msg_server_update_market_prices_test.go @@ -186,7 +186,7 @@ func TestUpdateMarketPrices_Valid(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgServer := keeper.NewMsgServerImpl(k) @@ -312,7 +312,7 @@ func TestUpdateMarketPrices_SkipNonDeterministicCheck_Valid(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) msgServer := keeper.NewMsgServerImpl(k) @@ -376,7 +376,7 @@ func TestUpdateMarketPrices_Error(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) + ctx, k, _, _, mockTimeKeeper := keepertest.PricesKeepers(t) mockTimeKeeper.On("Now").Return(constants.TimeT) msgServer := keeper.NewMsgServerImpl(k) keepertest.CreateTestMarkets(t, ctx, k) @@ -399,7 +399,7 @@ func TestUpdateMarketPrices_Error(t *testing.T) { func TestUpdateMarketPrices_Panic(t *testing.T) { // Init. - ctx, _, _, _, _, _ := keepertest.PricesKeepers(t) + ctx, _, _, _, _ := keepertest.PricesKeepers(t) mockKeeper := &mocks.PricesKeeper{} msgServer := keeper.NewMsgServerImpl(mockKeeper) diff --git a/protocol/x/prices/keeper/slinky_adapter_test.go b/protocol/x/prices/keeper/slinky_adapter_test.go index 5db09a2cd9..8eb41077d2 100644 --- a/protocol/x/prices/keeper/slinky_adapter_test.go +++ b/protocol/x/prices/keeper/slinky_adapter_test.go @@ -13,7 +13,7 @@ import ( ) func TestGetCurrencyPairFromID(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) marketNumber := 10 @@ -30,7 +30,7 @@ func TestGetCurrencyPairFromID(t *testing.T) { } func TestIDForCurrencyPair(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) marketNumber := 10 @@ -54,7 +54,7 @@ func TestIDForCurrencyPair(t *testing.T) { } func TestGetPriceForCurrencyPair(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) marketNumber := 10 @@ -78,7 +78,7 @@ func TestGetPriceForCurrencyPair(t *testing.T) { } func TestBadMarketData(t *testing.T) { - ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) _, err := keeper.CreateMarket( diff --git a/protocol/x/prices/keeper/smoothed_price.go b/protocol/x/prices/keeper/smoothed_price.go deleted file mode 100644 index cce78e84fd..0000000000 --- a/protocol/x/prices/keeper/smoothed_price.go +++ /dev/null @@ -1,54 +0,0 @@ -package keeper - -import ( - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/dydxprotocol/v4-chain/protocol/x/prices/types" -) - -// UpdateSmoothedPrices updates the internal map of smoothed prices for all markets. -// The smoothing is calculated with Basic Exponential Smoothing, see -// https://en.wikipedia.org/wiki/Exponential_smoothing -// If there is no valid index price for a market at this time, the smoothed price does not change. -func (k Keeper) UpdateSmoothedPrices( - ctx sdk.Context, - linearInterpolateFunc func(v0 uint64, v1 uint64, ppm uint32) (uint64, error), -) error { - allMarketParams := k.GetAllMarketParams(ctx) - indexPrices := k.indexPriceCache.GetValidMedianPrices(allMarketParams, k.timeProvider.Now()) - - // Track errors for each market. - updateErrors := make([]error, 0) - - // Iterate through allMarketParams instead of indexPrices to ensure that we generate deterministic error messages - // in the case of failed updates. - for _, marketParam := range allMarketParams { - indexPrice, exists := indexPrices[marketParam.Id] - if !exists { - continue - } - - smoothedPrice, ok := k.marketToSmoothedPrices.GetSmoothedPrice(marketParam.Id) - if !ok { - smoothedPrice = indexPrice - } - update, err := linearInterpolateFunc( - smoothedPrice, - indexPrice, - types.PriceSmoothingPpm, - ) - if err != nil { - updateErrors = append( - updateErrors, - fmt.Errorf("Error updating smoothed price for market %v: %w", marketParam.Id, err), - ) - continue - } - - k.marketToSmoothedPrices.PushSmoothedPrice(marketParam.Id, update) - } - - return errors.Join(updateErrors...) -} diff --git a/protocol/x/prices/keeper/smoothed_price_test.go b/protocol/x/prices/keeper/smoothed_price_test.go deleted file mode 100644 index 93237a2c13..0000000000 --- a/protocol/x/prices/keeper/smoothed_price_test.go +++ /dev/null @@ -1,128 +0,0 @@ -package keeper_test - -import ( - "fmt" - "testing" - - "github.com/dydxprotocol/v4-chain/protocol/daemons/pricefeed/api" - "github.com/dydxprotocol/v4-chain/protocol/lib" - "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" - keepertest "github.com/dydxprotocol/v4-chain/protocol/testutil/keeper" - "github.com/stretchr/testify/require" -) - -var ( - emptySmoothedPrices = map[uint32]uint64{} -) - -func errInterpolator(v0 uint64, v1 uint64, ppm uint32) (uint64, error) { - return 0, fmt.Errorf("error while interpolating") -} - -func alternatingErrInterpolator() func(v0 uint64, v1 uint64, ppm uint32) (uint64, error) { - var i int - return func(v0 uint64, v1 uint64, ppm uint32) (uint64, error) { - i++ - if i%2 == 0 { - return 0, fmt.Errorf("error while interpolating") - } - return lib.Uint64LinearInterpolate(v0, v1, ppm) - } -} - -func TestUpdateSmoothedPrices(t *testing.T) { - tests := map[string]struct { - smoothedPrices map[uint32]uint64 - indexPrices []*api.MarketPriceUpdate - expectedResult map[uint32]uint64 - linearInterpolateFunc func(v0 uint64, v1 uint64, ppm uint32) (uint64, error) - expectedErr string - }{ - "Empty result - No index prices, no smoothed prices": { - expectedResult: emptySmoothedPrices, - linearInterpolateFunc: lib.Uint64LinearInterpolate, - }, - "Unchanged - No index prices": { - smoothedPrices: constants.AtTimeTSingleExchangeSmoothedPrices, - expectedResult: constants.AtTimeTSingleExchangeSmoothedPrices, - linearInterpolateFunc: lib.Uint64LinearInterpolate, - }, - "Mixed updates and additions - mix of present and missing index prices, smoothed prices": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - smoothedPrices: map[uint32]uint64{ - constants.MarketId1: constants.Exchange1_Price1_TimeT.Price + 10, - constants.MarketId2: constants.Exchange2_Price2_TimeT.Price + 50, - constants.MarketId7: constants.Price1, - }, - expectedResult: map[uint32]uint64{ - constants.MarketId0: constants.Exchange0_Price4_TimeT.Price, - constants.MarketId1: constants.Exchange1_Price1_TimeT.Price + 7, - constants.MarketId2: constants.Exchange2_Price2_TimeT.Price + 35, - constants.MarketId3: constants.Exchange3_Price3_TimeT.Price, - constants.MarketId4: constants.Exchange3_Price3_TimeT.Price, - constants.MarketId7: constants.Price1, - }, - linearInterpolateFunc: lib.Uint64LinearInterpolate, - }, - "Initializes smoothed prices with index prices": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - expectedResult: constants.AtTimeTSingleExchangeSmoothedPrices, - linearInterpolateFunc: lib.Uint64LinearInterpolate, - }, - "All updated - multiple existing overlapped index and smoothed prices": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - smoothedPrices: constants.AtTimeTSingleExchangeSmoothedPricesPlus10, - expectedResult: constants.AtTimeTSingleExchangeSmoothedPricesPlus7, - linearInterpolateFunc: lib.Uint64LinearInterpolate, - }, - "Interpolation errors - returns error": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - smoothedPrices: constants.AtTimeTSingleExchangeSmoothedPricesPlus10, - linearInterpolateFunc: errInterpolator, - expectedErr: "Error updating smoothed price for market 0: error while interpolating\n" + - "Error updating smoothed price for market 1: error while interpolating\n" + - "Error updating smoothed price for market 2: error while interpolating\n" + - "Error updating smoothed price for market 3: error while interpolating\n" + - "Error updating smoothed price for market 4: error while interpolating", - expectedResult: constants.AtTimeTSingleExchangeSmoothedPricesPlus10, // no change - }, - "Single interpolation error - returns error, continues updating other markets": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - smoothedPrices: constants.AtTimeTSingleExchangeSmoothedPricesPlus10, - linearInterpolateFunc: alternatingErrInterpolator(), - expectedErr: "Error updating smoothed price for market 1: error while interpolating\n" + - "Error updating smoothed price for market 3: error while interpolating", - expectedResult: map[uint32]uint64{ - constants.MarketId0: constants.AtTimeTSingleExchangeSmoothedPricesPlus7[constants.MarketId0], // update - constants.MarketId1: constants.AtTimeTSingleExchangeSmoothedPricesPlus10[constants.MarketId1], // no change - constants.MarketId2: constants.AtTimeTSingleExchangeSmoothedPricesPlus7[constants.MarketId2], // update - constants.MarketId3: constants.AtTimeTSingleExchangeSmoothedPricesPlus10[constants.MarketId3], // update - constants.MarketId4: constants.AtTimeTSingleExchangeSmoothedPricesPlus7[constants.MarketId4], // update - }, // no change - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - // Setup. - ctx, k, _, indexPriceCache, marketToSmoothedPrices, mockTimeProvider := keepertest.PricesKeepers(t) - mockTimeProvider.On("Now").Return(constants.TimeT) - - keepertest.CreateTestMarkets(t, ctx, k) - indexPriceCache.UpdatePrices(tc.indexPrices) - for market, smoothedPrice := range tc.smoothedPrices { - marketToSmoothedPrices.PushSmoothedPrice(market, smoothedPrice) - } - - // Run. - err := k.UpdateSmoothedPrices(ctx, tc.linearInterpolateFunc) - if tc.expectedErr != "" { - require.EqualError(t, err, tc.expectedErr) - } else { - require.NoError(t, err) - } - - // Validate. - require.Equal(t, tc.expectedResult, marketToSmoothedPrices.GetSmoothedPricesForTest()) - }) - } -} diff --git a/protocol/x/prices/keeper/update_price.go b/protocol/x/prices/keeper/update_price.go index 6f4a5162a2..c7621e5c6b 100644 --- a/protocol/x/prices/keeper/update_price.go +++ b/protocol/x/prices/keeper/update_price.go @@ -96,33 +96,9 @@ func (k Keeper) GetValidMarketPriceUpdates( continue } - historicalSmoothedPrices := k.marketToSmoothedPrices.GetHistoricalSmoothedPrices(marketId) - // We generally expect to have a smoothed price history for each market, except during the first few blocks - // after network genesis or a network restart. In this scenario, we use the index price as the smoothed price. - if len(historicalSmoothedPrices) == 0 { - // Conditionally log missing smoothed prices at least 20s after genesis/restart/market creation. We expect - // that there will be a delay in populating historical smoothed prices after network genesis or a network - // restart, or when a market is created, because they depend on present index prices, and it takes the - // daemon some time to warm up. - if !k.IsRecentlyAvailable(ctx, marketId) { - log.ErrorLog( - ctx, - "Smoothed price for market does not exist", - constants.MarketIdLogKey, - marketId, - ) - } - historicalSmoothedPrices = []uint64{indexPrice} - } - smoothedPrice := historicalSmoothedPrices[0] - - proposalPrice := getProposalPrice(smoothedPrice, indexPrice, marketParamPrice.Price.Price) - shouldPropose, reasons := shouldProposePrice( - proposalPrice, - marketParamPrice, indexPrice, - historicalSmoothedPrices, + marketParamPrice, ) // If the index price would have updated, track how the proposal price changes the update @@ -131,7 +107,6 @@ func (k Keeper) GetValidMarketPriceUpdates( logPriceUpdateBehavior( ctx, marketParamPrice, - proposalPrice, indexPrice, marketMetricsLabel, shouldPropose, @@ -145,7 +120,7 @@ func (k Keeper) GetValidMarketPriceUpdates( updates, &types.MsgUpdateMarketPrices_MarketPrice{ MarketId: marketId, - Price: proposalPrice, + Price: indexPrice, }, ) } @@ -163,7 +138,6 @@ func logPriceUpdateBehavior( ctx sdk.Context, marketParamPrice types.MarketParamPrice, proposalPrice uint64, - indexPrice uint64, marketMetricsLabel gometrics.Label, shouldPropose bool, reasons []proposeCancellationReason, @@ -189,11 +163,10 @@ func logPriceUpdateBehavior( log.InfoLog( ctx, fmt.Sprintf( - "Proposal price (%v) %v for market (%v), index price (%v), oracle price (%v), min price change (%v)", + "Proposal price (%v) %v for market (%v), oracle price (%v), min price change (%v)", proposalPrice, loggingVerb, marketParamPrice.Param.Id, - indexPrice, marketParamPrice.Price.Price, getMinPriceChangeAmountForMarket(marketParamPrice), ), @@ -212,8 +185,6 @@ type proposeCancellationReason struct { func shouldProposePrice( proposalPrice uint64, marketParamPrice types.MarketParamPrice, - indexPrice uint64, - historicalSmoothedPrices []uint64, ) ( shouldPropose bool, reasons []proposeCancellationReason, @@ -221,58 +192,6 @@ func shouldProposePrice( reasons = make([]proposeCancellationReason, 0, 4) shouldPropose = true - // If any smoothed price crosses the old price compared to the index price, do not update. - reasons = append( - reasons, - proposeCancellationReason{ - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - ) - for _, smoothedPrice := range historicalSmoothedPrices { - if isCrossingOldPrice(PriceTuple{ - OldPrice: marketParamPrice.Price.Price, - IndexPrice: indexPrice, - NewPrice: smoothedPrice, - }) { - shouldPropose = false - reasons[len(reasons)-1].Value = true - break - } - } - - // If the proposal price crosses the old price compared to the index price, do not update. - reasons = append( - reasons, - proposeCancellationReason{ - Reason: metrics.ProposedPriceCrossesOraclePrice, - }, - ) - if isCrossingOldPrice(PriceTuple{ - OldPrice: marketParamPrice.Price.Price, - IndexPrice: indexPrice, - NewPrice: proposalPrice, - }) { - shouldPropose = false - reasons[len(reasons)-1].Value = true - } - - // If any smoothed price does not meet the min price change, do not update. - reasons = append( - reasons, - proposeCancellationReason{ - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - ) - for _, smoothedPrice := range historicalSmoothedPrices { - if !isAboveRequiredMinPriceChange(marketParamPrice, smoothedPrice) { - shouldPropose = false - reasons[len(reasons)-1].Value = true - break - } - } - // If the proposal price does not meet the min price change, do not update. reasons = append( reasons, diff --git a/protocol/x/prices/keeper/update_price_test.go b/protocol/x/prices/keeper/update_price_test.go index 6c61b89ec9..db2b017ce4 100644 --- a/protocol/x/prices/keeper/update_price_test.go +++ b/protocol/x/prices/keeper/update_price_test.go @@ -62,62 +62,13 @@ var ( } invalidMarket9DoesNotExistUpdate = constants.Market9_SingleExchange_AtTimeUpdate[0] - - // SmoothedPrice test constants. - validMarket0SmoothedPrices = map[uint32][]uint64{ - constants.MarketId0: {fiveBillionAndFiveMillion + 1}, - } - - invalidMarket0HistoricalSmoothedPricesCrossesOraclePrice = map[uint32][]uint64{ - constants.MarketId0: { - fiveBillionAndFiveMillion + 1, // Valid - fiveBillionMinusFiveMillionAndOne, // Invalid: crosses oracle price. - }, - } - - invalidMarket0HistoricalSmoothedPricesDoesNotMeetMinPriceChange = map[uint32][]uint64{ - constants.MarketId0: { - fiveBillionAndFiveMillion + 1, // Valid - constants.FiveBillion + 1, // Invalid: does not meet min price change. - }, - } - - invalidMarket2HistoricalSmoothedPricesCrossesOraclePrice = map[uint32][]uint64{ - constants.MarketId2: { - fiveBillionAndFiveMillion + 1, // Valid - fiveBillionMinusFiveMillionAndOne, // Invalid: crosses oracle price. - }, - } - - invalidMarket0SmoothedPriceTrendsAwayFromIndexPrice = map[uint32][]uint64{ - constants.MarketId0: {fiveBillionMinusFiveMillionAndOne}, - } - - invalidMarket2SmoothedPriceTrendsAwayFromIndexPrice = map[uint32][]uint64{ - constants.MarketId2: {constants.FiveBillion - 2}, - } - - market2SmoothedPriceNotProposed = map[uint32][]uint64{ - constants.MarketId2: {constants.FiveBillion + 3}, - } - - market2SmoothedPriceDoesNotMeetMinChangeUpdate = map[uint32][]uint64{ - constants.MarketId2: {constants.FiveBillion + 1}, - } - - invalidMarket9DoesNotExistSmoothedPrice = map[uint32][]uint64{ - constants.MarketId9: {1_000_000}, - } ) // Note: markets and exchanges are created by `CreateTestMarketsAndExchanges`. func TestGetValidMarketPriceUpdates(t *testing.T) { tests := map[string]struct { // Setup. - indexPrices []*api.MarketPriceUpdate - // historicalSmoothedIndexPrice prices for each market are expected to be ordered from most recent to least - // recent. - historicalSmoothedIndexPrices map[uint32][]uint64 + indexPrices []*api.MarketPriceUpdate skipCreateMarketsAndExchanges bool // Expected. @@ -139,71 +90,13 @@ func TestGetValidMarketPriceUpdates(t *testing.T) { indexPrices: []*api.MarketPriceUpdate{invalidMarket9DoesNotExistUpdate}, expectedMsg: emptyResult, }, - "Single result: index price used when no smoothed prices": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - expectedMsg: validMarket0UpdateResult, - }, - "Single result: no overlap between markets for index prices and smoothed prices": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - historicalSmoothedIndexPrices: invalidMarket9DoesNotExistSmoothedPrice, - expectedMsg: validMarket0UpdateResult, - }, - "Empty result: propose price is index price, does not meet min price change": { - indexPrices: []*api.MarketPriceUpdate{invalidMarket2PriceDoesNotMeetMinChangeUpdate}, - historicalSmoothedIndexPrices: market2SmoothedPriceNotProposed, - expectedMsg: emptyResult, - }, - "Empty result: propose price is smoothed price, does not meet min price change": { - indexPrices: []*api.MarketPriceUpdate{invalidMarket2PriceDoesNotMeetMinChangeUpdate}, - historicalSmoothedIndexPrices: market2SmoothedPriceDoesNotMeetMinChangeUpdate, - expectedMsg: emptyResult, - }, - "Empty result: propose price is good, but historical smoothed price does not meet min price change": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - historicalSmoothedIndexPrices: invalidMarket0HistoricalSmoothedPricesDoesNotMeetMinPriceChange, - expectedMsg: emptyResult, - }, - "Empty result: propose price is good, but historical smoothed price crosses oracle price": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - historicalSmoothedIndexPrices: invalidMarket0HistoricalSmoothedPricesCrossesOraclePrice, - expectedMsg: emptyResult, - }, - "Empty result: proposed price is smoothed price, meets min change but trends away from index price": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - historicalSmoothedIndexPrices: invalidMarket0SmoothedPriceTrendsAwayFromIndexPrice, - expectedMsg: emptyResult, - }, - "Empty result: proposed price does not meet min change and historical smoothed price crosses oracle price": { - indexPrices: []*api.MarketPriceUpdate{invalidMarket2PriceDoesNotMeetMinChangeUpdate}, - historicalSmoothedIndexPrices: invalidMarket2HistoricalSmoothedPricesCrossesOraclePrice, - expectedMsg: emptyResult, - }, - "Empty result: proposed price does not meet min change and smoothed price is trending away from index price": { - indexPrices: []*api.MarketPriceUpdate{invalidMarket2PriceDoesNotMeetMinChangeUpdate}, - historicalSmoothedIndexPrices: invalidMarket2SmoothedPriceTrendsAwayFromIndexPrice, - expectedMsg: emptyResult, + "Empty result: propose price does not meet min price change": { + indexPrices: []*api.MarketPriceUpdate{invalidMarket2PriceDoesNotMeetMinChangeUpdate}, + expectedMsg: emptyResult, }, "Single market price update": { - indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, - historicalSmoothedIndexPrices: validMarket0SmoothedPrices, - expectedMsg: validMarket0UpdateResult, - }, - "Multiple market price updates, some from smoothed price and some from index price": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - historicalSmoothedIndexPrices: map[uint32][]uint64{ - constants.MarketId0: {constants.Price4 - 1}, - constants.MarketId1: {constants.Price1 + 1}, - constants.MarketId2: {constants.Price2}, - }, - expectedMsg: &types.MsgUpdateMarketPrices{ - MarketPriceUpdates: []*types.MsgUpdateMarketPrices_MarketPrice{ - types.NewMarketPriceUpdate(constants.MarketId0, constants.Price4), - types.NewMarketPriceUpdate(constants.MarketId1, constants.Price1+1), - types.NewMarketPriceUpdate(constants.MarketId2, constants.Price2), - types.NewMarketPriceUpdate(constants.MarketId3, constants.Price3), - types.NewMarketPriceUpdate(constants.MarketId4, constants.Price3), - }, - }, + indexPrices: []*api.MarketPriceUpdate{validMarket0Update}, + expectedMsg: validMarket0UpdateResult, }, "Mix of valid and invalid index prices": { indexPrices: []*api.MarketPriceUpdate{ @@ -212,21 +105,10 @@ func TestGetValidMarketPriceUpdates(t *testing.T) { invalidMarket2PriceDoesNotMeetMinChangeUpdate, // Price does not meet min price change req. invalidMarket9DoesNotExistUpdate, // Market with id 9 does not exist. }, - historicalSmoothedIndexPrices: map[uint32][]uint64{ - constants.MarketId0: {validMarket0Update.ExchangePrices[0].Price}, - constants.MarketId1: {constants.Price4}, - constants.MarketId2: {constants.Price2}, - constants.MarketId9: {constants.Price4}, - }, expectedMsg: validMarket0UpdateResult, }, "Mix of valid, invalid, and missing smoothed prices": { indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - historicalSmoothedIndexPrices: map[uint32][]uint64{ - constants.MarketId0: {constants.Price4}, // Same as index price. - constants.MarketId1: {0}, // Invalid price, so index price is used. - constants.MarketId9: {constants.Price1}, // Invalid market. - }, expectedMsg: &types.MsgUpdateMarketPrices{ MarketPriceUpdates: []*types.MsgUpdateMarketPrices_MarketPrice{ types.NewMarketPriceUpdate(constants.MarketId0, constants.Price4), @@ -237,30 +119,11 @@ func TestGetValidMarketPriceUpdates(t *testing.T) { }, }, }, - "Mix of valid, invalid, and invalid historical smoothed prices": { - indexPrices: constants.AtTimeTSingleExchangePriceUpdate, - historicalSmoothedIndexPrices: map[uint32][]uint64{ - constants.MarketId0: { - constants.Price4, // Same as index price. - fiveBillionAndFiveMillion, // Invalid: crosses oracle price. - }, - constants.MarketId1: {constants.Price1}, // Valid: same as index price. - constants.MarketId9: {constants.Price1}, // Invalid market. - }, - expectedMsg: &types.MsgUpdateMarketPrices{ - MarketPriceUpdates: []*types.MsgUpdateMarketPrices_MarketPrice{ - types.NewMarketPriceUpdate(constants.MarketId1, constants.Price1), - types.NewMarketPriceUpdate(constants.MarketId2, constants.Price2), - types.NewMarketPriceUpdate(constants.MarketId3, constants.Price3), - types.NewMarketPriceUpdate(constants.MarketId4, constants.Price3), - }, - }, - }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, marketSmoothedPrices, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) if !tc.skipCreateMarketsAndExchanges { @@ -268,14 +131,6 @@ func TestGetValidMarketPriceUpdates(t *testing.T) { } indexPriceCache.UpdatePrices(tc.indexPrices) - // Smoothed prices are listed in reverse chronological order for test case constant legibility. - // Therefore, add them in reverse order to the `marketSmoothedPrices` cache. - for market, historicalSmoothedPrices := range tc.historicalSmoothedIndexPrices { - for i := len(historicalSmoothedPrices) - 1; i >= 0; i-- { - marketSmoothedPrices.PushSmoothedPrice(market, historicalSmoothedPrices[i]) - } - } - // Run. result := k.GetValidMarketPriceUpdates(ctx) diff --git a/protocol/x/prices/keeper/update_price_whitebox_test.go b/protocol/x/prices/keeper/update_price_whitebox_test.go index 85f816ac79..952805044e 100644 --- a/protocol/x/prices/keeper/update_price_whitebox_test.go +++ b/protocol/x/prices/keeper/update_price_whitebox_test.go @@ -9,15 +9,10 @@ import ( ) const ( - fiveBillionAndFiveMillion = constants.FiveBillion + constants.FiveMillion - fiveBillionMinusFiveMillionAndOne = constants.FiveBillion - constants.FiveMillion - 1 - fiveBillionAndTenMillion = constants.FiveBillion + 2*constants.FiveMillion + fiveBillionAndFiveMillion = constants.FiveBillion + constants.FiveMillion - testPriceValidUpdate = fiveBillionAndFiveMillion - testPriceLargeValidUpdate = fiveBillionAndTenMillion - testPriceDoesNotMeetMinPriceChange = constants.FiveBillion + 2 - testPriceCrossesOraclePrice = fiveBillionMinusFiveMillionAndOne - testPriceCrossesAndDoesNotMeetMinChange = constants.FiveBillion - 1 + testPriceValidUpdate = fiveBillionAndFiveMillion + testPriceDoesNotMeetMinPriceChange = constants.FiveBillion + 2 ) var ( @@ -29,308 +24,14 @@ var ( func TestShouldProposePrice(t *testing.T) { tests := map[string]struct { - proposalPrice uint64 - indexPrice uint64 - historicalSmoothedPrices []uint64 - expectShouldPropose bool - expectReasons []proposeCancellationReason + proposalPrice uint64 + expectShouldPropose bool + expectReasons []proposeCancellationReason }{ - "Should not propose: proposal price is smoothed price, crosses index price": { - proposalPrice: testPriceCrossesOraclePrice, - indexPrice: testPriceLargeValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceCrossesOraclePrice, - testPriceValidUpdate, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - // These are both true because the proposed price is the most recent smoothed price. - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: proposal price is smoothed price, does not meet min price change": { - proposalPrice: testPriceDoesNotMeetMinPriceChange, - indexPrice: testPriceLargeValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceDoesNotMeetMinPriceChange, - testPriceValidUpdate, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - }, - }, - "Should not propose: proposal price is index price, does not meet min price change": { - proposalPrice: testPriceDoesNotMeetMinPriceChange, - indexPrice: testPriceDoesNotMeetMinPriceChange, - historicalSmoothedPrices: []uint64{ - testPriceLargeValidUpdate, - testPriceValidUpdate, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - }, - }, - "Should not propose: a historical smoothed price crosses index price": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceDoesNotMeetMinPriceChange, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: multiple historical smoothed prices cross index price": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceCrossesOraclePrice, - testPriceCrossesOraclePrice, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: a historical smoothed price does not meet min price change": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceDoesNotMeetMinPriceChange, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: multiple historical smoothed prices do not meet min price change": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceDoesNotMeetMinPriceChange, - testPriceDoesNotMeetMinPriceChange, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: historical smoothed price crosses and does not meet min price change": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceCrossesAndDoesNotMeetMinChange, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: proposal price crosses and does not meet min price change": { - proposalPrice: testPriceCrossesAndDoesNotMeetMinChange, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceLargeValidUpdate, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - }, - }, - "Should not propose: multiple historical smoothed prices issues": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceDoesNotMeetMinPriceChange, - testPriceCrossesOraclePrice, - }, - expectShouldPropose: false, - expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, - { - Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, - Value: false, - }, - }, - }, - "Should not propose: multiple issues": { - proposalPrice: testPriceDoesNotMeetMinPriceChange, - indexPrice: testPriceValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceDoesNotMeetMinPriceChange, - testPriceCrossesOraclePrice, - }, + "Should not propose: proposal price does not meet min price change": { + proposalPrice: testPriceDoesNotMeetMinPriceChange, expectShouldPropose: false, expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: true, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: true, - }, { Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, Value: true, @@ -338,27 +39,9 @@ func TestShouldProposePrice(t *testing.T) { }, }, "Should propose": { - proposalPrice: testPriceValidUpdate, - indexPrice: testPriceLargeValidUpdate, - historicalSmoothedPrices: []uint64{ - testPriceValidUpdate, - testPriceLargeValidUpdate, - testPriceValidUpdate, - }, + proposalPrice: testPriceValidUpdate, expectShouldPropose: true, expectReasons: []proposeCancellationReason{ - { - Reason: metrics.RecentSmoothedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.ProposedPriceCrossesOraclePrice, - Value: false, - }, - { - Reason: metrics.RecentSmoothedPriceDoesNotMeetMinPriceChange, - Value: false, - }, { Reason: metrics.ProposedPriceDoesNotMeetMinPriceChange, Value: false, @@ -371,8 +54,6 @@ func TestShouldProposePrice(t *testing.T) { actualShouldPropose, actualReasons := shouldProposePrice( tc.proposalPrice, testMarketParamPrice, - tc.indexPrice, - tc.historicalSmoothedPrices, ) require.Equal(t, tc.expectShouldPropose, actualShouldPropose) require.Equal(t, tc.expectReasons, actualReasons) diff --git a/protocol/x/prices/keeper/util.go b/protocol/x/prices/keeper/util.go index 459e951462..ba23e77405 100644 --- a/protocol/x/prices/keeper/util.go +++ b/protocol/x/prices/keeper/util.go @@ -9,16 +9,6 @@ import ( "github.com/dydxprotocol/v4-chain/protocol/x/prices/types" ) -// getProposalPrice returns the proposed price update for the next block, which is either the smoothed price or the -// index price - whichever is closer to the current market price. In cases where the smoothed price and the index price -// are equidistant from the current market price, the smoothed price is chosen. -func getProposalPrice(smoothedPrice uint64, indexPrice uint64, marketPrice uint64) uint64 { - if lib.AbsDiffUint64(smoothedPrice, marketPrice) > lib.AbsDiffUint64(indexPrice, marketPrice) { - return indexPrice - } - return smoothedPrice -} - // isAboveRequiredMinPriceChange returns true if the new price meets the required min price change // for the market. Otherwise, returns false. func isAboveRequiredMinPriceChange(marketParamPrice types.MarketParamPrice, newPrice uint64) bool { diff --git a/protocol/x/prices/keeper/util_test.go b/protocol/x/prices/keeper/util_test.go index 6f82cab19d..c9cc826fe4 100644 --- a/protocol/x/prices/keeper/util_test.go +++ b/protocol/x/prices/keeper/util_test.go @@ -15,82 +15,6 @@ const ( maxUint32 = uint32(4_294_967_295) // 2 ^ 32 - 1 ) -func TestGetProposalPrice(t *testing.T) { - tests := map[string]struct { - smoothedPrice uint64 - indexPrice uint64 - marketPrice uint64 - expectedPrice uint64 - }{ - "smoothedPrice: marketPrice < smoothedPrice < indexPrice": { - smoothedPrice: uint64(1_000_000), - indexPrice: uint64(1_000_005), - marketPrice: uint64(900_000), - expectedPrice: uint64(1_000_000), - }, - "smoothedPrice: indexPrice < smoothedPrice < marketPrice": { - smoothedPrice: uint64(800_500), - indexPrice: uint64(800_000), - marketPrice: uint64(900_000), - expectedPrice: uint64(800_500), - }, - "indexPrice: marketPrice < indexPrice < smoothedPrice": { - smoothedPrice: uint64(1_000_000), - indexPrice: uint64(900_000), - marketPrice: uint64(800_000), - expectedPrice: uint64(900_000), - }, - "indexPrice: smoothedPrice < indexPrice < marketPrice": { - smoothedPrice: uint64(800_000), - indexPrice: uint64(900_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(900_000), - }, - "indexPrice: smoothedPrice << marketPrice < indexPrice": { - smoothedPrice: uint64(500_000), - indexPrice: uint64(1_100_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(1_100_000), - }, - "smoothedPrice: smoothedPrice < marketPrice << indexPrice": { - smoothedPrice: uint64(900_000), - indexPrice: uint64(1_500_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(900_000), - }, - "smoothedPrice: smoothedPrice < marketPrice < indexPrice": { - smoothedPrice: uint64(900_000), - indexPrice: uint64(1_100_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(900_000), - }, - "indexPrice: indexPrice < marketPrice << smoothedPrice": { - smoothedPrice: uint64(1_500_000), - indexPrice: uint64(900_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(900_000), - }, - "smoothedPrice: indexPrice << marketPrice < smoothedPrice": { - smoothedPrice: uint64(1_100_000), - indexPrice: uint64(500_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(1_100_000), - }, - "smoothedPrice: indexPrice < marketPrice < smoothedPrice": { - smoothedPrice: uint64(1_100_000), - indexPrice: uint64(900_000), - marketPrice: uint64(1_000_000), - expectedPrice: uint64(1_100_000), - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - price := getProposalPrice(tc.smoothedPrice, tc.indexPrice, tc.marketPrice) - require.Equal(t, tc.expectedPrice, price) - }) - } -} - func TestGetMinPriceChangeAmountForMarket(t *testing.T) { tests := map[string]struct { // Setup. diff --git a/protocol/x/prices/keeper/validate_market_price_updates_test.go b/protocol/x/prices/keeper/validate_market_price_updates_test.go index 10b6b92aca..a89998d90e 100644 --- a/protocol/x/prices/keeper/validate_market_price_updates_test.go +++ b/protocol/x/prices/keeper/validate_market_price_updates_test.go @@ -122,7 +122,7 @@ func TestPerformStatefulPriceUpdateValidation_Valid(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, k) @@ -207,7 +207,7 @@ func TestPerformStatefulPriceUpdateValidation_SkipNonDeterministicCheck_Valid(t for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, k) @@ -340,7 +340,7 @@ func TestPerformStatefulPriceUpdateValidation_Error(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, _, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, k) @@ -411,13 +411,10 @@ func TestGetMarketsMissingFromPriceUpdates(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { // Setup. - ctx, k, _, indexPriceCache, marketToSmoothedPrices, mockTimeProvider := keepertest.PricesKeepers(t) + ctx, k, _, indexPriceCache, mockTimeProvider := keepertest.PricesKeepers(t) mockTimeProvider.On("Now").Return(constants.TimeT) keepertest.CreateTestMarkets(t, ctx, k) - for market, price := range tc.smoothedIndexPrices { - marketToSmoothedPrices.PushSmoothedPrice(market, price) - } indexPriceCache.UpdatePrices(tc.indexPrices) // Run. diff --git a/protocol/x/prices/module_test.go b/protocol/x/prices/module_test.go index dde0745bdd..6dc781c82f 100644 --- a/protocol/x/prices/module_test.go +++ b/protocol/x/prices/module_test.go @@ -49,7 +49,7 @@ func createAppModule(t *testing.T) prices.AppModule { func createAppModuleWithKeeper(t *testing.T) (prices.AppModule, *prices_keeper.Keeper, sdk.Context) { appCodec := codec.NewProtoCodec(module.InterfaceRegistry) - ctx, keeper, _, _, _, mockTimeProvider := keeper.PricesKeepers(t) + ctx, keeper, _, _, mockTimeProvider := keeper.PricesKeepers(t) // Mock the time provider response for market creation. mockTimeProvider.On("Now").Return(constants.TimeT) diff --git a/protocol/x/prices/types/types.go b/protocol/x/prices/types/types.go index 41fa5a296c..2b7dd2e80d 100644 --- a/protocol/x/prices/types/types.go +++ b/protocol/x/prices/types/types.go @@ -40,11 +40,6 @@ type PricesKeeper interface { performNonDeterministicValidation bool, ) error - // Proposal related. - UpdateSmoothedPrices( - ctx sdk.Context, - linearInterpolateFunc func(v0 uint64, v1 uint64, ppm uint32) (uint64, error), - ) error GetValidMarketPriceUpdates( ctx sdk.Context, ) *MsgUpdateMarketPrices