From 70bb0455721f60728601a12debb36d6bee35db7a Mon Sep 17 00:00:00 2001 From: Will <82029448+wjthieme@users.noreply.github.com> Date: Fri, 15 Mar 2024 09:32:52 -0400 Subject: [PATCH] Make compute budget priority fee selection more configurable (#73) * Make compute budget priority fee selection more configurable * nits --- packages/common-sdk/package.json | 2 +- .../src/web3/transactions/compute-budget.ts | 20 ++++++++++++------- .../web3/transactions/transactions-builder.ts | 13 ++++++------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/common-sdk/package.json b/packages/common-sdk/package.json index 144c91b..0b60c35 100644 --- a/packages/common-sdk/package.json +++ b/packages/common-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@orca-so/common-sdk", - "version": "0.5.1", + "version": "0.5.2", "description": "Common Typescript components across Orca", "repository": "https://github.com/orca-so/orca-sdks", "author": "Orca Foundation", diff --git a/packages/common-sdk/src/web3/transactions/compute-budget.ts b/packages/common-sdk/src/web3/transactions/compute-budget.ts index 466f736..dfd0c2c 100644 --- a/packages/common-sdk/src/web3/transactions/compute-budget.ts +++ b/packages/common-sdk/src/web3/transactions/compute-budget.ts @@ -1,25 +1,31 @@ import { Connection, PublicKey, RecentPrioritizationFees } from "@solana/web3.js"; import { Instruction } from "./types"; +export const MICROLAMPORTS_PER_LAMPORT = 1_000_000; +export const DEFAULT_PRIORITY_FEE_PERCENTILE = 0.9; +export const DEFAULT_MAX_PRIORITY_FEE_LAMPORTS = 1000000; // 0.001 SOL + export async function getPriorityFeeInLamports( connection: Connection, computeBudgetLimit: number, instructions: Instruction[], + percentile: number ): Promise { const recentPriorityFees = await connection.getRecentPrioritizationFees({ lockedWritableAccounts: getLockWritableAccounts(instructions), }); - const priorityFee = getPriorityFeeSuggestion(recentPriorityFees); - return (priorityFee * computeBudgetLimit) / 1_000_000; + const priorityFee = getPriorityFeeSuggestion(recentPriorityFees, percentile); + return (priorityFee * computeBudgetLimit) / MICROLAMPORTS_PER_LAMPORT; } -function getPriorityFeeSuggestion(recentPriorityFees: RecentPrioritizationFees[]): number { - // Take the 80th percentile of the last 20 slots +function getPriorityFeeSuggestion(recentPriorityFees: RecentPrioritizationFees[], percentile: number): number { + // Take the Xth percentile of all the slots returned const sortedPriorityFees = recentPriorityFees - .sort((a, b) => a.slot - b.slot) - .slice(-20) .sort((a, b) => a.prioritizationFee - b.prioritizationFee); - const percentileIndex = Math.floor(sortedPriorityFees.length * 0.8); + const percentileIndex = Math.min( + Math.max(Math.floor(sortedPriorityFees.length * percentile), 0), + sortedPriorityFees.length - 1 + ); return sortedPriorityFees[percentileIndex].prioritizationFee; } diff --git a/packages/common-sdk/src/web3/transactions/transactions-builder.ts b/packages/common-sdk/src/web3/transactions/transactions-builder.ts index b83beba..fcad493 100644 --- a/packages/common-sdk/src/web3/transactions/transactions-builder.ts +++ b/packages/common-sdk/src/web3/transactions/transactions-builder.ts @@ -14,7 +14,7 @@ import { import { Wallet } from "../wallet"; import { Instruction, TransactionPayload } from "./types"; import { MEASUREMENT_BLOCKHASH } from "./constants"; -import { getPriorityFeeInLamports } from "./compute-budget"; +import { DEFAULT_MAX_PRIORITY_FEE_LAMPORTS, DEFAULT_PRIORITY_FEE_PERCENTILE, MICROLAMPORTS_PER_LAMPORT, getPriorityFeeInLamports } from "./compute-budget"; const DEFAULT_MAX_COMPUTE_UNIT_LIMIT = 1_400_000; @@ -66,6 +66,7 @@ type ComputeBudgetOption = { type: "auto"; maxPriorityFeeLamports?: number; computeBudgetLimit?: number; + percentile?: number; }; type SyncBuildOptions = BuildOptions & Required; @@ -234,7 +235,7 @@ export class TransactionBuilder { if (computeBudgetOption.type === "fixed") { const computeLimit = computeBudgetOption.computeBudgetLimit ?? DEFAULT_MAX_COMPUTE_UNIT_LIMIT; - const microLamports = Math.floor((computeBudgetOption.priorityFeeLamports * 1_000_000) / computeLimit); + const microLamports = Math.floor((computeBudgetOption.priorityFeeLamports * MICROLAMPORTS_PER_LAMPORT) / computeLimit); prependInstructions = [ ComputeBudgetProgram.setComputeUnitLimit({ units: computeLimit, @@ -312,10 +313,10 @@ export class TransactionBuilder { let finalComputeBudgetOption = computeBudgetOption ?? { type: "none" }; if (finalComputeBudgetOption.type === "auto") { const computeBudgetLimit = finalComputeBudgetOption.computeBudgetLimit ?? DEFAULT_MAX_COMPUTE_UNIT_LIMIT; - let priorityFeeLamports = await getPriorityFeeInLamports(this.connection, computeBudgetLimit, this.instructions); - if (finalComputeBudgetOption.maxPriorityFeeLamports) { - priorityFeeLamports = Math.min(priorityFeeLamports, finalComputeBudgetOption.maxPriorityFeeLamports); - } + const percentile = finalComputeBudgetOption.percentile ?? DEFAULT_PRIORITY_FEE_PERCENTILE; + const priorityFee = await getPriorityFeeInLamports(this.connection, computeBudgetLimit, this.instructions, percentile); + const maxPriorityFeeLamports = finalComputeBudgetOption.maxPriorityFeeLamports ?? DEFAULT_MAX_PRIORITY_FEE_LAMPORTS; + const priorityFeeLamports = Math.min(priorityFee, maxPriorityFeeLamports); finalComputeBudgetOption = { type: "fixed", priorityFeeLamports,