Skip to main content

Crate sof

Crate sof 

Expand description

SOF observer engine and plugin framework.

External users should usually start from crate::runtime and crate::framework.

§Start The Packaged Runtime

use sof::runtime::ObserverRuntime;

#[tokio::main]
async fn main() -> Result<(), sof::runtime::RuntimeError> {
    ObserverRuntime::new().run_until_termination_signal().await
}

§Attach One Plugin

use async_trait::async_trait;
use sof::{
    event::TxKind,
    framework::{ObserverPlugin, PluginConfig, PluginHost, TransactionEvent},
    runtime::ObserverRuntime,
};

#[derive(Clone, Copy, Debug, Default)]
struct NonVoteLogger;

#[async_trait]
impl ObserverPlugin for NonVoteLogger {
    fn config(&self) -> PluginConfig {
        PluginConfig::new().with_transaction()
    }

    async fn on_transaction(&self, event: &TransactionEvent) {
        if event.kind == TxKind::VoteOnly {
            return;
        }
        tracing::info!(slot = event.slot, kind = ?event.kind, "transaction observed");
    }
}

#[tokio::main]
async fn main() -> Result<(), sof::runtime::RuntimeError> {
    let host = PluginHost::builder().add_plugin(NonVoteLogger).build();

    ObserverRuntime::new()
        .with_plugin_host(host)
        .run_until_termination_signal()
        .await
}

§Request Explicit Inline Transaction Delivery

use async_trait::async_trait;
use sof::{
    event::TxKind,
    framework::{
        ObserverPlugin, PluginConfig, PluginHost, TransactionDispatchMode, TransactionEvent,
    },
    runtime::ObserverRuntime,
};

#[derive(Clone, Copy, Debug, Default)]
struct InlineTxLogger;

#[async_trait]
impl ObserverPlugin for InlineTxLogger {
    fn config(&self) -> PluginConfig {
        PluginConfig::new().with_transaction_mode(TransactionDispatchMode::Inline)
    }

    async fn on_transaction(&self, event: &TransactionEvent) {
        if event.kind == TxKind::VoteOnly {
            return;
        }
        tracing::info!(slot = event.slot, kind = ?event.kind, "inline transaction observed");
    }
}

#[tokio::main]
async fn main() -> Result<(), sof::runtime::RuntimeError> {
    let host = PluginHost::builder().add_plugin(InlineTxLogger).build();

    ObserverRuntime::new()
        .with_plugin_host(host)
        .run_until_termination_signal()
        .await
}

crate::framework::TransactionDispatchMode::Inline is an explicit delivery contract for on_transaction. SOF dispatches that hook as soon as one full serialized transaction is ready on the anchored contiguous inline path, and falls back to the completed-dataset point only when the early path is not yet reconstructable.

More user-facing examples live in crates/sof-observer/README.md and the published example programs under crates/sof-observer/examples/.

Modules§

event
Runtime transaction event types. Runtime event classifications shared by runtime and plugin surfaces.
framework
Plugin framework for attaching custom runtime hooks. Public plugin framework surface for embedding custom observers into SOF runtime.
runtime
Packaged runtime entrypoints for embedding SOF.
runtime_metrics
Runtime-stage counters for ingress, dataset reconstruction, and tx delivery.