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
pull/2782/head
Trevor Porter 1 year ago committed by GitHub
parent a82a8148cb
commit 1b98c13095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      typescript/token/src/adapters/SealevelTokenAdapter.ts

@ -6,6 +6,7 @@ import {
} from '@solana/spl-token'; } from '@solana/spl-token';
import { import {
AccountMeta, AccountMeta,
ComputeBudgetProgram,
Keypair, Keypair,
PublicKey, PublicKey,
SystemProgram, 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 export abstract class SealevelHypTokenAdapter
extends SealevelTokenAdapter extends SealevelTokenAdapter
implements IHypTokenAdapter implements IHypTokenAdapter
@ -271,15 +280,24 @@ export abstract class SealevelHypTokenAdapter
]), ]),
}); });
const setComputeLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit(
{
units: TRANSFER_REMOTE_COMPUTE_LIMIT,
},
);
const recentBlockhash = ( const recentBlockhash = (
await this.getProvider().getLatestBlockhash('finalized') await this.getProvider().getLatestBlockhash('finalized')
).blockhash; ).blockhash;
// @ts-ignore Workaround for bug in the web3 lib, sometimes uses recentBlockhash and sometimes uses blockhash // @ts-ignore Workaround for bug in the web3 lib, sometimes uses recentBlockhash and sometimes uses blockhash
const tx = new Transaction({ const tx = new Transaction({
feePayer: fromWalletPubKey, feePayer: fromWalletPubKey,
blockhash: recentBlockhash, blockhash: recentBlockhash,
recentBlockhash, recentBlockhash,
}).add(transferRemoteInstruction); })
.add(setComputeLimitInstruction)
.add(transferRemoteInstruction);
tx.partialSign(randomWallet); tx.partialSign(randomWallet);
return tx; return tx;
} }

Loading…
Cancel
Save