2

For some migration purpose I need to load a pda account with AccountInfo , reallocate and update the fields. I am able to make other parts right got stuck updating/modifying account data. Transaction is succeeding but account field is not getting updated.

Here is a minimal code example.

let collection_account: &mut AccountInfo = &mut ctx.accounts.collection_info;
        
let mut data:&[u8] = &** collection_account.try_borrow_mut_data().unwrap();
let mut collection_info: CollectionInfo = CollectionInfo::try_deserialize(&mut data).unwrap();

collection_info.version = CollectionInfo::VERSION;
#[derive(Accounts)]
#[instruction(collection_address: Pubkey)]
pub struct CollectionInfoMigration<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,

    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(
        mut,
        seeds = [ COLLECTION_INFO_SEED, collection_address.as_ref() ],
        bump,
    )]
    pub collection_info: AccountInfo<'info>,

    pub system_program: Program<'info, System>,
}

1 Answer 1

3

You should try deserializing using anchor_lang::Account::try_from and creating a mutable reference when instantiating the struct variable before changing the values:

let collection_info = &mut Account::<CollectionInfo>::try_from(&mut ctx.accounts.collection_info)?;
collection_info.version = CollectionInfo::VERSION;

You may also need to manually call the Account::exit function on the account after the mutations are complete because this Account is being created out-of-bound from the self-managing ones created via the Context struct:

collection_info.exit(&crate::ID)?;
1
  • 1
    That worked, Thanks a lot. Mar 7, 2023 at 17:02

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.