diff --git a/indexer/packages/postgres/__tests__/helpers/constants.ts b/indexer/packages/postgres/__tests__/helpers/constants.ts index 79007f2d9b..f873c46d64 100644 --- a/indexer/packages/postgres/__tests__/helpers/constants.ts +++ b/indexer/packages/postgres/__tests__/helpers/constants.ts @@ -226,6 +226,7 @@ export const defaultOrderGoodTilBlockTime: OrderCreateObject = { clientId: '2', goodTilBlock: undefined, goodTilBlockTime: '2023-01-22T00:00:00.000Z', + createdAtHeight: '1', orderFlags: ORDER_FLAG_LONG_TERM.toString(), }; diff --git a/indexer/packages/postgres/src/types/db-model-types.ts b/indexer/packages/postgres/src/types/db-model-types.ts index edcc4f9606..5243a413e7 100644 --- a/indexer/packages/postgres/src/types/db-model-types.ts +++ b/indexer/packages/postgres/src/types/db-model-types.ts @@ -66,6 +66,7 @@ export interface OrderFromDatabase extends IdBasedModelFromDatabase { updatedAtHeight: string; goodTilBlock?: string; goodTilBlockTime?: string; + // createdAtHeight is optional because short term orders do not have a createdAtHeight. createdAtHeight?: string; clientMetadata: string; triggerPrice?: string; diff --git a/indexer/packages/postgres/src/types/order-types.ts b/indexer/packages/postgres/src/types/order-types.ts index 8c027885a6..373ea21014 100644 --- a/indexer/packages/postgres/src/types/order-types.ts +++ b/indexer/packages/postgres/src/types/order-types.ts @@ -62,6 +62,7 @@ export interface OrderCreateObject { updatedAtHeight: string; goodTilBlock?: string; goodTilBlockTime?: string; + // createdAtHeight is optional because short term orders do not have a createdAtHeight. createdAtHeight?: string; clientMetadata: string; triggerPrice?: string, diff --git a/indexer/services/vulcan/__tests__/handlers/order-place-handler.test.ts b/indexer/services/vulcan/__tests__/handlers/order-place-handler.test.ts index 8ffc6337cc..d05feb2abd 100644 --- a/indexer/services/vulcan/__tests__/handlers/order-place-handler.test.ts +++ b/indexer/services/vulcan/__tests__/handlers/order-place-handler.test.ts @@ -62,7 +62,7 @@ import { onMessage } from '../../src/lib/on-message'; import { expectCanceledOrderStatus, expectOpenOrderIds, handleInitialOrderPlace } from '../helpers/helpers'; import { expectOffchainUpdateMessage, expectWebsocketOrderbookMessage, expectWebsocketSubaccountMessage } from '../helpers/websocket-helpers'; import { OrderbookSide } from '../../src/lib/types'; -import { getOrderIdHash } from '@dydxprotocol-indexer/v4-proto-parser'; +import { getOrderIdHash, isStatefulOrder } from '@dydxprotocol-indexer/v4-proto-parser'; jest.mock('@dydxprotocol-indexer/base', () => ({ ...jest.requireActual('@dydxprotocol-indexer/base'), @@ -1078,6 +1078,7 @@ function expectWebsocketMessagesSent( const orderTIF: TimeInForce = protocolTranslations.protocolOrderTIFToTIF( redisOrder.order!.timeInForce, ); + const isStateful: boolean = isStatefulOrder(redisOrder.order!.orderId!.orderFlags); const contents: SubaccountMessageContents = { orders: [ { @@ -1104,7 +1105,9 @@ function expectWebsocketMessagesSent( ?.toString(), goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(redisOrder.order!), ticker: redisOrder.ticker, - ...(dbOrder.createdAtHeight && { createdAtHeight: dbOrder.createdAtHeight }), + ...(isStateful && { createdAtHeight: dbOrder.createdAtHeight }), + ...(isStateful && { updatedAt: dbOrder.updatedAt }), + ...(isStateful && { updatedAtHeight: dbOrder.updatedAtHeight }), clientMetadata: redisOrder.order!.clientMetadata.toString(), triggerPrice: getTriggerPrice(redisOrder.order!, perpetualMarket), }, diff --git a/indexer/services/vulcan/__tests__/handlers/order-remove-handler.test.ts b/indexer/services/vulcan/__tests__/handlers/order-remove-handler.test.ts index fef7be2a20..7d62beac72 100644 --- a/indexer/services/vulcan/__tests__/handlers/order-remove-handler.test.ts +++ b/indexer/services/vulcan/__tests__/handlers/order-remove-handler.test.ts @@ -341,6 +341,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(removedRedisOrder.order!), ticker: redisTestConstants.defaultRedisOrder.ticker, removalReason: OrderRemovalReason[defaultOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedRedisOrder.order!.clientMetadata.toString(), triggerPrice, }, @@ -475,6 +478,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(removedRedisOrder.order!), ticker: redisTestConstants.defaultRedisOrder.ticker, removalReason: OrderRemovalReason[defaultOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedRedisOrder.order!.clientMetadata.toString(), triggerPrice, }, @@ -610,6 +616,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(removedRedisOrder.order!), ticker: redisTestConstants.defaultRedisOrder.ticker, removalReason: OrderRemovalReason[defaultOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedRedisOrder.order!.clientMetadata.toString(), triggerPrice, }], @@ -746,6 +755,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(removedRedisOrder.order!), ticker: redisTestConstants.defaultRedisOrder.ticker, removalReason: OrderRemovalReason[defaultOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedRedisOrder.order!.clientMetadata.toString(), triggerPrice, }], @@ -1041,6 +1053,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: removedOrder.goodTilBlockTime, ticker: removedRedisOrder.ticker, removalReason: OrderRemovalReason[statefulCancelationOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedOrder.clientMetadata.toString(), triggerPrice, }], @@ -1152,6 +1167,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: removedOrder.goodTilBlockTime, ticker: removedRedisOrder.ticker, removalReason: OrderRemovalReason[statefulCancelationOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedOrder.clientMetadata.toString(), triggerPrice, }], @@ -1271,6 +1289,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: removedOrder.goodTilBlockTime, ticker: removedRedisOrder.ticker, removalReason: OrderRemovalReason[statefulCancelationOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedOrder.clientMetadata.toString(), triggerPrice, }], @@ -1406,6 +1427,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: removedOrder.goodTilBlockTime, ticker: removedRedisOrder.ticker, removalReason: OrderRemovalReason[statefulCancelationOrderRemove.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: removedOrder.clientMetadata.toString(), triggerPrice, }], @@ -1537,6 +1561,9 @@ describe('OrderRemoveHandler', () => { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(removedRedisOrder.order!), ticker: redisTestConstants.defaultRedisOrder.ticker, removalReason: OrderRemovalReason[indexerExpiredOrderRemoved.reason], + createdAtHeight: removedOrder.createdAtHeight, + updatedAt: removedOrder.updatedAt, + updatedAtHeight: removedOrder.updatedAtHeight, clientMetadata: testConstants.defaultOrderGoodTilBlockTime.clientMetadata.toString(), }, ], diff --git a/indexer/services/vulcan/src/handlers/order-place-handler.ts b/indexer/services/vulcan/src/handlers/order-place-handler.ts index 9fbe366568..699bf933fb 100644 --- a/indexer/services/vulcan/src/handlers/order-place-handler.ts +++ b/indexer/services/vulcan/src/handlers/order-place-handler.ts @@ -16,6 +16,7 @@ import { perpetualMarketRefresher, protocolTranslations, OrderFromDatabase, + IsoString, } from '@dydxprotocol-indexer/postgres'; import { OpenOrdersCache, @@ -280,6 +281,8 @@ export class OrderPlaceHandler extends Handler { : APIOrderStatusEnum.BEST_EFFORT_OPENED ); const createdAtHeight: string | undefined = order?.createdAtHeight; + const updatedAt: IsoString | undefined = order?.updatedAt; + const updatedAtHeight: string | undefined = order?.updatedAtHeight; const contents: SubaccountMessageContents = { orders: [ { @@ -305,6 +308,8 @@ export class OrderPlaceHandler extends Handler { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(redisOrder.order!), ticker: redisOrder.ticker, ...(createdAtHeight && { createdAtHeight }), + ...(updatedAt && { updatedAt }), + ...(updatedAtHeight && { updatedAtHeight }), clientMetadata: redisOrder.order!.clientMetadata.toString(), triggerPrice: getTriggerPrice(redisOrder.order!, perpetualMarket), }, diff --git a/indexer/services/vulcan/src/handlers/order-remove-handler.ts b/indexer/services/vulcan/src/handlers/order-remove-handler.ts index 78bcd258e8..0672b865e5 100644 --- a/indexer/services/vulcan/src/handlers/order-remove-handler.ts +++ b/indexer/services/vulcan/src/handlers/order-remove-handler.ts @@ -13,6 +13,7 @@ import { SubaccountTable, apiTranslations, TimeInForce, + IsoString, } from '@dydxprotocol-indexer/postgres'; import { OpenOrdersCache, @@ -276,16 +277,23 @@ export class OrderRemoveHandler extends Handler { // If the remaining amount of the order in state is <= 0, the order is filled and // does not need to have it's status updated + let canceledOrder: OrderFromDatabase | undefined; if (stateRemainingQuantums.gt(0)) { - await runFuncWithTimingStat( + canceledOrder = await runFuncWithTimingStat( this.cancelOrderInPostgres(orderRemove), this.generateTimingStatsOptions('cancel_order_in_postgres'), ); + } else { + canceledOrder = await runFuncWithTimingStat( + OrderTable.findById(OrderTable.orderIdToUuid(orderRemove.removedOrderId!)), + this.generateTimingStatsOptions('find_order'), + ); } const subaccountMessage: Message = { value: this.createSubaccountWebsocketMessageFromRemoveOrderResult( removeOrderResult, + canceledOrder, orderRemove, perpetualMarket, ), @@ -505,6 +513,7 @@ export class OrderRemoveHandler extends Handler { protected createSubaccountWebsocketMessageFromRemoveOrderResult( removeOrderResult: RemoveOrderResult, + canceledOrder: OrderFromDatabase | undefined, orderRemove: OrderRemoveV1, perpetualMarket: PerpetualMarketFromDatabase, ): Buffer { @@ -512,6 +521,9 @@ export class OrderRemoveHandler extends Handler { const orderTIF: TimeInForce = protocolTranslations.protocolOrderTIFToTIF( redisOrder.order!.timeInForce, ); + const createdAtHeight: string | undefined = canceledOrder?.createdAtHeight; + const updatedAt: IsoString | undefined = canceledOrder?.updatedAt; + const updatedAtHeight: string | undefined = canceledOrder?.updatedAtHeight; const contents: SubaccountMessageContents = { orders: [ { @@ -541,6 +553,9 @@ export class OrderRemoveHandler extends Handler { goodTilBlockTime: protocolTranslations.getGoodTilBlockTime(redisOrder.order!), ticker: redisOrder.ticker, removalReason: OrderRemovalReason[orderRemove.reason], + ...(createdAtHeight && { createdAtHeight }), + ...(updatedAt && { updatedAt }), + ...(updatedAtHeight && { updatedAtHeight }), clientMetadata: redisOrder.order!.clientMetadata.toString(), triggerPrice: getTriggerPrice(redisOrder.order!, perpetualMarket), }, @@ -584,6 +599,9 @@ export class OrderRemoveHandler extends Handler { goodTilBlockTime: order.goodTilBlockTime ?? undefined, ticker: orderTicker, removalReason: OrderRemovalReason[orderRemove.reason], + createdAtHeight: order.createdAtHeight, + updatedAt: order.updatedAt, + updatedAtHeight: order.updatedAtHeight, clientMetadata: order.clientMetadata, triggerPrice: order.triggerPrice ?? undefined, },