Skip to content

[Feature/Draft] Add Slipstream Plugin Support#4175

Draft
dgrkotsonis wants to merge 3 commits intostagingfrom
add_slipstream_plugin_support
Draft

[Feature/Draft] Add Slipstream Plugin Support#4175
dgrkotsonis wants to merge 3 commits intostagingfrom
add_slipstream_plugin_support

Conversation

@dgrkotsonis
Copy link
Collaborator

@dgrkotsonis dgrkotsonis commented Mar 17, 2026

Summary

Wires the Slipstream plugin system (implemented currently on a feature branch in snarkVM) into snarkOS so that node operators can load one or more streaming plugins at startup and manage
them at runtime via authenticated REST endpoints. Validator and Client nodes both support plugins; Prover nodes do not (they do not finalize blocks).

This PR tracks snarkVM's stream_plugin_testing branch and adds the corresponding plumbing in snarkOS on a new add_slipstream_plugin_support branch. (TODO: Update once snarkVM changes merged in)


Changes

Cargo / feature wiring

  • Cargo.toml — Added snarkvm-slipstream-plugin-manager as a new workspace dependency
  • node/Cargo.toml — Added snarkvm-slipstream-plugin-manager as an optional dep; updated history and history-staking-rewards features to enable it alongside the
    corresponding snarkvm features.
  • node/rest/Cargo.toml — Same optional dep + feature wiring.
  • cli/Cargo.toml — Added history and history-staking-rewards features forwarding to snarkos-node.

CLI

  • cli/src/commands/start.rs — Added --slipstream-config PATH flag (repeatable; feature-gated). Empty slice is passed when the feature is disabled so the call site is always uniform.

Node layer

  • node/src/node.rs — Threaded slipstream_configs: &[PathBuf] through new_validator and new_client.
  • node/src/validator/mod.rs / node/src/client/mod.rs — After Ledger::load, if configs are provided a SlipstreamPluginService is initialized, its manager is injected
    into FinalizeStore, and the service is stored in an Arc<Mutex<Option<...>>> field. shut_down() takes and joins the service to trigger clean on_unload calls on all plugins.

REST API

  • node/rest/src/lib.rs — Registered four slipstream routes behind the existing JWT auth middleware (feature-gated). Added PUT and DELETE to CORS allowed methods.
  • node/rest/src/routes.rs — Implemented four handlers:
Method Path Description
GET /{network}/slipstream/plugins List loaded plugins
POST /{network}/slipstream/plugins Load a plugin from a config file
DELETE /{network}/slipstream/plugins/{name} Unload a plugin by name
PUT /{network}/slipstream/plugins/{name} Reload a plugin from a new config file

Error mapping: PluginNotLoaded → 404, PluginAlreadyLoaded → 422, all others → 500.

Tests / docs

  • node/tests/common/node.rs — Updated client() and validator() test helpers to pass &[] for the new parameter.
  • docs/slipstream_plugins.md — New operator guide covering: what Slipstream is, plugin ABI and build instructions, JSON5 config format, startup flags, full REST API reference, and curl examples.

Usage

Build with plugin support

cargo build --features history -p snarkos

Start a client node with two plugins

snarkos start --client \
--slipstream-config ~/.aleo/plugins/postgres/plugin.json5 \
--slipstream-config ~/.aleo/plugins/metrics/plugin.json5

List loaded plugins

curl -H "Authorization: Bearer $JWT" \
http://localhost:3030/mainnet/slipstream/plugins

Load a plugin at runtime

curl -X POST -H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"config_file":"/path/to/plugin.json5"}' \
http://localhost:3030/mainnet/slipstream/plugins


Notes

  • All plugin-related code is gated on #[cfg(any(feature = "history", feature = "history-staking-rewards"))], so builds without these features are unaffected.
  • Plugin manager lock errors (poisoned RwLock) surface as 500 errors; plugin call errors during finalize are logged as warnings and never propagated to the node.
  • The SlipstreamPluginService is stored behind interior mutability (Arc<Mutex<Option<...>>>) because NodeInterface::shut_down() takes &self.

@dgrkotsonis dgrkotsonis marked this pull request as draft March 17, 2026 22:19
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods([Method::GET, Method::POST, Method::OPTIONS])
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE, Method::OPTIONS])
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Would we prefer to keep these methods as-is? I can rework the routes if so

@@ -0,0 +1,198 @@
# Slipstream Plugins
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is there a better place to put this file rather than creating this new docs dir? (Unlike snarkVM there isn't a specific plugins crate to put this in)

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.

1 participant