Преглед изворни кода

fix: remove open book cache, improve startup speed

Filip Dunder пре 1 година
родитељ
комит
ab16a326f0
2 измењених фајлова са 39 додато и 69 уклоњено
  1. 27 34
      buy.ts
  2. 12 35
      market/market.ts

+ 27 - 34
buy.ts

@@ -3,7 +3,6 @@ import {
   LIQUIDITY_STATE_LAYOUT_V4,
   LiquidityPoolKeys,
   LiquidityStateV4,
-  MARKET_STATE_LAYOUT_V2,
   MARKET_STATE_LAYOUT_V3,
   MarketStateV3,
   Token,
@@ -31,7 +30,7 @@ import {
   createPoolKeys,
 } from './liquidity';
 import { retrieveEnvVariable } from './utils';
-import { getAllMarketsV3, MinimalMarketLayoutV3 } from './market';
+import { getMinimalMarketV3, MinimalMarketLayoutV3 } from './market';
 import pino from 'pino';
 import bs58 from 'bs58';
 import * as fs from 'fs';
@@ -144,17 +143,6 @@ async function init(): Promise<void> {
     `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`,
   );
 
-  logger.info(`Loading existing markets...`);
-  // get all open-book markets
-  const allMarkets = await getAllMarketsV3(
-    solanaConnection,
-    quoteToken.mint,
-    commitment,
-  );
-  existingOpenBookMarkets = new Set(allMarkets.map((p) => p.id.toString()));
-  logger.info(
-    `Loaded ${existingOpenBookMarkets.size} ${quoteToken.symbol} markets`,
-  );
   // check existing wallet for associated token account of quote mint
   const tokenAccounts = await getTokenAccounts(
     solanaConnection,
@@ -187,6 +175,21 @@ async function init(): Promise<void> {
   loadSnipeList();
 }
 
+function saveTokenAccount(mint: PublicKey, accountData: MinimalMarketLayoutV3) {
+  const ata = getAssociatedTokenAddressSync(mint, wallet.publicKey);
+  const tokenAccount = <MinimalTokenAccountData>{
+    address: ata,
+    mint: mint,
+    market: <MinimalMarketLayoutV3>{
+      bids: accountData.bids,
+      asks: accountData.asks,
+      eventQueue: accountData.eventQueue,
+    },
+  };
+  existingTokenAccounts.set(mint.toString(), tokenAccount);
+  return tokenAccount;
+}
+
 export async function processRaydiumPool(
   id: PublicKey,
   poolState: LiquidityStateV4,
@@ -216,21 +219,7 @@ export async function processOpenBookMarket(
       return;
     }
 
-    const ata = getAssociatedTokenAddressSync(
-      accountData.baseMint,
-      wallet.publicKey,
-    );
-    existingTokenAccounts.set(accountData.baseMint.toString(), <
-      MinimalTokenAccountData
-    >{
-      address: ata,
-      mint: accountData.baseMint,
-      market: <MinimalMarketLayoutV3>{
-        bids: accountData.bids,
-        asks: accountData.asks,
-        eventQueue: accountData.eventQueue,
-      },
-    });
+    saveTokenAccount(accountData.baseMint, accountData);
   } catch (e) {
     logger.error({ ...accountData, error: e }, `Failed to process market`);
   }
@@ -240,12 +229,16 @@ async function buy(
   accountId: PublicKey,
   accountData: LiquidityStateV4,
 ): Promise<void> {
-  const tokenAccount = existingTokenAccounts.get(
-    accountData.baseMint.toString(),
-  );
+  let tokenAccount = existingTokenAccounts.get(accountData.baseMint.toString());
 
   if (!tokenAccount) {
-    return;
+    // it's possible that we didn't have time to fetch open book data
+    const market = await getMinimalMarketV3(
+      solanaConnection,
+      accountData.marketId,
+      commitment,
+    );
+    tokenAccount = saveTokenAccount(accountData.baseMint, market);
   }
 
   tokenAccount.poolKeys = createPoolKeys(
@@ -378,10 +371,10 @@ const runListener = async () => {
     },
     commitment,
     [
-      { dataSize: MARKET_STATE_LAYOUT_V2.span },
+      { dataSize: MARKET_STATE_LAYOUT_V3.span },
       {
         memcmp: {
-          offset: MARKET_STATE_LAYOUT_V2.offsetOf('quoteMint'),
+          offset: MARKET_STATE_LAYOUT_V3.offsetOf('quoteMint'),
           bytes: quoteToken.mint.toBase58(),
         },
       },

+ 12 - 35
market/market.ts

@@ -1,46 +1,23 @@
 import { Commitment, Connection, PublicKey } from '@solana/web3.js';
-import {
-  GetStructureSchema,
-  MARKET_STATE_LAYOUT_V3,
-} from '@raydium-io/raydium-sdk';
-import {
-  MINIMAL_MARKET_STATE_LAYOUT_V3,
-  OPENBOOK_PROGRAM_ID,
-} from '../liquidity';
+import { GetStructureSchema, MARKET_STATE_LAYOUT_V3 } from '@raydium-io/raydium-sdk';
+import { MINIMAL_MARKET_STATE_LAYOUT_V3 } from '../liquidity';
 
-export type MinimalOpenBookAccountData = {
-  id: PublicKey;
-  programId: PublicKey;
-};
 export type MinimalMarketStateLayoutV3 = typeof MINIMAL_MARKET_STATE_LAYOUT_V3;
 export type MinimalMarketLayoutV3 =
   GetStructureSchema<MinimalMarketStateLayoutV3>;
 
-export async function getAllMarketsV3(
+export async function getMinimalMarketV3(
   connection: Connection,
-  quoteMint: PublicKey,
+  marketId: PublicKey,
   commitment?: Commitment,
-): Promise<MinimalOpenBookAccountData[]> {
-  const { span } = MARKET_STATE_LAYOUT_V3;
-  const accounts = await connection.getProgramAccounts(OPENBOOK_PROGRAM_ID, {
-    dataSlice: { offset: 0, length: 0 },
-    commitment: commitment,
-    filters: [
-      { dataSize: span },
-      {
-        memcmp: {
-          offset: MARKET_STATE_LAYOUT_V3.offsetOf('quoteMint'),
-          bytes: quoteMint.toBase58(),
-        },
-      },
-    ],
+): Promise<MinimalMarketLayoutV3> {
+  const marketInfo = await connection.getAccountInfo(marketId, {
+    commitment,
+    dataSlice: {
+      offset: MARKET_STATE_LAYOUT_V3.offsetOf('eventQueue'),
+      length: 32 * 3,
+    },
   });
 
-  return accounts.map(
-    (info) =>
-      <MinimalOpenBookAccountData>{
-        id: info.pubkey,
-        programId: OPENBOOK_PROGRAM_ID,
-      },
-  );
+  return MINIMAL_MARKET_STATE_LAYOUT_V3.decode(marketInfo!.data);
 }