From 64c6325ca1aa769fe0296f419530a48afe7f9459 Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Tue, 5 Dec 2023 15:07:02 -0500 Subject: [PATCH 1/2] geyser: allow custom name in config file (#33550) Allow loading the plugin name from the json config file as opposed to use plugin.name which is called before config file is passed to it. Allowing different plugins using the same executable to use different names. (cherry picked from commit c82fc6c98e050f62974bb2158f93269706e83deb) # Conflicts: # geyser-plugin-manager/src/geyser_plugin_manager.rs --- .../src/geyser_plugin_manager.rs | 84 +++++++++++++++++-- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/geyser-plugin-manager/src/geyser_plugin_manager.rs b/geyser-plugin-manager/src/geyser_plugin_manager.rs index 0698cf1a656363..1547a437e4f2ae 100644 --- a/geyser-plugin-manager/src/geyser_plugin_manager.rs +++ b/geyser-plugin-manager/src/geyser_plugin_manager.rs @@ -4,12 +4,48 @@ use { libloading::Library, log::*, solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, - std::path::Path, + std::{ + ops::{Deref, DerefMut}, + path::Path, + }, }; +#[derive(Debug)] +pub struct LoadedGeyserPlugin { + name: String, + plugin: Box, +} + +impl LoadedGeyserPlugin { + pub fn new(plugin: Box, name: Option) -> Self { + Self { + name: name.unwrap_or_else(|| plugin.name().to_owned()), + plugin, + } + } + + pub fn name(&self) -> &str { + &self.name + } +} + +impl Deref for LoadedGeyserPlugin { + type Target = Box; + + fn deref(&self) -> &Self::Target { + &self.plugin + } +} + +impl DerefMut for LoadedGeyserPlugin { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.plugin + } +} + #[derive(Default, Debug)] pub struct GeyserPluginManager { - pub plugins: Vec>, + pub plugins: Vec, libs: Vec, } @@ -107,6 +143,11 @@ impl GeyserPluginManager { }); } +<<<<<<< HEAD +======= + setup_logger_for_plugin(&*new_plugin.plugin)?; + +>>>>>>> c82fc6c98e (geyser: allow custom name in config file (#33550)) // Call on_load and push plugin new_plugin .on_load(new_config_file) @@ -177,6 +218,27 @@ impl GeyserPluginManager { data: None, })?; +<<<<<<< HEAD +======= + // Then see if a plugin with this name already exists. If so, abort + if self + .plugins + .iter() + .any(|plugin| plugin.name().eq(new_plugin.name())) + { + return Err(jsonrpc_core::Error { + code: ErrorCode::InvalidRequest, + message: format!( + "There already exists a plugin named {} loaded, while reloading {name}. Did not load requested plugin", + new_plugin.name() + ), + data: None, + }); + } + + setup_logger_for_plugin(&*new_plugin.plugin)?; + +>>>>>>> c82fc6c98e (geyser: allow custom name in config file (#33550)) // Attempt to on_load with new plugin match new_plugin.on_load(new_parsed_config_file) { // On success, push plugin and library @@ -264,7 +326,7 @@ pub enum GeyserPluginManagerError { #[cfg(not(test))] pub(crate) fn load_plugin_from_config( geyser_plugin_config_file: &Path, -) -> Result<(Box, Library, &str), GeyserPluginManagerError> { +) -> Result<(LoadedGeyserPlugin, Library, &str), GeyserPluginManagerError> { use std::{fs::File, io::Read, path::PathBuf}; type PluginConstructor = unsafe fn() -> *mut dyn GeyserPlugin; use libloading::Symbol; @@ -307,6 +369,8 @@ pub(crate) fn load_plugin_from_config( libpath = config_dir.join(libpath); } + let plugin_name = result["name"].as_str().map(|s| s.to_owned()); + let config_file = geyser_plugin_config_file .as_os_str() .to_str() @@ -321,7 +385,11 @@ pub(crate) fn load_plugin_from_config( let plugin_raw = constructor(); (Box::from_raw(plugin_raw), lib) }; - Ok((plugin, lib, config_file)) + Ok(( + LoadedGeyserPlugin::new(plugin, plugin_name), + lib, + config_file, + )) } #[cfg(test)] @@ -337,7 +405,7 @@ const TESTPLUGIN2_CONFIG: &str = "TESTPLUGIN2_CONFIG"; #[cfg(test)] pub(crate) fn load_plugin_from_config( geyser_plugin_config_file: &Path, -) -> Result<(Box, Library, &str), GeyserPluginManagerError> { +) -> Result<(LoadedGeyserPlugin, Library, &str), GeyserPluginManagerError> { if geyser_plugin_config_file.ends_with(TESTPLUGIN_CONFIG) { Ok(tests::dummy_plugin_and_library( tests::TestPlugin, @@ -359,7 +427,7 @@ pub(crate) fn load_plugin_from_config( mod tests { use { crate::geyser_plugin_manager::{ - GeyserPluginManager, TESTPLUGIN2_CONFIG, TESTPLUGIN_CONFIG, + GeyserPluginManager, LoadedGeyserPlugin, TESTPLUGIN2_CONFIG, TESTPLUGIN_CONFIG, }, libloading::Library, solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, @@ -369,9 +437,9 @@ mod tests { pub(super) fn dummy_plugin_and_library( plugin: P, config_path: &'static str, - ) -> (Box, Library, &'static str) { + ) -> (LoadedGeyserPlugin, Library, &'static str) { ( - Box::new(plugin), + LoadedGeyserPlugin::new(Box::new(plugin), None), Library::from(libloading::os::unix::Library::this()), config_path, ) From bccfc963da368d5c8916bbaf72a22a54989a83a2 Mon Sep 17 00:00:00 2001 From: Lijun Wang <83639177+lijunwangs@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:07:45 -0800 Subject: [PATCH 2/2] Fixed merge conflicts --- geyser-plugin-manager/src/geyser_plugin_manager.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/geyser-plugin-manager/src/geyser_plugin_manager.rs b/geyser-plugin-manager/src/geyser_plugin_manager.rs index 4ddac02aea4212..c5da56859e2b36 100644 --- a/geyser-plugin-manager/src/geyser_plugin_manager.rs +++ b/geyser-plugin-manager/src/geyser_plugin_manager.rs @@ -143,7 +143,6 @@ impl GeyserPluginManager { }); } - setup_logger_for_plugin(&*new_plugin.plugin)?; // Call on_load and push plugin new_plugin .on_load(new_config_file) @@ -230,7 +229,6 @@ impl GeyserPluginManager { }); } - setup_logger_for_plugin(&*new_plugin.plugin)?; // Attempt to on_load with new plugin match new_plugin.on_load(new_parsed_config_file) { // On success, push plugin and library