Skip to content

Commit

Permalink
Merge branch 'main' into jonfung/threadMessageTimingThroughIndexer
Browse files Browse the repository at this point in the history
  • Loading branch information
jonfung-dydx committed Mar 28, 2024
2 parents d590723 + 56761ac commit 3bd29ce
Show file tree
Hide file tree
Showing 171 changed files with 11,878 additions and 1,273 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ v4-proto-js/node_modules
v4-proto-js/src

.idea
.vscode
**/.DS_Store
19 changes: 17 additions & 2 deletions indexer/packages/kafka/src/websocket-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ export function getTriggerPrice(
return undefined;
}

export function createSubaccountWebsocketMessage(
export function generateSubaccountMessageContents(
redisOrder: RedisOrder,
order: OrderFromDatabase | undefined,
perpetualMarket: PerpetualMarketFromDatabase,
placementStatus: OrderPlaceV1_OrderPlacementStatus,
): Buffer {
): SubaccountMessageContents {
const orderTIF: TimeInForce = protocolTranslations.protocolOrderTIFToTIF(
redisOrder.order!.timeInForce,
);
Expand Down Expand Up @@ -90,6 +90,21 @@ export function createSubaccountWebsocketMessage(
},
],
};
return contents;
}

export function createSubaccountWebsocketMessage(
redisOrder: RedisOrder,
order: OrderFromDatabase | undefined,
perpetualMarket: PerpetualMarketFromDatabase,
placementStatus: OrderPlaceV1_OrderPlacementStatus,
): Buffer {
const contents: SubaccountMessageContents = generateSubaccountMessageContents(
redisOrder,
order,
perpetualMarket,
placementStatus,
);

const subaccountMessage: SubaccountMessage = SubaccountMessage.fromPartial({
contents: JSON.stringify(contents),
Expand Down
48 changes: 48 additions & 0 deletions indexer/packages/postgres/__tests__/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,16 @@ export const defaultAssetPositionId2: string = AssetPositionTable.uuid(
defaultAssetPosition2.subaccountId,
defaultAssetPosition2.assetId,
);
export const isolatedSubaccountAssetPosition: AssetPositionCreateObject = {
subaccountId: isolatedSubaccountId,
assetId: '0',
size: '5000',
isLong: true,
};
export const isolatedSubaccountAssetPositionId: string = AssetPositionTable.uuid(
isolatedSubaccountAssetPosition.subaccountId,
isolatedSubaccountAssetPosition.assetId,
);

// ============== PerpetualMarkets ==============

Expand Down Expand Up @@ -445,6 +455,28 @@ export const defaultPerpetualPositionId: string = PerpetualPositionTable.uuid(
defaultPerpetualPosition.openEventId,
);

export const isolatedPerpetualPosition: PerpetualPositionCreateObject = {
subaccountId: isolatedSubaccountId,
perpetualId: isolatedPerpetualMarket.id,
side: PositionSide.LONG,
status: PerpetualPositionStatus.OPEN,
size: '10',
maxSize: '25',
entryPrice: '20000',
sumOpen: '10',
sumClose: '0',
createdAt: createdDateTime.toISO(),
createdAtHeight: createdHeight,
openEventId: defaultTendermintEventId,
lastEventId: defaultTendermintEventId2,
settledFunding: '200000',
};

export const isolatedPerpetualPositionId: string = PerpetualPositionTable.uuid(
isolatedPerpetualPosition.subaccountId,
isolatedPerpetualPosition.openEventId,
);

// ============== Fills ==============

export const defaultFill: FillCreateObject = {
Expand Down Expand Up @@ -710,6 +742,22 @@ export const defaultFundingIndexUpdateId: string = FundingIndexUpdatesTable.uuid
defaultFundingIndexUpdate.perpetualId,
);

export const isolatedMarketFundingIndexUpdate: FundingIndexUpdatesCreateObject = {
perpetualId: isolatedPerpetualMarket.id,
eventId: defaultTendermintEventId,
rate: '0.0004',
oraclePrice: '10000',
fundingIndex: '10200',
effectiveAt: createdDateTime.toISO(),
effectiveAtHeight: createdHeight,
};

export const isolatedMarketFundingIndexUpdateId: string = FundingIndexUpdatesTable.uuid(
isolatedMarketFundingIndexUpdate.effectiveAtHeight,
isolatedMarketFundingIndexUpdate.eventId,
isolatedMarketFundingIndexUpdate.perpetualId,
);

// ========= Compliance Data ==========

export const blockedComplianceData: ComplianceDataCreateObject = {
Expand Down
39 changes: 0 additions & 39 deletions indexer/packages/postgres/__tests__/lib/api-translations.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { APITimeInForce, TimeInForce } from '../../src/types';
import {
getChildSubaccountNums,
getParentSubaccountNum,
isOrderTIFPostOnly,
orderTIFToAPITIF,
} from '../../src/lib/api-translations';
Expand Down Expand Up @@ -36,41 +34,4 @@ describe('apiTranslations', () => {
expect(isOrderTIFPostOnly(orderTimeInForce)).toEqual(expectedPostOnly);
});
});

describe('getChildSubaccountNums', () => {
it('Gets a list of all possible child subaccount numbers for a parent subaccount 0', () => {
const childSubaccounts = getChildSubaccountNums(0);
expect(childSubaccounts.length).toEqual(1000);
expect(childSubaccounts[0]).toEqual(0);
expect(childSubaccounts[1]).toEqual(128);
expect(childSubaccounts[999]).toEqual(128 * 999);
});
it('Gets a list of all possible child subaccount numbers for a parent subaccount 127', () => {
const childSubaccounts = getChildSubaccountNums(127);
expect(childSubaccounts.length).toEqual(1000);
expect(childSubaccounts[0]).toEqual(127);
expect(childSubaccounts[1]).toEqual(128 + 127);
expect(childSubaccounts[999]).toEqual(128 * 999 + 127);
});
});

describe('getChildSubaccountNums', () => {
it('Throws an error if the parent subaccount number is greater than or equal to the maximum parent subaccount number', () => {
expect(() => getChildSubaccountNums(128)).toThrowError('Parent subaccount number must be less than 128');
});
});

describe('getParentSubaccountNum', () => {
it('Gets the parent subaccount number from a child subaccount number', () => {
expect(getParentSubaccountNum(0)).toEqual(0);
expect(getParentSubaccountNum(128)).toEqual(0);
expect(getParentSubaccountNum(128 * 999 - 1)).toEqual(127);
});
});

describe('getParentSubaccountNum', () => {
it('Throws an error if the child subaccount number is greater than the max child subaccount number', () => {
expect(() => getParentSubaccountNum(128001)).toThrowError('Child subaccount number must be less than 128000');
});
});
});
29 changes: 1 addition & 28 deletions indexer/packages/postgres/src/lib/api-translations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TIME_IN_FORCE_TO_API_TIME_IN_FORCE, CHILD_SUBACCOUNT_MULTIPLIER, MAX_PARENT_SUBACCOUNTS } from '../constants';
import { TIME_IN_FORCE_TO_API_TIME_IN_FORCE } from '../constants';
import { APITimeInForce, TimeInForce } from '../types';

