Skip to content

Commit

Permalink
feat(oft-solana): add fallback for when getSimulationComputeUnits f…
Browse files Browse the repository at this point in the history
…ails (#1185)
  • Loading branch information
nazreen authored Jan 29, 2025
1 parent acef763 commit 4af9800
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-days-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@layerzerolabs/oft-solana-example": minor
---

fallback for getSimulationComputeUnits
18 changes: 14 additions & 4 deletions examples/oft-solana/tasks/solana/createOFT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ import { OFT_DECIMALS as DEFAULT_SHARED_DECIMALS, oft, types } from '@layerzerol
import { checkMultisigSigners, createMintAuthorityMultisig } from './multisig'
import { assertAccountInitialized } from './utils'

import { addComputeUnitInstructions, deriveConnection, deriveKeys, getExplorerTxLink, output } from './index'
import {
TransactionType,
addComputeUnitInstructions,
deriveConnection,
deriveKeys,
getExplorerTxLink,
output,
} from './index'

const DEFAULT_LOCAL_DECIMALS = 9

Expand Down Expand Up @@ -248,7 +255,8 @@ task('lz:oft:solana:create', 'Mints new SPL Token and creates new OFT Store acco
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.CreateToken
)
const createTokenTx = await txBuilder.sendAndConfirm(umi)
await assertAccountInitialized(connection, toWeb3JsPublicKey(mint.publicKey))
Expand Down Expand Up @@ -278,7 +286,8 @@ task('lz:oft:solana:create', 'Mints new SPL Token and creates new OFT Store acco
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.InitOft
)
const { signature } = await txBuilder.sendAndConfirm(umi)
console.log(`initOftTx: ${getExplorerTxLink(bs58.encode(signature), isTestnet)}`)
Expand Down Expand Up @@ -307,7 +316,8 @@ task('lz:oft:solana:create', 'Mints new SPL Token and creates new OFT Store acco
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.SetAuthority
)
const { signature } = await txBuilder.sendAndConfirm(umi)
console.log(`setAuthorityTx: ${getExplorerTxLink(bs58.encode(signature), isTestnet)}`)
Expand Down
12 changes: 10 additions & 2 deletions examples/oft-solana/tasks/solana/createOFTAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import { types as devtoolsTypes } from '@layerzerolabs/devtools-evm-hardhat'
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { OFT_DECIMALS, oft, types } from '@layerzerolabs/oft-v2-solana-sdk'

import { addComputeUnitInstructions, deriveConnection, deriveKeys, getExplorerTxLink, output } from './index'
import {
TransactionType,
addComputeUnitInstructions,
deriveConnection,
deriveKeys,
getExplorerTxLink,
output,
} from './index'

interface CreateOFTAdapterTaskArgs {
/**
Expand Down Expand Up @@ -81,7 +88,8 @@ task('lz:oft-adapter:solana:create', 'Creates new OFT Adapter (OFT Store PDA)')
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.InitOft
)
const { signature } = await txBuilder.sendAndConfirm(umi)
console.log(`initOftTx: ${getExplorerTxLink(bs58.encode(signature), eid == EndpointId.SOLANA_V2_TESTNET)}`)
Expand Down
67 changes: 58 additions & 9 deletions examples/oft-solana/tasks/solana/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import { toWeb3JsInstruction, toWeb3JsPublicKey } from '@metaplex-foundation/umi
import { AddressLookupTableAccount, Connection } from '@solana/web3.js'
import { getSimulationComputeUnits } from '@solana-developers/helpers'
import bs58 from 'bs58'
import { backOff } from 'exponential-backoff'

import { formatEid } from '@layerzerolabs/devtools'
import { promptToContinue } from '@layerzerolabs/io-devtools'
import { EndpointId, endpointIdToNetwork } from '@layerzerolabs/lz-definitions'
import { OftPDA } from '@layerzerolabs/oft-v2-solana-sdk'

Expand Down Expand Up @@ -155,22 +157,67 @@ export const getAddressLookupTable = async (connection: Connection, umi: Umi, fr
}
}

export enum TransactionType {
CreateToken = 'CreateToken',
CreateMultisig = 'CreateMultisig',
InitOft = 'InitOft',
SetAuthority = 'SetAuthority',
InitConfig = 'InitConfig',
SendOFT = 'SendOFT',
}

const TransactionCuEstimates: Record<TransactionType, number> = {
// for the sample values, they are: devnet, mainnet
[TransactionType.CreateToken]: 125_000, // actual sample: (59073, 123539), 55785 (more volatile as it has CPI to Metaplex)
[TransactionType.CreateMultisig]: 5_000, // actual sample: 3,230
[TransactionType.InitOft]: 70_000, // actual sample: 59207, 65198 (note: this is the only transaction that createOFTAdapter does)
[TransactionType.SetAuthority]: 8_000, // actual sample: 6424, 6472
[TransactionType.InitConfig]: 42_000, // actual sample: 33157, 40657
[TransactionType.SendOFT]: 230_000, // actual sample: 217,784
}

export const getComputeUnitPriceAndLimit = async (
connection: Connection,
ixs: Instruction[],
wallet: KeypairSigner,
lookupTableAccount: AddressLookupTableAccount
lookupTableAccount: AddressLookupTableAccount,
transactionType: TransactionType
) => {
const { averageFeeExcludingZeros } = await getFee(connection)
const priorityFee = Math.round(averageFeeExcludingZeros)
const computeUnitPrice = BigInt(priorityFee)

const computeUnits = await getSimulationComputeUnits(
connection,
ixs.map((ix) => toWeb3JsInstruction(ix)),
toWeb3JsPublicKey(wallet.publicKey),
[lookupTableAccount]
)
let computeUnits

try {
computeUnits = await backOff(
() =>
getSimulationComputeUnits(
connection,
ixs.map((ix) => toWeb3JsInstruction(ix)),
toWeb3JsPublicKey(wallet.publicKey),
[lookupTableAccount]
),
{
maxDelay: 3000,
numOfAttempts: 3,
}
)
} catch (e) {
console.error(`Error retrieving simulations compute units from RPC:`, e)
const continueByUsingHardcodedEstimate = await promptToContinue(
'Failed to call simulateTransaction on the RPC. This can happen when the network is congested. Would you like to use hardcoded estimates (TransactionCuEstimates) ? This may result in slightly overpaying for the transaction.'
)
if (!continueByUsingHardcodedEstimate) {
throw new Error(
'Failed to call simulateTransaction on the RPC and user chose to not continue with hardcoded estimate.'
)
}
console.log(
`Falling back to hardcoded estimate for ${transactionType}: ${TransactionCuEstimates[transactionType]} CUs`
)
computeUnits = TransactionCuEstimates[transactionType]
}

if (!computeUnits) {
throw new Error('Unable to compute units')
Expand All @@ -188,15 +235,17 @@ export const addComputeUnitInstructions = async (
eid: EndpointId,
txBuilder: TransactionBuilder,
umiWalletSigner: KeypairSigner,
computeUnitPriceScaleFactor: number
computeUnitPriceScaleFactor: number,
transactionType: TransactionType
) => {
const computeUnitLimitScaleFactor = 1.1 // hardcoded to 1.1 as the estimations are not perfect and can fall slightly short of the actual CU usage on-chain
const { addressLookupTableInput, lookupTableAccount } = await getAddressLookupTable(connection, umi, eid)
const { computeUnitPrice, computeUnits } = await getComputeUnitPriceAndLimit(
connection,
txBuilder.getInstructions(),
umiWalletSigner,
lookupTableAccount
lookupTableAccount,
transactionType
)
// Since transaction builders are immutable, we must be careful to always assign the result of the add and prepend
// methods to a new variable.
Expand Down
5 changes: 3 additions & 2 deletions examples/oft-solana/tasks/solana/multisig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { EndpointId } from '@layerzerolabs/lz-definitions'

import { assertAccountInitialized } from './utils'

import { addComputeUnitInstructions, getExplorerTxLink } from '.'
import { TransactionType, addComputeUnitInstructions, getExplorerTxLink } from '.'

export async function createMultisig(
connection: Connection,
Expand Down Expand Up @@ -58,7 +58,8 @@ export async function createMultisig(
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.CreateMultisig
)
}

Expand Down
11 changes: 9 additions & 2 deletions examples/oft-solana/tasks/solana/sendOFT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { EndpointId } from '@layerzerolabs/lz-definitions'
import { addressToBytes32 } from '@layerzerolabs/lz-v2-utilities'
import { oft } from '@layerzerolabs/oft-v2-solana-sdk'

import { addComputeUnitInstructions, deriveConnection, getExplorerTxLink, getLayerZeroScanLink } from './index'
import {
TransactionType,
addComputeUnitInstructions,
deriveConnection,
getExplorerTxLink,
getLayerZeroScanLink,
} from './index'

interface Args {
amount: number
Expand Down Expand Up @@ -119,7 +125,8 @@ task('lz:oft:solana:send', 'Send tokens from Solana to a target EVM chain')
fromEid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.SendOFT
)
const { signature } = await txBuilder.sendAndConfirm(umi)
const transactionSignatureBase58 = bs58.encode(signature)
Expand Down
5 changes: 3 additions & 2 deletions examples/oft-solana/tasks/solana/setAuthority.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { OftPDA } from '@layerzerolabs/oft-v2-solana-sdk'

import { checkMultisigSigners, createMintAuthorityMultisig } from './multisig'

import { addComputeUnitInstructions, deriveConnection, getExplorerTxLink } from './index'
import { TransactionType, addComputeUnitInstructions, deriveConnection, getExplorerTxLink } from './index'

interface SetAuthorityTaskArgs {
/**
Expand Down Expand Up @@ -194,7 +194,8 @@ task('lz:oft:solana:setauthority', 'Create a new Mint Authority SPL multisig and
eid,
txBuilder,
umiWalletSigner,
computeUnitPriceScaleFactor
computeUnitPriceScaleFactor,
TransactionType.SetAuthority
)
const { signature } = await txBuilder.sendAndConfirm(umi)
console.log(
Expand Down

0 comments on commit 4af9800

Please sign in to comment.