Skip to content

feat: add reload_plugin and unload_plugin admin RPCs#369

Merged
MicaiahReid merged 13 commits intosolana-foundation:mainfrom
0xsouravm:feat/reload-unload-admin-rpc
Nov 14, 2025
Merged

feat: add reload_plugin and unload_plugin admin RPCs#369
MicaiahReid merged 13 commits intosolana-foundation:mainfrom
0xsouravm:feat/reload-unload-admin-rpc

Conversation

@0xsouravm
Copy link
Copy Markdown
Contributor

@0xsouravm 0xsouravm commented Oct 15, 2025

Changes:

  • Added unload_plugin(meta, name) and reload_plugin(meta, name, config_file) RPC methods
  • Extended PluginManagerCommand enum with UnloadPlugin and ReloadPlugin variants
  • Created helper functions load_subgraph_plugin() and unload_plugin_by_uuid() to eliminate code duplication
  • Refactored the handler LoadConfig to use helpers and added UnloadPlugin and ReloadPlugin handler
  • Added plugin_uuid_map: HashMap<Uuid, usize> to track plugin indices for efficient unload/reload
  • Added DestoryCollection command to SubgraphCommand to destroy associated collection after unloading a plugin
  • Added unregister_collection and remove_collection methods to use in DestroyCollection command

Reference: #330

@lgalabru
Copy link
Copy Markdown
Collaborator

That's awesome, thanks @0xsouravm!
Have you been able to test this additions with Yellowstone or any other Geyser plugin?

@0xsouravm
Copy link
Copy Markdown
Contributor Author

No worries @lgalabru !!
I am actually struggling with the config file. I am trying to curl but I cannot get the config JSON right. Hence the serde parsing fails during load_plugin

@lgalabru
Copy link
Copy Markdown
Collaborator

@0xsouravm what's the issue you're seeing? if you're using Yellowstone, I think there's an issue with the proposed config file from the example in the repo - something with the plugin name that should not be there or something.

@0xsouravm
Copy link
Copy Markdown
Contributor Author

@lgalabru I was trying with the example config as @MicaiahReid suggested but the config JSON doesn't sit correctly. Can you tell me how load_config was previously tested? I could get the others working if I get the load_config working.

@MicaiahReid MicaiahReid force-pushed the feat/reload-unload-admin-rpc branch from bf11a07 to e930744 Compare October 29, 2025 19:15
@MicaiahReid MicaiahReid force-pushed the feat/reload-unload-admin-rpc branch from e930744 to 439db23 Compare November 12, 2025 15:05
@MicaiahReid
Copy link
Copy Markdown
Collaborator

Apologies on the latency for this PR, @0xsouravm 🙏

I spent some time testing this today. Here are the steps to test:

  1. Build an anchor project with subgraphs set up. This example project would work: https://github.com/txtx/surfpool-examples/tree/main/anchor/simple-pda
  2. Start surfpool in the root of that project with subgraphs
  3. You'll see the subgraphs deployed and a UUID for the subgraph
  4. Send the uuid in an unloadPlugin RPC method

I found that this does not work out of the box, but actually crashes surfpool.

};
Box::pin(async move { Ok(endpoint_url) })
// Return a JSON string containing both UUID and endpoint URL
let response = format!(r#"{{"uuid": "{}", "endpoint": "{}"}}"#, uuid, endpoint_url);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, the return result would yield the TUI logging:
image

Now, the TUI logs this, which doesn't really make much sense:
image

If we're going to log the UUID, it should be via simnet_events_tx.try_send(SimnetEvent::info(...)), and return the endpoint_url for this fn

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added logging through simnet_events_tx as you mentioned!

@0xsouravm
Copy link
Copy Markdown
Contributor Author

Hey @MicaiahReid ! No worries and thank you for guiding me how to test it. I ran into the same issues as you and now I fixed those and unload_plugin works as intended!

The issue - We weren't destroying the associated collection after unloading the plugin
The fix - Added a new subgraph command that handles destroying collections upon unload.

Screenshot 2025-11-13 at 9 20 22 AM

Please check out the above screenshot for the logs!

let _ = subgraph_commands_tx.send(SubgraphCommand::CreateCollection(
uuid,
config.data.clone(),
crossbeam_channel::bounded(0).0, // Temporary sender, will be replaced
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be fixed before merge, you should be using the notifier passed into PluginManagerCommand::LoadConfig

Copy link
Copy Markdown
Collaborator

@MicaiahReid MicaiahReid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff, thanks @0xsouravm!!

@MicaiahReid MicaiahReid merged commit 6b6d294 into solana-foundation:main Nov 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants