0

So just wanted a confirmation, i know init will check this and if its initialized it will error out, but what is the opposite of init check, i.e check the account passed is initialized ? does anchor automatically checks for initialization, if the type of the account is not AccountInfo but in form of the Account<'info,T> wrapper ? so if i do

``` 
#[derive(Accounts)
pub struct check<'info> {
test_initialization : Account<'info,test>
}
#[account]
pub test {
x : u32;
}```

can my program assume the account "test_initialization" was initialized in the above code snippet if it reaches the business logic side of it ?

2
  • is the Account<'info,T> wrapper implicit check enough , or I should add a initialized field and check it for instructions where i want the account to be initialized ? but i think this wont be necessary if the account wrapper works as i anticipate just need confirmation. Commented Jul 26, 2022 at 23:50
  • So long as you don't add themut constraint, the account will be read only
    – Henry E
    Commented Jul 27, 2022 at 7:44

3 Answers 3

2

There's no explicit check needed here. As long as there's no init, zero or zero_copy attribute for the account, the validator expects it to have been created. The answer to your question is yes, the program assumes the account is initialized and infact throws an error if it isn't.

1

It depends on what you mean by "initialised".

AccountInfo is, for all intent and purposes, unchecked. When using the Account wrapper though, the following gets checked:

  • Check that the account has some lamports. Otherwise, throw AccountNotInitialized.
  • Check if the account discriminator in the first 8 bytes of account data exists and matches the program. Otherwise, throw AccountDiscriminatorNotFound and AccountDiscriminatorMismatch respectively.
  • Finally, parse the account using AnchorDeserialize::deserialize. If failed, throw AccountDidNotDeserialize

Most of this logic is sprinkled around these parts of the source code if you want to dig deeper:

6
  • there is a check for initialization too i believe as init errors out if the account is already initialized , how does it check for it ? by checking the discriminator and giving the custom error "account already initialized " ? would clear it out if its refrence can be found on the codebase to see what does it do. Commented Jul 27, 2022 at 0:26
  • By initialization i mean, init has been called on the account, by a different anchor instruction Commented Jul 27, 2022 at 0:27
  • Do you mean AccountDiscriminatorAlreadySet? That one is thrown if the first 8 bytes of the account are not empty (0).
    – sohrab
    Commented Jul 27, 2022 at 0:32
  • wait i think its called Expected Account to be already initialized or smth Commented Jul 27, 2022 at 0:54
  • That's AccountNotInitialized (my first bullet point): github.com/coral-xyz/anchor/blob/…
    – sohrab
    Commented Jul 27, 2022 at 1:01
0

In general Anchor assumes it's initialized, if you're using UncheckedAccount or similar , can use the following. (unless init is provided)

pub fn assert_initialized<T: Pack + IsInitialized>(
    account_info: &AccountInfo,
) -> Result<T, ProgramError> {
    let account: T = T::unpack_unchecked(&account_info.data.borrow())?;
    if !account.is_initialized() {
        Err(ErrorCode::UninitializedAccount.into())
    } else {
        Ok(account)
    }
}

Lifted off:

https://github.com/metaplex-foundation/metaplex-program-library/blob/e057c72645b32a5b3776a6a93e33440e719a0ddd/auction-house/program/src/utils.rs#L249-L256

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.