Skip to main content

snarkvm_slipstream_plugin_interface/
slipstream_plugin_interface.rs

1// Copyright (c) 2019-2026 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use anyhow::Result;
17use std::any::Any;
18
19/// Discriminant-only companion to [`BroadcastEvent`], used by
20/// [`SlipstreamPlugin::subscribed_events`] to declare which event types a plugin
21/// wishes to receive without carrying data payloads.
22#[derive(Copy, Clone, Debug, PartialEq, Eq)]
23pub enum BroadcastEventKind {
24    /// Mapping key-value update during canonical finalize.
25    MappingUpdate,
26    /// Staking reward distribution during canonical finalize.
27    StakingReward,
28}
29
30/// A single event dispatched to plugins via [`SlipstreamPlugin::on_broadcast`].
31///
32/// All `&[u8]` fields carry little-endian byte representations of the
33/// corresponding snarkVM console types (serialized via `ToBytes`).
34///
35/// Derives `Copy` — every field is `Copy` (`&[u8]`, `u32`, `u64`) — so the
36/// same value can be passed to multiple plugins in a dispatch loop without cloning.
37#[derive(Copy, Clone, Debug)]
38pub enum BroadcastEvent<'a> {
39    /// A mapping key-value pair was inserted or updated during canonical finalize.
40    MappingUpdate { program_id: &'a [u8], mapping_name: &'a [u8], key: &'a [u8], value: &'a [u8], block_height: u32 },
41    /// A staking reward was distributed to a staker during canonical finalize.
42    StakingReward { staker: &'a [u8], validator: &'a [u8], reward: u64, new_stake: u64, block_height: u32 },
43}
44
45impl BroadcastEvent<'_> {
46    /// Returns the discriminant of this event.
47    pub fn kind(&self) -> BroadcastEventKind {
48        match self {
49            BroadcastEvent::MappingUpdate { .. } => BroadcastEventKind::MappingUpdate,
50            BroadcastEvent::StakingReward { .. } => BroadcastEventKind::StakingReward,
51        }
52    }
53}
54
55/// The interface for Aleo Slipstream plugins. A plugin must implement
56/// the `SlipstreamPlugin` trait to work with the runtime. In addition,
57/// the dynamic library must export a `C` function `_create_plugin` that
58/// creates the implementation of the plugin.
59pub trait SlipstreamPlugin: Any + Send + Sync + std::fmt::Debug {
60    /// Returns the name of the plugin.
61    fn name(&self) -> &'static str;
62
63    /// The callback called when a plugin is loaded by the system, used for
64    /// doing whatever initialization is required by the plugin. The
65    /// `_config_file` contains the name of the config file (JSON format) with
66    /// a `libpath` field indicating the full path of the shared library.
67    fn on_load(&mut self, _config_file: &str, _is_reload: bool) -> Result<()> {
68        Ok(())
69    }
70
71    /// The callback called right before a plugin is unloaded by the system.
72    /// Used for doing cleanup before unload.
73    fn on_unload(&mut self) {}
74
75    /// Returns the event kinds this plugin subscribes to.
76    ///
77    /// The manager checks this before serializing and dispatching each event,
78    /// so plugins that return an empty slice pay no serialization cost. Defaults
79    /// to no subscriptions.
80    fn subscribed_events(&self) -> &[BroadcastEventKind] {
81        &[]
82    }
83
84    /// Receives a single broadcast event from the plugin manager.
85    ///
86    /// Only invoked when the event's kind appears in [`subscribed_events`].
87    fn on_broadcast(&self, _event: BroadcastEvent<'_>) -> Result<()> {
88        Ok(())
89    }
90}