0

I'm working on a Solana program and encountered an issue related to state management with Program Derived Accounts (PDAs).

I successfully created a state for my Solana program and saved it to a PDA (Program Derived Account). However, when I attempt to retrieve the state from the PDA, I encounter the following error: Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Failed to serialize or deserialize account data: Unknown

here is instruction code:

use borsh::{BorshSerialize, BorshDeserialize};
use solana_program::{
    account_info::{AccountInfo, next_account_info},
    entrypoint::ProgramResult,
    program_error::ProgramError,
    pubkey::Pubkey,
    sysvar::{rent::Rent, Sysvar},
};
use std::collections::BTreeMap;
use crate::state::{State, Distribution};
use solana_program::msg;


#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct InitializeArgs {
    pub initial_ticket_prices: Vec<u64>,
    pub initial_token_addresses: Vec<Pubkey>,
    pub min_buy_amounts: Vec<u64>,
    pub distributions: Vec<Distribution>,
    pub max_tickets_per_user: u64,
    pub total_tickets_threshold: u64,
    pub depth: u64,
    pub rewards_percent_by_depth: Vec<u64>,
    pub ref_code_length: u64
}

pub fn initialize(program_id: &Pubkey, accounts: &[AccountInfo], args: InitializeArgs) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let state_account = next_account_info(account_info_iter)?;
    
    let mut state = State::try_from_slice(&state_account.data.borrow()).unwrap_or_else(|_| State {
        ticket_prices: BTreeMap::new(),
        min_buy_amounts: BTreeMap::new(),
        deposited_by_token: BTreeMap::new(),
        address_to_ref_code: BTreeMap::new(),
        ref_code_to_address: BTreeMap::new(),
        referrer_to_referrals: BTreeMap::new(),
        referral_to_referrer: BTreeMap::new(),
        user_tickets: BTreeMap::new(),
        user_rewards: BTreeMap::new(),
        rewards_percent_by_depth: BTreeMap::new(),
        distributions: Vec::new(),
        max_tickets_per_user: 0,
        total_tickets_threshold: 0,
        ref_code_length: 0,
        total_tickets: 0,
        depth: 0,
        paused: false,
    });
    
    let token_addresses_clone = args.initial_token_addresses.clone();

    args.initial_token_addresses.into_iter().zip(args.initial_ticket_prices).for_each(|(token_address, price)| {
        state.ticket_prices.insert(token_address, price);
    });

    token_addresses_clone.into_iter().zip(args.min_buy_amounts).for_each(|(token_address, amount)| {
        state.min_buy_amounts.insert(token_address, amount);
    });

    state.distributions = args.distributions;
    state.max_tickets_per_user = args.max_tickets_per_user;
    state.total_tickets_threshold = args.total_tickets_threshold;
    state.depth = args.depth;
    state.ref_code_length = args.ref_code_length;
    
    args.rewards_percent_by_depth.into_iter().enumerate().for_each(|(index, percent)| {
        state.rewards_percent_by_depth.insert(index as u64 + 1, percent);
    });

    state.serialize(&mut *state_account.data.borrow_mut())?;
    
    let state = State::try_from_slice(&state_account.data.borrow())?;
        
    Ok(())
}
1
  • This all looks correct. Maybe you need to wait until the transaction with initialize is confirmed before sending your next transaction, or perhaps the next transaction is using an incorrect pubkey.
    – Jon C
    Commented Feb 16 at 20:16

0

Your Answer

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