Skip to content

Commit

Permalink
WIP utils.
Browse files Browse the repository at this point in the history
  • Loading branch information
blockiosaurus committed Feb 17, 2024
1 parent e77c53c commit c2ff054
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 23 deletions.
10 changes: 10 additions & 0 deletions programs/mpl-asset/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ pub enum MplAssetError {
/// 0 - Invalid System Program
#[error("Invalid System Program")]
InvalidSystemProgram,

/// 1 - Error deserializing account
#[error("Error deserializing account")]
DeserializationError,

/// 2 - Error serializing account
#[error("Error serializing account")]
SerializationError,

/// 3 - Plugins not initialized
#[error("Plugins not initialized")]
PluginsNotInitialized,

/// 4 - Plugin not found
#[error("Plugin not found")]
PluginNotFound,
}

impl PrintProgramError for MplAssetError {
Expand Down
1 change: 1 addition & 0 deletions programs/mpl-asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod instruction;
pub mod plugins;
pub mod processor;
pub mod state;
pub mod utils;

pub use solana_program;

Expand Down
36 changes: 28 additions & 8 deletions programs/mpl-asset/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ mod utils;

pub use collection::*;
pub use royalties::*;
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
};
pub use utils::*;

use borsh::{BorshDeserialize, BorshSerialize};
use std::collections::HashMap;

use crate::state::Authority;
use crate::{
error::MplAssetError,
state::{Authority, Key},
};

