Skip to content

Commit e8f6130

Browse files
authored
fix: properly init geyser plugin for rpc and use valid dummy Library (#402)
<!-- greptile_comment --> ## Greptile Summary Implements a workaround for geyser plugin initialization by creating a dummy Library handle, as the plugin is not loaded from a .so file. While functional, this approach requires careful consideration. - Unsafe code and memory leaks introduced in `magicblock-api/src/init_geyser_service.rs` through `Box::leak` and `transmute` for dummy Library creation - Added proper `LoadedGeyserPlugin` initialization and registration with plugin manager - Current implementation may need future refinement to address memory management concerns <!-- /greptile_comment -->
1 parent 68eef55 commit e8f6130

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

magicblock-api/src/init_geyser_service.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::sync::Arc;
22

3+
use libloading::Library;
34
use log::*;
45
use magicblock_config::GeyserGrpcConfig;
56
use magicblock_geyser_plugin::{
@@ -10,7 +11,7 @@ use magicblock_geyser_plugin::{
1011
rpc::GeyserRpcService,
1112
};
1213
use solana_geyser_plugin_manager::{
13-
geyser_plugin_manager::GeyserPluginManager,
14+
geyser_plugin_manager::{GeyserPluginManager, LoadedGeyserPlugin},
1415
geyser_plugin_service::GeyserPluginServiceError,
1516
};
1617

@@ -65,8 +66,8 @@ pub fn init_geyser_service(
6566
),
6667
..Default::default()
6768
};
68-
let manager = GeyserPluginManager::new();
69-
let rpc_service = {
69+
let mut manager = GeyserPluginManager::new();
70+
let (plugin, rpc_service) = {
7071
let plugin = GrpcGeyserPlugin::create(config)
7172
.map_err(|err| {
7273
error!("Failed to load geyser plugin: {:?}", err);
@@ -82,8 +83,22 @@ pub fn init_geyser_service(
8283
"Launched GRPC Geyser service on '{}'",
8384
geyser_grpc.socket_addr()
8485
);
85-
plugin.rpc()
86+
let rpc_service = plugin.rpc();
87+
// hack: we don't load the geyser plugin from .so file, as such we don't own a handle to
88+
// Library, to bypass this, we just make up one from a pointer to a leaked 8 byte memory,
89+
// and forget about it, this should work as long as geyser plugin manager doesn't try to do
90+
// anything fancy with that handle, and when drop method of the Library is called, nothing
91+
// bad happens if the address is garbage, as long as it's not null
92+
// (admittedly ugly solution)
93+
let dummy = Box::leak(Box::new(0usize)) as *const usize;
94+
let lib =
95+
unsafe { std::mem::transmute::<*const usize, Library>(dummy) };
96+
(
97+
LoadedGeyserPlugin::new(lib, Box::new(plugin), None),
98+
rpc_service,
99+
)
86100
};
101+
manager.plugins.push(plugin);
87102

88103
Ok((manager, rpc_service))
89104
}

0 commit comments

Comments
 (0)