Skip to main content

rings_node/extension/
mod.rs

1//! This module provide basic mechanism.
2
3pub mod ext;
4pub mod protocols;
5pub mod transport;
6use std::result::Result;
7use std::sync::Arc;
8
9use async_trait::async_trait;
10use rings_core::message::CustomMessage;
11use rings_core::message::Message;
12use rings_core::message::MessagePayload;
13use rings_core::message::MessageVerificationExt;
14use rings_core::swarm::callback::SwarmCallback;
15
16use crate::extension::ext::Envelope;
17use crate::extension::ext::Extensions;
18use crate::extension::transport::platform::run_detached;
19use crate::provider::Provider;
20
21/// Backend handles inbound custom messages from the Swarm, routing each decoded
22/// [`Envelope`] to its namespace's protocol via the [`Extensions`] registry. The
23/// registry is shared with the [`Provider`], so protocols registered there are visible
24/// to inbound dispatch here. Each protocol's interpreter does its IO through a
25/// namespace-scoped [`Scope`](ext::Scope); the underlying router capability is internal.
26/// Dispatch owns a detached task so a swarm callback deadline stops waiting without
27/// cancelling an already committed protocol transition or its ordered effect trace.
28pub struct Backend {
29    extensions: Extensions,
30}
31
32impl Backend {
33    /// Create a new backend over a provider, sharing its protocol registry.
34    pub fn new(provider: Arc<Provider>) -> Self {
35        Self {
36            extensions: provider.extensions(),
37        }
38    }
39}
40
41#[cfg_attr(rings_browser, async_trait(?Send))]
42#[cfg_attr(rings_native, async_trait)]
43impl SwarmCallback for Backend {
44    async fn on_inbound(
45        &self,
46        payload: &MessagePayload,
47    ) -> Result<(), rings_core::error::CallbackError> {
48        let data: Message = payload.transaction.data()?;
49
50        let Message::CustomMessage(CustomMessage(msg)) = data else {
51            return Ok(());
52        };
53
54        let envelope = Envelope::decode(&msg)?;
55        let from = payload.transaction.signer();
56        let extensions = self.extensions.clone();
57        let dispatch =
58            run_detached(async move { extensions.dispatch(from, envelope).await }).await?;
59        dispatch?;
60
61        Ok(())
62    }
63}