// macro_rules! plugin_instruction {
// ($a:expr, $b:expr) => {
Expand All @@ -35,20 +40,35 @@ pub enum Plugin {
// Burn = plugin_instruction!(Plugin::Metadata, 2),
//}

#[repr(C)]
#[derive(Clone, BorshSerialize, BorshDeserialize, Debug)]
pub struct RegistryData {
pub offset: usize,
pub authorities: Vec<Authority>,
}

#[repr(C)]
#[derive(Clone, BorshSerialize, BorshDeserialize, Debug)]
pub struct PluginRegistry {
pub registry: HashMap<Plugin, RegistryData>,
pub registry: Vec<(Key, RegistryData)>,
// pub third_party_registry: HashMap<Authority, usize>,
}

pub trait DataStorage {
fn get_required_length(&self);
fn save(&self, data: &mut [u8]);
fn load(&self, data: &[u8]);
fn load_mut(&self, data: &mut [u8]);
impl PluginRegistry {
pub fn load(account: &AccountInfo, offset: usize) -> Result<Self, ProgramError> {
let mut bytes: &[u8] = &(*account.data).borrow()[offset..];
PluginRegistry::deserialize(&mut bytes).map_err(|error| {
msg!("Error: {}", error);
MplAssetError::DeserializationError.into()
})
}

pub fn save(&self, account: &AccountInfo, offset: usize) -> ProgramResult {
borsh::to_writer(&mut account.data.borrow_mut()[offset..], self).map_err(|error| {
msg!("Error: {}", error);
MplAssetError::SerializationError.into()
})
}
}

// pub trait PluginTrait
Expand Down
77 changes: 69 additions & 8 deletions programs/mpl-asset/src/plugins/utils.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,77 @@
use super::Plugin;
use borsh::BorshDeserialize;
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
pubkey::Pubkey,
};

//TODO: Implement this function
pub fn create_idempotent() {
// Create plugin header and registry if it doesn't exist
use crate::{
error::MplAssetError,
state::{Asset, Key, PluginHeader},
utils::DataBlob,
};

use super::{Plugin, PluginRegistry};

//TODO:keith: Implement this function
/// Create plugin header and registry if it doesn't exist
pub fn create_idempotent(account: &AccountInfo) -> ProgramResult {
let mut bytes: &[u8] = &(*account.data).borrow();
let asset = Asset::deserialize(&mut bytes)?;

// Check if the plugin header and registry exist.
if asset.get_size() == account.data_len() {
// They don't exist, so create them.
let header = PluginHeader {
version: 1,
plugin_map_offset: asset.get_size() + PluginHeader::get_initial_size(),
};
let registry = PluginRegistry { registry: vec![] };

header.save(account, asset.get_size())?;
registry.save(account, header.plugin_map_offset)?;
}

Ok(())
}

//TODO: Implement this function
pub fn fetch_plugin(plugin: u8) -> Plugin {
// Create plugin header and registry if it doesn't exist
pub fn assert_plugins_initialized(account: &AccountInfo) -> ProgramResult {
let mut bytes: &[u8] = &(*account.data).borrow();
let asset = Asset::deserialize(&mut bytes).unwrap();

if asset.get_size() == account.data_len() {
return Err(MplAssetError::PluginsNotInitialized.into());
}

Ok(())
}

//TODO:keith: Implement this function
pub fn fetch_plugin(
account: &AccountInfo,
plugin: Key,
) -> Result<((Vec<Pubkey>, Plugin)), ProgramError> {
// Fetch the plugin from the registry.
let mut bytes: &[u8] = &(*account.data).borrow();
let asset = Asset::deserialize(&mut bytes)?;

let header = PluginHeader::load(account, asset.get_size())?;
let PluginRegistry { registry } = PluginRegistry::load(account, header.plugin_map_offset)?;

let plugin_data = registry
.iter()
.find(|(key, _)| *key == plugin)
.map(|(_, data)| data)
.ok_or(MplAssetError::PluginNotFound)?;

let authorities = plugin_data
.authorities
.iter()
.map(|authority| authority.key)
.collect();
}

//TODO: Implement this function
//TODO:keith: Implement this function
pub fn list_plugins() -> Vec<u8> {
// Create plugin header and registry if it doesn't exist
vec![]
}
2 changes: 1 addition & 1 deletion programs/mpl-asset/src/processor/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{

#[repr(C)]
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)]
pub(crate) struct CreateArgs {
pub struct CreateArgs {
pub data_state: DataState,
pub name: String,
pub uri: String,
Expand Down
16 changes: 16 additions & 0 deletions programs/mpl-asset/src/state/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use borsh::{BorshDeserialize, BorshSerialize};
use shank::ShankAccount;
use solana_program::{keccak, program_error::ProgramError, pubkey::Pubkey};

use crate::utils::DataBlob;

use super::{Compressible, Key};

#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)]
Expand All @@ -13,6 +15,10 @@ pub struct Asset {
pub uri: String, //4
}

impl Asset {
pub const BASE_LENGTH: usize = 1 + 32 + 32 + 4 + 4;
}

impl Compressible for Asset {
fn hash(&self) -> Result<[u8; 32], ProgramError> {
let serialized_data = self.try_to_vec()?;
Expand All @@ -21,6 +27,16 @@ impl Compressible for Asset {
}
}

impl DataBlob for Asset {
fn get_initial_size() -> usize {
Asset::BASE_LENGTH
}

fn get_size(&self) -> usize {
Asset::BASE_LENGTH + self.name.len() + self.uri.len()
}
}

#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)]
pub struct HashedAsset {
pub key: Key, //1
Expand Down
23 changes: 17 additions & 6 deletions programs/mpl-asset/src/state/plugin_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,38 @@ use solana_program::msg;
use solana_program::program_error::ProgramError;

use crate::error::MplAssetError;
use crate::utils::DataBlob;

#[repr(C)]
#[derive(Clone, BorshSerialize, BorshDeserialize, Debug)]
pub struct PluginHeader {
pub version: u8,
pub plugin_map_offset: usize,
pub version: u8, // 1
pub plugin_map_offset: usize, // 8
}

impl PluginHeader {
pub fn load(account: &AccountInfo) -> Result<Self, ProgramError> {
let mut bytes: &[u8] = &(*account.data).borrow();
pub fn load(account: &AccountInfo, offset: usize) -> Result<Self, ProgramError> {
let mut bytes: &[u8] = &(*account.data).borrow()[offset..];
PluginHeader::deserialize(&mut bytes).map_err(|error| {
msg!("Error: {}", error);
MplAssetError::DeserializationError.into()
})
}

pub fn save(&self, account: &AccountInfo) -> ProgramResult {
borsh::to_writer(&mut account.data.borrow_mut()[..], self).map_err(|error| {
pub fn save(&self, account: &AccountInfo, offset: usize) -> ProgramResult {
borsh::to_writer(&mut account.data.borrow_mut()[offset..], self).map_err(|error| {
msg!("Error: {}", error);
MplAssetError::SerializationError.into()
})
}
}

impl DataBlob for PluginHeader {
fn get_initial_size() -> usize {
1 + 8
}

fn get_size(&self) -> usize {
1 + 8
}
}

0 comments on commit c2ff054

Please sign in to comment.