2

Per the Solana Cookbook, I'd like to set a transaction priority by using fees.

  transaction.add(
    ComputeBudgetProgram.setComputeUnitLimit({
      units: 1_000_000,
    })
  );

  transaction.add(
    ComputeBudgetProgram.setComputeUnitPrice({
      microLamports: 1,
    })
  );

This fails on the local validator (but not on mainnet-beta) with

failed to send transaction: Transaction simulation failed: Error processing Instruction 0: invalid instruction data

which I figure is fair since I haven't added the compute budget program to my local validator like I have with other apps memo... for the memo app, and meta for Metaplex etc. However when I run:

$ solana program dump -u m ComputeBudget111111111111111111111111111111 compute_budget_program.so

I receive:

Error: ComputeBudget111111111111111111111111111111 is not a BPF program

How can I use the ComputeBudget program on the local validator?

Edit: full function, for John:

// Taken from
// import { transfer } from "@solana/spl-token";
// And modified to add 'memo'
// And remove redundant options.
export const makeTransaction = async (
  connection: Connection,
  // Original code just calls these 'source' and 'destination' but let's be clearer
  sourceTokenAccount: PublicKey,
  recipientWalletAddress: PublicKey,
  ownerAndPayer: Keypair,
  amount: number | bigint,
  mintAddress: PublicKey,
  memo: string | null = null
): Promise<Transaction> => {
  // These were moved out of the original transfer since they're static

  // SPL Token program account
  const programId = TOKEN_PROGRAM_ID;

  // Signing accounts if `owner` is a multisig
  const multiSigners: Array<Signer> = [];

  log(`TODO: make recipient account for `, mintAddress);

  log(`Sending tokens with memo "${memo}"`);

  const transaction = new TransactionConstructor();

  // 1M microlamports = 1 lamport
  // computeUnitLimit of 1Million units * computeUnitPrice of one microlamport = 1 lamport
  // Transaction now costs 5000 (normal price) + 1 lamport
  // See https://solanacookbook.com/references/basic-transactions.html#how-to-change-compute-budget-fee-priority-for-a-transaction

  // Normal transaction price is 5000 lamports per signature
  // TODO: remove when
  // https://solana.stackexchange.com/questions/5600/error-downloading-the-computebudget-program-to-use-on-local-validator
  // is resolved

  const isLocalhost =
    connection.rpcEndpoint.includes("127.0.0.1") ||
    connection.rpcEndpoint.includes("localhost");
  if (!isLocalhost) {
    // "The value provided in microLamports will be multiplied by the CU budget to determine the Prioritization Fee in Lamports."
    log(`Adding priority fee`);

    transaction.add(
      ComputeBudgetProgram.setComputeUnitLimit({
        units: 200_000, // compute units
      })
    );

    transaction.add(
      ComputeBudgetProgram.setComputeUnitPrice({
        microLamports: 5500, // lamports per compute unit
      })
    );
  }

  // Find out if we need to make token account for the recipient and add an instruction for that if necessary

  // Get the reciever token account address (even if it doesn't exist yet)
  let destinationTokenAccount = await getAssociatedTokenAddress(
    mintAddress,
    recipientWalletAddress
  );

  if (checkTokenAccountCreated(connection, destinationTokenAccount)) {
    log(`Token account already exists, no need to make it`);
  } else {
    log(`Token account does not exist, adding instruction to make it`);
    // If the account does not exist, add the create account instruction to the transaction
    // Logic from node_modules/@solana/spl-token/src/actions/getOrCreateAssociatedTokenAccount.ts
    transaction.add(
      createAssociatedTokenAccountInstruction(
        ownerAndPayer.publicKey,
        destinationTokenAccount,
        recipientWalletAddress,
        mintAddress,
        TOKEN_PROGRAM_ID,
        ASSOCIATED_TOKEN_PROGRAM_ID
      )
    );
  }

  transaction.add(
    createTransferInstruction(
      sourceTokenAccount,
      destinationTokenAccount,
      ownerAndPayer.publicKey,
      amount,
      multiSigners,
      programId
    )
  );

  // 'memo' is added by us
  // See https://solana.stackexchange.com/questions/3789/how-do-i-add-a-note-memo-to-my-solana-transactions-using-web3-js
  // Don't bother adding if memo is an empty string
  if (memo && memo.length) {
    await transaction.add(
      new TransactionInstruction({
        keys: [
          { pubkey: ownerAndPayer.publicKey, isSigner: true, isWritable: true },
        ],
        data: Buffer.from(memo, "utf-8"),
        programId: new PublicKey(MEMO_PROGRAM),
      })
    );
  }

  // We need to add these to get an estimated fee
  let blockhashAndHeight = await connection.getLatestBlockhash("finalized");
  transaction.recentBlockhash = blockhashAndHeight.blockhash;
  transaction.feePayer = ownerAndPayer.publicKey;

  return transaction;
};
4
  • 1
    can you share how are you building and sending the transaction? I just ran the code from the cookbook example with solana-test-validator running and it seems to work
    – john
    Feb 3, 2023 at 4:20
  • @john it works for me too, in mainnet-beta. Just not on localhost. I've added the relevant parts to the example already (in the spirit of a short reproducible example) but I can do the full paste if you like. One sec...
    – mikemaccana
    Feb 3, 2023 at 10:05
  • To @pepeIKO's point, can you tell us what the output of solana-test-validator --version is? Feb 18, 2023 at 4:20
  • @stevelusher solana-test-validator 1.14.16 (src:ab6f3bda; feat:3488713414)
    – mikemaccana
    Feb 20, 2023 at 10:21

1 Answer 1

3

I tried running an example similar to this one and it works for me. My only idea is that your local validator isn't up to date. You can run solana validators to check which version are most validators on and compare it to your local validator's version (solana -V).

You can update your local installation with solana-install update, or just reinstall completely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.