From 1b98c13095ecfec61cc08285095a73628313311f Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Tue, 3 Oct 2023 13:22:34 +0100 Subject: [PATCH] Request 1M compute units in transfer remote (#2771) ### Description Because incremental merkle tree insertion complexity can change depending on what the index in the merkle tree is, we ran into a situation where the 200k default compute limit wasn't enough when trying to perform a transfer remote on sealevel. Normal cost for index 257, about 158k units: https://explorer.solana.com/tx/4oB9b6PaaKvGMhrQS7XGmi7zBpX3GUW99sbVrSjFwm5AVT96emKF4NH6gn2y9cLMLep8wQJ9LqwJifG5QMpr4BAs Index 255, about 245k units!: https://explorer.solana.com/tx/3v6SbrT58smwnLdnrEFaMXowaEDmo6EpPmKFTUMe9aESo5FTExmJdr2uMH5QJW9hnZTqrB1mfFZe4Vmu75CCAyPs The fix is to simply request more units. Solana tx fees don't actually charge you more if you use more units. Txs have a global cap of 1.4M units -- I'm just requesting 1M here as a balance between having lots of units & not bricking ourselves if the max compute unit amount ever decreases ### Drive-by changes n/a ### Related issues n/a ### Backward compatibility Yes ### Testing I tested a version of this in the UI - I went to the commit where we published 1.5.1, and then published a 1.5.1-beta2 version with this change and moved the UI over to it. Opening this now so we can get this in main and move the UI over to a less sketchy version --- .../src/adapters/SealevelTokenAdapter.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/typescript/token/src/adapters/SealevelTokenAdapter.ts b/typescript/token/src/adapters/SealevelTokenAdapter.ts index f88758d0b..d3b8b7b12 100644 --- a/typescript/token/src/adapters/SealevelTokenAdapter.ts +++ b/typescript/token/src/adapters/SealevelTokenAdapter.ts @@ -6,6 +6,7 @@ import { } from '@solana/spl-token'; import { AccountMeta, + ComputeBudgetProgram, Keypair, PublicKey, SystemProgram, @@ -153,6 +154,14 @@ export class SealevelTokenAdapter } } +// The compute limit to set for the transfer remote instruction. +// This is typically around ~160k, but can be higher depending on +// the index in the merkle tree, which can result in more moderately +// more expensive merkle tree insertion. +// Because a higher compute limit doesn't increase the fee for a transaction, +// we generously request 1M units. +const TRANSFER_REMOTE_COMPUTE_LIMIT = 1_000_000; + export abstract class SealevelHypTokenAdapter extends SealevelTokenAdapter implements IHypTokenAdapter @@ -271,15 +280,24 @@ export abstract class SealevelHypTokenAdapter ]), }); + const setComputeLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit( + { + units: TRANSFER_REMOTE_COMPUTE_LIMIT, + }, + ); + const recentBlockhash = ( await this.getProvider().getLatestBlockhash('finalized') ).blockhash; + // @ts-ignore Workaround for bug in the web3 lib, sometimes uses recentBlockhash and sometimes uses blockhash const tx = new Transaction({ feePayer: fromWalletPubKey, blockhash: recentBlockhash, recentBlockhash, - }).add(transferRemoteInstruction); + }) + .add(setComputeLimitInstruction) + .add(transferRemoteInstruction); tx.partialSign(randomWallet); return tx; }