Skip to content

Slipstream Plugin Integration/Interface#3190

Open
dgrkotsonis wants to merge 59 commits intostagingfrom
stream_plugin_testing
Open

Slipstream Plugin Integration/Interface#3190
dgrkotsonis wants to merge 59 commits intostagingfrom
stream_plugin_testing

Conversation

@dgrkotsonis
Copy link
Copy Markdown
Collaborator

@dgrkotsonis dgrkotsonis commented Mar 16, 2026

Overview

Introduces a plugin framework for streaming canonical finalize events out of snarkVM to external consumers via dynamically loaded shared libraries. This enables downstream services (e.g., explorer backends) to receive real-time mapping updates and staking rewards at block finalization time.

Related PRs/Repos:


New Crates

plugins/slipstream_plugin_interface

Defines:

  • SlipstreamPlugin trait — trait all plugins must implement. Contains on_load(), on_unload(), subscribed_events(), on_broadcast() (see below)
  • BroadcastEvent enum — MappingUpdate and StakingReward variants carrying little-endian serialized byte slices
  • BroadcastEventKind — used for subscription opt-in checks
Method Description
on_load / on_unload Lifecycle hooks
on_broadcast Called when a mapping key-value is inserted/updated during canonical finalize or per staker during reward distribution. Broadcasts a generic event type to the plugin for processing.
subscribed_events Returns the event types the plugin subscribes to

Note: At the moment, any mappings filtering (of certain functions/programs) must be handled by the plugins themselves, on_broadcast() gets called for all mappings if the plugin is subscribed to historical mappings

plugins/slipstream_plugin_manager

Manages loaded plugins and their backing libloading::Library handles.

  • LoadedSlipstreamPlugin — wrapper holding a boxed plugin + its name; implements Deref/DerefMut
  • SlipstreamPluginManager
    • from_config_files() - takes a vec of paths to plugin config files (JSON5) and loads them into the manager via libloading
    • unload() — fires on_unload() on each plugin then drops the libraries
    • has_subscribers() — aggregate opt-in checks
    • broadcast() — fan-out broadcast to all interested plugins
    • list_plugins() - return the names of all loaded plugins

Core runtime integration (gated behind --features slipstream-plugins)

ledger/store/src/program/finalize.rs FinalizeStore now has three Arc-wrapped fields shared across all store clones:

  • is_finalize_mode: Arc — guards plugin notifications to canonical finalize only
  • slipstream_block_height: Arc — current block height for event payloads
  • slipstream_plugin_manager: Arc<RwLock<Option>> — installed after construction via set_slipstream_plugin_manager()

update_key_value() and replace_mapping() serialize their arguments before the storage call and fan-out MappingUpdate events to subscribed plugins after each successful write. Serialization is skipped entirely when is_finalize_mode is false or has_subscribers() returns false.

notify_staking_reward() broadcasts StakingReward events with the same finalize-mode guard.

synthesizer/src/vm/finalize.rs

  • Canonical finalize sets is_finalize_mode = true before execution and resets it to false in a finally-style block regardless of success or failure.
  • Staking reward notifications are emitted for both history-staking-rewards-enabled and disabled builds.

Design notes

  • Speculative execution is never observed by plugins — the is_finalize_mode flag ensures dry-run and speculative passes produce no plugin callbacks
  • Fault isolation — a misbehaving plugin cannot crash the node; broadcast errors are warnings only
  • wasm32 guard — a compile-time check in the manager crate prevents building on wasm32 targets where libloading is unavailable

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:

#[no_mangle]
pub extern "C" fn _create_plugin() -> *mut dyn SlipstreamPlugin {
    Box::into_raw(Box::new(MyPlugin::new()))
}

Startup

SlipstreamPluginManager::from_config_files() takes a slice of config file paths and returns a manager object:

let manager = SlipstreamPluginManager::from_config_files(&[
    PathBuf::from("/etc/aleo/plugins/my_plugin.json5"),
])?;

Errors from plugin callbacks (on_broadcast) are logged as warnings and never propagated — a misbehaving plugin will not crash the node.

