From 0aa18784bf0e09d4ff43c9bc04b91b44c0a5a4ac Mon Sep 17 00:00:00 2001 From: Stanislav Cherviakov Date: Wed, 6 Nov 2024 11:24:34 +0000 Subject: [PATCH] enable indexing Merkle trees on other SVMs, copied from https://github.com/metaplex-foundation/digital-asset-rpc-infrastructure/pull/211 --- Cargo.lock | 120 ++++++++++++---------- blockbuster/Cargo.toml | 7 +- blockbuster/src/programs/bubblegum/mod.rs | 91 +++++++++++----- 3 files changed, 137 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec9f11a..8d35b78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -231,7 +231,6 @@ dependencies = [ "anchor-derive-accounts", "anchor-derive-serde", "anchor-derive-space", - "anchor-syn", "arrayref", "base64 0.13.1", "bincode", @@ -512,7 +511,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -661,8 +660,10 @@ dependencies = [ "flatbuffers", "lazy_static", "log", + "mpl-account-compression", "mpl-bubblegum", "mpl-core", + "mpl-noop", "mpl-token-metadata", "plerkle_serialization", "rand 0.8.5", @@ -674,7 +675,7 @@ dependencies = [ "solana-transaction-status", "solana-zk-token-sdk", "spl-account-compression", - "spl-concurrent-merkle-tree 0.2.0", + "spl-concurrent-merkle-tree", "spl-noop", "spl-pod", "spl-token", @@ -751,7 +752,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", "syn_derive", ] @@ -868,7 +869,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1184,7 +1185,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1195,7 +1196,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1307,7 +1308,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1330,7 +1331,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1412,7 +1413,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -1553,7 +1554,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -2217,6 +2218,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mpl-account-compression" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2ad6a6ba15b2e880d43b94f40510f1b64f2981a843cfc7b8877919467d2ab1a" +dependencies = [ + "anchor-lang", + "bytemuck", + "mpl-noop", + "solana-program", + "spl-concurrent-merkle-tree", +] + [[package]] name = "mpl-bubblegum" version = "1.5.0" @@ -2251,6 +2265,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "mpl-noop" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179556a9254920ca8b150b18728d2f3106879f710c1ef5a049a8f0d5b03eede5" +dependencies = [ + "solana-program", +] + [[package]] name = "mpl-token-metadata" version = "4.1.2" @@ -2359,7 +2382,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -2440,7 +2463,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -2452,7 +2475,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -2734,7 +2757,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3190,7 +3213,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3258,7 +3281,7 @@ checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3322,7 +3345,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3334,7 +3357,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3601,7 +3624,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -3993,7 +4016,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4224,14 +4247,14 @@ dependencies = [ [[package]] name = "spl-account-compression" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8314ec6ae26084ec7c6c0802c3dc173ee86aee5f5d5026a3f82c52cfe1c07" +checksum = "2785042005954aec5d5db7fcb99a78754b222be906a89d10a3d66ebdbc8e9548" dependencies = [ "anchor-lang", "bytemuck", "solana-program", - "spl-concurrent-merkle-tree 0.4.0", + "spl-concurrent-merkle-tree", "spl-noop", ] @@ -4253,20 +4276,9 @@ dependencies = [ [[package]] name = "spl-concurrent-merkle-tree" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141eaea58588beae81b71d101373a53f096737739873de42d6b1368bc2b8fc30" -dependencies = [ - "bytemuck", - "solana-program", - "thiserror", -] - -[[package]] -name = "spl-concurrent-merkle-tree" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d1bbb97252d8a1b90d3d56425038928382a306b71dbba4c836973c94b33f96" +checksum = "a14033366e14117679851c7759c3d66c6430a495f0523bd88076d3a275828931" dependencies = [ "bytemuck", "solana-program", @@ -4292,7 +4304,7 @@ checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4304,7 +4316,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.72", + "syn 2.0.87", "thiserror", ] @@ -4363,7 +4375,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4524,9 +4536,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -4542,7 +4554,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4623,22 +4635,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4732,7 +4744,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -4847,7 +4859,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -5059,7 +5071,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -5093,7 +5105,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5381,7 +5393,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] @@ -5401,7 +5413,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.87", ] [[package]] diff --git a/blockbuster/Cargo.toml b/blockbuster/Cargo.toml index deb5325..578c3b6 100644 --- a/blockbuster/Cargo.toml +++ b/blockbuster/Cargo.toml @@ -12,11 +12,12 @@ readme = "../README.md" bytemuck = { version = "1.18.0", features = ["derive"] } spl-token-2022 = { version = "1.0", features = ["no-entrypoint"] } -spl-account-compression = { version = "0.4.1", features = ["no-entrypoint"] } +spl-account-compression = { version = "0.4.2", features = ["no-entrypoint"] } spl-noop = { version = "0.2.0", features = ["no-entrypoint"] } mpl-bubblegum = { git = "https://github.com/metaplex-foundation/mpl-bubblegum.git", rev = "07678e6", features = ["test-sbf", "serde"] } - +mpl-account-compression = { version = "0.4.2", features = ["no-entrypoint"]} mpl-core = { version = "=0.8.0-beta.1", features = ["serde"] } +mpl-noop = { version = "0.2.1", features = ["no-entrypoint"]} mpl-token-metadata = { version = "4.1.1", features = ["serde"] } spl-token = { version = "4.0.0", features = ["no-entrypoint"] } async-trait = "0.1.57" @@ -42,4 +43,4 @@ rand = "0.8.5" serde_json = "1.0.89" solana-client = "~1.18.11" solana-geyser-plugin-interface = "~1.18.11" -spl-concurrent-merkle-tree = "0.2.0" +spl-concurrent-merkle-tree = "0.4.1" diff --git a/blockbuster/src/programs/bubblegum/mod.rs b/blockbuster/src/programs/bubblegum/mod.rs index 91f5eac..d3910d6 100644 --- a/blockbuster/src/programs/bubblegum/mod.rs +++ b/blockbuster/src/programs/bubblegum/mod.rs @@ -20,12 +20,6 @@ pub use mpl_bubblegum::{ InstructionName, LeafSchemaEvent, ID, }; use solana_sdk::pubkey::Pubkey; -pub use spl_account_compression::events::{ - AccountCompressionEvent::{self, ApplicationData, ChangeLog}, - ApplicationDataEvent, ChangeLogEvent, ChangeLogEventV1, -}; - -use spl_noop; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -92,7 +86,7 @@ pub enum Payload { //TODO add more of the parsing here to minimize program transformer code pub struct BubblegumInstruction { pub instruction: InstructionName, - pub tree_update: Option, + pub tree_update: Option, pub leaf_update: Option, pub payload: Option, } @@ -164,6 +158,10 @@ impl ProgramParser for BubblegumParser { if let Some(ixs) = inner_ix { for (pid, cix) in ixs.iter() { if pid == &spl_noop::id() && !cix.data.is_empty() { + use spl_account_compression::events::{ + AccountCompressionEvent::{self, ApplicationData, ChangeLog}, + ApplicationDataEvent, ChangeLogEvent, + }; match AccountCompressionEvent::try_from_slice(&cix.data) { Ok(result) => match result { ChangeLog(changelog_event) => { @@ -173,27 +171,40 @@ impl ProgramParser for BubblegumParser { ApplicationData(app_data) => { let ApplicationDataEvent::V1(app_data) = app_data; let app_data = app_data.application_data; - - let event_type_byte = if !app_data.is_empty() { - &app_data[0..1] - } else { - return Err(BlockbusterError::DeserializationError); - }; - - match BubblegumEventType::try_from_slice(event_type_byte)? { - BubblegumEventType::Uninitialized => { - return Err(BlockbusterError::MissingBubblegumEventData); - } - BubblegumEventType::LeafSchemaEvent => { - b_inst.leaf_update = - Some(LeafSchemaEvent::try_from_slice(&app_data)?); - } - } + b_inst.leaf_update = + Some(get_bubblegum_leaf_schema_event(app_data)?); + } + }, + Err(e) => { + warn!( + "Error while deserializing txn {:?} with spl-noop data: {:?}", + txn_id, e + ); + } + } + } else if pid == &mpl_noop::id() && !cix.data.is_empty() { + use mpl_account_compression::events::{ + AccountCompressionEvent::{self, ApplicationData, ChangeLog}, + ApplicationDataEvent, ChangeLogEvent, + }; + match AccountCompressionEvent::try_from_slice(&cix.data) { + Ok(result) => match result { + ChangeLog(mpl_changelog_event) => { + let ChangeLogEvent::V1(mpl_changelog_event) = mpl_changelog_event; + let spl_change_log_event = + convert_mpl_to_spl_change_log_event(mpl_changelog_event); + b_inst.tree_update = Some(spl_change_log_event); + } + ApplicationData(app_data) => { + let ApplicationDataEvent::V1(app_data) = app_data; + let app_data = app_data.application_data; + b_inst.leaf_update = + Some(get_bubblegum_leaf_schema_event(app_data)?); } }, Err(e) => { warn!( - "Error while deserializing txn {:?} with noop data: {:?}", + "Error while deserializing txn {:?} with mpl-noop data: {:?}", txn_id, e ); } @@ -258,6 +269,38 @@ impl ProgramParser for BubblegumParser { } } +fn get_bubblegum_leaf_schema_event(app_data: Vec) -> Result { + let event_type_byte = if !app_data.is_empty() { + &app_data[0..1] + } else { + return Err(BlockbusterError::DeserializationError); + }; + + match BubblegumEventType::try_from_slice(event_type_byte)? { + BubblegumEventType::Uninitialized => Err(BlockbusterError::MissingBubblegumEventData), + BubblegumEventType::LeafSchemaEvent => Ok(LeafSchemaEvent::try_from_slice(&app_data)?), + } +} + +// Convert from mpl-account-compression `ChangeLogEventV1` to +// spl-account-compression `ChangeLogEventV1`. +fn convert_mpl_to_spl_change_log_event( + mpl_changelog_event: mpl_account_compression::events::ChangeLogEventV1, +) -> spl_account_compression::events::ChangeLogEventV1 { + spl_account_compression::events::ChangeLogEventV1 { + id: mpl_changelog_event.id, + path: mpl_changelog_event + .path + .iter() + .map(|path_node| spl_account_compression::state::PathNode { + node: path_node.node, + index: path_node.index, + }) + .collect(), + seq: mpl_changelog_event.seq, + index: mpl_changelog_event.index, + } +} // See Bubblegum documentation for offsets and positions: // https://github.com/metaplex-foundation/mpl-bubblegum/blob/main/programs/bubblegum/README.md#-verify_creator-and-unverify_creator fn build_creator_verification_payload(