/**
Expand All @@ -20,30 +20,3 @@ export function isOrderTIFPostOnly(timeInForce: TimeInForce): boolean {
export function orderTIFToAPITIF(timeInForce: TimeInForce): APITimeInForce {
return TIME_IN_FORCE_TO_API_TIME_IN_FORCE[timeInForce];
}

/**
* Gets a list of all possible child subaccount numbers for a parent subaccount number
* Child subaccounts = [128*0+parentSubaccount, 128*1+parentSubaccount ... 128*999+parentSubaccount]
* @param parentSubaccount
* @returns
*/
export function getChildSubaccountNums(parentSubaccountNum: number): number[] {
if (parentSubaccountNum >= MAX_PARENT_SUBACCOUNTS) {
throw new Error(`Parent subaccount number must be less than ${MAX_PARENT_SUBACCOUNTS}`);
}
return Array.from({ length: CHILD_SUBACCOUNT_MULTIPLIER },
(_, i) => MAX_PARENT_SUBACCOUNTS * i + parentSubaccountNum);
}

/**
* Gets the parent subaccount number from a child subaccount number
* Parent subaccount = childSubaccount % 128
* @param childSubaccountNum
* @returns
*/
export function getParentSubaccountNum(childSubaccountNum: number): number {
if (childSubaccountNum > MAX_PARENT_SUBACCOUNTS * CHILD_SUBACCOUNT_MULTIPLIER) {
throw new Error(`Child subaccount number must be less than ${MAX_PARENT_SUBACCOUNTS * CHILD_SUBACCOUNT_MULTIPLIER}`);
}
return childSubaccountNum % MAX_PARENT_SUBACCOUNTS;
}
28 changes: 28 additions & 0 deletions indexer/packages/redis/src/helpers/order-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { OrderTable, PerpetualMarketFromDatabase, protocolTranslations } from '@dydxprotocol-indexer/postgres';
import { IndexerOrder, RedisOrder, RedisOrder_TickerType } from '@dydxprotocol-indexer/v4-protos';

