diff --git a/Cargo.lock b/Cargo.lock index 5e1f640..57b2bc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2146,7 +2146,7 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plerkle" -version = "1.5.3+solana.1.16.15" +version = "1.6.0+solana.1.16.15" dependencies = [ "async-trait", "base64 0.21.2", @@ -2179,7 +2179,7 @@ dependencies = [ [[package]] name = "plerkle_messenger" -version = "1.5.3" +version = "1.6.0" dependencies = [ "async-mutex", "async-trait", @@ -2197,7 +2197,7 @@ dependencies = [ [[package]] name = "plerkle_serialization" -version = "1.5.3+solana.1.16.15" +version = "1.6.0+solana.1.16.15" dependencies = [ "bs58", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 5257975..4e079a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [workspace] members = [ - "plerkle_messenger", # 1.5.3 - "plerkle", # 1.5.3+solana.1.16.15 - "plerkle_serialization", # 1.5.3+solana.1.16.15 + "plerkle", # 1.6.0+solana.1.16.15 + "plerkle_messenger", # 1.6.0 + "plerkle_serialization", # 1.6.0+solana.1.16.15 ] [profile.release] diff --git a/plerkle/Cargo.toml b/plerkle/Cargo.toml index a3ee02d..0b26184 100644 --- a/plerkle/Cargo.toml +++ b/plerkle/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "plerkle" description = "Geyser plugin with dynamic config reloading, message bus agnostic abstractions and a whole lot of fun." -version = "1.5.3+solana.1.16.15" +version = "1.6.0+solana.1.16.15" authors = ["Metaplex Developers "] repository = "https://github.com/metaplex-foundation/digital-asset-validator-plugin" license = "AGPL-3.0" @@ -26,8 +26,8 @@ flatbuffers = "23.1.21" hex = "0.4.3" lazy_static = "1.4.0" log = "0.4.17" -plerkle_messenger = { path = "../plerkle_messenger", version = "1.5.2", features = ["redis"] } -plerkle_serialization = { path = "../plerkle_serialization", version = "1.5.2" } +plerkle_messenger = { path = "../plerkle_messenger", version = "1.6.0", features = ["redis"] } +plerkle_serialization = { path = "../plerkle_serialization", version = "1.6.0" } serde = "1.0.144" serde_derive = "1.0.103" serde_json = "1.0.83" diff --git a/plerkle/src/error.rs b/plerkle/src/error.rs index b1a0ca3..2623417 100644 --- a/plerkle/src/error.rs +++ b/plerkle/src/error.rs @@ -1,5 +1,7 @@ use thiserror::Error; +use solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPluginError; + #[derive(Error, Debug)] pub enum PlerkleError { #[error("General Plugin Config Error ({msg})")] @@ -19,4 +21,14 @@ pub enum PlerkleError { #[error("Unable to Send Event to Stream ({msg})")] EventStreamError { msg: String }, + + #[error("Unable to acquire lock for updating slots seen. Error message: ({msg})")] + SlotsSeenLockError { msg: String }, +} + +// Implement the From trait for the PlerkleError to convert it into GeyserPluginError +impl From for GeyserPluginError { + fn from(err: PlerkleError) -> Self { + GeyserPluginError::Custom(Box::new(err)) + } } diff --git a/plerkle/src/geyser_plugin_nft.rs b/plerkle/src/geyser_plugin_nft.rs index f8ad1e4..411eea5 100644 --- a/plerkle/src/geyser_plugin_nft.rs +++ b/plerkle/src/geyser_plugin_nft.rs @@ -24,13 +24,11 @@ use solana_geyser_plugin_interface::geyser_plugin_interface::{ use solana_sdk::{message::AccountKeys, pubkey::Pubkey, signature::Signature}; use std::{ collections::BTreeSet, - convert::TryFrom, fmt::{Debug, Formatter}, fs::File, io::Read, net::UdpSocket, - ops::Bound::Included, - ops::RangeBounds, + ops::{Bound::Included, RangeBounds}, sync::{Arc, Mutex}, }; use tokio::{ @@ -89,7 +87,6 @@ impl SlotStore { } } -#[allow(clippy::type_complexity)] #[derive(Default)] pub(crate) struct Plerkle<'a> { runtime: Option, @@ -98,13 +95,54 @@ pub(crate) struct Plerkle<'a> { sender: Option>>, started_at: Option, handle_startup: bool, - slots_seen: Mutex, + slots_seen: Arc>, + #[allow(clippy::type_complexity)] account_event_cache: Arc)>>>, + #[allow(clippy::type_complexity)] transaction_event_cache: Arc)>>>, conf_level: Option, } -#[derive(Deserialize, PartialEq, Eq, Debug)] +trait PlerklePrivateMethods { + fn get_plerkle_block_info<'b>( + &self, + blockinfo: ReplicaBlockInfoVersions<'b>, + ) -> plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2<'b>; +} + +impl<'a> PlerklePrivateMethods for Plerkle<'a> { + fn get_plerkle_block_info<'b>( + &self, + blockinfo: ReplicaBlockInfoVersions<'b>, + ) -> plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2<'b> { + match blockinfo { + ReplicaBlockInfoVersions::V0_0_1(block_info) => { + plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2 { + parent_slot: 0, + parent_blockhash: "", + slot: block_info.slot, + blockhash: block_info.blockhash, + block_time: block_info.block_time, + block_height: block_info.block_height, + executed_transaction_count: 0, + } + } + ReplicaBlockInfoVersions::V0_0_2(block_info) => { + plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2 { + parent_slot: 0, + parent_blockhash: "", + slot: block_info.slot, + blockhash: block_info.blockhash, + block_time: block_info.block_time, + block_height: block_info.block_height, + executed_transaction_count: 0, + } + } + } + } +} + +#[derive(Deserialize, PartialEq, Debug)] pub enum ConfirmationLevel { Processed, Rooted, @@ -145,7 +183,7 @@ impl<'a> Plerkle<'a> { sender: None, started_at: None, handle_startup: false, - slots_seen: Mutex::new(SlotStore::new()), + slots_seen: Arc::new(Mutex::new(SlotStore::new())), account_event_cache: Arc::new(DashMap::new()), transaction_event_cache: Arc::new(DashMap::new()), conf_level: None, @@ -527,10 +565,13 @@ impl GeyserPlugin for Plerkle<'static> { status: SlotStatus, ) -> solana_geyser_plugin_interface::geyser_plugin_interface::Result<()> { info!("Slot status update: {:?} {:?}", slot, status); - let mut slots_seen = self.slots_seen.lock().unwrap(); if status == SlotStatus::Processed { if let Some(parent) = parent { - slots_seen.insert(parent); + let mut seen = self + .slots_seen + .lock() + .map_err(|e| PlerkleError::SlotsSeenLockError { msg: e.to_string() })?; + seen.insert(parent) } } if status == self.get_confirmation_level() { @@ -557,11 +598,15 @@ impl GeyserPlugin for Plerkle<'static> { } } - let slots_to_purge = slots_seen.needs_purge(slot); + let mut seen: std::sync::MutexGuard<'_, SlotStore> = self + .slots_seen + .lock() + .map_err(|e| PlerkleError::SlotsSeenLockError { msg: e.to_string() })?; + let slots_to_purge = seen.needs_purge(slot); if let Some(purgable) = slots_to_purge { debug!("Purging slots: {:?}", purgable); for slot in &purgable { - slots_seen.remove(*slot); + seen.remove(*slot); } let cl = self.account_event_cache.clone(); @@ -662,48 +707,17 @@ impl GeyserPlugin for Plerkle<'static> { Ok(()) } - fn notify_block_metadata( - &self, - blockinfo: ReplicaBlockInfoVersions, - ) -> solana_geyser_plugin_interface::geyser_plugin_interface::Result<()> { + fn notify_block_metadata(&self, blockinfo: ReplicaBlockInfoVersions) -> Result<()> { let seen = Instant::now(); + let plerkle_blockinfo = self.get_plerkle_block_info(blockinfo); + // Get runtime and sender channel. let runtime = self.get_runtime()?; let sender = self.get_sender_clone()?; // Serialize data. - let rep: plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2; let builder = FlatBufferBuilder::new(); - - let block_info = match blockinfo { - ReplicaBlockInfoVersions::V0_0_1(block_info) => { - // Hope to remove this when coupling is not an issue. - rep = plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2 { - parent_slot: 0, - parent_blockhash: "", - slot: block_info.slot, - blockhash: block_info.blockhash, - block_time: block_info.block_time, - block_height: block_info.block_height, - executed_transaction_count: 0, - }; - &rep - } - ReplicaBlockInfoVersions::V0_0_2(block_info) => { - rep = plerkle_serialization::solana_geyser_plugin_interface_shims::ReplicaBlockInfoV2 { - parent_slot: block_info.parent_slot, - parent_blockhash: block_info.parent_blockhash, - slot: block_info.slot, - blockhash: block_info.blockhash, - block_time: block_info.block_time, - block_height: block_info.block_height, - executed_transaction_count: block_info.executed_transaction_count, - }; - &rep - } - }; - - let builder = serialize_block(builder, block_info); + let builder = serialize_block(builder, &plerkle_blockinfo); // Send block info over channel. runtime.spawn(async move { diff --git a/plerkle_messenger/Cargo.toml b/plerkle_messenger/Cargo.toml index 503a6a7..2bd4b55 100644 --- a/plerkle_messenger/Cargo.toml +++ b/plerkle_messenger/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "plerkle_messenger" description = "Metaplex Messenger trait for Geyser plugin producer/consumer patterns." -version = "1.5.3" +version = "1.6.0" authors = ["Metaplex Developers "] repository = "https://github.com/metaplex-foundation/digital-asset-validator-plugin" license = "AGPL-3.0" diff --git a/plerkle_serialization/Cargo.toml b/plerkle_serialization/Cargo.toml index fda8939..f51420e 100644 --- a/plerkle_serialization/Cargo.toml +++ b/plerkle_serialization/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "plerkle_serialization" description = "Metaplex Flatbuffers Plerkle Serialization for Geyser plugin producer/consumer patterns." -version = "1.5.3+solana.1.16.15" +version = "1.6.0+solana.1.16.15" authors = ["Metaplex Developers "] repository = "https://github.com/metaplex-foundation/digital-asset-validator-plugin" license = "AGPL-3.0" @@ -13,7 +13,7 @@ publish = false bs58 = "0.4.0" chrono = "0.4.22" flatbuffers = "23.1.21" -serde = { version = "1.0.152"} +serde = "1.0.152" solana-sdk = "=1.16.15" solana-transaction-status = "=1.16.15" thiserror = "1.0.32" diff --git a/plerkle_serialization/src/account_info_generated.rs b/plerkle_serialization/src/account_info_generated.rs index dbb85f1..c915609 100644 --- a/plerkle_serialization/src/account_info_generated.rs +++ b/plerkle_serialization/src/account_info_generated.rs @@ -1,10 +1,10 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated use crate::common_generated::*; -use core::cmp::Ordering; -use core::mem; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow}; diff --git a/plerkle_serialization/src/block_info_generated.rs b/plerkle_serialization/src/block_info_generated.rs index 16b5421..715aa0e 100644 --- a/plerkle_serialization/src/block_info_generated.rs +++ b/plerkle_serialization/src/block_info_generated.rs @@ -1,9 +1,9 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated -use core::cmp::Ordering; -use core::mem; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow}; diff --git a/plerkle_serialization/src/common_generated.rs b/plerkle_serialization/src/common_generated.rs index e8c8b85..8720574 100644 --- a/plerkle_serialization/src/common_generated.rs +++ b/plerkle_serialization/src/common_generated.rs @@ -1,9 +1,9 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated -use core::cmp::Ordering; -use core::mem; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow}; diff --git a/plerkle_serialization/src/compiled_instruction_generated.rs b/plerkle_serialization/src/compiled_instruction_generated.rs index 24b7953..f37b608 100644 --- a/plerkle_serialization/src/compiled_instruction_generated.rs +++ b/plerkle_serialization/src/compiled_instruction_generated.rs @@ -1,10 +1,10 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated use crate::common_generated::*; -use core::cmp::Ordering; -use core::mem; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow}; diff --git a/plerkle_serialization/src/serializer/serializer_stable.rs b/plerkle_serialization/src/serializer/serializer_stable.rs index bb46a5d..8488a9c 100644 --- a/plerkle_serialization/src/serializer/serializer_stable.rs +++ b/plerkle_serialization/src/serializer/serializer_stable.rs @@ -1,8 +1,8 @@ -use crate::error::PlerkleSerializationError; -use crate::solana_geyser_plugin_interface_shims::{ - ReplicaAccountInfoV2, ReplicaBlockInfoV2, ReplicaTransactionInfoV2, SlotStatus, -}; use crate::{ + error::PlerkleSerializationError, + solana_geyser_plugin_interface_shims::{ + ReplicaAccountInfoV2, ReplicaBlockInfoV2, ReplicaTransactionInfoV2, SlotStatus, + }, AccountInfo, AccountInfoArgs, BlockInfo, BlockInfoArgs, CompiledInnerInstruction, CompiledInnerInstructionArgs, CompiledInnerInstructions, CompiledInnerInstructionsArgs, CompiledInstruction, CompiledInstructionArgs, Pubkey as FBPubkey, Pubkey, SlotStatusInfo, @@ -11,11 +11,13 @@ use crate::{ }; use chrono::Utc; use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use solana_sdk::message::{SanitizedMessage, VersionedMessage}; -use solana_sdk::transaction::VersionedTransaction; -use solana_transaction_status::option_serializer::OptionSerializer; +use solana_sdk::{ + message::{SanitizedMessage, VersionedMessage}, + transaction::VersionedTransaction, +}; use solana_transaction_status::{ - EncodedConfirmedTransactionWithStatusMeta, UiInstruction, UiTransactionStatusMeta, + option_serializer::OptionSerializer, EncodedConfirmedTransactionWithStatusMeta, UiInstruction, + UiTransactionStatusMeta, }; pub fn serialize_account<'a>( @@ -136,11 +138,11 @@ pub fn serialize_transaction<'a>( for inner_instructions in inner_instructions_vec.iter() { let index = inner_instructions.index; let mut instructions_fb_vec = Vec::with_capacity(inner_instructions.instructions.len()); - for instruction in inner_instructions.instructions.iter() { - let compiled_instruction = &instruction.instruction; - let program_id_index = compiled_instruction.program_id_index; - let accounts = Some(builder.create_vector(&compiled_instruction.accounts)); - let data = Some(builder.create_vector(&compiled_instruction.data)); + for compiled_instruction in inner_instructions.instructions.iter() { + let program_id_index = compiled_instruction.instruction.program_id_index; + let accounts = + Some(builder.create_vector(&compiled_instruction.instruction.accounts)); + let data = Some(builder.create_vector(&compiled_instruction.instruction.data)); let compiled = CompiledInstruction::create( &mut builder, &CompiledInstructionArgs { @@ -262,18 +264,16 @@ pub fn seralize_encoded_transaction_with_status( mut builder: FlatBufferBuilder, tx: EncodedConfirmedTransactionWithStatusMeta, ) -> Result { - let meta: UiTransactionStatusMeta = tx.transaction.meta.ok_or_else(|| { - PlerkleSerializationError::SerializationError( - "Missing meta data for transaction".to_string(), - ) - })?; + let meta: UiTransactionStatusMeta = + tx.transaction + .meta + .ok_or(PlerkleSerializationError::SerializationError( + "Missing meta data for transaction".to_string(), + ))?; // Get `UiTransaction` out of `EncodedTransactionWithStatusMeta`. - let ui_transaction: VersionedTransaction = - tx.transaction.transaction.decode().ok_or_else(|| { - PlerkleSerializationError::SerializationError( - "Transaction cannot be decoded".to_string(), - ) - })?; + let ui_transaction: VersionedTransaction = tx.transaction.transaction.decode().ok_or( + PlerkleSerializationError::SerializationError("Transaction cannot be decoded".to_string()), + )?; let msg = ui_transaction.message; let atl_keys = msg.address_table_lookups(); let account_keys = msg.static_account_keys(); diff --git a/plerkle_serialization/src/slot_status_info_generated.rs b/plerkle_serialization/src/slot_status_info_generated.rs index 14444f0..691208e 100644 --- a/plerkle_serialization/src/slot_status_info_generated.rs +++ b/plerkle_serialization/src/slot_status_info_generated.rs @@ -1,9 +1,9 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated -use core::cmp::Ordering; -use core::mem; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow}; diff --git a/plerkle_serialization/src/transaction_info_generated.rs b/plerkle_serialization/src/transaction_info_generated.rs index da08149..7e03190 100644 --- a/plerkle_serialization/src/transaction_info_generated.rs +++ b/plerkle_serialization/src/transaction_info_generated.rs @@ -1,11 +1,10 @@ +#![allow(clippy::all)] // automatically generated by the FlatBuffers compiler, do not modify // @generated -use crate::common_generated::*; -use crate::compiled_instruction_generated::*; -use core::cmp::Ordering; -use core::mem; +use crate::{common_generated::*, compiled_instruction_generated::*}; +use core::{cmp::Ordering, mem}; extern crate flatbuffers; use self::flatbuffers::{EndianScalar, Follow};