Slipstream Plugin Integration/Interface#3190
Conversation
0341a32 to
b77006b
Compare
There was a problem hiding this comment.
Pull request overview
Adds a Slipstream plugin system to stream canonical mapping updates and staking rewards to external services via dynamically loaded plugins, avoiding RPC-based polling.
Changes:
- Introduces new plugin interface + plugin manager crates (dynamic loading via
libloading, JSON5 config parsing). - Wires canonical-finalize lifecycle signaling into the VM + finalize store so storage writes can fan out events to plugins.
- Extends
ledger/storefeature flags to include the plugin manager dependency forhistoryandhistory-staking-rewards.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| utilities/src/bytes.rs | Minor refactor using is_multiple_of(8) for clarity. |
| synthesizer/src/vm/finalize.rs | Sets/reset canonical-finalize mode flag; emits staking reward notifications; some whitespace-only edits. |
| ledger/store/src/program/finalize.rs | Adds finalize-mode flag + plugin manager installation; notifies plugins on mapping updates and staking rewards. |
| ledger/store/Cargo.toml | history* features now pull in slipstream plugin manager. |
| plugins/slipstream_plugin_interface/src/slipstream_plugin_interface.rs | Defines the SlipstreamPlugin trait and callback surface. |
| plugins/slipstream_plugin_interface/src/lib.rs | Exposes the interface module. |
| plugins/slipstream_plugin_interface/README.md | Documents plugin config and library export convention. |
| plugins/slipstream_plugin_interface/Cargo.toml | New crate manifest for the interface. |
| plugins/slipstream_plugin_manager/src/slipstream_manager.rs | Implements plugin loading/unloading + fan-out notification logic + tests. |
| plugins/slipstream_plugin_manager/src/slipstream_service.rs | Adds a small service wrapper around the manager. |
| plugins/slipstream_plugin_manager/src/lib.rs | Module exports for manager/service. |
| plugins/slipstream_plugin_manager/Cargo.toml | New crate manifest for the manager. |
| Cargo.toml | Adds the new plugin crates to the workspace and workspace dependencies. |
| Cargo.lock | Adds transitive deps (e.g., json5, pest*) and the new crates. |
adf0c33 to
77faa25
Compare
7fb6b76 to
933fbf9
Compare
vicsn
left a comment
There was a problem hiding this comment.
Mostly LGTM! Few questions
| #[cfg(all(feature = "history", feature = "slipstream-plugins"))] | ||
| if let Some((pid, mname, k, v)) = plugin_data { | ||
| #[cfg(feature = "history")] | ||
| let height = self.storage.current_block_height().load(Ordering::SeqCst); |
| #[cfg(all(feature = "history", feature = "slipstream-plugins"))] | ||
| if let Some((pid, mname, serialized_entries)) = plugin_data { | ||
| #[cfg(feature = "history")] | ||
| let height = self.storage.current_block_height().load(Ordering::SeqCst); |
| ])?; | ||
| ``` | ||
|
|
||
| > **Note:** Not yet wired up to any CLI flags or environment variables. How/where `SlipstreamPluginService` gets constructed and passed into the VM still needs to be plumbed in (likely in snarkOS or wherever the VM is instantiated). |
|
|
||
| > **Note:** Not yet wired up to any CLI flags or environment variables. How/where `SlipstreamPluginService` gets constructed and passed into the VM still needs to be plumbed in (likely in snarkOS or wherever the VM is instantiated). | ||
|
|
||
| > Errors from plugin callbacks (`notify_mapping_update`, `notify_staking_reward`) are logged as warnings and never propagated — a misbehaving plugin will not crash the node. No newline at end of file |
There was a problem hiding this comment.
I personally like the "fail loudly" philosophy. But proper error handling/metrics is also more work so can be left for the future.
| // Signal to Slipstream plugins that canonical finalize is starting. | ||
| #[cfg(feature = "slipstream-plugins")] | ||
| { | ||
| tracing::info!(target: "slipstream", "atomic_finalize: is_finalize_mode → true"); |
There was a problem hiding this comment.
Is debug maybe a better log level?
Can/should this code block be hidden inside of the atomic_finalize! macro?
| // limitations under the License. | ||
|
|
||
| use snarkvm_slipstream_plugin_interface::slipstream_plugin_interface::SlipstreamPlugin; | ||
| use tokio::sync::oneshot::Sender as OneShotSender; |
There was a problem hiding this comment.
Nit: separate deps local to this repo and external to this repo with a newline
Overview
Adds a Slipstream Plugin system for streaming real-time mappings and staking data to external services without relying on RPC calls.
Related PRs/Repos:
New Crates
plugins/slipstream_plugin_interfaceDefines the
SlipstreamPlugintrait — the interface all plugins must implement.on_load/on_unloadnotify_mapping_updatenotify_staking_rewardhistory_enabled/history_staking_rewards_enabledplugins/slipstream_plugin_managerManages loaded plugins and their backing
libloading::Libraryhandles.LoadedSlipstreamPlugin— wrapper holding a boxed plugin + its name; implementsDeref/DerefMutSlipstreamPluginManagerunload()— fireson_unload()on each plugin then drops the librarieshistory_mappings_enabled()/history_staking_rewards_enabled()— aggregate opt-in checksnotify_mapping_update()— fan-out broadcast to all interested pluginsSlipstreamService— async service wrapping the manager (separate file)Plugin Config File (JSON5)
Each plugin requires a config file:
Plugin Library Convention
The shared library (
.so/.dylib/.dll) must export a C function:Startup
SlipstreamPluginService::new()takes a slice of config file paths: