Skip to content

Commit

Permalink
Add external plugin validation functions (#85)
Browse files Browse the repository at this point in the history
* Add validations for external plugins on lifecycle events

* Remove external_plugin_validate from plugin_checks
  • Loading branch information
danenbm authored Apr 25, 2024
1 parent 9580567 commit e939cb2
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 57 deletions.
25 changes: 16 additions & 9 deletions programs/mpl-core/src/plugins/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ pub struct DataStore {
pub data_len: usize,
}

impl PluginValidation for DataStore {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}

fn validate_transfer(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

impl From<&DataStoreInitInfo> for DataStore {
fn from(init_info: &DataStoreInitInfo) -> Self {
Self {
Expand All @@ -46,15 +62,6 @@ pub struct DataStoreInitInfo {
pub schema: Option<ExternalPluginSchema>,
}

impl PluginValidation for DataStoreInitInfo {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

/// Data store update info.
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, Eq, PartialEq)]
pub struct DataStoreUpdateInfo {
Expand Down
62 changes: 47 additions & 15 deletions programs/mpl-core/src/plugins/external_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,31 +93,63 @@ impl ExternalPlugin {

/// Validate the add external plugin lifecycle event.
pub(crate) fn validate_create(
init_info: &ExternalPluginInitInfo,
external_plugin: &ExternalPlugin,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
match init_info {
ExternalPluginInitInfo::LifecycleHook(init_info) => init_info.validate_create(ctx),
ExternalPluginInitInfo::Oracle(init_info) => init_info.validate_create(ctx),
ExternalPluginInitInfo::DataStore(init_info) => init_info.validate_create(ctx),
match external_plugin {
ExternalPlugin::LifecycleHook(lifecycle_hook) => lifecycle_hook.validate_create(ctx),
ExternalPlugin::Oracle(oracle) => oracle.validate_create(ctx),
ExternalPlugin::DataStore(data_store) => data_store.validate_create(ctx),
}
}

/// Route the validation of the update action to the appropriate plugin.
pub(crate) fn validate_update(
external_plugin: &ExternalPlugin,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
match external_plugin {
ExternalPlugin::LifecycleHook(lifecycle_hook) => lifecycle_hook.validate_update(ctx),
ExternalPlugin::Oracle(oracle) => oracle.validate_update(ctx),
ExternalPlugin::DataStore(data_store) => data_store.validate_update(ctx),
}
}

/// Route the validation of the burn action to the appropriate plugin.
pub(crate) fn validate_burn(
external_plugin: &ExternalPlugin,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
match external_plugin {
ExternalPlugin::LifecycleHook(lifecycle_hook) => lifecycle_hook.validate_burn(ctx),
ExternalPlugin::Oracle(oracle) => oracle.validate_burn(ctx),
ExternalPlugin::DataStore(data_store) => data_store.validate_burn(ctx),
}
}

/// Route the validation of the transfer action to the appropriate external plugin.
pub(crate) fn validate_transfer(
external_plugin: &ExternalPlugin,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
match external_plugin {
ExternalPlugin::LifecycleHook(lifecycle_hook) => lifecycle_hook.validate_transfer(ctx),
ExternalPlugin::Oracle(oracle) => oracle.validate_transfer(ctx),
ExternalPlugin::DataStore(data_store) => data_store.validate_transfer(ctx),
}
}

/// Validate the add external plugin lifecycle event.
pub(crate) fn validate_add_external_plugin(
init_info: &ExternalPluginInitInfo,
external_plugin: &ExternalPlugin,
ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
match init_info {
ExternalPluginInitInfo::LifecycleHook(init_info) => {
init_info.validate_add_external_plugin(ctx)
}
ExternalPluginInitInfo::Oracle(init_info) => {
init_info.validate_add_external_plugin(ctx)
}
ExternalPluginInitInfo::DataStore(init_info) => {
init_info.validate_add_external_plugin(ctx)
match external_plugin {
ExternalPlugin::LifecycleHook(lifecycle_hook) => {
lifecycle_hook.validate_add_external_plugin(ctx)
}
ExternalPlugin::Oracle(oracle) => oracle.validate_add_external_plugin(ctx),
ExternalPlugin::DataStore(data_store) => data_store.validate_add_external_plugin(ctx),
}
}

Expand Down
7 changes: 5 additions & 2 deletions programs/mpl-core/src/plugins/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,10 @@ pub(crate) fn validate_plugin_checks<'a>(
asset: Option<&AccountInfo<'a>>,
collection: Option<&AccountInfo<'a>>,
resolved_authorities: &[Authority],
validate_fp: fn(&Plugin, &PluginValidationContext) -> Result<ValidationResult, ProgramError>,
plugin_validate_fp: fn(
&Plugin,
&PluginValidationContext,
) -> Result<ValidationResult, ProgramError>,
) -> Result<ValidationResult, ProgramError> {
let mut approved = false;
let mut rejected = false;
Expand All @@ -836,7 +839,7 @@ pub(crate) fn validate_plugin_checks<'a>(
target_plugin: new_plugin,
};

let result = validate_fp(&Plugin::load(account, registry_record.offset)?, &ctx)?;
let result = plugin_validate_fp(&Plugin::load(account, registry_record.offset)?, &ctx)?;
match result {
ValidationResult::Rejected => rejected = true,
ValidationResult::Approved => approved = true,
Expand Down
25 changes: 16 additions & 9 deletions programs/mpl-core/src/plugins/lifecycle_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ pub struct LifecycleHook {
pub data_len: usize, // 8
}

impl PluginValidation for LifecycleHook {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}

fn validate_transfer(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

impl From<&LifecycleHookInitInfo> for LifecycleHook {
fn from(init_info: &LifecycleHookInitInfo) -> Self {
Self {
Expand Down Expand Up @@ -62,15 +78,6 @@ pub struct LifecycleHookInitInfo {
pub schema: Option<ExternalPluginSchema>,
}

impl PluginValidation for LifecycleHookInitInfo {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

/// Lifecycle hook update info.
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, Eq, PartialEq)]
pub struct LifecycleHookUpdateInfo {
Expand Down
25 changes: 16 additions & 9 deletions programs/mpl-core/src/plugins/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ pub struct Oracle {
pub results_offset: ValidationResultsOffset,
}

impl PluginValidation for Oracle {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}

fn validate_transfer(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

impl From<&OracleInitInfo> for Oracle {
fn from(init_info: &OracleInitInfo) -> Self {
Self {
Expand Down Expand Up @@ -50,15 +66,6 @@ pub struct OracleInitInfo {
pub results_offset: Option<ValidationResultsOffset>,
}

impl PluginValidation for OracleInitInfo {
fn validate_add_external_plugin(
&self,
_ctx: &PluginValidationContext,
) -> Result<ValidationResult, ProgramError> {
Ok(ValidationResult::Pass)
}
}

/// Oracle update info.
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, Eq, PartialEq)]
pub struct OracleUpdateInfo {
Expand Down
14 changes: 10 additions & 4 deletions programs/mpl-core/src/processor/add_external_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ pub(crate) fn add_external_plugin<'a>(
target_plugin: None,
};

if ExternalPlugin::validate_add_external_plugin(&args.init_info, &validation_ctx)?
== ValidationResult::Rejected
if ExternalPlugin::validate_add_external_plugin(
&ExternalPlugin::from(&args.init_info),
&validation_ctx,
)? == ValidationResult::Rejected
{
return Err(MplCoreError::InvalidAuthority.into());
}
Expand All @@ -75,6 +77,7 @@ pub(crate) fn add_external_plugin<'a>(
AssetV1::validate_add_external_plugin,
CollectionV1::validate_add_external_plugin,
Plugin::validate_add_external_plugin,
Some(ExternalPlugin::validate_add_external_plugin),
)?;

// Increment sequence number and save only if it is `Some(_)`.
Expand Down Expand Up @@ -123,8 +126,10 @@ pub(crate) fn add_collection_external_plugin<'a>(
target_plugin: None,
};

if ExternalPlugin::validate_add_external_plugin(&args.init_info, &validation_ctx)?
== ValidationResult::Rejected
if ExternalPlugin::validate_add_external_plugin(
&ExternalPlugin::from(&args.init_info),
&validation_ctx,
)? == ValidationResult::Rejected
{
return Err(MplCoreError::InvalidAuthority.into());
}
Expand All @@ -139,6 +144,7 @@ pub(crate) fn add_collection_external_plugin<'a>(
PluginType::check_add_external_plugin,
CollectionV1::validate_add_external_plugin,
Plugin::validate_add_external_plugin,
Some(ExternalPlugin::validate_add_external_plugin),
)?;

process_add_external_plugin::<CollectionV1>(
Expand Down
2 changes: 2 additions & 0 deletions programs/mpl-core/src/processor/add_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub(crate) fn add_plugin<'a>(
AssetV1::validate_add_plugin,
CollectionV1::validate_add_plugin,
Plugin::validate_add_plugin,
None,
)?;

// Increment sequence number and save only if it is `Some(_)`.
Expand Down Expand Up @@ -141,6 +142,7 @@ pub(crate) fn add_collection_plugin<'a>(
PluginType::check_add_plugin,
CollectionV1::validate_add_plugin,
Plugin::validate_add_plugin,
None,
)?;

process_add_plugin::<CollectionV1>(
Expand Down
2 changes: 2 additions & 0 deletions programs/mpl-core/src/processor/approve_plugin_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub(crate) fn approve_plugin_authority<'a>(
AssetV1::validate_approve_plugin_authority,
CollectionV1::validate_approve_plugin_authority,
Plugin::validate_approve_plugin_authority,
None,
)?;

// Increment sequence number and save only if it is `Some(_)`.
Expand Down Expand Up @@ -117,6 +118,7 @@ pub(crate) fn approve_collection_plugin_authority<'a>(
PluginType::check_approve_plugin_authority,
CollectionV1::validate_approve_plugin_authority,
Plugin::validate_approve_plugin_authority,
None,
)?;

process_approve_plugin_authority::<CollectionV1>(
Expand Down
4 changes: 3 additions & 1 deletion programs/mpl-core/src/processor/burn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg};
use crate::{
error::MplCoreError,
instruction::accounts::{BurnCollectionV1Accounts, BurnV1Accounts},
plugins::{Plugin, PluginType},
plugins::{ExternalPlugin, Plugin, PluginType},
state::{AssetV1, CollectionV1, CompressionProof, Key, SolanaAccount, Wrappable},
utils::{
close_program_account, load_key, rebuild_account_state_from_proof_data, resolve_authority,
Expand Down Expand Up @@ -96,6 +96,7 @@ pub(crate) fn burn<'a>(accounts: &'a [AccountInfo<'a>], args: BurnV1Args) -> Pro
AssetV1::validate_burn,
CollectionV1::validate_burn,
Plugin::validate_burn,
Some(ExternalPlugin::validate_burn),
)?;

process_burn(ctx.accounts.asset, authority)?;
Expand Down Expand Up @@ -138,6 +139,7 @@ pub(crate) fn burn_collection<'a>(
PluginType::check_burn,
CollectionV1::validate_burn,
Plugin::validate_burn,
Some(ExternalPlugin::validate_burn),
)?;

process_burn(ctx.accounts.collection, authority)
Expand Down
1 change: 1 addition & 0 deletions programs/mpl-core/src/processor/compress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub(crate) fn compress<'a>(
AssetV1::validate_compress,
CollectionV1::validate_compress,
Plugin::validate_compress,
None,
)?;

// Compress the asset and plugin registry into account space.
Expand Down
6 changes: 4 additions & 2 deletions programs/mpl-core/src/processor/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,10 @@ pub(crate) fn process_create<'a>(
new_owner: None,
target_plugin: None,
};
if ExternalPlugin::validate_create(plugin_init_info, &validation_ctx)?
== ValidationResult::Rejected
if ExternalPlugin::validate_create(
&ExternalPlugin::from(plugin_init_info),
&validation_ctx,
)? == ValidationResult::Rejected
{
approved = false;
}
Expand Down
6 changes: 4 additions & 2 deletions programs/mpl-core/src/processor/create_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,10 @@ pub(crate) fn process_create_collection<'a>(
new_owner: None,
target_plugin: None,
};
if ExternalPlugin::validate_create(plugin_init_info, &validation_ctx)?
== ValidationResult::Rejected
if ExternalPlugin::validate_create(
&ExternalPlugin::from(plugin_init_info),
&validation_ctx,
)? == ValidationResult::Rejected
{
approved = false;
};
Expand Down
1 change: 1 addition & 0 deletions programs/mpl-core/src/processor/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub(crate) fn decompress<'a>(
AssetV1::validate_decompress,
CollectionV1::validate_decompress,
Plugin::validate_decompress,
None,
)?;

// TODO Enable compression.
Expand Down
2 changes: 2 additions & 0 deletions programs/mpl-core/src/processor/remove_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub(crate) fn remove_plugin<'a>(
AssetV1::validate_remove_plugin,
CollectionV1::validate_remove_plugin,
Plugin::validate_remove_plugin,
None,
)?;

// Increment sequence number and save only if it is `Some(_)`.
Expand Down Expand Up @@ -133,6 +134,7 @@ pub(crate) fn remove_collection_plugin<'a>(
PluginType::check_remove_plugin,
CollectionV1::validate_remove_plugin,
Plugin::validate_remove_plugin,
None,
)?;

process_remove_plugin(
Expand Down
2 changes: 2 additions & 0 deletions programs/mpl-core/src/processor/revoke_plugin_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub(crate) fn revoke_plugin_authority<'a>(
AssetV1::validate_revoke_plugin_authority,
CollectionV1::validate_revoke_plugin_authority,
Plugin::validate_revoke_plugin_authority,
None,
)?;

// Increment sequence number and save only if it is `Some(_)`.
Expand Down Expand Up @@ -138,6 +139,7 @@ pub(crate) fn revoke_collection_plugin_authority<'a>(
PluginType::check_revoke_plugin_authority,
CollectionV1::validate_revoke_plugin_authority,
Plugin::validate_revoke_plugin_authority,
None,
)?;

let resolved_authorities =
Expand Down
Loading

0 comments on commit e939cb2

Please sign in to comment.