Build One Process That Observes And Submits
Start here when one service should both observe traffic and submit transactions from that local view.
This is a useful execution shape, but it is not mandatory. sof-tx still works on its own with
RPC, Jito, and signed-byte flows.
This combined shape only reaches its latency potential when ingress is also early.
Use This When
- you want fresh local leader and topology state
- you want
sofandsof-txin the same process - you do not need restart-safe replay as the first requirement
The Shape
You are combining:
sofas the observer/runtimesof-txas the transaction SDKPluginHostTxProviderAdapteras the bridge between them
That adapter consumes blockhash, leader, and topology events from sof, then exposes them through
the provider traits that sof-tx already understands.
That path is complete today in raw-shred and gossip-backed SOF runtimes. Built-in processed
provider adapters such as Yellowstone, LaserStream, and websocket now cover transactions,
transaction status, accounts, block-meta, logs, and slots, but they still do not form a complete
built-in sof-tx control-plane source on their own.
The packaged runtime now supports one mixed built-in shape:
- built-in provider-stream transaction ingress
- gossip bootstrap for cluster topology in the same runtime
PluginHostTxProviderAdapter::topology_only(...)
That mixed mode is enough for topology-backed direct routing, but it still does not provide
leader-schedule or reorg hooks. When you need the full control-plane surface, keep using
raw-shred/gossip runtimes or ProviderStreamMode::Generic.
Canonical Example
Use the full example in:
crates/sof-solana-compat/examples/submit_all_at_once_with_sof.rs
It shows the whole shape cleanly:
PluginHostTxProviderAdapterregistered on aPluginHost- RPC-backed blockhash refresh plus SOF-backed leader routing
- direct, RPC, and Jito transports configured together
SubmitPlan::all_at_once(vec![Direct, Rpc, Jito])sof-solana-compat::TxBuilderand unsigned submit helpers on top ofsof-tx
Why This Shape Is Useful
The main benefit is local control:
sofsees live traffic directly- the adapter turns that into local control-plane inputs
sof-txcan use those inputs for direct or hybrid submission decisions
This avoids depending on a separate internal control-plane service for the first version.
The caveat is the same one everywhere else in SOF: local freshness still depends on ingress freshness first.
What You Usually Add Next
- add
SubmitRoute::Directonce TPU target quality is good enough - flow-safety checks before submit
- your own strategy loop around
TxBuilder - metrics around stale control plane, blockhash freshness, and submit outcomes
When Not To Use This Shape First
Do not start here if:
- you only need RPC-based transaction submission
- you need replay/recovery before you need low-latency local freshness
- you have not yet proved your observer logic and your submit logic independently