diff --git a/package.json b/package.json index 508b751e0..44ed869ba 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "@solana/spl-token": "0.4.8", "@solana/web3.js": "^1.95.2", "@switchboard-xyz/common": "^2.4.4", - "@switchboard-xyz/on-demand": "^1.2.38", + "@switchboard-xyz/on-demand": "^1.2.51", "@switchboard-xyz/sbv2-lite": "^0.1.6", "@switchboard-xyz/solana.js": "^3.2.5", "big.js": "^6.1.1", diff --git a/ts/client/scripts/manageFeeWs.ts b/ts/client/scripts/manageFeeWs.ts index 01006deb2..47a414aca 100644 --- a/ts/client/scripts/manageFeeWs.ts +++ b/ts/client/scripts/manageFeeWs.ts @@ -42,8 +42,8 @@ export function manageFeeWebSocket( }); ws.addEventListener('error', (error) => { - console.log('Fee WebSocket error:', error); - onMeanCalculated(-1); + // console.log('Fee WebSocket error:', error); + onMeanCalculated(null); ws?.close(); }); diff --git a/ts/client/scripts/sb-on-demand-crank.ts b/ts/client/scripts/sb-on-demand-crank.ts index a3a715e55..11a4abdd1 100644 --- a/ts/client/scripts/sb-on-demand-crank.ts +++ b/ts/client/scripts/sb-on-demand-crank.ts @@ -34,7 +34,7 @@ import { import { PerpMarketIndex } from '../src/accounts/perp'; import { MangoClient } from '../src/client'; import { MANGO_V4_ID, MANGO_V4_MAIN_GROUP } from '../src/constants'; -import { createComputeBudgetIx } from '../src/utils/rpc'; +import { createComputeBudgetIx, createComputeLimitIx } from '../src/utils/rpc'; import { manageFeeWebSocket } from './manageFeeWs'; import { getOraclesForMangoGroup, @@ -202,7 +202,7 @@ async function setupBackgroundRefresh( function (a, b) { return a.oracle.oraclePk.equals(b.oracle.oraclePk); }, - ); + ).slice(0, 6); console.log( `[main] round candidates | Stale: ${staleOracles @@ -212,68 +212,62 @@ async function setupBackgroundRefresh( .join(', ')}`, ); - // todo use chunk - // todo use luts - - // const [pullIxs, luts] = await PullFeed.fetchUpdateManyIx( - // sbOnDemandProgram as any, - // { - // feeds: oraclesToCrank.map((o) => new PublicKey(o.oracle.oraclePk)), - // numSignatures: 3, - // }, - // ); - - const recentSlothashes = await RecentSlotHashes.fetchLatestNSlothashes( - connection as any, - 30, + if ( + oraclesToCrank.length == 0 + ) { + await new Promise((r) => setTimeout(r, SLEEP_MS)); + continue; + } + + // can do 6 per tx + const numSignatures = 2; + const [pullIx, _luts] = await PullFeed.fetchUpdateManyIx( + sbOnDemandProgram as any, + { + feeds: oraclesToCrank.map((o) => new PublicKey(o.oracle.oraclePk)), + numSignatures, + crossbarClient, + payer: user.publicKey, + }, ); - const pullIxs = ( - await Promise.all( - oraclesToCrank.map(async (oracle) => { - const pullIx = await preparePullIx( - sbOnDemandProgram, - oracle, - recentSlothashes, - ); - return pullIx !== undefined ? pullIx : null; - }), - ) - ).filter((pullIx) => pullIx !== null); const ixPreparedAt = Date.now(); - const ixsChunks = chunk(shuffle(pullIxs), 2, false); const lamportsPerCu_ = Math.min( Math.max(lamportsPerCu ?? 150_000, 150_000), 500_000, ); + const cuLimit = 150_000 + oraclesToCrank.length * 30_000 * numSignatures; + // dont await, fire and forget sendSignAndConfirmTransactions({ connection, wallet: new Wallet(user), backupConnections: [ - ...(CLUSTER_URL_2 ? [new Connection(LITE_RPC_URL!, 'recent')] : []), + ...(LITE_RPC_URL ? [new Connection(LITE_RPC_URL!, 'recent')] : []), ...(CLUSTER_URL_2 ? [new Connection(CLUSTER_URL_2!, 'recent')] : []), ], // fail rather quickly and retry submission from scratch // timeout using finalized to stay below switchboard oracle staleness limit timeoutStrategy: { block, startBlockCheckAfterSecs: 20 }, - transactionInstructions: ixsChunks.map((txChunk) => ({ + transactionInstructions: [{ instructionsSet: [ { signers: [], transactionInstruction: createComputeBudgetIx(lamportsPerCu_), }, - ...txChunk.map((tx) => ({ + { + signers: [], + transactionInstruction: createComputeLimitIx(cuLimit), + }, + { signers: [], - transactionInstruction: tx, - // TODO disable alts for now - // alts: SBOD_ORACLE_LUTS.map(x=>new PublicKey(x)), - })), + transactionInstruction: pullIx, + } ], sequenceType: SequenceType.Parallel, - })), + }], config: { maxTxesInBatch: 10, autoRetry: false, diff --git a/ts/client/src/accounts/oracle.ts b/ts/client/src/accounts/oracle.ts index 94d33ed2c..d1b606e44 100644 --- a/ts/client/src/accounts/oracle.ts +++ b/ts/client/src/accounts/oracle.ts @@ -434,7 +434,7 @@ export function isOracleStaleOrUnconfident( } if (debug && deviation) { console.log( - `- ${debugPrefix?.padStart(30)}: deviation within confidence tolerance ${deviation.mul(I80F48.fromNumber(100)).div(confFilter).toFixed(3)}%`, + `- ${debugPrefix?.padStart(30)}: deviation within confidence tolerance ${deviation.div(price).mul(I80F48.fromNumber(100)).toFixed(3)}%`, ); } diff --git a/ts/client/src/utils/rpc.ts b/ts/client/src/utils/rpc.ts index 7e01a7987..053f7b322 100644 --- a/ts/client/src/utils/rpc.ts +++ b/ts/client/src/utils/rpc.ts @@ -288,6 +288,15 @@ export const createComputeBudgetIx = ( return computeBudgetIx; }; +export const createComputeLimitIx = ( + units: number, +): TransactionInstruction => { + const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({ + units, + }); + return computeBudgetIx; +}; + export class MangoError extends Error { message: string; txid: string; diff --git a/yarn.lock b/yarn.lock index 963b02d3b..477d2007c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -901,7 +901,7 @@ dependencies: tslib "^2.4.0" -"@switchboard-xyz/common@^2.3.16", "@switchboard-xyz/common@^2.4.4", "@switchboard-xyz/common@^2.4.7": +"@switchboard-xyz/common@^2.3.16", "@switchboard-xyz/common@^2.4.4": version "2.4.7" resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.4.7.tgz#7b582e7cdd4c17a3d4e36beead520a5363f4f0a8" integrity sha512-gkUuy7n15gq+D0IKkqKsSqgWb1w5t3rfpjdTkJX0AAlL75QXZfi5fL4Ttwb22ALOWYLYuvYCD0uXFyczgMMkIQ== @@ -918,16 +918,33 @@ protobufjs "^7.2.6" yaml "^2.5.0" -"@switchboard-xyz/on-demand@^1.2.38": - version "1.2.38" - resolved "https://registry.yarnpkg.com/@switchboard-xyz/on-demand/-/on-demand-1.2.38.tgz#de368176a89b05c365d916c5cb419e1cf918acf3" - integrity sha512-BaZc78dDbmofJmk60SD0dDsf953rnQ9MaTeUrFyn8Z0zRiu79hTJMeKisKbC/pOCG7EMpZZRF/sqXujRfG6QFw== +"@switchboard-xyz/common@^2.5.3": + version "2.5.5" + resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.5.5.tgz#773c20584877af86abe724e9787de8f3e6385bce" + integrity sha512-/qUmZlrfQyckvHGzS5Cj2+Ocd3eE64rPjQb1eEocc5dv4HXZMqbBbpM6BwURrQhZ65i3jO1evhTcAk3TVqCA8w== + dependencies: + "@solana/web3.js" "^1.93.0" + axios "^1.7.2" + big.js "^6.2.1" + bn.js "^5.2.1" + bs58 "^5.0.0" + cron-validator "^1.3.1" + decimal.js "^10.4.3" + js-sha256 "^0.11.0" + lodash "^4.17.21" + protobufjs "^7.2.6" + yaml "^2.5.0" + +"@switchboard-xyz/on-demand@^1.2.51": + version "1.2.51" + resolved "https://registry.yarnpkg.com/@switchboard-xyz/on-demand/-/on-demand-1.2.51.tgz#ad42a0855dcff59d3cd7e34ba4dc9ea4531bfddf" + integrity sha512-IqtAEtYdCRQqG8a3tL5WOcLgBco8Iionu60Q+hQzCslQw76zDlkToHkI+71ASulFdZ2z+2XjaKV5ZVqPcYgP7g== dependencies: "@brokerloop/ttlcache" "^3.2.3" "@coral-xyz/anchor-30" "npm:@coral-xyz/anchor@0.30.1" "@solana/web3.js" "^1.95.0" "@solworks/soltoolkit-sdk" "^0.0.23" - "@switchboard-xyz/common" "^2.4.7" + "@switchboard-xyz/common" "^2.5.3" axios "^1.7.4" big.js "^6.2.1" bs58 "^5.0.0" @@ -2766,14 +2783,14 @@ node-addon-api@^5.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== -node-fetch@3.3.2, "node-fetch@npm:@blockworks-foundation/node-fetch@2.6.11": +node-fetch@3.3.2, node-fetch@^2.6.12, node-fetch@^2.7.0, "node-fetch@npm:@blockworks-foundation/node-fetch@2.6.11": version "2.6.11" resolved "https://registry.yarnpkg.com/@blockworks-foundation/node-fetch/-/node-fetch-2.6.11.tgz#fb536ef0e6a960e7b7993f3c1d3b3bba9bdfbc56" integrity sha512-HeDTxpIypSR4qCoqgUXGr8YL4OG1z7BbV4VhQ9iQs+pt2wV3MtqO+sQk2vXK3WDKu5C6BsbGmWE22BmIrcuOOw== dependencies: whatwg-url "^5.0.0" -node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.7.0: +node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==