Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
},
"homepage": "https://github.com/solana-program/compute-budget#readme",
"peerDependencies": {
"@solana/kit": "^6.1.0"
"@solana/kit": "^6.3.0"
},
"devDependencies": {
"@solana/eslint-config-solana": "^3.0.3",
"@solana/kit": "^6.1.0",
"@solana/kit": "^6.3.0",
"@types/node": "^24",
"@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.16.1",
Expand Down
928 changes: 547 additions & 381 deletions clients/js/pnpm-lock.yaml

Large diffs are not rendered by default.

25 changes: 10 additions & 15 deletions clients/js/src/estimateComputeLimitInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
isTransactionMessageWithDurableNonceLifetime,
pipe,
Rpc,
RpcSimulateTransactionResult,
SimulateTransactionApi,
Slot,
SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT,
Expand Down Expand Up @@ -140,30 +141,24 @@ async function simulateTransactionAndGetConsumedUnits({
const wireTransactionBytes = getBase64EncodedWireTransaction(transaction);

try {
const {
value: { err: transactionError, unitsConsumed },
} = await rpc
.simulateTransaction(wireTransactionBytes, {
...simulateConfig,
encoding: 'base64',
sigVerify: false,
})
const response = await rpc
.simulateTransaction(wireTransactionBytes, { ...simulateConfig, encoding: 'base64', sigVerify: false })
.send({ abortSignal });
if (unitsConsumed == null) {
const { err: transactionError, ...simulationResult } = response.value as RpcSimulateTransactionResult;
if (simulationResult.unitsConsumed == null) {
// This should never be hit, because all RPCs should support `unitsConsumed` by now.
throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT);
}
// FIXME(https://github.com/anza-xyz/agave/issues/1295): The simulation response returns
// compute units as a u64, but the `SetComputeLimit` instruction only accepts a u32. Until
// this changes, downcast it.
const downcastUnitsConsumed = unitsConsumed > 4_294_967_295n ? 4_294_967_295 : Number(unitsConsumed);
if (transactionError) {
throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, {
...simulationResult,
cause: getSolanaErrorFromTransactionError(transactionError),
unitsConsumed: downcastUnitsConsumed,
});
}
return downcastUnitsConsumed;
// FIXME(https://github.com/anza-xyz/agave/issues/1295): The simulation response returns
// compute units as a u64, but the `SetComputeLimit` instruction only accepts a u32. Until
// this changes, downcast it.
return simulationResult.unitsConsumed > 4_294_967_295n ? 4_294_967_295 : Number(simulationResult.unitsConsumed);
} catch (e) {
if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT)) throw e;
throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT, { cause: e });
Expand Down
23 changes: 14 additions & 9 deletions clients/js/test/estimateComputeLimitInternal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,22 +236,27 @@ describe('estimateComputeUnitLimit', () => {
await expect(estimatePromise).resolves.toBe(1400000);
});

it('throws with the transaction SolanaError as cause when the transaction fails in simulation', async () => {
it('throws with the full simulation data when the transaction fails in simulation', async () => {
expect.assertions(1);
const transactionError: TransactionError = 'AccountNotFound';
sendSimulateTransactionRequest.mockResolvedValue({
value: { err: transactionError, unitsConsumed: 42n },
});
const { err, ...mockSimulationResult } = {
accounts: null,
err: transactionError,
innerInstructions: null,
loadedAccountsDataSize: 42,
logs: ['Program log: Simulated'],
replacementBlockhash: null,
returnData: null,
unitsConsumed: 42n,
};
sendSimulateTransactionRequest.mockResolvedValue({ value: { err, ...mockSimulationResult } });

const estimatePromise = estimateComputeUnitLimit({
rpc,
transactionMessage: mockTransactionMessage,
});
const estimatePromise = estimateComputeUnitLimit({ rpc, transactionMessage: mockTransactionMessage });

await expect(estimatePromise).rejects.toThrow(
new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, {
cause: new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND),
unitsConsumed: 42,
...mockSimulationResult,
}),
);
});
Expand Down
2 changes: 2 additions & 0 deletions clients/rust/src/generated/instructions/request_heap_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl RequestHeapFrame {
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
Expand Down Expand Up @@ -151,6 +152,7 @@ impl<'a, 'b> RequestHeapFrameCpi<'a, 'b> {
) -> solana_program::entrypoint::ProgramResult {
self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::vec_init_then_push)]
pub fn invoke_signed_with_remaining_accounts(
Expand Down
2 changes: 2 additions & 0 deletions clients/rust/src/generated/instructions/request_units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl RequestUnits {
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
Expand Down Expand Up @@ -162,6 +163,7 @@ impl<'a, 'b> RequestUnitsCpi<'a, 'b> {
) -> solana_program::entrypoint::ProgramResult {
self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::vec_init_then_push)]
pub fn invoke_signed_with_remaining_accounts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl SetComputeUnitLimit {
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
Expand Down Expand Up @@ -151,6 +152,7 @@ impl<'a, 'b> SetComputeUnitLimitCpi<'a, 'b> {
) -> solana_program::entrypoint::ProgramResult {
self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::vec_init_then_push)]
pub fn invoke_signed_with_remaining_accounts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl SetComputeUnitPrice {
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
Expand Down Expand Up @@ -154,6 +155,7 @@ impl<'a, 'b> SetComputeUnitPriceCpi<'a, 'b> {
) -> solana_program::entrypoint::ProgramResult {
self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::vec_init_then_push)]
pub fn invoke_signed_with_remaining_accounts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl SetLoadedAccountsDataSizeLimit {
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
Expand Down Expand Up @@ -155,6 +156,7 @@ impl<'a, 'b> SetLoadedAccountsDataSizeLimitCpi<'a, 'b> {
) -> solana_program::entrypoint::ProgramResult {
self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
}
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::clone_on_copy)]
#[allow(clippy::vec_init_then_push)]
pub fn invoke_signed_with_remaining_accounts(
Expand Down
Loading
Loading