From 64130d7e149f8f8a3c61addd3249dea34b5f2274 Mon Sep 17 00:00:00 2001 From: wphan Date: Mon, 28 Oct 2024 15:08:22 -0700 Subject: [PATCH 1/5] fix bundlesender limit --- src/bundleSender.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bundleSender.ts b/src/bundleSender.ts index 3126c47e..41168b87 100644 --- a/src/bundleSender.ts +++ b/src/bundleSender.ts @@ -505,7 +505,7 @@ export class BundleSender { // +1 for tip tx, jito max is 5 let b: Bundle | Error = new Bundle( signedTxs, - Math.max(signedTxs.length + 1, 5) + maxAllowedTxs ); if (addTipTx) { From 388e1f10aba818da35f7882f14a468fe748f0138 Mon Sep 17 00:00:00 2001 From: wphan Date: Mon, 28 Oct 2024 15:49:53 -0700 Subject: [PATCH 2/5] debug empty txs --- src/bots/makerBidAskTwapCrank.ts | 2 +- src/bundleSender.ts | 5 +-- .../filler/fillerMultithreaded.ts | 32 ++++++++++++++----- .../spotFiller/spotFillerMultithreaded.ts | 25 ++++++++++++--- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/bots/makerBidAskTwapCrank.ts b/src/bots/makerBidAskTwapCrank.ts index f6d0058e..aceab428 100644 --- a/src/bots/makerBidAskTwapCrank.ts +++ b/src/bots/makerBidAskTwapCrank.ts @@ -57,7 +57,7 @@ const TX_LAND_RATE_THRESHOLD = process.env.TX_LAND_RATE_THRESHOLD ? parseFloat(process.env.TX_LAND_RATE_THRESHOLD) || 0.5 : 0.5; const NUM_MAKERS_TO_LOOK_AT_FOR_TWAP_CRANK = 2; -const TX_PER_JITO_BUNDLE = 5; +const TX_PER_JITO_BUNDLE = 3; function isCriticalError(e: Error): boolean { // retrying on this error is standard diff --git a/src/bundleSender.ts b/src/bundleSender.ts index 41168b87..3156abef 100644 --- a/src/bundleSender.ts +++ b/src/bundleSender.ts @@ -503,10 +503,7 @@ export class BundleSender { } // +1 for tip tx, jito max is 5 - let b: Bundle | Error = new Bundle( - signedTxs, - maxAllowedTxs - ); + let b: Bundle | Error = new Bundle(signedTxs, maxAllowedTxs); if (addTipTx) { const tipAccountToUse = diff --git a/src/experimental-bots/filler/fillerMultithreaded.ts b/src/experimental-bots/filler/fillerMultithreaded.ts index 2b68f79e..795ccb58 100644 --- a/src/experimental-bots/filler/fillerMultithreaded.ts +++ b/src/experimental-bots/filler/fillerMultithreaded.ts @@ -1607,7 +1607,10 @@ export class FillerMultithreaded { let makerInfosToUse = makerInfos; const buildTxWithMakerInfos = async ( makers: DataAndSlot[] - ): Promise => { + ): Promise => { + if (makers.length === 0) { + return undefined; + } ixs.push( await this.driftClient.getFillPerpOrderIx( await getUserAccountPublicKey( @@ -1694,6 +1697,9 @@ export class FillerMultithreaded { }; let simResult = await buildTxWithMakerInfos(makerInfosToUse); + if (simResult === undefined) { + return true; + } let txAccounts = simResult.tx.message.getAccountKeys({ addressLookupTableAccounts: this.lookupTableAccounts, }).length; @@ -1706,9 +1712,6 @@ export class FillerMultithreaded { ); makerInfosToUse = makerInfosToUse.slice(0, makerInfosToUse.length - 1); simResult = await buildTxWithMakerInfos(makerInfosToUse); - txAccounts = simResult.tx.message.getAccountKeys({ - addressLookupTableAccounts: this.lookupTableAccounts!, - }).length; } if (makerInfosToUse.length === 0) { @@ -1718,14 +1721,27 @@ export class FillerMultithreaded { return true; } + if (simResult === undefined) { + logger.error( + `${logPrefix} No simResult after ${attempt} attempts (fillTxId: ${fillTxId})` + ); + return true; + } + + txAccounts = simResult.tx.message.getAccountKeys({ + addressLookupTableAccounts: this.lookupTableAccounts!, + }).length; + logger.info( - `${logPrefix} tryFillMultiMakerPerpNodes estimated CUs: ${simResult.cuEstimate} (fillTxId: ${fillTxId})` + `${logPrefix} tryFillMultiMakerPerpNodes estimated CUs: ${ + simResult!.cuEstimate + } (fillTxId: ${fillTxId})` ); - if (simResult.simError) { + if (simResult!.simError) { logger.error( `${logPrefix} Error simulating multi maker perp node (fillTxId: ${fillTxId}): ${JSON.stringify( - simResult.simError + simResult!.simError )}\nTaker slot: ${takerUserSlot}\nMaker slots: ${makerInfosToUse .map((m) => ` ${m.data.maker.toBase58()}: ${m.slot}`) .join('\n')}` @@ -1735,7 +1751,7 @@ export class FillerMultithreaded { this.sendFillTxAndParseLogs( fillTxId, [nodeToFill], - simResult.tx, + simResult!.tx, buildForBundle ); } else { diff --git a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts index 4286d469..07c080ae 100644 --- a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts +++ b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts @@ -993,7 +993,10 @@ export class SpotFillerMultithreaded { let makerInfosToUse = makerInfos; const buildTxWithMakerInfos = async ( makers: DataAndSlot[] - ): Promise => { + ): Promise => { + if (makers.length === 0) { + return undefined; + } ixs.push( await this.driftClient.getFillSpotOrderIx( new PublicKey(takerUserPubKey), @@ -1042,6 +1045,9 @@ export class SpotFillerMultithreaded { }; let simResult = await buildTxWithMakerInfos(makerInfosToUse); + if (simResult === undefined) { + return true; + } let txAccounts = simResult.tx.message.getAccountKeys({ addressLookupTableAccounts: this.lookupTableAccounts, }).length; @@ -1054,9 +1060,6 @@ export class SpotFillerMultithreaded { ); makerInfosToUse = makerInfosToUse.slice(0, makerInfosToUse.length - 1); simResult = await buildTxWithMakerInfos(makerInfosToUse); - txAccounts = simResult.tx.message.getAccountKeys({ - addressLookupTableAccounts: this.lookupTableAccounts, - }).length; } if (makerInfosToUse.length === 0) { @@ -1065,6 +1068,16 @@ export class SpotFillerMultithreaded { ); return true; } + if (simResult === undefined) { + logger.error( + `No simResult after ${attempt} attempts (fillTxId: ${fillTxId})` + ); + return true; + } + + txAccounts = simResult.tx.message.getAccountKeys({ + addressLookupTableAccounts: this.lookupTableAccounts, + }).length; logger.info( `tryFillMultiMakerSpotNodes estimated CUs: ${simResult.cuEstimate} (fillTxId: ${fillTxId})` @@ -1197,7 +1210,9 @@ export class SpotFillerMultithreaded { units: 1_400_000, }), ]; - if (!buildForBundle) { + if (buildForBundle) { + ixs.push(this.bundleSender!.getTipIx()); + } else { const priorityFee = Math.floor( this.priorityFeeSubscriber.getPriorityFees( 'spot', From 0727714c057d63da5feaa4d527af94bc86e97066 Mon Sep 17 00:00:00 2001 From: wphan Date: Mon, 28 Oct 2024 16:29:20 -0700 Subject: [PATCH 3/5] check for empty txs --- .../filler/fillerMultithreaded.ts | 18 ++++++++++++++++++ .../spotFiller/spotFillerMultithreaded.ts | 9 +++++++++ 2 files changed, 27 insertions(+) diff --git a/src/experimental-bots/filler/fillerMultithreaded.ts b/src/experimental-bots/filler/fillerMultithreaded.ts index 795ccb58..da246ca1 100644 --- a/src/experimental-bots/filler/fillerMultithreaded.ts +++ b/src/experimental-bots/filler/fillerMultithreaded.ts @@ -1236,6 +1236,8 @@ export class FillerMultithreaded { ); } + const nonActionIxCount = ixs.length; + nodeToTrigger.node.haveTrigger = true; // @ts-ignore const buffer = Buffer.from(nodeToTrigger.node.userAccountData.data); @@ -1288,6 +1290,15 @@ export class FillerMultithreaded { ixs = removePythIxs(ixs); } + if (ixs.length === nonActionIxCount) { + logger.warn( + `${logPrefix} No ixs in trigger tx (account: ${ + nodeToTrigger.node.userAccount + }, order ${nodeToTrigger.node.order.orderId.toString()})` + ); + return; + } + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, @@ -2072,6 +2083,8 @@ export class FillerMultithreaded { ); } + const nonActionIxCount = ixs.length; + ixs.push( ...(await this.driftClient.getSettlePNLsIxs( [ @@ -2086,6 +2099,11 @@ export class FillerMultithreaded { )) ); + if (ixs.length === nonActionIxCount) { + logger.warn(`${logPrefix} No ixs in settlePnls tx`); + return; + } + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, diff --git a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts index 07c080ae..61ac30fb 100644 --- a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts +++ b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts @@ -721,6 +721,8 @@ export class SpotFillerMultithreaded { ); } + const nonActionIxCount = ixs.length; + ixs.push( await this.driftClient.getTriggerOrderIx( new PublicKey(nodeToTrigger.node.userAccount), @@ -736,6 +738,13 @@ export class SpotFillerMultithreaded { ); } + if (ixs.length === nonActionIxCount) { + logger.warn( + `${logPrefix} No ixs in trigger tx for (account: ${nodeToTrigger.node.userAccount.toString()}, order: ${nodeToTrigger.node.order.orderId.toString()})` + ); + return; + } + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, From e8e06663f15a60f6e8ef1b97cf8e81e2c398c00d Mon Sep 17 00:00:00 2001 From: wphan Date: Mon, 28 Oct 2024 16:53:07 -0700 Subject: [PATCH 4/5] add missing tip ixs --- src/experimental-bots/filler/fillerMultithreaded.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/experimental-bots/filler/fillerMultithreaded.ts b/src/experimental-bots/filler/fillerMultithreaded.ts index da246ca1..2bebb19b 100644 --- a/src/experimental-bots/filler/fillerMultithreaded.ts +++ b/src/experimental-bots/filler/fillerMultithreaded.ts @@ -1583,7 +1583,9 @@ export class FillerMultithreaded { ixs.push(...pythIxs); } - if (!buildForBundle) { + if (buildForBundle) { + ixs.push(this.bundleSender!.getTipIx()); + } else { ixs.push( getPriorityFeeInstruction( Math.floor( @@ -1809,7 +1811,9 @@ export class FillerMultithreaded { ixs.push(...pythIxs); } - if (!buildForBundle) { + if (buildForBundle) { + ixs.push(this.bundleSender!.getTipIx()); + } else { ixs.push( getPriorityFeeInstruction( Math.floor( From b5348a78476bbb15bbc10b75d098c97473bed1da Mon Sep 17 00:00:00 2001 From: wphan Date: Mon, 28 Oct 2024 17:14:47 -0700 Subject: [PATCH 5/5] add memo --- .../filler/fillerMultithreaded.ts | 16 ++++++++++++++++ .../spotFiller/spotFillerMultithreaded.ts | 19 +++++++++++++++++++ src/utils.ts | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/src/experimental-bots/filler/fillerMultithreaded.ts b/src/experimental-bots/filler/fillerMultithreaded.ts index 2bebb19b..710ac3aa 100644 --- a/src/experimental-bots/filler/fillerMultithreaded.ts +++ b/src/experimental-bots/filler/fillerMultithreaded.ts @@ -61,6 +61,7 @@ import { // getStaleOracleMarketIndexes, handleSimResultError, logMessageForNodeToFill, + MEMO_PROGRAM_ID, removePythIxs, simulateAndGetTxWithCUs, SimulateAndGetTxWithCUsResponse, @@ -1680,6 +1681,13 @@ export class FillerMultithreaded { ixs = removePythIxs(ixs); } + ixs.push( + new TransactionInstruction({ + programId: MEMO_PROGRAM_ID, + keys: [], + data: Buffer.from(`mm-perp ${fillTxId} ${makers.length}`, 'utf-8'), + }) + ); const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, @@ -1893,6 +1901,14 @@ export class FillerMultithreaded { ixs = removePythIxs(ixs); } + ixs.push( + new TransactionInstruction({ + programId: MEMO_PROGRAM_ID, + keys: [], + data: Buffer.from(`ff-perp ${fillTxId}`, 'utf-8'), + }) + ); + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, diff --git a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts index 61ac30fb..ad5a159f 100644 --- a/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts +++ b/src/experimental-bots/spotFiller/spotFillerMultithreaded.ts @@ -48,6 +48,7 @@ import { RuntimeSpec, } from '../../metrics'; import { + MEMO_PROGRAM_ID, SimulateAndGetTxWithCUsResponse, getAllPythOracleUpdateIxs, getFillSignatureFromUserAccountAndOrderId, @@ -1023,6 +1024,15 @@ export class SpotFillerMultithreaded { await this.driftClient.getRevertFillIx(user.userAccountPublicKey) ); } + + ixs.push( + new TransactionInstruction({ + programId: MEMO_PROGRAM_ID, + keys: [], + data: Buffer.from(`mm-spot ${fillTxId} ${makers.length}`, 'utf-8'), + }) + ); + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, @@ -1254,6 +1264,15 @@ export class SpotFillerMultithreaded { await this.driftClient.getRevertFillIx(user.userAccountPublicKey) ); } + + ixs.push( + new TransactionInstruction({ + programId: MEMO_PROGRAM_ID, + keys: [], + data: Buffer.from(`ff-spot ${fillTxId}`, 'utf-8'), + }) + ); + const simResult = await simulateAndGetTxWithCUs({ ixs, connection: this.driftClient.connection, diff --git a/src/utils.ts b/src/utils.ts index 93aa21e4..8c6146d7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -70,6 +70,10 @@ export const TOKEN_FAUCET_PROGRAM_ID = new PublicKey( 'V4v1mQiAdLz4qwckEb45WqHYceYizoib39cDBHSWfaB' ); +export const MEMO_PROGRAM_ID = new PublicKey( + 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr' +); + const JUPITER_SLIPPAGE_BPS = 100; export const PRIORITY_FEE_SERVER_RATE_LIMIT_PER_MIN = 300;