Skip to content

Commit

Permalink
[TRA-209] Skip various order placement logic for vault orders (#1332)
Browse files Browse the repository at this point in the history
* Skip various order placement logic for vault orders
  • Loading branch information
tqin7 authored Apr 4, 2024
1 parent b5ed196 commit 8e3ac79
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 88 deletions.
22 changes: 11 additions & 11 deletions protocol/mocks/ClobKeeper.go

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

2 changes: 1 addition & 1 deletion protocol/x/clob/ante/clob.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (cd ClobDecorator) AnteHandle(

case *types.MsgPlaceOrder:
if msg.Order.OrderId.IsStatefulOrder() {
err = cd.clobKeeper.PlaceStatefulOrder(ctx, msg)
err = cd.clobKeeper.PlaceStatefulOrder(ctx, msg, false)

log.DebugLog(ctx, "Received new stateful order",
log.Tx, cometbftlog.NewLazySprintf("%X", tmhash.Sum(ctx.TxBytes())),
Expand Down
4 changes: 4 additions & 0 deletions protocol/x/clob/ante/clob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func TestClobDecorator_MsgPlaceOrder(t *testing.T) {
mck.On("PlaceStatefulOrder",
ctx,
constants.Msg_PlaceOrder_LongTerm,
false,
).Return(
nil,
)
Expand All @@ -113,6 +114,7 @@ func TestClobDecorator_MsgPlaceOrder(t *testing.T) {
mck.On("PlaceStatefulOrder",
ctx,
constants.Msg_PlaceOrder_Conditional,
false,
).Return(
nil,
)
Expand Down Expand Up @@ -155,6 +157,7 @@ func TestClobDecorator_MsgPlaceOrder(t *testing.T) {
mck.On("PlaceStatefulOrder",
ctx,
constants.Msg_PlaceOrder_LongTerm,
false,
).Return(
nil,
)
Expand Down Expand Up @@ -183,6 +186,7 @@ func TestClobDecorator_MsgPlaceOrder(t *testing.T) {
mck.On("PlaceStatefulOrder",
ctx,
constants.Msg_PlaceOrder_LongTerm,
false,
).Return(
clobtypes.ErrGoodTilBlockTimeExceedsStatefulOrderTimeWindow,
)
Expand Down
56 changes: 30 additions & 26 deletions protocol/x/clob/keeper/msg_server_place_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (k msgServer) PlaceOrder(goCtx context.Context, msg *types.MsgPlaceOrder) (
) {
ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName)

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

Expand All @@ -36,9 +36,11 @@ func (k msgServer) PlaceOrder(goCtx context.Context, msg *types.MsgPlaceOrder) (
// 1. persisting the placement on chain.
// 2. updating ProcessProposerMatchesEvents with the new stateful order placement.
// 3. adding order placement on-chain indexer event.
// Various logs, metrics, and validations are skipped for orders internal to the protocol.
func (k Keeper) HandleMsgPlaceOrder(
ctx sdk.Context,
msg *types.MsgPlaceOrder,
isInternalOrder bool,
) (err error) {
lib.AssertDeliverTxMode(ctx)

Expand All @@ -52,31 +54,33 @@ func (k Keeper) HandleMsgPlaceOrder(
log.Msg, msg,
)

defer func() {
metrics.IncrSuccessOrErrorCounter(
err,
types.ModuleName,
metrics.PlaceOrder,
metrics.DeliverTx,
msg.Order.GetOrderLabels()...,
)
if err != nil {
if errors.Is(err, types.ErrStatefulOrderCollateralizationCheckFailed) {
telemetry.IncrCounterWithLabels(
[]string{
types.ModuleName,
metrics.PlaceOrder,
metrics.CollateralizationCheckFailed,
},
1,
msg.Order.GetOrderLabels(),
)
log.InfoLog(ctx, "Place Order Expected Error", log.Error, err)
return
if !isInternalOrder {
defer func() {
metrics.IncrSuccessOrErrorCounter(
err,
types.ModuleName,
metrics.PlaceOrder,
metrics.DeliverTx,
msg.Order.GetOrderLabels()...,
)
if err != nil {
if errors.Is(err, types.ErrStatefulOrderCollateralizationCheckFailed) {
telemetry.IncrCounterWithLabels(
[]string{
types.ModuleName,
metrics.PlaceOrder,
metrics.CollateralizationCheckFailed,
},
1,
msg.Order.GetOrderLabels(),
)
log.InfoLog(ctx, "Place Order Expected Error", log.Error, err)
return
}
log.ErrorLogWithError(ctx, "Error placing order", err)
}
log.ErrorLogWithError(ctx, "Error placing order", err)
}
}()
}()
}

// 1. Ensure the order is not a Short-Term order.
order := msg.GetOrder()
Expand Down Expand Up @@ -105,7 +109,7 @@ func (k Keeper) HandleMsgPlaceOrder(
// - stateful order validation.
// - collateralization check.
// - writing the order to state and the memstore.
if err := k.PlaceStatefulOrder(ctx, msg); err != nil {
if err := k.PlaceStatefulOrder(ctx, msg, isInternalOrder); err != nil {
return err
}

Expand Down
168 changes: 168 additions & 0 deletions protocol/x/clob/keeper/msg_server_place_order_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import (
"testing"
"time"

comettypes "github.com/cometbft/cometbft/types"
"github.com/dydxprotocol/v4-chain/protocol/dtypes"
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/mocks"
testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app"
clobtest "github.com/dydxprotocol/v4-chain/protocol/testutil/clob"
"github.com/dydxprotocol/v4-chain/protocol/testutil/constants"
keepertest "github.com/dydxprotocol/v4-chain/protocol/testutil/keeper"
assettypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types"
blocktimetypes "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/types"
"github.com/dydxprotocol/v4-chain/protocol/x/clob/keeper"
"github.com/dydxprotocol/v4-chain/protocol/x/clob/types"
Expand Down Expand Up @@ -396,3 +399,168 @@ func TestPlaceOrder_Success(t *testing.T) {
})
}
}

func TestHandleMsgPlaceOrder(t *testing.T) {
testOrder := &types.Order{
OrderId: types.OrderId{
SubaccountId: constants.Alice_Num0,
ClientId: 0,
OrderFlags: types.OrderIdFlags_LongTerm,
ClobPairId: 0,
},
Side: types.Order_SIDE_BUY,
Quantums: 100,
Subticks: 10_000,
GoodTilOneof: &types.Order_GoodTilBlockTime{GoodTilBlockTime: 15},
}
tests := map[string]struct {
// Whether order is internal.
isInternalOrder bool
// Quantums of USDC that subaccount has.
assetQuantums int64
// Whether a cancellation exists for the order.
cancellationExists bool
// Whether a removal exists for the order.
removalExists bool
// Whether equity tier limit exists.
equityTierLimitExists bool

// Expected error.
expectedError error
}{
"Success - Place an Internal Order, Validations are Skipped": {
isInternalOrder: true,
assetQuantums: -1_000_000_000,
cancellationExists: false,
removalExists: false,
equityTierLimitExists: true,
},
"Error - Place an Internal Order, Order Already Cancelled": {
isInternalOrder: true,
assetQuantums: -1_000_000_000,
cancellationExists: true,
removalExists: false,
equityTierLimitExists: true,
expectedError: types.ErrStatefulOrderPreviouslyCancelled,
},
"Error - Place an Internal Order, Order Already Removed": {
isInternalOrder: true,
assetQuantums: -1_000_000_000,
cancellationExists: false,
removalExists: true,
equityTierLimitExists: true,
expectedError: types.ErrStatefulOrderPreviouslyRemoved,
},
"Success - Place an External Order, All Validations Pass": {
isInternalOrder: false,
assetQuantums: 1_000_000_000,
cancellationExists: false,
removalExists: false,
equityTierLimitExists: true,
},
"Error - Place an External Order, Order Already Cancelled": {
isInternalOrder: false,
assetQuantums: 1_000_000_000,
cancellationExists: true,
removalExists: false,
equityTierLimitExists: true,
expectedError: types.ErrStatefulOrderPreviouslyCancelled,
},
"Error - Place an External Order, Order Already Removed": {
isInternalOrder: false,
assetQuantums: 1_000_000_000,
cancellationExists: false,
removalExists: true,
equityTierLimitExists: true,
expectedError: types.ErrStatefulOrderPreviouslyRemoved,
},
"Error - Place an External Order, Equity Tier Limit Reached": {
isInternalOrder: false,
assetQuantums: 1,
cancellationExists: false,
removalExists: false,
equityTierLimitExists: true,
expectedError: types.ErrOrderWouldExceedMaxOpenOrdersEquityTierLimit,
},
"Error - Place an External Order, Collateralization Check Failed": {
isInternalOrder: false,
assetQuantums: -1_000_000_000,
cancellationExists: false,
removalExists: false,
equityTierLimitExists: false,
expectedError: types.ErrStatefulOrderCollateralizationCheckFailed,
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
// Initialize tApp and ctx.
tApp := testapp.NewTestAppBuilder(t).WithGenesisDocFn(func() (genesis comettypes.GenesisDoc) {
genesis = testapp.DefaultGenesis()
testapp.UpdateGenesisDocWithAppStateForModule(
&genesis,
func(genesisState *satypes.GenesisState) {
genesisState.Subaccounts = []satypes.Subaccount{
{
Id: &testOrder.OrderId.SubaccountId,
AssetPositions: []*satypes.AssetPosition{
{
AssetId: assettypes.AssetUsdc.Id,
Quantums: dtypes.NewInt(tc.assetQuantums),
},
},
},
}
},
)
testapp.UpdateGenesisDocWithAppStateForModule(
&genesis,
func(genesisState *types.GenesisState) {
if !tc.equityTierLimitExists {
genesisState.EquityTierLimitConfig = types.EquityTierLimitConfiguration{
ShortTermOrderEquityTiers: genesisState.EquityTierLimitConfig.ShortTermOrderEquityTiers,
StatefulOrderEquityTiers: nil,
}
}
},
)
return genesis
}).Build()
ctx := tApp.InitChain().WithIsCheckTx(false)
k := tApp.App.ClobKeeper

// Add order to placed cancellations / removals if specified.
ppme := k.GetProcessProposerMatchesEvents(ctx)
if tc.cancellationExists {
ppme.PlacedStatefulCancellationOrderIds = []types.OrderId{testOrder.OrderId}
}
if tc.removalExists {
ppme.RemovedStatefulOrderIds = []types.OrderId{testOrder.OrderId}
}
k.MustSetProcessProposerMatchesEvents(ctx, ppme)

// Place order.
err := k.HandleMsgPlaceOrder(
ctx,
&types.MsgPlaceOrder{
Order: *testOrder,
},
tc.isInternalOrder,
)
if tc.expectedError == nil {
require.NoError(t, err)

// Ensure order placement exists in state.
placement, found := k.GetLongTermOrderPlacement(ctx, testOrder.OrderId)
require.True(t, found)
require.Equal(t, *testOrder, placement.Order)
} else {
require.ErrorContains(t, err, tc.expectedError.Error())

// Ensure order placement does not exist in state.
_, found := k.GetLongTermOrderPlacement(ctx, testOrder.OrderId)
require.False(t, found)
}
})
}
}
Loading

0 comments on commit 8e3ac79

Please sign in to comment.