From 2c89b8c980ba135ee0c44a0f76c35b19c3b25dd1 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Sat, 9 Mar 2024 21:37:05 -0500 Subject: [PATCH] Dedeuping update. --- .../src/processor/approve_plugin_authority.rs | 4 +- programs/mpl-core/src/processor/update.rs | 229 +++++++----------- 2 files changed, 92 insertions(+), 141 deletions(-) diff --git a/programs/mpl-core/src/processor/approve_plugin_authority.rs b/programs/mpl-core/src/processor/approve_plugin_authority.rs index 316a2d28..9b4eaa3f 100644 --- a/programs/mpl-core/src/processor/approve_plugin_authority.rs +++ b/programs/mpl-core/src/processor/approve_plugin_authority.rs @@ -101,7 +101,5 @@ fn process_approve_plugin_authority<'a, T: CoreAsset + DataBlob + SolanaAccount> &mut plugin_registry, payer, system_program, - )?; - - Ok(()) + ) } diff --git a/programs/mpl-core/src/processor/update.rs b/programs/mpl-core/src/processor/update.rs index 7d345e4a..7809398e 100644 --- a/programs/mpl-core/src/processor/update.rs +++ b/programs/mpl-core/src/processor/update.rs @@ -7,7 +7,7 @@ use solana_program::{ use crate::{ error::MplCoreError, instruction::accounts::{UpdateAccounts, UpdateCollectionAccounts}, - plugins::{Plugin, PluginType, RegistryRecord}, + plugins::{Plugin, PluginHeader, PluginRegistry, PluginType, RegistryRecord}, state::{Asset, Collection, DataBlob, Key, SolanaAccount, UpdateAuthority}, utils::{ load_key, resize_or_reallocate_account, resolve_payer, validate_asset_permissions, @@ -65,72 +65,15 @@ pub(crate) fn update<'a>(accounts: &'a [AccountInfo<'a>], args: UpdateArgs) -> P dirty = true; } if dirty { - if let (Some(mut plugin_header), Some(mut plugin_registry)) = - (plugin_header, plugin_registry) - { - let new_asset_size = asset.get_size() as isize; - let size_diff = new_asset_size - .checked_sub(asset_size) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_size = (ctx.accounts.asset.data_len() as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_registry_offset = (plugin_header.plugin_registry_offset as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let registry_offset = plugin_header.plugin_registry_offset; - plugin_header.plugin_registry_offset = new_registry_offset as usize; - - let plugin_offset = asset_size - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_plugin_offset = new_asset_size - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - - // //TODO: This is memory intensive, we should use memmove instead probably. - let src = ctx.accounts.asset.data.borrow()[(plugin_offset as usize)..registry_offset] - .to_vec(); - - resize_or_reallocate_account( - ctx.accounts.asset, - payer, - ctx.accounts.system_program, - new_size as usize, - )?; - - sol_memcpy( - &mut ctx.accounts.asset.data.borrow_mut()[(new_plugin_offset as usize)..], - &src, - src.len(), - ); - - plugin_header.save(ctx.accounts.asset, new_asset_size as usize)?; - plugin_registry.registry = plugin_registry - .registry - .iter_mut() - .map(|record| { - let new_offset = (record.offset as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - Ok(RegistryRecord { - plugin_type: record.plugin_type, - offset: new_offset as usize, - authority: record.authority.clone(), - }) - }) - .collect::, MplCoreError>>()?; - plugin_registry.save(ctx.accounts.asset, new_registry_offset as usize)?; - } else { - resize_or_reallocate_account( - ctx.accounts.asset, - payer, - ctx.accounts.system_program, - asset.get_size(), - )?; - } - - asset.save(ctx.accounts.asset, 0)?; + process_update( + asset, + &plugin_header, + &plugin_registry, + asset_size, + ctx.accounts.asset, + payer, + ctx.accounts.system_program, + )?; } Ok(()) @@ -154,7 +97,7 @@ pub(crate) fn update_collection<'a>( assert_signer(ctx.accounts.authority)?; let payer = resolve_payer(ctx.accounts.authority, ctx.accounts.payer)?; - let (mut asset, plugin_header, plugin_registry) = validate_collection_permissions( + let (mut collection, plugin_header, plugin_registry) = validate_collection_permissions( ctx.accounts.authority, ctx.accounts.collection, None, @@ -164,90 +107,100 @@ pub(crate) fn update_collection<'a>( Plugin::validate_update, )?; - let asset_size = asset.get_size() as isize; + let collection_size = collection.get_size() as isize; let mut dirty = false; if let Some(new_update_authority) = ctx.accounts.new_update_authority { - asset.update_authority = *new_update_authority.key; + collection.update_authority = *new_update_authority.key; dirty = true; } if let Some(new_name) = &args.new_name { - asset.name = new_name.clone(); + collection.name = new_name.clone(); dirty = true; } if let Some(new_uri) = &args.new_uri { - asset.uri = new_uri.clone(); + collection.uri = new_uri.clone(); dirty = true; } if dirty { - if let (Some(mut plugin_header), Some(mut plugin_registry)) = - (plugin_header, plugin_registry) - { - let new_asset_size = asset.get_size() as isize; - let size_diff = new_asset_size - .checked_sub(asset_size) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_size = (ctx.accounts.collection.data_len() as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_registry_offset = (plugin_header.plugin_registry_offset as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let registry_offset = plugin_header.plugin_registry_offset; - plugin_header.plugin_registry_offset = new_registry_offset as usize; - - let plugin_offset = asset_size - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - let new_plugin_offset = new_asset_size - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - - // //TODO: This is memory intensive, we should use memmove instead probably. - let src = ctx.accounts.collection.data.borrow() - [(plugin_offset as usize)..registry_offset] - .to_vec(); - - resize_or_reallocate_account( - ctx.accounts.collection, - payer, - ctx.accounts.system_program, - new_size as usize, - )?; - - sol_memcpy( - &mut ctx.accounts.collection.data.borrow_mut()[(new_plugin_offset as usize)..], - &src, - src.len(), - ); - - plugin_header.save(ctx.accounts.collection, new_asset_size as usize)?; - plugin_registry.registry = plugin_registry - .registry - .iter_mut() - .map(|record| { - let new_offset = (record.offset as isize) - .checked_add(size_diff) - .ok_or(MplCoreError::NumericalOverflow)?; - Ok(RegistryRecord { - plugin_type: record.plugin_type, - offset: new_offset as usize, - authority: record.authority.clone(), - }) + process_update( + collection, + &plugin_header, + &plugin_registry, + collection_size, + ctx.accounts.collection, + payer, + ctx.accounts.system_program, + )?; + } + + Ok(()) +} + +fn process_update<'a, T: DataBlob + SolanaAccount>( + core: T, + plugin_header: &Option, + plugin_registry: &Option, + core_size: isize, + account: &AccountInfo<'a>, + payer: &AccountInfo<'a>, + system_program: &AccountInfo<'a>, +) -> ProgramResult { + if let (Some(mut plugin_header), Some(mut plugin_registry)) = + (plugin_header.clone(), plugin_registry.clone()) + { + let new_asset_size = core.get_size() as isize; + let size_diff = new_asset_size + .checked_sub(core_size) + .ok_or(MplCoreError::NumericalOverflow)?; + let new_size = (account.data_len() as isize) + .checked_add(size_diff) + .ok_or(MplCoreError::NumericalOverflow)?; + let new_registry_offset = (plugin_header.plugin_registry_offset as isize) + .checked_add(size_diff) + .ok_or(MplCoreError::NumericalOverflow)?; + let registry_offset = plugin_header.plugin_registry_offset; + plugin_header.plugin_registry_offset = new_registry_offset as usize; + + let plugin_offset = core_size + .checked_add(size_diff) + .ok_or(MplCoreError::NumericalOverflow)?; + let new_plugin_offset = new_asset_size + .checked_add(size_diff) + .ok_or(MplCoreError::NumericalOverflow)?; + + // //TODO: This is memory intensive, we should use memmove instead probably. + let src = account.data.borrow()[(plugin_offset as usize)..registry_offset].to_vec(); + + resize_or_reallocate_account(account, payer, system_program, new_size as usize)?; + + sol_memcpy( + &mut account.data.borrow_mut()[(new_plugin_offset as usize)..], + &src, + src.len(), + ); + + plugin_header.save(account, new_asset_size as usize)?; + plugin_registry.registry = plugin_registry + .registry + .iter_mut() + .map(|record| { + let new_offset = (record.offset as isize) + .checked_add(size_diff) + .ok_or(MplCoreError::NumericalOverflow)?; + Ok(RegistryRecord { + plugin_type: record.plugin_type, + offset: new_offset as usize, + authority: record.authority.clone(), }) - .collect::, MplCoreError>>()?; - plugin_registry.save(ctx.accounts.collection, new_registry_offset as usize)?; - } else { - resize_or_reallocate_account( - ctx.accounts.collection, - payer, - ctx.accounts.system_program, - asset.get_size(), - )?; - } - - asset.save(ctx.accounts.collection, 0)?; + }) + .collect::, MplCoreError>>()?; + plugin_registry.save(account, new_registry_offset as usize)?; + } else { + resize_or_reallocate_account(account, payer, system_program, core.get_size())?; } + core.save(account, 0)?; + Ok(()) }