From ca6cd9eaa9ab23a7a40eea1273ce89e32650a895 Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 25 Sep 2023 12:39:31 +0100 Subject: [PATCH] Fix review comments --- clients/rust/Cargo.lock | 5 +- clients/rust/Cargo.toml | 3 +- clients/rust/src/lib.rs | 45 +--------------- clients/rust/src/traits.rs | 65 ++++++++++++++++++++++++ clients/rust/src/{util.rs => utils.rs} | 0 clients/rust/tests/mint.rs | 8 +++ clients/rust/tests/setup/tree_manager.rs | 48 ++++++++++++----- clients/rust/tests/transfer.rs | 4 ++ 8 files changed, 120 insertions(+), 58 deletions(-) create mode 100644 clients/rust/src/traits.rs rename clients/rust/src/{util.rs => utils.rs} (100%) diff --git a/clients/rust/Cargo.lock b/clients/rust/Cargo.lock index 547840e7..fe83e099 100644 --- a/clients/rust/Cargo.lock +++ b/clients/rust/Cargo.lock @@ -790,9 +790,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] @@ -2269,6 +2269,7 @@ version = "0.10.1" dependencies = [ "assert_matches", "borsh 0.10.3", + "bytemuck", "kaigan", "num-derive 0.3.3", "num-traits", diff --git a/clients/rust/Cargo.toml b/clients/rust/Cargo.toml index 89655604..fbe53e91 100644 --- a/clients/rust/Cargo.toml +++ b/clients/rust/Cargo.toml @@ -27,6 +27,7 @@ thiserror = "^1.0" [dev-dependencies] assert_matches = "1.5.0" +bytemuck = "1.14.0" solana-program-test = "^1.14" solana-sdk = "^1.14" spl-account-compression = { version="0.2.0", features = ["no-entrypoint", "cpi"] } @@ -34,4 +35,4 @@ spl-associated-token-account = { version = ">= 1.1.3, < 3.0", features = ["no-en spl-concurrent-merkle-tree = "0.2.0" spl-merkle-tree-reference = "0.1.0" spl-noop = { version = "0.1.3", features = ["no-entrypoint"] } -spl-token = { version = ">= 3.5.0, < 5.0", features = ["no-entrypoint"] } \ No newline at end of file +spl-token = { version = ">= 3.5.0, < 5.0", features = ["no-entrypoint"] } diff --git a/clients/rust/src/lib.rs b/clients/rust/src/lib.rs index 2e468f30..b05af6d1 100644 --- a/clients/rust/src/lib.rs +++ b/clients/rust/src/lib.rs @@ -1,48 +1,7 @@ mod generated; pub mod hash; -pub mod util; +mod traits; +pub mod utils; pub use generated::programs::MPL_BUBBLEGUM_ID as ID; -use generated::types::{LeafSchema, Version}; pub use generated::*; -use solana_program::keccak; - -// additional methods for the `LeafSchema` type - -impl LeafSchema { - pub fn hash(&self) -> [u8; 32] { - match self { - LeafSchema::V1 { - id, - owner, - delegate, - nonce, - data_hash, - creator_hash, - } => keccak::hashv(&[ - &[self.version().to_bytes()], - id.as_ref(), - owner.as_ref(), - delegate.as_ref(), - nonce.to_le_bytes().as_ref(), - data_hash.as_ref(), - creator_hash.as_ref(), - ]) - .to_bytes(), - } - } - - pub fn version(&self) -> Version { - match self { - LeafSchema::V1 { .. } => Version::V1, - } - } -} - -impl Version { - pub fn to_bytes(&self) -> u8 { - match self { - Version::V1 => 1, - } - } -} diff --git a/clients/rust/src/traits.rs b/clients/rust/src/traits.rs new file mode 100644 index 00000000..e55d12a7 --- /dev/null +++ b/clients/rust/src/traits.rs @@ -0,0 +1,65 @@ +use solana_program::keccak; + +use crate::types::{LeafSchema, Version}; + +// LeafSchema + +impl LeafSchema { + pub fn hash(&self) -> [u8; 32] { + match self { + LeafSchema::V1 { + id, + owner, + delegate, + nonce, + data_hash, + creator_hash, + } => keccak::hashv(&[ + &[self.version().to_bytes()], + id.as_ref(), + owner.as_ref(), + delegate.as_ref(), + nonce.to_le_bytes().as_ref(), + data_hash.as_ref(), + creator_hash.as_ref(), + ]) + .to_bytes(), + } + } + + pub fn version(&self) -> Version { + match self { + LeafSchema::V1 { .. } => Version::V1, + } + } +} + +impl Default for LeafSchema { + fn default() -> Self { + Self::V1 { + id: Default::default(), + owner: Default::default(), + delegate: Default::default(), + nonce: 0, + data_hash: [0; 32], + creator_hash: [0; 32], + } + } +} + +// Version + +impl Version { + pub fn to_bytes(&self) -> u8 { + match self { + Version::V1 => 1, + } + } +} + +#[allow(clippy::derivable_impls)] +impl Default for Version { + fn default() -> Self { + Version::V1 + } +} diff --git a/clients/rust/src/util.rs b/clients/rust/src/utils.rs similarity index 100% rename from clients/rust/src/util.rs rename to clients/rust/src/utils.rs diff --git a/clients/rust/tests/mint.rs b/clients/rust/tests/mint.rs index 9882d642..76ab48d6 100644 --- a/clients/rust/tests/mint.rs +++ b/clients/rust/tests/mint.rs @@ -57,6 +57,10 @@ mod mint { // Then one cNFT is minted. assert_eq!(tree_manager.minted(), 1); + + // And the merkle tree root is updated. + + tree_manager.assert_root(&mut context).await; } #[tokio::test] @@ -108,5 +112,9 @@ mod mint { assert_eq!(tree_manager.minted(), 10); assert!(!tree_manager.get_proof(9).is_empty()); + + // And the merkle tree root is updated. + + tree_manager.assert_root(&mut context).await; } } diff --git a/clients/rust/tests/setup/tree_manager.rs b/clients/rust/tests/setup/tree_manager.rs index 62328e1c..0fe7e9a2 100644 --- a/clients/rust/tests/setup/tree_manager.rs +++ b/clients/rust/tests/setup/tree_manager.rs @@ -1,16 +1,18 @@ use mpl_bubblegum::{ accounts::TreeConfig, hash::{hash_creators, hash_metadata}, - instructions::{CreateTreeConfigBuilder, InstructionAccount, MintV1Builder, TransferBuilder}, + instructions::{CreateTreeConfigBuilder, MintV1Builder, TransferBuilder}, types::{LeafSchema, MetadataArgs}, - util::get_asset_id, + utils::get_asset_id, }; -use solana_program::{pubkey::Pubkey, system_instruction}; +use solana_program::{instruction::AccountMeta, pubkey::Pubkey, system_instruction}; use solana_program_test::{BanksClientError, ProgramTestContext}; use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction}; use spl_account_compression::{state::CONCURRENT_MERKLE_TREE_HEADER_SIZE_V1, ConcurrentMerkleTree}; use spl_merkle_tree_reference::{MerkleTree, Node}; +use crate::get_account; + pub struct TreeManager { /// A keypair to represent the merkle tree account. pub tree: Keypair, @@ -149,8 +151,17 @@ impl TreeManager = self + .get_proof(*nonce as u32) + .iter() + .map(|node| AccountMeta { + pubkey: Pubkey::new_from_array(*node), + is_signer: false, + is_writable: false, + }) + .collect(); + + let transfer_ix = TransferBuilder::new() .leaf_delegate(owner.pubkey(), false) .leaf_owner(owner.pubkey(), true) .merkle_tree(self.tree.pubkey()) @@ -160,15 +171,12 @@ impl TreeManager TreeManager>(); + let tree = &mut data[..size]; + + let tree = + bytemuck::try_from_bytes::>(tree) + .unwrap(); + let root = tree.change_logs[tree.active_index as usize].root; + + assert_eq!(root, self.proof_tree.root); + } } diff --git a/clients/rust/tests/transfer.rs b/clients/rust/tests/transfer.rs index 39c41dfc..d58e04c3 100644 --- a/clients/rust/tests/transfer.rs +++ b/clients/rust/tests/transfer.rs @@ -74,5 +74,9 @@ mod transfer { let LeafSchema::V1 { owner, .. } = leaf; assert_eq!(owner, receiver); + + // And the merkle tree root is updated. + + tree_manager.assert_root(&mut context).await; } }