Solana CookbookTransactions
How to Optimize Compute Requested
Optimizing the Compute Requested on a transaction is important to ensure that the transaction is both processed in a timely manner as well as to avoid paying too much in priority fees.
import {Connection,TransactionInstruction,ComputeBudgetProgram,SystemProgram,Keypair,LAMPORTS_PER_SOL,PublicKey,sendAndConfirmTransaction,Transaction} from "@solana/web3.js";async function getSimulationComputeUnits(connection: Connection,instructions: Array<TransactionInstruction>,payerKey: PublicKey) {try {const recentBlockhash = await connection.getLatestBlockhash();// Include compute budget instructions in simulationconst simulationInstructions = [ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 100 }),ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }), // High limit for simulation...instructions];const transaction = new Transaction();transaction.recentBlockhash = recentBlockhash.blockhash;transaction.feePayer = payerKey;transaction.add(...simulationInstructions);const simulation = await connection.simulateTransaction(transaction);console.log("Simulated Transaction:", simulation);if (simulation.value.err) {console.error("Simulation error:", simulation.value.err);return 200000; // Fallback value}return simulation.value.unitsConsumed || 200000;} catch (error) {console.error("Error during simulation:", error);return 200000; // Fallback value}}async function buildOptimalTransaction(connection: Connection,instructions: Array<TransactionInstruction>,signer: Keypair,priorityFee: number) {const [computeUnits, recentBlockhash] = await Promise.all([getSimulationComputeUnits(connection, instructions, signer.publicKey),connection.getLatestBlockhash()]);const finalInstructions: TransactionInstruction[] = [];finalInstructions.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priorityFee }));if (computeUnits) {const unitsWithMargin = Math.floor(computeUnits * 1.1); // add 10% margin of errorconsole.log("Compute Units with extra 10% margin:", unitsWithMargin);finalInstructions.push(ComputeBudgetProgram.setComputeUnitLimit({ units: unitsWithMargin }));}finalInstructions.push(...instructions);const transaction = new Transaction();transaction.recentBlockhash = recentBlockhash.blockhash;transaction.feePayer = signer.publicKey;transaction.add(...finalInstructions);return {transaction};}async function main() {const connection = new Connection("http://localhost:8899", {commitment: "confirmed"});const sender = Keypair.generate();const recipient = Keypair.generate();const amount = LAMPORTS_PER_SOL / 2; // 0.5 SOLconst signature = await connection.requestAirdrop(sender.publicKey,LAMPORTS_PER_SOL);const { blockhash, lastValidBlockHeight } =await connection.getLatestBlockhash();await connection.confirmTransaction({blockhash,lastValidBlockHeight,signature});// Create transfer instructionconst transferInstruction = SystemProgram.transfer({fromPubkey: sender.publicKey,toPubkey: recipient.publicKey,lamports: amount});const priorityFee = 100; // microLamports// Build optimal transactionconst transaction = await buildOptimalTransaction(connection,[transferInstruction],sender,priorityFee);const transactionSignature = await sendAndConfirmTransaction(connection,transaction.transaction,[sender]);console.log("Transaction sent:", transactionSignature);}main().catch(console.error);
Console
Click to execute the code.
Is this page helpful?