/**
* Creates a `RedisOrder` given an `Order` and the corresponding `PerpetualMarket` for the `Order`.
* @param order
* @param perpetualMarket
* @returns
*/
export function convertToRedisOrder(
order: IndexerOrder,
perpetualMarket: PerpetualMarketFromDatabase,
): RedisOrder {
return {
order,
id: OrderTable.orderIdToUuid(order.orderId!),
ticker: perpetualMarket.ticker,
tickerType: RedisOrder_TickerType.TICKER_TYPE_PERPETUAL,
price: protocolTranslations.subticksToPrice(
order.subticks.toString(),
perpetualMarket,
),
size: protocolTranslations.quantumsToHumanFixedString(
order.quantums.toString(),
perpetualMarket.atomicResolution,
),
};
}
1 change: 1 addition & 0 deletions indexer/packages/redis/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * as StateFilledQuantumsCache from './caches/state-filled-quantums-cache'
export { placeOrder } from './caches/place-order';
export { removeOrder } from './caches/remove-order';
export { updateOrder } from './caches/update-order';
export * from './helpers/order-helper';

export * from './types';
export { redisConfigSchema } from './config';
Expand Down
22 changes: 21 additions & 1 deletion indexer/packages/v4-proto-parser/__tests__/order-helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IndexerOrderId } from '@dydxprotocol-indexer/v4-protos';
import { getOrderIdHash, isStatefulOrder } from '../src/order-helpers';
import { getOrderIdHash, isLongTermOrder, isStatefulOrder } from '../src/order-helpers';
import { ORDER_FLAG_CONDITIONAL, ORDER_FLAG_LONG_TERM, ORDER_FLAG_SHORT_TERM } from '../src';

describe('getOrderIdHash', () => {
Expand Down Expand Up @@ -65,3 +65,23 @@ describe('isStatefulOrder', () => {
expect(isStatefulOrder(flag)).toEqual(isStateful);
});
});

describe('isLongTermOrder', () => {
it.each([
[ORDER_FLAG_SHORT_TERM.toString(), 'string', false],
['4', 'string', false],
[ORDER_FLAG_CONDITIONAL.toString(), 'string', false],
[ORDER_FLAG_LONG_TERM.toString(), 'string', true],
[ORDER_FLAG_SHORT_TERM, 'number', false],
[3, 'number', false],
[ORDER_FLAG_CONDITIONAL, 'number', false],
[ORDER_FLAG_LONG_TERM, 'number', true],
['abc', 'string', false],
])('Checks if flag %s with type %s is a long term order', (
flag: number | string,
_type: string,
isLongTerm: boolean,
) => {
expect(isLongTermOrder(flag)).toEqual(isLongTerm);
});
});
9 changes: 9 additions & 0 deletions indexer/packages/v4-proto-parser/src/order-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ export function isStatefulOrder(orderFlag: number | String): boolean {
return numberOrderFlag === ORDER_FLAG_CONDITIONAL || numberOrderFlag === ORDER_FLAG_LONG_TERM;
}

export function isLongTermOrder(orderFlag: number | String): boolean {
const numberOrderFlag: number = Number(orderFlag);
// A string that is not a number will be converted to NaN, and should return false.
if (Number.isNaN(numberOrderFlag)) {
return false;
}
return numberOrderFlag === ORDER_FLAG_LONG_TERM;
}

export function requiresImmediateExecution(tif: IndexerOrder_TimeInForce): boolean {
return (
tif === IndexerOrder_TimeInForce.TIME_IN_FORCE_FILL_OR_KILL ||
Expand Down
Loading

0 comments on commit 3bd29ce

Please sign in to comment.