diff --git a/protocol/x/prices/keeper/currency_pair_id_cache.go b/protocol/x/prices/keeper/currency_pair_id_cache.go index f188260bc90..018dcf5f70d 100644 --- a/protocol/x/prices/keeper/currency_pair_id_cache.go +++ b/protocol/x/prices/keeper/currency_pair_id_cache.go @@ -33,3 +33,12 @@ func (c *CurrencyPairIDCache) GetIDForCurrencyPair(currencyPair string) (uint64, id, found := c.currencyPairToID[currencyPair] return id, found } + +// Remove removes the currency-pair (by ID) from the cache +func (c *CurrencyPairIDCache) Remove(id uint64) { + currencyPair, found := c.idToCurrencyPair[id] + if found { + delete(c.idToCurrencyPair, id) + delete(c.currencyPairToID, currencyPair) + } +} diff --git a/protocol/x/prices/keeper/market_param.go b/protocol/x/prices/keeper/market_param.go index be3eaab8101..304ed827dcf 100644 --- a/protocol/x/prices/keeper/market_param.go +++ b/protocol/x/prices/keeper/market_param.go @@ -5,6 +5,7 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/dydxprotocol/v4-chain/protocol/daemons/pricefeed/metrics" + "github.com/dydxprotocol/v4-chain/protocol/lib/slinky" "cosmossdk.io/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -48,6 +49,20 @@ func (k Keeper) ModifyMarketParam( marketParamStore := k.getMarketParamStore(ctx) b := k.cdc.MustMarshal(&updatedMarketParam) marketParamStore.Set(lib.Uint32ToKey(updatedMarketParam.Id), b) + + // if the market pair has been changed, we need to update the in-memory market pair cache + if existingParam.Pair != updatedMarketParam.Pair { + // remove the old cache entry + k.currencyPairIDCache.Remove(uint64(existingParam.Id)) + + // add the new cache entry + cp, err := slinky.MarketPairToCurrencyPair(updatedMarketParam.Pair) + if err == nil { + k.currencyPairIDCache.AddCurrencyPair(uint64(updatedMarketParam.Id), cp.String()) + } else { + k.Logger(ctx).Error("failed to add currency pair to cache", "pair", updatedMarketParam.Pair) + } + } // Generate indexer event. k.GetIndexerEventManager().AddTxnEvent( diff --git a/protocol/x/prices/keeper/market_param_test.go b/protocol/x/prices/keeper/market_param_test.go index 709a82a438a..5bd44388e8a 100644 --- a/protocol/x/prices/keeper/market_param_test.go +++ b/protocol/x/prices/keeper/market_param_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/dydxprotocol/v4-chain/protocol/daemons/pricefeed/metrics" + "github.com/dydxprotocol/v4-chain/protocol/lib/slinky" errorsmod "cosmossdk.io/errors" @@ -45,6 +46,62 @@ func TestModifyMarketParam(t *testing.T) { } } +func TestModifyMarketParamUpdatesCache(t *testing.T) { + ctx, keeper, _, _, _, mockTimeProvider := keepertest.PricesKeepers(t) + mockTimeProvider.On("Now").Return(constants.TimeT) + ctx = ctx.WithTxBytes(constants.TestTxBytes) + + id := uint32(1) + oldParam := types.MarketParam{ + Id: id, + Pair: "foo-bar", + MinExchanges: uint32(2), + Exponent: 8, + MinPriceChangePpm: uint32(50), + ExchangeConfigJson: `{"id":"1"}`, + } + mp, err := keeper.CreateMarket(ctx, oldParam, types.MarketPrice{ + Id: id, + Exponent: 8, + Price: 1, + }) + require.NoError(t, err) + + // check that the existing entry exists + cp, err := slinky.MarketPairToCurrencyPair(mp.Pair) + require.NoError(t, err) + + // check that the existing entry exists + cpID, found := keeper.GetIDForCurrencyPair(ctx, cp) + require.True(t, found) + require.Equal(t, uint64(id), cpID) + + // modify the market param + newParam, err := keeper.ModifyMarketParam( + ctx, + types.MarketParam{ + Id: id, + Pair: "bar-foo", + MinExchanges: uint32(2), + Exponent: 8, + MinPriceChangePpm: uint32(50), + ExchangeConfigJson: `{"id":"1"}`, + }, + ) + require.NoError(t, err) + + // check that the existing entry does not exist + _, found = keeper.GetIDForCurrencyPair(ctx, cp) + require.False(t, found) + + // check that the new entry exists + cp, err = slinky.MarketPairToCurrencyPair(newParam.Pair) + require.NoError(t, err) + cpID, found = keeper.GetIDForCurrencyPair(ctx, cp) + require.True(t, found) + require.Equal(t, uint64(id), cpID) +} + func TestModifyMarketParam_Errors(t *testing.T) { validExchangeConfigJson := `{"exchanges":[{"exchangeName":"Binance","ticker":"BTCUSDT"}]}` tests := map[string]struct {