Aleo Slipstream Plugin Interface
This crate enables a plugin to be added into a SnarkVM runtime to take actions at the time of
mapping updates at block finalization; for example, saving historical mapping state and staking
data to an external database. The plugin must implement the SlipstreamPlugin trait. See
slipstream_plugin_interface.rs for the full interface definition.
Feature flag: compile with
--features slipstream-pluginsto enable plugin support. Plugin callbacks fire only during canonical finalize — speculative and dry-run executions are never observed by plugins.
Components
plugins/slipstream_plugin_interface
Defines the SlipstreamPlugin trait — the interface all plugins must implement.
| Method | Description |
|---|---|
on_load / on_unload |
Lifecycle hooks called on startup and shutdown |
subscribed_events |
Returns the event types a plugin subscribes to. Defaults to &[] — a plugin that does not override this method receives no callbacks. |
on_broadcast |
Called once per key-value update (and once per entry in a replace_mapping batch). Only fires for event kinds in the subscribed list. |
plugins/slipstream_plugin_manager
Manages loaded plugins and their backing libloading::Library handles.
LoadedSlipstreamPlugin— wrapper holding a boxed plugin + its name; implementsDeref/DerefMutSlipstreamPluginManagerfrom_config_files— takes a slice of config file paths and loads one plugin per fileload_plugin(path)/unload_plugin(name)— load or unload a single plugin at runtimeunload()— fireson_unload()on every plugin then drops the libraries; field declaration order guarantees all plugin code finishes executing before the backing.sois unmappedhas_subscribers()— aggregate opt-in check; used internally to skip serialization when no plugin is interested in an event kindbroadcast()— fan-out broadcast to all interested pluginslist_plugins()— returns the names of all loaded plugins
Plugin Config File (JSON5)
Each plugin requires a config file:
{
"libpath": "/path/to/libmy_plugin.so", // required; relative paths resolve from the config file's dir
"name": "my_plugin" // optional; overrides the plugin's name() return value
}
Plugin Library Convention
The shared library (.so / .dylib / .dll) must export a C function:
pub extern "C"
Broadcast Event Format
All byte-slice fields in BroadcastEvent are serialized in little-endian format (via
to_bytes_le()). Plugin implementations must deserialize accordingly.
Startup
SlipstreamPluginManager::from_config_files() takes a slice of config file paths and returns a
manager object. Install it into the FinalizeStore before the node begins processing blocks:
let manager = from_config_files?;
finalize_store.set_slipstream_plugin_manager;
Shutdown
Call manager.unload() during graceful shutdown before aborting tasks. This fires on_unload()
on every plugin — the right place for flushing buffers, closing connections, etc.:
if let Some = finalize_store.slipstream_plugin_manager.write.as_mut
Errors from plugin callbacks (
on_broadcast) are logged as warnings and never propagated — a misbehaving plugin will not crash the node.