Skip to content

Add compute unit helpers #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

lorisleiva
Copy link
Member

@lorisleiva lorisleiva commented May 13, 2025

This PR brings the following high-level helpers to the @solana-program/compute-budget JS client:

  • const MAX_COMPUTE_UNIT_LIMIT (1_400_000): The maximum units assignable to a transaction. This can be used as a temporary value when simulating a transaction to estimate its actual CU.

  • const PROVISORY_COMPUTE_UNIT_LIMIT (0): A temporary value that can be used to signal that the transaction should be simulated to get its CUs before being sent. It is safer to use than MAX_COMPUTE_UNIT_LIMIT because the transaction will fail to execute unless it is properly estimated.

  • function estimateComputeUnitLimitFactory: Brought from @solana/kit and renamed it from getComputeUnitEstimateForTransactionMessageFactory since the function is now part of a narrower namespace (i.e. @solana-program/compute-budget). Aside from being renamed and refactored internally to use some more granular helpers, it works exactly the same. Tests were also brought from @solana/kit and converted from Jest to Vitest.

    const estimateCUs = estimateComputeUnitLimitFactory({ rpc });
    
    const estimatedCUs: number = await estimateCUs(transactionMessage);
  • function estimateAndUpdateProvisoryComputeUnitLimitFactory: A slightly higher-level helper that accepts a function returned by estimateComputeUnitLimitFactory and return a function that estimates and updates the compute unit limit instruction if and only if it isn't already set to an explicit value (i.e. not PROVISORY_COMPUTE_UNIT_LIMIT nor MAX_COMPUTE_UNIT_LIMIT).

    const estimateAndUpdateCUs = estimateAndUpdateProvisoryComputeUnitLimitFactory(
        estimateComputeUnitLimitFactory({ rpc })
    );
    
    const transactionMessageWithCUs = await estimateAndUpdateCUs(transactionMessage);
  • function updateOrAppendSetComputeUnitLimitInstruction: Updates the first SetComputeUnitLimit instruction in a transaction message with the given units, or appends a new instruction if none exists. A function of the current value can be provided instead of a static value.

    const updatedTransactionMessage = updateOrAppendSetComputeUnitLimitInstruction(
      // E.g. Keep the current limit if it is set, otherwise set it to the maximum.
      (currentUnits) => currentUnits === null ? MAX_COMPUTE_UNIT_LIMIT : currentUnits,
      transactionMessage,
    );
  • function fillProvisorySetComputeUnitLimitInstruction : Appends a SetComputeUnitLimit instruction with a provisory compute unit limit to a given transaction message if and only if it does not already have one.

    const transactionMessage = pipe(
      createTransactionMessage({ version: 0 }),
      fillProvisorySetComputeUnitLimitInstruction,
      // ...
    );
  • function updateOrAppendSetComputeUnitPriceInstruction : Updates the first SetComputeUnitPrice instruction in a transaction message with the given micro-Lamports, or appends a new instruction if none exists. A function of the current value can be provided instead of a static value.

    const updatedTransactionMessage = updateOrAppendSetComputeUnitPriceInstruction(
      // E.g. double the current price or set it to 10_000 if it isn't set.
      (currentPrice) => currentPrice === null ? 10_000 : currentPrice * 2,
      transactionMessage,
    );
  • function setTransactionMessageComputeUnitPrice : Appends a SetComputeUnitPrice instruction with the provided micro-Lamports.

    const transactionMessage = pipe(
      createTransactionMessage({ version: 0 }),
      (m) => setTransactionMessageComputeUnitPrice(10_000, m),
      // ...
    );

Note that some of these helpers will be useful when configuring TransactionPlanners and TransactionPlanExecutors in the future. At this point, we may consider adding decorators for these types directly in this package.

@lorisleiva lorisleiva marked this pull request as ready for review May 15, 2025 13:21
@lorisleiva lorisleiva requested a review from steveluscher May 15, 2025 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant