2

Following error occurs when I try to run anchor test:

Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Program failed to complete
      at Connection.sendEncodedTransaction (node_modules/@solana/web3.js/src/connection.ts:4819:13)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at Connection.sendRawTransaction (node_modules/@solana/web3.js/src/connection.ts:4778:20)
      at sendAndConfirmRawTransaction (node_modules/@project-serum/anchor/src/provider.ts:288:21)
      at AnchorProvider.sendAndConfirm (node_modules/@project-serum/anchor/src/provider.ts:148:14)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@project-serum/anchor/src/program/namespace/rpc.ts:29:16)

Here is the program code:

use anchor_lang::prelude::*;

declare_id!("57GYguBdvQKBbRsARLpAVFmC2XvPNMa3dPP9qHhZvkoE");

#[program]
pub mod house {
    use super::*;

    pub fn init_house(ctx: Context<InitHouse>, payout_amount: u8) -> Result<()> {
        InitHouse::initialise_house(ctx, payout_amount)
    }
}

impl InitHouse<'_>  {
    pub fn initialise_house(ctx: Context<Self>, fee_amount: u8) -> Result<()> {
        let vault = &mut ctx.accounts.vault;
        // vault.fee_vault = *ctx.accounts.fee_vault.to_account_info().key;
        vault.fee_amount = fee_amount;
        vault.bump = *ctx.bumps.get("house-vault").unwrap();

        Ok(())
    }
}


#[derive(Accounts)]
pub struct InitHouse<'info> {
    // space: 8 discriminator + 32 house vault account + 32 fee vault
    // + 1 fee amount + 6 * 1  bet amounts + 1 bump
    #[account(
        init,
        payer = user,
        space = 8 + 32 + 32 + 1 + 6 + 1,
        seeds = [
            b"house-vault".as_ref(),
            user.key().as_ref()
        ],
        bump
    )]
    pub vault: Account<'info, HouseState>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[account]
pub struct HouseState {
    pub house_vault: Pubkey,
    pub fee_vault: Pubkey,
    pub fee_amount: u8,
    pub bet_amounts: [u8; 6],
    pub bump: u8,
}

Here is the test script:

import * as anchor from "@project-serum/anchor";
import { web3 } from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { CoinFlip } from "../target/types/coin_flip";

// const SOLANA_URL = 'https://api.devnet.solana.com';
const SOLANA_URL = 'http://localhost:8899';


describe("coin-flip", () => {
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.CoinFlip as Program<CoinFlip>;
  const programOwner = (anchor.getProvider().wallet as AnchorWallet).payer;


  it("Init house", async () => {
     const [houseVaultPDA, _] = await web3.PublicKey
        .findProgramAddress(
          [
            Buffer.from("house-vault"),
            programOwner.publicKey.toBuffer()
          ],
          program.programId
        );
     console.log('House Vault PDA: ', houseVaultPDA.toString());

      await program.methods
           .initHouse(new anchor.BN(95))
           .accounts({
               user: programOwner.publicKey,
               vault: houseVaultPDA
           })
           .rpc();
    });
});

I was trying to solve this error by myself but with no luck. I know the Instruction 0 is SystemProgram.CreateAccount, and checked that programOwner has enough SOL to create a PDA.

2 Answers 2

3

The problem is in this line:

vault.bump = *ctx.bumps.get("house-vault").unwrap();

You have to use the name of the account, not the seed to get the bump. So the correct code in your case will be:

vault.bump = *ctx.bumps.get("vault").unwrap();
1

I've changed your code a little bit. There seemed to be a problem with: vault.bump = *ctx.bumps.get("house-vault").unwrap();. It seems this is where it was failing. Here is the refactored code:

lib.rs:

use anchor_lang::prelude::*;

declare_id!("GNHuocp4uyUSUcQiS854jpubRJqQmVLYqZW4RMfH472o");

#[program]
pub mod house {
    use super::*;

    pub fn init_house(ctx: Context<InitHouse>, payout_amount: u64, base_bump: u8) -> Result<()> {
        InitHouse::initialise_house(ctx, payout_amount, base_bump)
    }
}

#[derive(Accounts)]
pub struct InitHouse<'info> {
    // space: 8 discriminator + 32 house vault account + 32 fee vault
    // + 1 fee amount + 6 * 1  bet amounts + 1 bump
    #[account(
        init,
        payer = user,
        space = 8 + 32 + 32 + 1 + 6 + 8,
        seeds = [
            b"house-vault".as_ref(),
            user.key().as_ref()
        ],
        bump
    )]
    pub vault: Account<'info, HouseState>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

impl InitHouse<'_>  {
    pub fn initialise_house(ctx: Context<Self>, fee_amount: u64, base_bump: u8) -> Result<()> {
        let vault = &mut ctx.accounts.vault;
        // // vault.fee_vault = *ctx.accounts.fee_vault.to_account_info().key;
        vault.fee_amount = fee_amount;
        //vault.bump = *ctx.bumps.get("house-vault").unwrap();
        vault.bump = base_bump;

        Ok(())
    }
}

#[account]
pub struct HouseState {
    pub house_vault: Pubkey,
    pub fee_vault: Pubkey,
    pub fee_amount: u64,
    pub bet_amounts: [u8; 6],
    pub bump: u8,
}

And here is the test file:

import * as anchor from "@project-serum/anchor";
import { web3 } from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { House } from "../target/types/house";
import { utf8 } from "@project-serum/anchor/dist/cjs/utils/bytes";
import { BN } from "bn.js";

// const SOLANA_URL = 'https://api.devnet.solana.com';
const SOLANA_URL = 'http://localhost:8899';

describe("coin-flip", () => {
  anchor.setProvider(anchor.AnchorProvider.env());
  const program = anchor.workspace.House as Program<House>;

  // const programOwner = (anchor.getProvider().wallet as AnchorWallet).payer;
  const programOwner = anchor.AnchorProvider.local().wallet.publicKey;


  it("Init house", async () => {
    const [houseVaultPDA, baseBump] = await web3.PublicKey.findProgramAddress(
      [utf8.encode("house-vault"), programOwner.toBuffer()],
      program.programId
    );
    let bn = new BN(95, undefined, "le");
    console.log('House Vault PDA: ', houseVaultPDA.toString());
    console.log(typeof bn);
    await program.methods
      .initHouse(new BN(95), baseBump)
      .accounts({
        user: programOwner,
        vault: houseVaultPDA
      }).rpc();
  });
});

Also notice I have changed fee amount from u8 to u64. If you need to use u8 - you should not have to use BN because BN returns an array of bytes and u8 will expect a single byte only.

Hope this helps.

2
  • This solved the problem. What is preferable way to calculate bump: on client side or in program?
    – Void
    Sep 3, 2022 at 17:03
  • 1
    I think when generating new bump - program is better,
    – Dmitry R
    Sep 3, 2022 at 17:13

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.