Merge pull request #172 from drift-labs/master
slot staleness for vamm orders remove from cache
This commit is contained in:
@@ -1,21 +1,20 @@
|
|||||||
import {
|
import {
|
||||||
BN,
|
|
||||||
DLOBSubscriber,
|
DLOBSubscriber,
|
||||||
DLOBSubscriptionConfig,
|
DLOBSubscriptionConfig,
|
||||||
DriftEnv,
|
DriftEnv,
|
||||||
L2OrderBookGenerator,
|
L2OrderBookGenerator,
|
||||||
MarketType,
|
MarketType,
|
||||||
PositionDirection,
|
PositionDirection,
|
||||||
groupL2,
|
|
||||||
isVariant,
|
isVariant,
|
||||||
} from '@drift-labs/sdk';
|
} from '@drift-labs/sdk';
|
||||||
import { RedisClient } from '@drift/common';
|
import { RedisClient } from '@drift/common';
|
||||||
|
import { logger } from '../utils/logger';
|
||||||
import {
|
import {
|
||||||
SubscriberLookup,
|
SubscriberLookup,
|
||||||
addMarketSlotToResponse,
|
addMarketSlotToResponse,
|
||||||
addOracletoResponse,
|
addOracletoResponse,
|
||||||
l2WithBNToStrings,
|
l2WithBNToStrings,
|
||||||
|
parsePositiveIntArray,
|
||||||
} from '../utils/utils';
|
} from '../utils/utils';
|
||||||
import { setHealthStatus, HEALTH_STATUS } from '../core/metrics';
|
import { setHealthStatus, HEALTH_STATUS } from '../core/metrics';
|
||||||
|
|
||||||
@@ -26,23 +25,24 @@ type wsMarketArgs = {
|
|||||||
depth: number;
|
depth: number;
|
||||||
includeVamm: boolean;
|
includeVamm: boolean;
|
||||||
numVammOrders?: number;
|
numVammOrders?: number;
|
||||||
grouping?: number;
|
|
||||||
fallbackL2Generators?: L2OrderBookGenerator[];
|
fallbackL2Generators?: L2OrderBookGenerator[];
|
||||||
updateOnChange?: boolean;
|
updateOnChange?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
const PERP_MAKRET_STALENESS_THRESHOLD = 30 * 60 * 1000;
|
const PERP_MAKRET_STALENESS_THRESHOLD = 30 * 60 * 1000;
|
||||||
const SPOT_MAKRET_STALENESS_THRESHOLD = 60 * 60 * 1000;
|
const SPOT_MAKRET_STALENESS_THRESHOLD = 60 * 60 * 1000;
|
||||||
|
const STALE_ORACLE_REMOVE_VAMM_THRESHOLD = 100;
|
||||||
|
|
||||||
const PERP_MARKETS_TO_SKIP_SLOT_CHECK = {
|
const PERP_MARKETS_TO_SKIP_SLOT_CHECK =
|
||||||
'mainnet-beta': [17, 25],
|
process.env.PERP_MARKETS_TO_SKIP_SLOT_CHECK !== undefined
|
||||||
devnet: [17, 21, 23],
|
? parsePositiveIntArray(process.env.PERP_MARKETS_TO_SKIP_SLOT_CHECK)
|
||||||
};
|
: [];
|
||||||
|
const SPOT_MARKETS_TO_SKIP_SLOT_CHECK =
|
||||||
const SPOT_MARKETS_TO_SKIP_SLOT_CHECK = {
|
process.env.SPOT_MARKETS_TO_SKIP_SLOT_CHECK !== undefined
|
||||||
'mainnet-beta': [6, 8, 10, 15],
|
? parsePositiveIntArray(process.env.SPOT_MARKETS_TO_SKIP_SLOT_CHECK)
|
||||||
devnet: [],
|
: [];
|
||||||
};
|
|
||||||
|
|
||||||
export type wsMarketInfo = {
|
export type wsMarketInfo = {
|
||||||
marketIndex: number;
|
marketIndex: number;
|
||||||
@@ -59,9 +59,6 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
Map<number, { slot: number; ts: number }>
|
Map<number, { slot: number; ts: number }>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
public skipSlotStalenessCheckMarketsPerp: number[];
|
|
||||||
public skipSlotStalenessCheckMarketsSpot: number[];
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: DLOBSubscriptionConfig & {
|
config: DLOBSubscriptionConfig & {
|
||||||
env: DriftEnv;
|
env: DriftEnv;
|
||||||
@@ -85,11 +82,6 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
this.lastMarketSlotMap.set(MarketType.SPOT, new Map());
|
this.lastMarketSlotMap.set(MarketType.SPOT, new Map());
|
||||||
this.lastMarketSlotMap.set(MarketType.PERP, new Map());
|
this.lastMarketSlotMap.set(MarketType.PERP, new Map());
|
||||||
|
|
||||||
this.skipSlotStalenessCheckMarketsPerp =
|
|
||||||
PERP_MARKETS_TO_SKIP_SLOT_CHECK[config.env];
|
|
||||||
this.skipSlotStalenessCheckMarketsSpot =
|
|
||||||
SPOT_MARKETS_TO_SKIP_SLOT_CHECK[config.env];
|
|
||||||
|
|
||||||
for (const market of config.perpMarketInfos) {
|
for (const market of config.perpMarketInfos) {
|
||||||
const perpMarket = this.driftClient.getPerpMarketAccount(
|
const perpMarket = this.driftClient.getPerpMarketAccount(
|
||||||
market.marketIndex
|
market.marketIndex
|
||||||
@@ -138,9 +130,25 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
|
|
||||||
getL2AndSendMsg(marketArgs: wsMarketArgs): void {
|
getL2AndSendMsg(marketArgs: wsMarketArgs): void {
|
||||||
const clientPrefix = this.redisClient.forceGetClient().options.keyPrefix;
|
const clientPrefix = this.redisClient.forceGetClient().options.keyPrefix;
|
||||||
const grouping = marketArgs.grouping;
|
|
||||||
const { marketName, ...l2FuncArgs } = marketArgs;
|
const { marketName, ...l2FuncArgs } = marketArgs;
|
||||||
const l2 = this.getL2(l2FuncArgs);
|
const marketType = isVariant(marketArgs.marketType, 'perp')
|
||||||
|
? 'perp'
|
||||||
|
: 'spot';
|
||||||
|
|
||||||
|
// Test for oracle staleness to know whether to include vamm
|
||||||
|
const dlobSlot = this.slotSource.getSlot();
|
||||||
|
const oracleSlot =
|
||||||
|
marketType === 'perp'
|
||||||
|
? this.driftClient.getOracleDataForPerpMarket(marketArgs.marketIndex)
|
||||||
|
.slot
|
||||||
|
: this.driftClient.getOracleDataForSpotMarket(marketArgs.marketIndex)
|
||||||
|
.slot;
|
||||||
|
let includeVamm = marketArgs.includeVamm;
|
||||||
|
if (dlobSlot - oracleSlot > STALE_ORACLE_REMOVE_VAMM_THRESHOLD) {
|
||||||
|
logger.info('Oracle is stale, removing vamm orders');
|
||||||
|
includeVamm = false;
|
||||||
|
}
|
||||||
|
const l2 = this.getL2({ ...l2FuncArgs, includeVamm });
|
||||||
const slot = l2.slot;
|
const slot = l2.slot;
|
||||||
const lastMarketSlotAndTime = this.lastMarketSlotMap
|
const lastMarketSlotAndTime = this.lastMarketSlotMap
|
||||||
.get(marketArgs.marketType)
|
.get(marketArgs.marketType)
|
||||||
@@ -154,18 +162,8 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
if (slot) {
|
if (slot) {
|
||||||
delete l2.slot;
|
delete l2.slot;
|
||||||
}
|
}
|
||||||
const marketType = isVariant(marketArgs.marketType, 'perp')
|
|
||||||
? 'perp'
|
const l2Formatted = l2WithBNToStrings(l2);
|
||||||
: 'spot';
|
|
||||||
let l2Formatted: any;
|
|
||||||
if (grouping) {
|
|
||||||
const groupingBN = new BN(grouping);
|
|
||||||
l2Formatted = l2WithBNToStrings(
|
|
||||||
groupL2(l2, groupingBN, marketArgs.depth)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
l2Formatted = l2WithBNToStrings(l2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marketArgs.updateOnChange) {
|
if (marketArgs.updateOnChange) {
|
||||||
if (
|
if (
|
||||||
@@ -200,13 +198,9 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
// Check if slot diffs are too large for oracle
|
// Check if slot diffs are too large for oracle
|
||||||
const skipSlotCheck =
|
const skipSlotCheck =
|
||||||
(marketType === 'perp' &&
|
(marketType === 'perp' &&
|
||||||
this.skipSlotStalenessCheckMarketsPerp.includes(
|
PERP_MARKETS_TO_SKIP_SLOT_CHECK.includes(marketArgs.marketIndex)) ||
|
||||||
marketArgs.marketIndex
|
|
||||||
)) ||
|
|
||||||
(marketType === 'spot' &&
|
(marketType === 'spot' &&
|
||||||
this.skipSlotStalenessCheckMarketsSpot.includes(
|
SPOT_MARKETS_TO_SKIP_SLOT_CHECK.includes(marketArgs.marketIndex));
|
||||||
marketArgs.marketIndex
|
|
||||||
));
|
|
||||||
if (
|
if (
|
||||||
Math.abs(slot - parseInt(l2Formatted['oracleData']['slot'])) >
|
Math.abs(slot - parseInt(l2Formatted['oracleData']['slot'])) >
|
||||||
this.killSwitchSlotDiffThreshold &&
|
this.killSwitchSlotDiffThreshold &&
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
redisChannel = getRedisChannelFromMessage(parsedMessage);
|
redisChannel = getRedisChannelFromMessage(parsedMessage);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const requestChannel = sanitiseChannelForClient(parsedMessage?.channel);
|
const requestChannel = sanitiseChannelForClient(
|
||||||
|
parsedMessage?.channel
|
||||||
|
);
|
||||||
if (requestChannel) {
|
if (requestChannel) {
|
||||||
ws.send(
|
ws.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -214,7 +216,9 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
redisChannel = getRedisChannelFromMessage(parsedMessage);
|
redisChannel = getRedisChannelFromMessage(parsedMessage);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const requestChannel = sanitiseChannelForClient(parsedMessage?.channel);
|
const requestChannel = sanitiseChannelForClient(
|
||||||
|
parsedMessage?.channel
|
||||||
|
);
|
||||||
if (requestChannel) {
|
if (requestChannel) {
|
||||||
console.log('Error unsubscribing from channel:', error.message);
|
console.log('Error unsubscribing from channel:', error.message);
|
||||||
ws.send(
|
ws.send(
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@@ -414,7 +414,7 @@
|
|||||||
kuler "^2.0.0"
|
kuler "^2.0.0"
|
||||||
|
|
||||||
"@drift-labs/sdk@file:./drift-common/protocol/sdk", "@drift-labs/sdk@file:drift-common/protocol/sdk":
|
"@drift-labs/sdk@file:./drift-common/protocol/sdk", "@drift-labs/sdk@file:drift-common/protocol/sdk":
|
||||||
version "2.82.0-beta.16"
|
version "2.84.0-beta.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@coral-xyz/anchor" "0.28.1-beta.2"
|
"@coral-xyz/anchor" "0.28.1-beta.2"
|
||||||
"@ellipsis-labs/phoenix-sdk" "^1.4.2"
|
"@ellipsis-labs/phoenix-sdk" "^1.4.2"
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
"@drift/common@file:./drift-common/common-ts":
|
"@drift/common@file:./drift-common/common-ts":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@drift-labs/sdk" "file:../Library/Caches/Yarn/v6/npm-@drift-common-1.0.0-886bdde9-d98f-4a7b-8526-a3c8414e8bbc-1715733801694/node_modules/@drift/protocol/sdk"
|
"@drift-labs/sdk" "file:../../Library/Caches/Yarn/v6/npm-@drift-common-1.0.0-e79f07a6-e675-4831-af0e-f2c460b62255-1718639556768/node_modules/@drift/protocol/sdk"
|
||||||
"@jest/globals" "^29.3.1"
|
"@jest/globals" "^29.3.1"
|
||||||
"@slack/web-api" "^6.4.0"
|
"@slack/web-api" "^6.4.0"
|
||||||
"@solana/spl-token" "^0.3.8"
|
"@solana/spl-token" "^0.3.8"
|
||||||
@@ -443,6 +443,7 @@
|
|||||||
rxjs "^7.8.1"
|
rxjs "^7.8.1"
|
||||||
tiny-invariant "^1.3.1"
|
tiny-invariant "^1.3.1"
|
||||||
tweetnacl "^1.0.3"
|
tweetnacl "^1.0.3"
|
||||||
|
typescript "^5.4.5"
|
||||||
|
|
||||||
"@ellipsis-labs/phoenix-sdk@^1.4.2":
|
"@ellipsis-labs/phoenix-sdk@^1.4.2":
|
||||||
version "1.4.2"
|
version "1.4.2"
|
||||||
@@ -5759,6 +5760,11 @@ typescript@4.5.4:
|
|||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
|
||||||
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
|
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
|
||||||
|
|
||||||
|
typescript@^5.4.5:
|
||||||
|
version "5.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
|
||||||
|
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
|
||||||
|
|
||||||
uid2@0.0.3:
|
uid2@0.0.3:
|
||||||
version "0.0.3"
|
version "0.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82"
|
resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82"
|
||||||
|
|||||||
Reference in New Issue
Block a user