Skip to content

Commit

Permalink
[CT-856] Add order replacement to fix vault causing orderbook flicker…
Browse files Browse the repository at this point in the history
…ing (#1602)
  • Loading branch information
chenyaoy committed Jun 20, 2024
1 parent f9c62f8 commit d50c3a1
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 56 deletions.
1 change: 1 addition & 0 deletions protocol/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,7 @@ func New(
app.PerpetualsKeeper,
app.PricesKeeper,
app.SubaccountsKeeper,
app.IndexerEventManager,
[]string{
lib.GovModuleAddress.String(),
delaymsgmoduletypes.ModuleAddress.String(),
Expand Down
17 changes: 17 additions & 0 deletions protocol/indexer/events/stateful_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ func NewLongTermOrderPlacementEvent(
}
}

func NewLongTermOrderReplacementEvent(
oldOrderId clobtypes.OrderId,
order clobtypes.Order,
) *StatefulOrderEventV1 {
oldIndexerOrderId := v1.OrderIdToIndexerOrderId(oldOrderId)
indexerOrder := v1.OrderToIndexerOrder(order)
orderReplace := StatefulOrderEventV1_LongTermOrderReplacementV1{
OldOrderId: &oldIndexerOrderId,
Order: &indexerOrder,
}
return &StatefulOrderEventV1{
Event: &StatefulOrderEventV1_OrderReplacement{
OrderReplacement: &orderReplace,
},
}
}

func NewStatefulOrderRemovalEvent(
removedOrderId clobtypes.OrderId,
reason sharedtypes.OrderRemovalReason,
Expand Down
8 changes: 4 additions & 4 deletions protocol/mocks/ClobKeeper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions protocol/testutil/keeper/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func createVaultKeeper(
&mocks.PerpetualsKeeper{},
&mocks.PricesKeeper{},
&mocks.SubaccountsKeeper{},
&mocks.IndexerEventManager{},
[]string{
lib.GovModuleAddress.String(),
delaymsgtypes.ModuleAddress.String(),
Expand Down
25 changes: 14 additions & 11 deletions protocol/x/clob/keeper/msg_server_cancel_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (k msgServer) CancelOrder(
) (resp *types.MsgCancelOrderResponse, err error) {
ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName)

if err := k.Keeper.HandleMsgCancelOrder(ctx, msg); err != nil {
if err := k.Keeper.HandleMsgCancelOrder(ctx, msg, false); err != nil {
return nil, err
}

Expand All @@ -37,6 +37,7 @@ func (k msgServer) CancelOrder(
func (k Keeper) HandleMsgCancelOrder(
ctx sdk.Context,
msg *types.MsgCancelOrder,
isInternalOrder bool,
) (err error) {
lib.AssertDeliverTxMode(ctx)

Expand Down Expand Up @@ -110,17 +111,19 @@ func (k Keeper) HandleMsgCancelOrder(
k.MustSetProcessProposerMatchesEvents(ctx, processProposerMatchesEvents)

// 4. Add the relevant on-chain Indexer event for the cancellation.
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewStatefulOrderRemovalEvent(
msg.OrderId,
indexershared.OrderRemovalReason_ORDER_REMOVAL_REASON_USER_CANCELED,
if !isInternalOrder { // vault order indexer event logic is handled elsewhere
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewStatefulOrderRemovalEvent(
msg.OrderId,
indexershared.OrderRemovalReason_ORDER_REMOVAL_REASON_USER_CANCELED,
),
),
),
)
)
}

return nil
}
40 changes: 22 additions & 18 deletions protocol/x/clob/keeper/msg_server_place_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,31 +114,35 @@ func (k Keeper) HandleMsgPlaceOrder(

// 4. Emit the new order placement indexer event.
if order.IsConditionalOrder() {
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewConditionalOrderPlacementEvent(
order,
if !isInternalOrder { // vault order indexer event logic is handled elsewhere
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewConditionalOrderPlacementEvent(
order,
),
),
),
)
)
}
processProposerMatchesEvents.PlacedConditionalOrderIds = append(
processProposerMatchesEvents.PlacedConditionalOrderIds,
order.OrderId,
)
} else {
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewLongTermOrderPlacementEvent(
order,
if !isInternalOrder { // vault order indexer event logic is handled elsewhere
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewLongTermOrderPlacementEvent(
order,
),
),
),
)
)
}
processProposerMatchesEvents.PlacedLongTermOrderIds = append(
processProposerMatchesEvents.PlacedLongTermOrderIds,
order.OrderId,
Expand Down
1 change: 1 addition & 0 deletions protocol/x/clob/types/clob_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ClobKeeper interface {
HandleMsgCancelOrder(
ctx sdk.Context,
msg *MsgCancelOrder,
isInternalOrder bool,
) (err error)
HandleMsgPlaceOrder(
ctx sdk.Context,
Expand Down
36 changes: 22 additions & 14 deletions protocol/x/vault/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ 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
perpetualsKeeper types.PerpetualsKeeper
pricesKeeper types.PricesKeeper
subaccountsKeeper types.SubaccountsKeeper
authorities map[string]struct{}
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
clobKeeper types.ClobKeeper
perpetualsKeeper types.PerpetualsKeeper
pricesKeeper types.PricesKeeper
subaccountsKeeper types.SubaccountsKeeper
indexerEventManager indexer_manager.IndexerEventManager
authorities map[string]struct{}
}
)

Expand All @@ -30,19 +32,25 @@ func NewKeeper(
perpetualsKeeper types.PerpetualsKeeper,
pricesKeeper types.PricesKeeper,
subaccountsKeeper types.SubaccountsKeeper,
indexerEventManager indexer_manager.IndexerEventManager,
authorities []string,
) *Keeper {
return &Keeper{
cdc: cdc,
storeKey: storeKey,
clobKeeper: clobKeeper,
perpetualsKeeper: perpetualsKeeper,
pricesKeeper: pricesKeeper,
subaccountsKeeper: subaccountsKeeper,
authorities: lib.UniqueSliceToSet(authorities),
cdc: cdc,
storeKey: storeKey,
clobKeeper: clobKeeper,
perpetualsKeeper: perpetualsKeeper,
pricesKeeper: pricesKeeper,
subaccountsKeeper: subaccountsKeeper,
indexerEventManager: indexerEventManager,
authorities: lib.UniqueSliceToSet(authorities),
}
}

func (k Keeper) GetIndexerEventManager() indexer_manager.IndexerEventManager {
return k.indexerEventManager
}

func (k Keeper) HasAuthority(authority string) bool {
_, ok := k.authorities[authority]
return ok
Expand Down
39 changes: 35 additions & 4 deletions protocol/x/vault/keeper/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (

errorsmod "cosmossdk.io/errors"
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/lib"
"github.com/dydxprotocol/v4-chain/protocol/lib/log"
"github.com/dydxprotocol/v4-chain/protocol/lib/metrics"
Expand All @@ -24,6 +26,7 @@ func (k Keeper) RefreshAllVaultOrders(ctx sdk.Context) {
defer totalSharesIterator.Close()
for ; totalSharesIterator.Valid(); totalSharesIterator.Next() {
vaultId, err := types.GetVaultIdFromStateKey(totalSharesIterator.Key())

if err != nil {
log.ErrorLogWithError(ctx, "Failed to get vault ID from state key", err)
continue
Expand Down Expand Up @@ -84,7 +87,7 @@ func (k Keeper) RefreshVaultClobOrders(ctx sdk.Context, vaultId types.VaultId) (
err := k.clobKeeper.HandleMsgCancelOrder(ctx, clobtypes.NewMsgCancelOrderStateful(
order.OrderId,
uint32(ctx.BlockTime().Unix())+orderExpirationSeconds,
))
), true)
if err != nil {
log.ErrorLogWithError(ctx, "Failed to cancel order", err, "order", order, "vaultId", vaultId)
}
Expand All @@ -94,24 +97,52 @@ func (k Keeper) RefreshVaultClobOrders(ctx sdk.Context, vaultId types.VaultId) (
)
}
}

// Place new CLOB orders.
ordersToPlace, err := k.GetVaultClobOrders(ctx, vaultId)
if err != nil {
log.ErrorLogWithError(ctx, "Failed to get vault clob orders to place", err, "vaultId", vaultId)
return err
}
for _, order := range ordersToPlace {

for i, order := range ordersToPlace {
err := k.PlaceVaultClobOrder(ctx, order)
if err != nil {
log.ErrorLogWithError(ctx, "Failed to place order", err, "order", order, "vaultId", vaultId)
}

vaultId.IncrCounterWithLabels(
metrics.VaultPlaceOrder,
metrics.GetLabelForBoolValue(metrics.Success, err == nil),
)
}

// Send indexer messages. We expect ordersToCancel and ordersToPlace to have the same length
// and the order to place at each index to be a replacement of the order to cancel at the same index.
replacedOrder := ordersToCancel[i]
if replacedOrder == nil {
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewLongTermOrderPlacementEvent(
*order,
),
),
)
} else {
k.GetIndexerEventManager().AddTxnEvent(
ctx,
indexerevents.SubtypeStatefulOrder,
indexerevents.StatefulOrderEventVersion,
indexer_manager.GetBytes(
indexerevents.NewLongTermOrderReplacementEvent(
replacedOrder.OrderId,
*order,
),
),
)
}
}
return nil
}

Expand Down
Loading

0 comments on commit d50c3a1

Please sign in to comment.