diff --git a/src/dlob-subscriber/DLOBSubscriberIO.ts b/src/dlob-subscriber/DLOBSubscriberIO.ts index 64d2a54..5cff973 100644 --- a/src/dlob-subscriber/DLOBSubscriberIO.ts +++ b/src/dlob-subscriber/DLOBSubscriberIO.ts @@ -4,6 +4,7 @@ import { DLOBSubscriptionConfig, L2OrderBookGenerator, MarketType, + PositionDirection, groupL2, isVariant, } from '@drift-labs/sdk'; @@ -248,6 +249,35 @@ export class DLOBSubscriberIO extends DLOBSubscriber { `last_update_orderbook_${marketType}_${marketArgs.marketIndex}_depth_5`, JSON.stringify(l2Formatted_depth5) ); + + const oraclePriceData = + marketType === 'spot' + ? this.driftClient.getOracleDataForSpotMarket(marketArgs.marketIndex) + : this.driftClient.getOracleDataForPerpMarket(marketArgs.marketIndex); + const bids = this.dlob + .getBestMakers({ + marketIndex: marketArgs.marketIndex, + marketType: marketArgs.marketType, + direction: PositionDirection.LONG, + slot: slot, + oraclePriceData, + numMakers: 4, + }) + .map((x) => x.toString()); + const asks = this.dlob + .getBestMakers({ + marketIndex: marketArgs.marketIndex, + marketType: marketArgs.marketType, + direction: PositionDirection.SHORT, + slot, + oraclePriceData, + numMakers: 4, + }) + .map((x) => x.toString()); + this.redisClient.client.set( + `last_update_orderbook_best_makers_${marketType}_${marketArgs.marketIndex}`, + JSON.stringify({ bids, asks, slot }) + ); } getL3AndSendMsg(marketArgs: wsMarketArgs): void { diff --git a/src/index.ts b/src/index.ts index 8824173..3fa4e52 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,6 @@ import { DriftEnv, SlotSubscriber, Wallet, - getUserStatsAccountPublicKey, getVariant, initialize, isVariant, @@ -720,8 +719,7 @@ const main = async (): Promise => { marketIndex, marketType, side, // bid or ask - limit, // number of unique makers to return, if undefined will return all - includeUserStats, + limit, } = req.query; const { normedMarketType, normedMarketIndex, error } = validateDlobQuery( @@ -752,9 +750,46 @@ const main = async (): Promise => { return; } normedLimit = parseInt(limit as string); + } else { + normedLimit = 4; } - const topMakers = new Set(); + let topMakers: string[]; + if (useRedis) { + const redisClient = isVariant(normedMarketType, 'perp') + ? perpMarketRedisMap.get(normedMarketIndex).client + : spotMarketRedisMap.get(normedMarketIndex).client; + const redisResponse = await redisClient.client.get( + `last_update_orderbook_best_makers_${getVariant( + normedMarketType + )}_${marketIndex}` + ); + if (redisResponse) { + const parsedResponse = JSON.parse(redisResponse); + if ( + parsedResponse && + Math.abs(dlobProvider.getSlot() - parsedResponse.slot) < + SLOT_STALENESS_TOLERANCE + ) { + if (side === 'bid') { + topMakers = parsedResponse.bids; + } else { + topMakers = parsedResponse.asks; + } + } + } + } + + if (topMakers) { + cacheHitCounter.add(1, { + miss: false, + }); + res.writeHead(200); + res.end(JSON.stringify(topMakers)); + return; + } + + const topMakersSet = new Set(); let foundMakers = 0; const findMakers = async (sideGenerator: Generator) => { for (const side of sideGenerator) { @@ -763,23 +798,10 @@ const main = async (): Promise => { } if (side.userAccount) { const maker = side.userAccount; - if (topMakers.has(maker)) { + if (topMakersSet.has(maker)) { continue; } else { - if (`${includeUserStats}`.toLowerCase() === 'true') { - const userAccount = dlobProvider.getUserAccount( - new PublicKey(side.userAccount) - ); - topMakers.add([ - userAccount, - getUserStatsAccountPublicKey( - driftClient.program.programId, - userAccount.authority - ), - ]); - } else { - topMakers.add(side.userAccount); - } + topMakersSet.add(side.userAccount); foundMakers++; } } else { @@ -811,9 +833,12 @@ const main = async (): Promise => { ) ); } - + topMakers = [...topMakersSet]; + cacheHitCounter.add(1, { + miss: true, + }); res.writeHead(200); - res.end(JSON.stringify([...topMakers])); + res.end(JSON.stringify(topMakers)); } catch (err) { next(err); }