(
program_id: &Pubkey,
ctx: Context<Allocate>,
args: AllocateInput,
)
| 28 | /// 2. `[optional]` system_program |
| 29 | #[inline(always)] |
| 30 | pub fn process_allocate( |
| 31 | program_id: &Pubkey, |
| 32 | ctx: Context<Allocate>, |
| 33 | args: AllocateInput, |
| 34 | ) -> ProgramResult { |
| 35 | // account validation |
| 36 | |
| 37 | require!( |
| 38 | ctx.accounts.asset.is_signer(), |
| 39 | ProgramError::MissingRequiredSignature, |
| 40 | "asset" |
| 41 | ); |
| 42 | |
| 43 | // offset on the account data where the new extension will be written; this will |
| 44 | // include any padding required to maintain the 8-bytes alignment |
| 45 | let (exists, offset) = if ctx.accounts.asset.data_is_empty() { |
| 46 | (false, Asset::LEN) |
| 47 | } else { |
| 48 | require!( |
| 49 | ctx.accounts.asset.owner() == program_id, |
| 50 | ProgramError::IllegalOwner, |
| 51 | "asset" |
| 52 | ); |
| 53 | |
| 54 | require!( |
| 55 | ctx.accounts.asset.data_len() >= Asset::LEN, |
| 56 | AssetError::InvalidAccountLength, |
| 57 | "asset" |
| 58 | ); |
| 59 | |
| 60 | let data = ctx.accounts.asset.try_borrow_data()?; |
| 61 | |
| 62 | // make sure that the asset is not already initialized |
| 63 | require!( |
| 64 | data[0] == Discriminator::Uninitialized.into(), |
| 65 | AssetError::AlreadyInitialized, |
| 66 | "asset" |
| 67 | ); |
| 68 | // and the account does not have the extension |
| 69 | require!( |
| 70 | !Asset::contains(args.extension.extension_type, &data), |
| 71 | AssetError::AlreadyInitialized, |
| 72 | "extension [{:?}] already initialized", |
| 73 | args.extension.extension_type |
| 74 | ); |
| 75 | |
| 76 | ( |
| 77 | // the account exists |
| 78 | true, |
| 79 | // if there is an extension on the account, need to make sure it has all |
| 80 | // its data written before initializing a new one |
| 81 | if let Some((extension, offset)) = Asset::last_extension(&data) { |
| 82 | require!( |
| 83 | extension.length() as usize + offset <= data.len(), |
| 84 | AssetError::IncompleteExtensionData, |
| 85 | "incomplete [{:?}] extension data", |
| 86 | extension.extension_type() |
| 87 | ); |
no test coverage detected