diff --git a/protocol/app/app.go b/protocol/app/app.go index 2395c040da..d33bdfe888 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -1184,6 +1184,7 @@ func New( app.PricesKeeper, app.SendingKeeper, app.SubaccountsKeeper, + app.IndexerEventManager, []string{ lib.GovModuleAddress.String(), delaymsgmoduletypes.ModuleAddress.String(), diff --git a/protocol/indexer/events/upsert_vault.go b/protocol/indexer/events/upsert_vault.go index b0e7ac8756..781347f564 100644 --- a/protocol/indexer/events/upsert_vault.go +++ b/protocol/indexer/events/upsert_vault.go @@ -2,7 +2,6 @@ package events import ( v1 "github.com/dydxprotocol/v4-chain/protocol/indexer/protocol/v1" - clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" ) @@ -10,12 +9,12 @@ import ( // representing an create / update of a vault. func NewUpsertVaultEvent( vaultAddress string, - clobPairId clobtypes.ClobPairId, + clobPairId uint32, status types.VaultStatus, ) *UpsertVaultEventV1 { return &UpsertVaultEventV1{ Address: vaultAddress, - ClobPairId: uint32(clobPairId), + ClobPairId: clobPairId, Status: v1.VaultStatusToIndexerVaultStatus(status), } } diff --git a/protocol/testutil/keeper/vault.go b/protocol/testutil/keeper/vault.go index 1090b05fad..3170f71306 100644 --- a/protocol/testutil/keeper/vault.go +++ b/protocol/testutil/keeper/vault.go @@ -4,8 +4,10 @@ import ( "testing" dbm "github.com/cosmos/cosmos-db" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" "github.com/dydxprotocol/v4-chain/protocol/lib" delaymsgtypes "github.com/dydxprotocol/v4-chain/protocol/x/delaymsg/types" + "github.com/stretchr/testify/mock" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" @@ -50,6 +52,13 @@ func createVaultKeeper( storeKey := storetypes.NewKVStoreKey(types.StoreKey) stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + mockMsgSender := &mocks.IndexerMessageSender{} + mockMsgSender.On("Enabled").Return(true) + mockMsgSender.On("SendOnchainData", mock.Anything).Return() + mockMsgSender.On("SendOffchainData", mock.Anything).Return() + + mockIndexerEventsManager := indexer_manager.NewIndexerEventManager(mockMsgSender, transientStoreKey, true) + k := keeper.NewKeeper( cdc, storeKey, @@ -59,6 +68,7 @@ func createVaultKeeper( &mocks.PricesKeeper{}, &mocks.SendingKeeper{}, &mocks.SubaccountsKeeper{}, + mockIndexerEventsManager, []string{ lib.GovModuleAddress.String(), delaymsgtypes.ModuleAddress.String(), diff --git a/protocol/x/vault/keeper/keeper.go b/protocol/x/vault/keeper/keeper.go index 48148a525f..35579dc4af 100644 --- a/protocol/x/vault/keeper/keeper.go +++ b/protocol/x/vault/keeper/keeper.go @@ -7,21 +7,23 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" "github.com/dydxprotocol/v4-chain/protocol/lib" "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" ) type ( Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - clobKeeper types.ClobKeeper - delayMsgKeeper types.DelayMsgKeeper - perpetualsKeeper types.PerpetualsKeeper - pricesKeeper types.PricesKeeper - sendingKeeper types.SendingKeeper - subaccountsKeeper types.SubaccountsKeeper - authorities map[string]struct{} + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + clobKeeper types.ClobKeeper + delayMsgKeeper types.DelayMsgKeeper + perpetualsKeeper types.PerpetualsKeeper + pricesKeeper types.PricesKeeper + sendingKeeper types.SendingKeeper + subaccountsKeeper types.SubaccountsKeeper + indexerEventManager indexer_manager.IndexerEventManager + authorities map[string]struct{} } ) @@ -34,18 +36,20 @@ func NewKeeper( pricesKeeper types.PricesKeeper, sendingKeeper types.SendingKeeper, subaccountsKeeper types.SubaccountsKeeper, + indexerEventManager indexer_manager.IndexerEventManager, authorities []string, ) *Keeper { return &Keeper{ - cdc: cdc, - storeKey: storeKey, - clobKeeper: clobKeeper, - delayMsgKeeper: delayMsgKeeper, - perpetualsKeeper: perpetualsKeeper, - pricesKeeper: pricesKeeper, - sendingKeeper: sendingKeeper, - subaccountsKeeper: subaccountsKeeper, - authorities: lib.UniqueSliceToSet(authorities), + cdc: cdc, + storeKey: storeKey, + clobKeeper: clobKeeper, + delayMsgKeeper: delayMsgKeeper, + perpetualsKeeper: perpetualsKeeper, + pricesKeeper: pricesKeeper, + sendingKeeper: sendingKeeper, + subaccountsKeeper: subaccountsKeeper, + indexerEventManager: indexerEventManager, + authorities: lib.UniqueSliceToSet(authorities), } } @@ -58,4 +62,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With(log.ModuleKey, fmt.Sprintf("x/%s", types.ModuleName)) } +func (k Keeper) GetIndexerEventManager() indexer_manager.IndexerEventManager { + return k.indexerEventManager +} + func (k Keeper) InitializeForGenesis(ctx sdk.Context) {} diff --git a/protocol/x/vault/keeper/orders_test.go b/protocol/x/vault/keeper/orders_test.go index 6b20c325fe..4e6d96af8b 100644 --- a/protocol/x/vault/keeper/orders_test.go +++ b/protocol/x/vault/keeper/orders_test.go @@ -168,6 +168,8 @@ func TestRefreshAllVaultOrders(t *testing.T) { ) require.NoError(t, err) } + // Clear events from setting vault params + tApp.App.IndexerEventManager.ClearEvents(ctx) // Check that there's no stateful orders yet. allStatefulOrders := tApp.App.ClobKeeper.GetAllStatefulOrders(ctx) diff --git a/protocol/x/vault/keeper/params.go b/protocol/x/vault/keeper/params.go index 4bd7783945..3e6273138b 100644 --- a/protocol/x/vault/keeper/params.go +++ b/protocol/x/vault/keeper/params.go @@ -4,6 +4,8 @@ import ( "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" ) @@ -70,6 +72,19 @@ func (k Keeper) SetVaultParams( store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte(types.VaultParamsKeyPrefix)) store.Set(vaultId.ToStateKey(), b) + k.GetIndexerEventManager().AddTxnEvent( + ctx, + indexerevents.SubtypeUpsertVault, + indexerevents.UpsertVaultEventVersion, + indexer_manager.GetBytes( + indexerevents.NewUpsertVaultEvent( + vaultId.ToModuleAccountAddress(), + vaultId.Number, + vaultParams.Status, + ), + ), + ) + return nil } diff --git a/protocol/x/vault/keeper/params_test.go b/protocol/x/vault/keeper/params_test.go index 3d4e8a5c0f..97783d1d4c 100644 --- a/protocol/x/vault/keeper/params_test.go +++ b/protocol/x/vault/keeper/params_test.go @@ -3,9 +3,17 @@ package keeper_test import ( "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gogoproto/proto" "github.com/dydxprotocol/v4-chain/protocol/dtypes" + "github.com/dydxprotocol/v4-chain/protocol/indexer" + indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" + "github.com/dydxprotocol/v4-chain/protocol/indexer/msgsender" + v1 "github.com/dydxprotocol/v4-chain/protocol/indexer/protocol/v1" testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" + "github.com/dydxprotocol/v4-chain/protocol/x/vault/keeper" "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" "github.com/stretchr/testify/require" ) @@ -54,16 +62,32 @@ func TestGetSetVaultParams(t *testing.T) { vaultId types.VaultId // Vault params to set. vaultParams *types.VaultParams + // Expected on-chain indexer events + expectedIndexerEvents []*indexerevents.UpsertVaultEventV1 // Expected error. expectedErr error }{ "Success - Vault Clob 0": { vaultId: constants.Vault_Clob0, vaultParams: &constants.VaultParams, + expectedIndexerEvents: []*indexerevents.UpsertVaultEventV1{ + { + Address: constants.Vault_Clob0.ToModuleAccountAddress(), + ClobPairId: constants.Vault_Clob0.Number, + Status: v1.VaultStatusToIndexerVaultStatus(constants.VaultParams.Status), + }, + }, }, "Success - Vault Clob 1": { vaultId: constants.Vault_Clob1, vaultParams: &constants.VaultParams, + expectedIndexerEvents: []*indexerevents.UpsertVaultEventV1{ + { + Address: constants.Vault_Clob1.ToModuleAccountAddress(), + ClobPairId: constants.Vault_Clob1.Number, + Status: v1.VaultStatusToIndexerVaultStatus(constants.VaultParams.Status), + }, + }, }, "Success - Non-existent Vault Params": { vaultId: constants.Vault_Clob1, @@ -88,7 +112,11 @@ func TestGetSetVaultParams(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - tApp := testapp.NewTestAppBuilder(t).Build() + msgSender := msgsender.NewIndexerMessageSenderInMemoryCollector() + appOpts := map[string]interface{}{ + indexer.MsgSenderInstanceForTest: msgSender, + } + tApp := testapp.NewTestAppBuilder(t).WithAppOptions(appOpts).Build() ctx := tApp.InitChain() k := tApp.App.VaultKeeper @@ -109,6 +137,11 @@ func TestGetSetVaultParams(t *testing.T) { require.True(t, exists) require.Equal(t, *tc.vaultParams, p) } + + if tc.expectedErr == nil && tc.vaultParams != nil { + upsertVaultEventsInBlock := getUpsertVaultEventsFromIndexerBlock(ctx, &k) + require.ElementsMatch(t, tc.expectedIndexerEvents, upsertVaultEventsInBlock) + } }) } } @@ -197,3 +230,25 @@ func TestGetSetOperatorParams(t *testing.T) { require.Error(t, err) require.Equal(t, newParams, k.GetOperatorParams(ctx)) } + +func getUpsertVaultEventsFromIndexerBlock( + ctx sdk.Context, + keeper *keeper.Keeper, +) []*indexerevents.UpsertVaultEventV1 { + block := keeper.GetIndexerEventManager().ProduceBlock(ctx) + var upsertVaultEvents []*indexerevents.UpsertVaultEventV1 + for _, event := range block.Events { + if event.Subtype != indexerevents.SubtypeUpsertVault { + continue + } + if _, ok := event.OrderingWithinBlock.(*indexer_manager.IndexerTendermintEvent_TransactionIndex); ok { + var upsertVaultEvent indexerevents.UpsertVaultEventV1 + err := proto.Unmarshal(event.DataBytes, &upsertVaultEvent) + if err != nil { + panic(err) + } + upsertVaultEvents = append(upsertVaultEvents, &upsertVaultEvent) + } + } + return upsertVaultEvents +}