From e1f08d79ed371c8958018f1fc34d4225d089171a Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Tue, 1 Aug 2023 04:53:01 +0500 Subject: [PATCH 1/6] Update Collection mint --- consumer/src/backend.rs | 18 +++++++- consumer/src/events.rs | 57 ++++++++++++++++++++++--- consumer/src/solana.rs | 93 ++++++++++++++++++++++++++++++++++++++--- core/proto.lock | 12 +++--- core/proto.toml | 8 ++-- 5 files changed, 164 insertions(+), 24 deletions(-) diff --git a/consumer/src/backend.rs b/consumer/src/backend.rs index cbd656d..7fa6714 100644 --- a/consumer/src/backend.rs +++ b/consumer/src/backend.rs @@ -1,7 +1,8 @@ use holaplex_hub_nfts_solana_core::proto::{ - MetaplexMasterEditionTransaction, SolanaPendingTransaction, TransferMetaplexAssetTransaction, + MetaplexMasterEditionTransaction, MintMetaplexMetadataTransaction, SolanaPendingTransaction, + TransferMetaplexAssetTransaction, }; -use holaplex_hub_nfts_solana_entity::collections; +use holaplex_hub_nfts_solana_entity::{collections, collection_mints}; use hub_core::prelude::*; use solana_program::pubkey::Pubkey; @@ -54,6 +55,12 @@ pub struct UpdateMasterEditionAddresses { pub update_authority: Pubkey, } +#[derive(Clone)] +pub struct UpdateCollectionMintAddresses { + pub metadata: Pubkey, + pub update_authority: Pubkey, +} + #[derive(Clone)] pub struct TransferAssetAddresses { pub owner: Pubkey, @@ -101,6 +108,13 @@ pub trait CollectionBackend { collection: &collections::Model, txn: MetaplexMasterEditionTransaction, ) -> Result>; + + fn update_mint( + &self, + collection: &collections::Model, + mint: &collection_mints::Model, + txn: MintMetaplexMetadataTransaction, + ) -> Result>; } pub trait MintBackend { diff --git a/consumer/src/events.rs b/consumer/src/events.rs index 8034c39..ec46567 100644 --- a/consumer/src/events.rs +++ b/consumer/src/events.rs @@ -4,11 +4,12 @@ use holaplex_hub_nfts_solana_core::{ nft_events::Event as NftEvent, solana_nft_events::Event as SolanaNftEvent, treasury_events::{Event as TreasuryEvent, SolanaTransactionResult, TransactionStatus}, - MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, - MintMetaplexMetadataTransaction, SolanaCompletedMintTransaction, - SolanaCompletedTransferTransaction, SolanaCompletedUpdateTransaction, - SolanaFailedTransaction, SolanaNftEventKey, SolanaNftEvents, SolanaPendingTransaction, - SolanaTransactionFailureReason, TransferMetaplexAssetTransaction, + MetaplexMasterEditionTransaction, + MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, + SolanaCompletedMintTransaction, SolanaCompletedTransferTransaction, + SolanaCompletedUpdateTransaction, SolanaFailedTransaction, SolanaNftEventKey, + SolanaNftEvents, SolanaPendingTransaction, SolanaTransactionFailureReason, + TransferMetaplexAssetTransaction, }, sea_orm::{DatabaseConnection, DbErr, Set}, Collection, CollectionMint, CompressionLeaf, Services, @@ -109,6 +110,7 @@ pub enum EventKind { UpdateCollection, MintToCollection, RetryMintToCollection, + UpdateCollectionMint, } impl EventKind { @@ -125,6 +127,7 @@ impl EventKind { Self::UpdateCollection => "collection update", Self::MintToCollection => "mint to collection", Self::RetryMintToCollection => "mint to collection retry", + Self::UpdateCollectionMint => "collection mint update", } } @@ -145,6 +148,9 @@ impl EventKind { EventKind::RetryMintToCollection => { SolanaNftEvent::RetryMintToCollectionSigningRequested(tx) }, + EventKind::UpdateCollectionMint => { + SolanaNftEvent::UpdateCollectionMintSigningRequested(tx) + }, } } @@ -286,6 +292,11 @@ impl EventKind { address: collection_mint.mint, }) }, + Self::UpdateCollectionMint => { + SolanaNftEvent::UpdateCollectionMintSubmitted(SolanaCompletedUpdateTransaction { + signature, + }) + }, }) } @@ -302,6 +313,7 @@ impl EventKind { Self::UpdateCollection => SolanaNftEvent::UpdateCollectionFailed(tx), Self::MintToCollection => SolanaNftEvent::MintToCollectionFailed(tx), Self::RetryMintToCollection => SolanaNftEvent::RetryMintToCollectionFailed(tx), + Self::UpdateCollectionMint => SolanaNftEvent::UpdateCollectionMintFailed(tx), } } } @@ -435,6 +447,18 @@ impl Processor { ) .await }, + Some(NftEvent::SolanaUpdateCollectionMint(payload)) => { + self.process_nft( + EventKind::UpdateCollectionMint, + &key, + self.update_collection_mint( + &UncompressedRef(self.solana()), + &key, + payload, + ), + ) + .await + }, _ => Ok(()), } }, @@ -735,7 +759,28 @@ impl Processor { Ok(tx.into()) } - async fn transfer_asset( + async fn update_collection_mint( + &self, + backend: &B, + key: &SolanaNftEventKey, + payload: MintMetaplexMetadataTransaction, + ) -> ProcessResult { + let collection_id = Uuid::parse_str(&key.id.clone())?; + let collection = Collection::find_by_id(&self.db, collection_id) + .await? + .ok_or(ProcessorErrorKind::RecordNotFound)?; + let mint = CollectionMint::find_by_id(&self.db, collection_id) + .await? + .ok_or(ProcessorErrorKind::RecordNotFound)?; + + let tx = backend + .update_mint(&collection, &mint, payload) + .map_err(ProcessorErrorKind::Solana)?; + + Ok(tx.into()) + } + + async fn transfer_asset ( &self, _key: &SolanaNftEventKey, payload: TransferMetaplexAssetTransaction, diff --git a/consumer/src/solana.rs b/consumer/src/solana.rs index d15231e..3d2910c 100644 --- a/consumer/src/solana.rs +++ b/consumer/src/solana.rs @@ -1,9 +1,10 @@ use anchor_lang::{prelude::AccountMeta, AnchorDeserialize, InstructionData}; -use holaplex_hub_nfts_solana_core::proto::{ - treasury_events::SolanaTransactionResult, MasterEdition, MetaplexMasterEditionTransaction, - MetaplexMetadata, MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, - TransferMetaplexAssetTransaction, -}; +use holaplex_hub_nfts_solana_core:: + proto::{ + treasury_events::SolanaTransactionResult, MasterEdition, MetaplexMasterEditionTransaction, + MetaplexMetadata, MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, + TransferMetaplexAssetTransaction, + }; use holaplex_hub_nfts_solana_entity::{collection_mints, collections, compression_leafs}; use hub_core::{anyhow::Result, clap, prelude::*, thiserror, uuid::Uuid}; use mpl_bubblegum::state::metaplex_adapter::{ @@ -41,7 +42,7 @@ use crate::{ backend::{ CollectionBackend, MasterEditionAddresses, MintBackend, MintCompressedMintV1Addresses, MintEditionAddresses, MintMetaplexAddresses, TransactionResponse, TransferAssetAddresses, - TransferBackend, TransferCompressedMintV1Addresses, UpdateMasterEditionAddresses, + TransferBackend, TransferCompressedMintV1Addresses, UpdateMasterEditionAddresses, UpdateCollectionMintAddresses, }, }; @@ -468,6 +469,86 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { }, }) } + + fn update_mint( + &self, + collection: &collections::Model, + collection_mint: &collection_mints::Model, + txn: MintMetaplexMetadataTransaction, + ) -> Result> { + let MintMetaplexMetadataTransaction { + metadata, + .. + } = txn; + let metadata = metadata.ok_or(SolanaErrorNotFoundMessage::Metadata)?; + let payer: Pubkey = self.0.treasury_wallet_address; + let rpc = &self.0.rpc_client; + + let MetaplexMetadata { + name, + symbol, + seller_fee_basis_points, + metadata_uri, + creators, + owner_address, + } = metadata; + let update_authority: Pubkey = owner_address.parse()?; + let mint_pubkey: Pubkey = collection_mint.mint.parse()?; + + let (metadata, _) = Pubkey::find_program_address( + &[ + b"metadata", + mpl_token_metadata::ID.as_ref(), + mint_pubkey.as_ref(), + ], + &mpl_token_metadata::ID, + ); + + let blockhash = rpc.get_latest_blockhash()?; + + let update_ins: Instruction = mpl_token_metadata::instruction::update_metadata_accounts_v2( + mpl_token_metadata::ID, + metadata, + update_authority, + None, + Some(DataV2 { + name, + symbol, + uri: metadata_uri, + seller_fee_basis_points: seller_fee_basis_points.try_into()?, + creators: Some( + creators + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?, + ), + collection: Some(mpl_token_metadata::state::Collection { + verified: true, + key: collection.mint.parse()?, + }), + uses: None, + }), + None, + None, + ); + + let message = solana_program::message::Message::new_with_blockhash( + &[update_ins], + Some(&update_authority), + &blockhash, + ); + + let serialized_message = message.serialize(); + + Ok(TransactionResponse { + serialized_message, + signatures_or_signers_public_keys: vec![update_authority.to_string(), payer.to_string()], + addresses: UpdateCollectionMintAddresses { + metadata, + update_authority, + }, + }) + } } impl<'a> MintBackend for EditionRef<'a> { diff --git a/core/proto.lock b/core/proto.lock index 2e734d8..7b413d0 100644 --- a/core/proto.lock +++ b/core/proto.lock @@ -1,14 +1,14 @@ [[schemas]] subject = "nfts" -version = 22 -sha512 = "c9920f6a5792b067396c88e40b9bd2adfcb55b582734aff924a67a9d5841a5e2839fc734c1bbff66f402f9a9d8852ca5fef1339aaaa3d5b05aa7868ddfa375c1" +version = 1 +sha512 = "c4032c35d77a78090c17d230dfae7955577a6172bc60921c4821e76690c89d3f858d2b358ca41e34fc25468f430107d4c1552e4529dc48db61e4f5545a6ef82c" [[schemas]] subject = "solana_nfts" -version = 7 -sha512 = "73570b9e58f91a06901ba6455986ce1a0d3675e33860d2447160d711a8cebcfb78cfc714fb08644ad83495dc8612b0b123203561af6d93d29ffb0256725047ba" +version = 1 +sha512 = "2a57c4200577f8a6efa36e2c045a5bd3eb0dba11466659a80dd82f5422db4ac119f529d391805d14449b0ffac6048ae789727075882f9b0496dac710e32f4ff5" [[schemas]] subject = "treasury" -version = 19 -sha512 = "af9c5b6f8f6aef713a686b9253ef87a2332e8a69b4e0adbeab3a587ef2b74c09b510e3b017bf75bc2d1e083846073dcfd39cd104d95a4a76406a3a7fa0dbe2fb" +version = 1 +sha512 = "f3ff35aeb4bfa3a76b4cb985c4f2fc4b3dab1d0bb1585d4d720ff2c1087a879b56531efd3ecdebbb0968fae23371ec03aa944eec0ed07c0a3db7d66aa2074e2e" diff --git a/core/proto.toml b/core/proto.toml index 1aef615..bf3f36e 100644 --- a/core/proto.toml +++ b/core/proto.toml @@ -1,7 +1,7 @@ [registry] -endpoint = "https://schemas.holaplex.tools" +endpoint = "http://localhost:8081" [schemas] -nfts = 22 -treasury = 19 -solana_nfts = 7 +nfts = 1 +treasury = 1 +solana_nfts = 1 From 0309bb975c2bd13964b87800900c1a21a9b14eef Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Wed, 2 Aug 2023 17:10:49 +0500 Subject: [PATCH 2/6] use correct collection id --- consumer/src/events.rs | 4 ++-- consumer/src/solana.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/consumer/src/events.rs b/consumer/src/events.rs index ec46567..15b74d7 100644 --- a/consumer/src/events.rs +++ b/consumer/src/events.rs @@ -765,11 +765,11 @@ impl Processor { key: &SolanaNftEventKey, payload: MintMetaplexMetadataTransaction, ) -> ProcessResult { - let collection_id = Uuid::parse_str(&key.id.clone())?; + let collection_id = Uuid::parse_str(&payload.collection_id)?; let collection = Collection::find_by_id(&self.db, collection_id) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; - let mint = CollectionMint::find_by_id(&self.db, collection_id) + let mint = CollectionMint::find_by_id(&self.db, key.id.parse()?) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; diff --git a/consumer/src/solana.rs b/consumer/src/solana.rs index 3d2910c..5eefe95 100644 --- a/consumer/src/solana.rs +++ b/consumer/src/solana.rs @@ -529,12 +529,12 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { uses: None, }), None, - None, + Some(true), ); let message = solana_program::message::Message::new_with_blockhash( &[update_ins], - Some(&update_authority), + Some(&payer), &blockhash, ); @@ -542,7 +542,7 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { Ok(TransactionResponse { serialized_message, - signatures_or_signers_public_keys: vec![update_authority.to_string(), payer.to_string()], + signatures_or_signers_public_keys: vec![payer.to_string(), update_authority.to_string()], addresses: UpdateCollectionMintAddresses { metadata, update_authority, From 248a112b53c0dc8ebf6e3ea34df2775064ec87a8 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 7 Aug 2023 20:02:54 +0500 Subject: [PATCH 3/6] save update revision --- consumer/src/backend.rs | 9 +-- consumer/src/events.rs | 47 ++++++++++----- consumer/src/solana.rs | 30 +++++----- core/proto.lock | 8 +-- core/proto.toml | 8 +-- entity/src/lib.rs | 1 + entity/src/mod.rs | 3 +- entity/src/prelude.rs | 2 +- entity/src/update_revisions.rs | 21 +++++++ migration/src/lib.rs | 4 +- .../src/m20230807_135202_update_revisions.rs | 58 +++++++++++++++++++ 11 files changed, 148 insertions(+), 43 deletions(-) create mode 100644 entity/src/update_revisions.rs create mode 100644 migration/src/m20230807_135202_update_revisions.rs diff --git a/consumer/src/backend.rs b/consumer/src/backend.rs index 7fa6714..24fc08c 100644 --- a/consumer/src/backend.rs +++ b/consumer/src/backend.rs @@ -1,8 +1,8 @@ use holaplex_hub_nfts_solana_core::proto::{ - MetaplexMasterEditionTransaction, MintMetaplexMetadataTransaction, SolanaPendingTransaction, - TransferMetaplexAssetTransaction, + MetaplexMasterEditionTransaction, SolanaPendingTransaction, TransferMetaplexAssetTransaction, + UpdateSolanaMintPayload, }; -use holaplex_hub_nfts_solana_entity::{collections, collection_mints}; +use holaplex_hub_nfts_solana_entity::{collection_mints, collections}; use hub_core::prelude::*; use solana_program::pubkey::Pubkey; @@ -57,6 +57,7 @@ pub struct UpdateMasterEditionAddresses { #[derive(Clone)] pub struct UpdateCollectionMintAddresses { + pub payer: Pubkey, pub metadata: Pubkey, pub update_authority: Pubkey, } @@ -113,7 +114,7 @@ pub trait CollectionBackend { &self, collection: &collections::Model, mint: &collection_mints::Model, - txn: MintMetaplexMetadataTransaction, + txn: UpdateSolanaMintPayload, ) -> Result>; } diff --git a/consumer/src/events.rs b/consumer/src/events.rs index 15b74d7..6beea3a 100644 --- a/consumer/src/events.rs +++ b/consumer/src/events.rs @@ -4,17 +4,18 @@ use holaplex_hub_nfts_solana_core::{ nft_events::Event as NftEvent, solana_nft_events::Event as SolanaNftEvent, treasury_events::{Event as TreasuryEvent, SolanaTransactionResult, TransactionStatus}, - MetaplexMasterEditionTransaction, - MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, - SolanaCompletedMintTransaction, SolanaCompletedTransferTransaction, - SolanaCompletedUpdateTransaction, SolanaFailedTransaction, SolanaNftEventKey, - SolanaNftEvents, SolanaPendingTransaction, SolanaTransactionFailureReason, - TransferMetaplexAssetTransaction, + MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, + MintMetaplexMetadataTransaction, SolanaCompletedMintTransaction, + SolanaCompletedTransferTransaction, SolanaCompletedUpdateTransaction, + SolanaFailedTransaction, SolanaNftEventKey, SolanaNftEvents, SolanaPendingTransaction, + SolanaTransactionFailureReason, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }, - sea_orm::{DatabaseConnection, DbErr, Set}, + sea_orm::{ActiveModelTrait, DatabaseConnection, DbErr, Set}, Collection, CollectionMint, CompressionLeaf, Services, }; -use holaplex_hub_nfts_solana_entity::{collection_mints, collections, compression_leafs}; +use holaplex_hub_nfts_solana_entity::{ + collection_mints, collections, compression_leafs, update_revisions, +}; use hub_core::{ chrono::Utc, prelude::*, @@ -30,7 +31,7 @@ use solana_sdk::signature::Signature; use crate::{ backend::{ CollectionBackend, MasterEditionAddresses, MintBackend, MintEditionAddresses, - MintMetaplexAddresses, TransferBackend, + MintMetaplexAddresses, TransferBackend, UpdateCollectionMintAddresses, }, solana::{CompressedRef, EditionRef, Solana, SolanaAssetIdError, UncompressedRef}, }; @@ -447,7 +448,7 @@ impl Processor { ) .await }, - Some(NftEvent::SolanaUpdateCollectionMint(payload)) => { + Some(NftEvent::SolanaUpdatedCollectionMint(payload)) => { self.process_nft( EventKind::UpdateCollectionMint, &key, @@ -763,13 +764,13 @@ impl Processor { &self, backend: &B, key: &SolanaNftEventKey, - payload: MintMetaplexMetadataTransaction, + payload: UpdateSolanaMintPayload, ) -> ProcessResult { let collection_id = Uuid::parse_str(&payload.collection_id)?; - let collection = Collection::find_by_id(&self.db, collection_id) + let collection = Collection::find_by_id(&self.db.get(), collection_id) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; - let mint = CollectionMint::find_by_id(&self.db, key.id.parse()?) + let mint = CollectionMint::find_by_id(&self.db.get(), key.id.parse()?) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; @@ -777,10 +778,28 @@ impl Processor { .update_mint(&collection, &mint, payload) .map_err(ProcessorErrorKind::Solana)?; + let UpdateCollectionMintAddresses { + payer, + metadata, + update_authority, + } = tx.addresses.clone(); + let msg_bytes = tx.serialized_message.clone(); + + let revision = update_revisions::ActiveModel { + id: Set(key.id.parse()?), + mint_id: Set(mint.id), + serialized_message: Set(msg_bytes), + payer: Set(payer.to_string()), + metadata: Set(metadata.to_string()), + update_authority: Set(update_authority.to_string()), + }; + + revision.insert(self.db.get()).await?; + Ok(tx.into()) } - async fn transfer_asset ( + async fn transfer_asset( &self, _key: &SolanaNftEventKey, payload: TransferMetaplexAssetTransaction, diff --git a/consumer/src/solana.rs b/consumer/src/solana.rs index 5eefe95..309c24d 100644 --- a/consumer/src/solana.rs +++ b/consumer/src/solana.rs @@ -1,10 +1,9 @@ use anchor_lang::{prelude::AccountMeta, AnchorDeserialize, InstructionData}; -use holaplex_hub_nfts_solana_core:: - proto::{ - treasury_events::SolanaTransactionResult, MasterEdition, MetaplexMasterEditionTransaction, - MetaplexMetadata, MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, - TransferMetaplexAssetTransaction, - }; +use holaplex_hub_nfts_solana_core::proto::{ + treasury_events::SolanaTransactionResult, MasterEdition, MetaplexMasterEditionTransaction, + MetaplexMetadata, MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, + TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, +}; use holaplex_hub_nfts_solana_entity::{collection_mints, collections, compression_leafs}; use hub_core::{anyhow::Result, clap, prelude::*, thiserror, uuid::Uuid}; use mpl_bubblegum::state::metaplex_adapter::{ @@ -42,7 +41,8 @@ use crate::{ backend::{ CollectionBackend, MasterEditionAddresses, MintBackend, MintCompressedMintV1Addresses, MintEditionAddresses, MintMetaplexAddresses, TransactionResponse, TransferAssetAddresses, - TransferBackend, TransferCompressedMintV1Addresses, UpdateMasterEditionAddresses, UpdateCollectionMintAddresses, + TransferBackend, TransferCompressedMintV1Addresses, UpdateCollectionMintAddresses, + UpdateMasterEditionAddresses, }, }; @@ -474,13 +474,11 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { &self, collection: &collections::Model, collection_mint: &collection_mints::Model, - txn: MintMetaplexMetadataTransaction, + payload: UpdateSolanaMintPayload, ) -> Result> { - let MintMetaplexMetadataTransaction { - metadata, - .. - } = txn; - let metadata = metadata.ok_or(SolanaErrorNotFoundMessage::Metadata)?; + let metadata = payload + .metadata + .ok_or(SolanaErrorNotFoundMessage::Metadata)?; let payer: Pubkey = self.0.treasury_wallet_address; let rpc = &self.0.rpc_client; @@ -542,8 +540,12 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { Ok(TransactionResponse { serialized_message, - signatures_or_signers_public_keys: vec![payer.to_string(), update_authority.to_string()], + signatures_or_signers_public_keys: vec![ + payer.to_string(), + update_authority.to_string(), + ], addresses: UpdateCollectionMintAddresses { + payer, metadata, update_authority, }, diff --git a/core/proto.lock b/core/proto.lock index 7b413d0..ac98020 100644 --- a/core/proto.lock +++ b/core/proto.lock @@ -1,14 +1,14 @@ [[schemas]] subject = "nfts" -version = 1 -sha512 = "c4032c35d77a78090c17d230dfae7955577a6172bc60921c4821e76690c89d3f858d2b358ca41e34fc25468f430107d4c1552e4529dc48db61e4f5545a6ef82c" +version = 24 +sha512 = "e4be4beae6db9911bd5a5ab9d807dc9b0c027dba67bfb5c114cf805edba9f67c758769a7dd9d69d0f692e567fc35001d69d00b9aa59a92b9ef004aba79fbc6b9" [[schemas]] subject = "solana_nfts" -version = 1 +version = 8 sha512 = "2a57c4200577f8a6efa36e2c045a5bd3eb0dba11466659a80dd82f5422db4ac119f529d391805d14449b0ffac6048ae789727075882f9b0496dac710e32f4ff5" [[schemas]] subject = "treasury" -version = 1 +version = 20 sha512 = "f3ff35aeb4bfa3a76b4cb985c4f2fc4b3dab1d0bb1585d4d720ff2c1087a879b56531efd3ecdebbb0968fae23371ec03aa944eec0ed07c0a3db7d66aa2074e2e" diff --git a/core/proto.toml b/core/proto.toml index bf3f36e..5262175 100644 --- a/core/proto.toml +++ b/core/proto.toml @@ -1,7 +1,7 @@ [registry] -endpoint = "http://localhost:8081" +endpoint = "https://schemas.holaplex.tools" [schemas] -nfts = 1 -treasury = 1 -solana_nfts = 1 +nfts = 24 +treasury = 20 +solana_nfts = 8 \ No newline at end of file diff --git a/entity/src/lib.rs b/entity/src/lib.rs index 04ce5b9..1e19917 100644 --- a/entity/src/lib.rs +++ b/entity/src/lib.rs @@ -1,5 +1,6 @@ pub mod collection_mints; pub mod collections; pub mod compression_leafs; +pub mod update_revisions; pub mod prelude; diff --git a/entity/src/mod.rs b/entity/src/mod.rs index 6690f3a..4ff1864 100644 --- a/entity/src/mod.rs +++ b/entity/src/mod.rs @@ -5,4 +5,5 @@ pub mod prelude; pub mod collection_mints; pub mod editions; pub mod certified_collections; -pub mod compression_leafs; \ No newline at end of file +pub mod compression_leafs; +pub mod update_revisions; \ No newline at end of file diff --git a/entity/src/prelude.rs b/entity/src/prelude.rs index be23938..9c26550 100644 --- a/entity/src/prelude.rs +++ b/entity/src/prelude.rs @@ -2,5 +2,5 @@ pub use super::{ collection_mints::Entity as CollectionMints, collections::Entity as Collections, - compression_leafs::Entity as CompressionLeafs, + compression_leafs::Entity as CompressionLeafs, update_revisions::Entity as UpdateRevisions, }; diff --git a/entity/src/update_revisions.rs b/entity/src/update_revisions.rs new file mode 100644 index 0000000..640173a --- /dev/null +++ b/entity/src/update_revisions.rs @@ -0,0 +1,21 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "update_revisions")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub mint_id: Uuid, + #[sea_orm(column_type = "Binary(BlobSize::Blob(None))")] + pub serialized_message: Vec, + pub payer: String, + pub metadata: String, + pub update_authority: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/migration/src/lib.rs b/migration/src/lib.rs index b5c18d9..4efe28a 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -6,6 +6,7 @@ mod m20230614_132203_make_associated_token_account_nullable_on_collection_mints; mod m20230616_091724_backfill_associated_token_account_on_collection_mints; mod m20230721_135829_set_default_collection_and_mint_id; mod m20230725_143421_add_compression_leafs_table; +mod m20230807_135202_update_revisions; pub struct Migrator; @@ -17,8 +18,9 @@ impl MigratorTrait for Migrator { Box::new(m20230530_131917_create_collection_mints_table::Migration), Box::new(m20230614_132203_make_associated_token_account_nullable_on_collection_mints::Migration), Box::new(m20230616_091724_backfill_associated_token_account_on_collection_mints::Migration), - Box::new(m20230725_143421_add_compression_leafs_table::Migration), Box::new(m20230721_135829_set_default_collection_and_mint_id::Migration), + Box::new(m20230725_143421_add_compression_leafs_table::Migration), + Box::new(m20230807_135202_update_revisions::Migration), ] } } diff --git a/migration/src/m20230807_135202_update_revisions.rs b/migration/src/m20230807_135202_update_revisions.rs new file mode 100644 index 0000000..87a06f0 --- /dev/null +++ b/migration/src/m20230807_135202_update_revisions.rs @@ -0,0 +1,58 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(UpdateRevisions::Table) + .if_not_exists() + .col( + ColumnDef::new(UpdateRevisions::Id) + .uuid() + .not_null() + .primary_key(), + ) + .col(ColumnDef::new(UpdateRevisions::MintId).uuid().not_null()) + .col( + ColumnDef::new(UpdateRevisions::SerializedMessage) + .binary() + .not_null(), + ) + .col(ColumnDef::new(UpdateRevisions::Payer).string().not_null()) + .col( + ColumnDef::new(UpdateRevisions::Metadata) + .string() + .not_null(), + ) + .col( + ColumnDef::new(UpdateRevisions::UpdateAuthority) + .string() + .not_null(), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(UpdateRevisions::Table).to_owned()) + .await + } +} + +#[derive(Iden)] +enum UpdateRevisions { + Table, + Id, + MintId, + SerializedMessage, + Payer, + Metadata, + UpdateAuthority, +} From 29b0825c3f458114e3f3171ff3f69d2ca3fd511f Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Wed, 9 Aug 2023 00:24:36 +0500 Subject: [PATCH 4/6] support retry update mint --- consumer/src/backend.rs | 7 +++++- consumer/src/events.rs | 53 ++++++++++++++++++++++++++++++++++++++--- consumer/src/solana.rs | 34 +++++++++++++++++++++++++- core/proto.lock | 12 +++++----- core/proto.toml | 6 ++--- 5 files changed, 98 insertions(+), 14 deletions(-) diff --git a/consumer/src/backend.rs b/consumer/src/backend.rs index 24fc08c..3515f4e 100644 --- a/consumer/src/backend.rs +++ b/consumer/src/backend.rs @@ -2,7 +2,7 @@ use holaplex_hub_nfts_solana_core::proto::{ MetaplexMasterEditionTransaction, SolanaPendingTransaction, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }; -use holaplex_hub_nfts_solana_entity::{collection_mints, collections}; +use holaplex_hub_nfts_solana_entity::{collection_mints, collections, update_revisions}; use hub_core::prelude::*; use solana_program::pubkey::Pubkey; @@ -116,6 +116,11 @@ pub trait CollectionBackend { mint: &collection_mints::Model, txn: UpdateSolanaMintPayload, ) -> Result>; + + fn retry_update_mint( + &self, + revision: &update_revisions::Model, + ) -> Result>; } pub trait MintBackend { diff --git a/consumer/src/events.rs b/consumer/src/events.rs index 6beea3a..3598f8e 100644 --- a/consumer/src/events.rs +++ b/consumer/src/events.rs @@ -10,7 +10,7 @@ use holaplex_hub_nfts_solana_core::{ SolanaFailedTransaction, SolanaNftEventKey, SolanaNftEvents, SolanaPendingTransaction, SolanaTransactionFailureReason, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }, - sea_orm::{ActiveModelTrait, DatabaseConnection, DbErr, Set}, + sea_orm::{ActiveModelTrait, DatabaseConnection, DbErr, EntityTrait, Set}, Collection, CollectionMint, CompressionLeaf, Services, }; use holaplex_hub_nfts_solana_entity::{ @@ -112,6 +112,7 @@ pub enum EventKind { MintToCollection, RetryMintToCollection, UpdateCollectionMint, + RetryUpdateCollectionMint, } impl EventKind { @@ -129,6 +130,7 @@ impl EventKind { Self::MintToCollection => "mint to collection", Self::RetryMintToCollection => "mint to collection retry", Self::UpdateCollectionMint => "collection mint update", + Self::RetryUpdateCollectionMint => "collection mint update retry", } } @@ -152,6 +154,9 @@ impl EventKind { EventKind::UpdateCollectionMint => { SolanaNftEvent::UpdateCollectionMintSigningRequested(tx) }, + EventKind::RetryUpdateCollectionMint => { + SolanaNftEvent::RetryUpdateMintSigningRequested(tx) + }, } } @@ -298,6 +303,11 @@ impl EventKind { signature, }) }, + Self::RetryUpdateCollectionMint => { + SolanaNftEvent::RetryUpdateMintSubmitted(SolanaCompletedUpdateTransaction { + signature, + }) + }, }) } @@ -315,6 +325,7 @@ impl EventKind { Self::MintToCollection => SolanaNftEvent::MintToCollectionFailed(tx), Self::RetryMintToCollection => SolanaNftEvent::RetryMintToCollectionFailed(tx), Self::UpdateCollectionMint => SolanaNftEvent::UpdateCollectionMintFailed(tx), + Self::RetryUpdateCollectionMint => SolanaNftEvent::RetryUpdateMintFailed(tx), } } } @@ -460,6 +471,17 @@ impl Processor { ) .await }, + Some(NftEvent::SolanaRetryUpdatedCollectionMint(_)) => { + self.process_nft( + EventKind::RetryUpdateCollectionMint, + &key, + self.retry_update_collection_mint( + &UncompressedRef(self.solana()), + &key, + ), + ) + .await + }, _ => Ok(()), } }, @@ -508,6 +530,14 @@ impl Processor { self.process_treasury(EventKind::RetryCreateCollection, key, res) .await }, + Some(TreasuryEvent::SolanaUpdateCollectionMintSigned(res)) => { + self.process_treasury(EventKind::UpdateCollectionMint, key, res) + .await + }, + Some(TreasuryEvent::SolanaRetryUpdateCollectionMintSigned(res)) => { + self.process_treasury(EventKind::RetryUpdateCollectionMint, key, res) + .await + }, _ => Ok(()), } }, @@ -767,10 +797,10 @@ impl Processor { payload: UpdateSolanaMintPayload, ) -> ProcessResult { let collection_id = Uuid::parse_str(&payload.collection_id)?; - let collection = Collection::find_by_id(&self.db.get(), collection_id) + let collection = Collection::find_by_id(self.db.get(), collection_id) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; - let mint = CollectionMint::find_by_id(&self.db.get(), key.id.parse()?) + let mint = CollectionMint::find_by_id(self.db.get(), key.id.parse()?) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; @@ -799,6 +829,23 @@ impl Processor { Ok(tx.into()) } + async fn retry_update_collection_mint( + &self, + backend: &B, + key: &SolanaNftEventKey, + ) -> ProcessResult { + let revision = update_revisions::Entity::find_by_id(Uuid::from_str(&key.id)?) + .one(self.db.get()) + .await? + .ok_or(ProcessorErrorKind::RecordNotFound)?; + + let tx = backend + .retry_update_mint(&revision) + .map_err(ProcessorErrorKind::Solana)?; + + Ok(tx.into()) + } + async fn transfer_asset( &self, _key: &SolanaNftEventKey, diff --git a/consumer/src/solana.rs b/consumer/src/solana.rs index 309c24d..80f1216 100644 --- a/consumer/src/solana.rs +++ b/consumer/src/solana.rs @@ -4,7 +4,9 @@ use holaplex_hub_nfts_solana_core::proto::{ MetaplexMetadata, MintMetaplexEditionTransaction, MintMetaplexMetadataTransaction, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }; -use holaplex_hub_nfts_solana_entity::{collection_mints, collections, compression_leafs}; +use holaplex_hub_nfts_solana_entity::{ + collection_mints, collections, compression_leafs, update_revisions, +}; use hub_core::{anyhow::Result, clap, prelude::*, thiserror, uuid::Uuid}; use mpl_bubblegum::state::metaplex_adapter::{ Collection, Creator as BubblegumCreator, TokenProgramVersion, @@ -551,6 +553,36 @@ impl<'a> CollectionBackend for UncompressedRef<'a> { }, }) } + + fn retry_update_mint( + &self, + revision: &update_revisions::Model, + ) -> Result> { + let rpc = &self.0.rpc_client; + + let update_authority: Pubkey = revision.update_authority.parse()?; + let metadata = revision.metadata.parse()?; + let payer = Pubkey::from_str(&revision.payer)?; + + let mut message: solana_program::message::Message = + bincode::deserialize(&revision.serialized_message)?; + + let blockhash = rpc.get_latest_blockhash()?; + message.recent_blockhash = blockhash; + + Ok(TransactionResponse { + serialized_message: message.serialize(), + signatures_or_signers_public_keys: vec![ + payer.to_string(), + update_authority.to_string(), + ], + addresses: UpdateCollectionMintAddresses { + payer, + metadata, + update_authority, + }, + }) + } } impl<'a> MintBackend for EditionRef<'a> { diff --git a/core/proto.lock b/core/proto.lock index ac98020..3812abf 100644 --- a/core/proto.lock +++ b/core/proto.lock @@ -1,14 +1,14 @@ [[schemas]] subject = "nfts" -version = 24 -sha512 = "e4be4beae6db9911bd5a5ab9d807dc9b0c027dba67bfb5c114cf805edba9f67c758769a7dd9d69d0f692e567fc35001d69d00b9aa59a92b9ef004aba79fbc6b9" +version = 25 +sha512 = "90dadff6bc75b59bb79d9ed2a65d582923f9ce66b5915c020306571bb446d68ff6648543386838510a60081d7cbb14f43fa2ae22c4c8ecd85874bee4323dd26a" [[schemas]] subject = "solana_nfts" -version = 8 -sha512 = "2a57c4200577f8a6efa36e2c045a5bd3eb0dba11466659a80dd82f5422db4ac119f529d391805d14449b0ffac6048ae789727075882f9b0496dac710e32f4ff5" +version = 9 +sha512 = "312a84e8ae8b9222c7ec2b307d036dae0bd8dac4363e813c2fcffd5d7fba8741bd802953b1ec0a96baf57a7ce852debb724fcccf3b0bd8a27a9e4cc60344a56f" [[schemas]] subject = "treasury" -version = 20 -sha512 = "f3ff35aeb4bfa3a76b4cb985c4f2fc4b3dab1d0bb1585d4d720ff2c1087a879b56531efd3ecdebbb0968fae23371ec03aa944eec0ed07c0a3db7d66aa2074e2e" +version = 21 +sha512 = "734cff313b8b4854b9a4c03cfd6f95f07b1fd86f8678393ab466443d9da4d6e7c9fc400bdbcc718d83e6c7711857941d4b6dc0ea5d1d926f05a7859a65a15509" diff --git a/core/proto.toml b/core/proto.toml index 5262175..002d0f7 100644 --- a/core/proto.toml +++ b/core/proto.toml @@ -2,6 +2,6 @@ endpoint = "https://schemas.holaplex.tools" [schemas] -nfts = 24 -treasury = 20 -solana_nfts = 8 \ No newline at end of file +nfts = 25 +treasury = 21 +solana_nfts = 9 \ No newline at end of file From 3cda71f834a35be6b77828f3c2e7cec66cbf1ab7 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Fri, 11 Aug 2023 06:36:28 +0500 Subject: [PATCH 5/6] Use correct mint id for querying mint record --- consumer/src/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consumer/src/events.rs b/consumer/src/events.rs index 3598f8e..ed9cdba 100644 --- a/consumer/src/events.rs +++ b/consumer/src/events.rs @@ -800,7 +800,7 @@ impl Processor { let collection = Collection::find_by_id(self.db.get(), collection_id) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; - let mint = CollectionMint::find_by_id(self.db.get(), key.id.parse()?) + let mint = CollectionMint::find_by_id(self.db.get(), payload.mint_id.parse()?) .await? .ok_or(ProcessorErrorKind::RecordNotFound)?; From 3928cb106ac5c99cf1d298ea09752b9f966ebb23 Mon Sep 17 00:00:00 2001 From: raykast Date: Thu, 17 Aug 2023 09:26:26 -0700 Subject: [PATCH 6/6] Fix cargo fmt checks failing. --- .github/workflows/cargo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 9ba3e9c..00f1e13 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -85,7 +85,7 @@ jobs: - name: Install rust nightly uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2022-12-11 + toolchain: 1.69.0 override: true components: rustfmt, clippy - name: cargo fmt