Skip to content

Commit 0e3a1e8

Browse files
authored
Merge pull request solana-labs#116 from jarry-xiao/more-bgum-parsing
adds more validation to bgum and parses redeem and cancel redeem
2 parents c1b7f08 + a67db30 commit 0e3a1e8

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

contracts/programs/bubblegum/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ pub enum BubblegumError {
66
AssetOwnerMismatch,
77
#[msg("PublicKeyMismatch")]
88
PublicKeyMismatch,
9+
#[msg("Hashing Mismatch Within Leaf Schema")]
10+
HashingMismatch,
11+
#[msg("Unsupported Schema Version")]
12+
UnsupportedSchemaVersion,
913
}

contracts/programs/bubblegum/src/lib.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ use {
1010
Nonce, Voucher,
1111
metaplex_adapter::{MetadataArgs, TokenProgramVersion},
1212
NewNFTEvent,
13+
NFTDecompressionEvent
1314
},
1415
gummyroll::{program::Gummyroll, Node},
16+
crate::error::BubblegumError,
1517
crate::utils::{append_leaf,
1618
insert_or_append_leaf,
1719
replace_leaf,
1820
get_asset_id,
21+
cmp_bytes,
22+
cmp_pubkeys,
23+
assert_pubkey_equal,
1924
},
2025
anchor_lang::{
2126
prelude::*,
@@ -321,8 +326,6 @@ pub fn get_instruction_type(full_bytes: &[u8]) -> InstructionName {
321326

322327
#[program]
323328
pub mod bubblegum {
324-
use crate::error::BubblegumError;
325-
use crate::utils::assert_pubkey_equal;
326329
use super::*;
327330

328331
pub fn create_tree(
@@ -582,8 +585,29 @@ pub mod bubblegum {
582585

583586
pub fn decompress_v1(ctx: Context<DecompressV1>, metadata: MetadataArgs) -> Result<()> {
584587
// Allocate and create mint
585-
let data_hash = hash_metadata(&metadata)?;
586-
assert_eq!(ctx.accounts.voucher.leaf_schema.data_hash(), data_hash);
588+
let incoming_data_hash = hash_metadata(&metadata)?;
589+
let event = match ctx.accounts.voucher.leaf_schema {
590+
LeafSchema::V1 {
591+
owner,
592+
data_hash,
593+
nonce,
594+
..
595+
} => {
596+
if !cmp_bytes(&data_hash, &incoming_data_hash, 32) {
597+
return Err(BubblegumError::HashingMismatch.into());
598+
}
599+
if !cmp_pubkeys(&owner, ctx.accounts.owner.key) {
600+
return Err(BubblegumError::AssetOwnerMismatch.into());
601+
}
602+
Ok(NFTDecompressionEvent {
603+
version: Version::V1,
604+
tree_id: ctx.accounts.voucher.merkle_slab.key(),
605+
id: get_asset_id(&ctx.accounts.voucher.merkle_slab.key(), nonce),
606+
nonce: nonce
607+
})
608+
}
609+
_ => Err(BubblegumError::UnsupportedSchemaVersion)
610+
}?;
587611
let voucher = &ctx.accounts.voucher;
588612
match metadata.token_program_version {
589613
TokenProgramVersion::Original => {
@@ -740,6 +764,7 @@ pub mod bubblegum {
740764
&[ctx.bumps["mint_authority"]],
741765
]],
742766
)?;
767+
emit!(event);
743768
Ok(())
744769
}
745770

contracts/programs/bubblegum/src/state/leaf_schema.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl LeafSchema {
9595
LeafSchema::V1 { data_hash, .. } => *data_hash,
9696
}
9797
}
98+
9899

99100
pub fn to_event(&self) -> LeafSchemaEvent {
100101
LeafSchemaEvent {

contracts/programs/bubblegum/src/state/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,18 @@ impl Voucher {
3535
}
3636
}
3737
}
38+
3839
#[event]
3940
pub struct NewNFTEvent {
4041
pub version: Version,
4142
pub metadata: MetadataArgs,
4243
pub nonce: u64,
4344
}
45+
46+
#[event]
47+
pub struct NFTDecompressionEvent {
48+
pub version: Version,
49+
pub id: Pubkey,
50+
pub tree_id: Pubkey,
51+
pub nonce: u64,
52+
}

contracts/programs/bubblegum/src/utils.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ pub fn cmp_pubkeys(a: &Pubkey, b: &Pubkey) -> bool {
8787
sol_memcmp(a.as_ref(), b.as_ref(), PUBKEY_BYTES) == 0
8888
}
8989

90+
pub fn cmp_bytes(a: &[u8], b: &[u8], size: usize) -> bool {
91+
sol_memcmp(a.as_ref(), b.as_ref(), size) == 0
92+
}
93+
9094
pub fn assert_pubkey_equal(a: &Pubkey, b: &Pubkey, error: Option<anchor_lang::error::Error>) -> Result<()> {
9195
if !cmp_pubkeys(a, b) {
9296
if error.is_some() {

0 commit comments

Comments
 (0)