Skip to content

Commit

Permalink
Merging in main.
Browse files Browse the repository at this point in the history
  • Loading branch information
blockiosaurus committed Feb 19, 2024
2 parents 2d1e7fb + a364cf2 commit 23ba4c6
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 33 deletions.
2 changes: 1 addition & 1 deletion clients/js/test/transfer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ test('it cannot transfer an asset if not the owner', async (t) => {
authority: attacker,
}).sendAndConfirm(umi);

t.throwsAsync(result, { name: 'InvalidAuthority' })
await t.throwsAsync(result, { name: 'InvalidAuthority' })

const afterAsset = await fetchAsset(umi, assetAddress.publicKey);
// console.log("Account State:", afterAsset);
Expand Down
20 changes: 5 additions & 15 deletions programs/mpl-asset/src/processor/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use borsh::{BorshDeserialize, BorshSerialize};
use mpl_utils::assert_signer;
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, program::invoke,
program_error::ProgramError,
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
};

use crate::{
Expand Down Expand Up @@ -31,25 +30,16 @@ pub(crate) fn transfer<'a>(accounts: &'a [AccountInfo<'a>], args: TransferArgs)

match load_key(ctx.accounts.asset_address, 0)? {
Key::HashedAsset => {
// TODO: Needs to be in helper.
// Check that arguments passed in result in on-chain hash.
let compression_proof = args
.compression_proof
.ok_or(MplAssetError::MissingCompressionProof)?;
let mut asset = Asset::from(compression_proof);
let args_asset_hash = asset.hash()?;
let current_account_hash = HashedAsset::load(ctx.accounts.asset_address, 0)?.hash;
if args_asset_hash != current_account_hash {
return Err(MplAssetError::IncorrectAssetHash.into());
}
let mut asset = Asset::verify_proof(ctx.accounts.asset_address, compression_proof)?;

// TODO: Needs to be in helper.
// Update owner and send Noop instruction.
asset.owner = *ctx.accounts.new_owner.key;
let serialized_data = asset.try_to_vec()?;
invoke(&spl_noop::instruction(serialized_data), &[])?;

// Make a new hashed asset with updated owner.
asset.wrap()?;

// Make a new hashed asset with updated owner and save to account.
HashedAsset::new(asset.hash()?).save(ctx.accounts.asset_address, 0)
}
Key::Asset => {
Expand Down
33 changes: 28 additions & 5 deletions programs/mpl-asset/src/state/asset.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use borsh::{BorshDeserialize, BorshSerialize};
use shank::ShankAccount;
use solana_program::{keccak, program_error::ProgramError, pubkey::Pubkey};
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, keccak, program::invoke,
program_error::ProgramError, pubkey::Pubkey,
};

use crate::state::{CompressionProof, DataBlob, Key, SolanaAccount};

use super::Compressible;
use crate::{
error::MplAssetError,
state::{Compressible, CompressionProof, DataBlob, HashedAsset, Key, SolanaAccount},
};

#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)]
pub struct Asset {
Expand All @@ -17,14 +21,33 @@ pub struct Asset {

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

// Check that a compression proof results in same on-chain hash.
pub fn verify_proof(
hashed_asset: &AccountInfo,
compression_proof: CompressionProof,
) -> Result<Asset, ProgramError> {
let asset = Self::from(compression_proof);
let asset_hash = asset.hash()?;
let current_account_hash = HashedAsset::load(hashed_asset, 0)?.hash;
if asset_hash != current_account_hash {
return Err(MplAssetError::IncorrectAssetHash.into());
}

Ok(asset)
}
}

impl Compressible for Asset {
fn hash(&self) -> Result<[u8; 32], ProgramError> {
let serialized_data = self.try_to_vec()?;

Ok(keccak::hash(serialized_data.as_slice()).to_bytes())
}

fn wrap(&self) -> ProgramResult {
let serialized_data = self.try_to_vec()?;
invoke(&spl_noop::instruction(serialized_data), &[])
}
}

impl DataBlob for Asset {
Expand Down
5 changes: 0 additions & 5 deletions programs/mpl-asset/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ pub enum ExtraAccounts {
owner_pda: Option<Pubkey>,
},
}

pub trait Compressible {
fn hash(&self) -> Result<[u8; 32], ProgramError>;
}

#[derive(Clone, Copy, BorshSerialize, BorshDeserialize, Debug, PartialEq, Eq, FromPrimitive)]
pub enum Key {
Uninitialized,
Expand Down
11 changes: 4 additions & 7 deletions programs/mpl-asset/src/state/traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{error::MplAssetError, state::Key};
use crate::{error::MplAssetError, state::Key, utils::load_key};
use borsh::{BorshDeserialize, BorshSerialize};
use num_traits::FromPrimitive;
use solana_program::account_info::AccountInfo;
use solana_program::entrypoint::ProgramResult;
use solana_program::msg;
Expand Down Expand Up @@ -36,9 +35,7 @@ pub trait SolanaAccount: BorshSerialize + BorshDeserialize {
}
}

pub fn load_key(account: &AccountInfo, offset: usize) -> Result<Key, ProgramError> {
let key = Key::from_u8((*account.data).borrow()[offset])
.ok_or(MplAssetError::DeserializationError)?;

Ok(key)
pub trait Compressible {
fn hash(&self) -> Result<[u8; 32], ProgramError>;
fn wrap(&self) -> ProgramResult;
}

0 comments on commit 23ba4c6

Please sign in to comment.