@dgrkotsonis dgrkotsonis marked this pull request as draft March 16, 2026 13:42
@dgrkotsonis dgrkotsonis force-pushed the stream_plugin_testing branch from 0341a32 to b77006b Compare March 16, 2026 14:00
@dgrkotsonis dgrkotsonis changed the title save place to check on first iteration of diffs First Iteration of Stream Plugin (Draft) Mar 16, 2026
@dgrkotsonis dgrkotsonis changed the title First Iteration of Stream Plugin (Draft) Slipstream Plugin Integration/Interface (Draft) Mar 16, 2026
@miazn miazn requested a review from Copilot March 20, 2026 15:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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/store feature flags to include the plugin manager dependency for history and history-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.

Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread synthesizer/src/vm/finalize.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_service.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_service.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread ledger/store/Cargo.toml
@dgrkotsonis dgrkotsonis force-pushed the stream_plugin_testing branch from adf0c33 to 77faa25 Compare March 27, 2026 17:28
@dgrkotsonis dgrkotsonis marked this pull request as ready for review April 1, 2026 21:21
@dgrkotsonis dgrkotsonis changed the title Slipstream Plugin Integration/Interface (Draft) Slipstream Plugin Integration/Interface Apr 1, 2026
@dgrkotsonis dgrkotsonis requested a review from ljedrz April 1, 2026 21:26
@dgrkotsonis dgrkotsonis force-pushed the stream_plugin_testing branch from 7fb6b76 to 933fbf9 Compare April 3, 2026 18:04
Copy link
Copy Markdown
Collaborator

@vicsn vicsn left a comment

Choose a reason for hiding this comment

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

Mostly LGTM! Few questions

Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread plugins/slipstream_plugin_interface/README.md Outdated
Comment thread plugins/slipstream_plugin_interface/README.md Outdated
Comment thread synthesizer/src/vm/finalize.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread ledger/store/src/program/finalize.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_manager.rs Outdated
Comment thread plugins/slipstream_plugin_manager/src/slipstream_service.rs Outdated
Copy link
Copy Markdown
Collaborator

@ljedrz ljedrz left a comment

Choose a reason for hiding this comment

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

Left some comments.

Comment thread synthesizer/src/vm/finalize.rs Outdated
Copy link
Copy Markdown
Member

@iamalwaysuncomfortable iamalwaysuncomfortable left a comment

Choose a reason for hiding this comment

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

One question and one change requested

Question: Serialization Formats

If we use to_bytes_le() that ensures all consumers must have SnarkVM onboard to deserialize it downstream anywhere which ensures indexers can only work in JS or Rust. Most chain indexing services who might be interested in Aleo data will prefer gRPC or JSON. If we make this current choice we should be lucid that we'll have to serve this transformed data formats from slipstream consumers to most other 3rd parties (unless they decide they want to use SnarkVM, but most people won't want to do this).

That makes it such that for most external parties the flow will be:
SnarkVM --> Slipstream Plugin --> gRPC/JSON --> 3rd party consumer

Most people won't do this:
SnarkVM --> 3rd party slipstream impl

This is fine, but let's make sure we're confidently making this choice.

Changes

The slipstream interface trait shouldn't have a method per datastream, the data should be encapsulated with an enum and just publish that. Trait implementors can then handle that enum at their own callsite.

Comment thread ledger/store/src/program/finalize.rs
Comment thread ledger/store/src/program/finalize.rs
Comment thread plugins/slipstream_plugin_interface/src/slipstream_plugin_interface.rs Outdated
Comment thread plugins/slipstream_plugin_interface/src/slipstream_plugin_interface.rs Outdated
@vicsn
Copy link
Copy Markdown
Collaborator

vicsn commented Apr 18, 2026

@dgrkotsonis are all comments addressed? Can you request new reviews via github if they are? Or if there's too much back and forth organize a videocall with reviewers so we don't let this grow stale. I'll merge once they approve

@dgrkotsonis dgrkotsonis force-pushed the stream_plugin_testing branch from 03b9871 to 8c526ce Compare April 27, 2026 20:25
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.

5 participants