This document describes the subscription system in fuel-core that enables clients to receive real-time updates about blockchain events. Subscriptions are exposed through the GraphQL API and use Server-Sent Events (SSE) for transport.
For information about the GraphQL API architecture and endpoints, see API Service Architecture. For transaction lifecycle and status tracking, see Transaction Status Tracking.
The subscription system provides streaming updates for:
All subscriptions use HTTP-based Server-Sent Events (SSE) with cookie-based session management for maintaining persistent connections. The underlying implementation uses tokio::sync::watch channels to broadcast updates to multiple subscribers.
Sources: crates/client/src/client.rs551-581 crates/fuel-core/src/schema/tx.rs678-854
Sources: crates/client/src/client.rs551-581 crates/fuel-core/src/schema/tx.rs678-854
Subscriptions use Server-Sent Events (SSE) over HTTP rather than WebSockets. The transport implementation resides in FailoverTransport.
| Aspect | Implementation |
|---|---|
| Protocol | HTTP/1.1 with SSE |
| Endpoint | POST /v1/graphql-sub |
| Session Management | Cookie-based |
| Reconnection | Automatic failover across multiple URLs |
| Message Format | JSON-serialized GraphQL responses |
| Connection Type | Unidirectional (server → client) |
The client's subscribe method signature demonstrates the generic subscription pattern:
The method returns a Pin<Box<Stream>> that yields deserialized GraphQL responses. The transport layer handles reconnection and failover automatically.
Sources: crates/client/src/client.rs551-581 High-Level Diagram 5
The system provides three related but distinct transaction status subscriptions:
Monitors an existing transaction's status changes by transaction ID.
GraphQL Schema:
Server Implementation:
The resolver uses transaction_status_change helper to create a stream from TxStatusManager:
The subscription filters out preconfirmation events if include_preconfirmation is false or not provided.
Client Usage:
Sources: crates/fuel-core/src/schema/tx.rs683-737 crates/client/assets/schema.sdl1348-1357
Submits a transaction and waits only for the final status (Success, Failure, or SqueezedOut).
GraphQL Schema:
Server Implementation: The resolver submits the transaction to the TxPool, then immediately subscribes to status changes but filters to only yield final statuses:
Client Usage:
Sources: crates/fuel-core/src/schema/tx.rs766-793 crates/client/src/client.rs885-925
Submits a transaction and returns a stream containing all intermediate states including Submitted and Preconfirmation statuses.
GraphQL Schema:
Client Usage Pattern:
Sources: crates/fuel-core/src/schema/tx.rs795-826 tests/tests/tx.rs372-396
The TransactionStatus enum represents all possible transaction states:
| Status | Description | Final State |
|---|---|---|
SubmittedStatus | Transaction accepted by TxPool | No |
PreconfirmationSuccessStatus | Preconfirmation indicates likely success | No |
PreconfirmationFailureStatus | Preconfirmation indicates likely failure | No |
SuccessStatus | Transaction successfully included in block | Yes |
FailureStatus | Transaction failed execution in block | Yes |
SqueezedOutStatus | Transaction removed from TxPool | Yes |
Sources: crates/fuel-core/src/schema/tx/types.rs144-152 crates/client/src/client/types.rs113-154
Streams new block import events as they occur.
GraphQL Schema:
Server Implementation:
The subscription receives ImportResult events from the block importer and serializes them using the postcard binary format:
The events contain:
Client Usage:
Sources: crates/fuel-core/src/schema/tx.rs828-854 crates/client/src/client.rs1045-1066
A broadcast subscription that streams all transaction preconfirmations across the network.
GraphQL Schema:
Purpose:
Unlike statusChange which monitors a specific transaction, this subscription broadcasts preconfirmation updates for all transactions. This is useful for monitoring network activity or building transaction explorers.
Server Implementation:
The subscription yields only PreconfirmationSuccessStatus or PreconfirmationFailureStatus events.
Client Usage:
Sources: crates/fuel-core/src/schema/tx.rs739-764 tests/tests/tx.rs494-513
Two subscriptions enable streaming contract state:
Streams all storage slots for a given contract.
GraphQL Schema:
Each emitted item contains:
key: Bytes32 - The storage slot keyvalue: HexString - The storage slot valueClient Usage:
Sources: crates/client/src/client.rs999-1017
Streams all asset balances for a given contract.
GraphQL Schema:
Each emitted item contains:
contract: ContractId - The contract IDamount: U64 - The balance amountassetId: AssetId - The asset identifierClient Usage:
Sources: crates/client/src/client.rs1020-1042
The core subscription mechanism in FuelClient:
The implementation performs automatic chain state tracking:
This pattern:
FailoverTransportSources: crates/client/src/client.rs551-581
Subscriptions respect the client's ConsistencyPolicy:
When subscribing, the current required block height is passed to ensure consistent reads:
This guarantees that subscription events are consistent with the client's view of the chain state.
Sources: crates/client/src/client.rs227-257 crates/client/src/client.rs486-491
The FailoverTransport provides automatic failover for subscriptions across multiple node URLs. If the current node connection fails, the client automatically attempts to reconnect to alternative nodes:
| Feature | Implementation |
|---|---|
| URL List | Vec<Url> of node endpoints |
| Default Index | AtomicUsize tracking current node |
| Automatic Retry | Iterates through URLs on failure |
| Sticky Behavior | Updates default index on success |
Sources: High-Level Diagram 5
All transaction-related subscriptions are grouped in the TxStatusSubscription resolver. The #[Subscription] macro from async-graphql handles:
Sources: crates/fuel-core/src/schema/tx.rs678-826
Transaction subscriptions obtain their data from DynTxStatusManager:
The TxStatusManager uses tokio::sync::watch channels to broadcast status updates to all subscribers. When a transaction status changes:
TxStatusManager receives update from executor/importerSources: crates/fuel-core/src/schema/tx.rs693-712
Subscriptions frequently transform the underlying stream to filter or modify events:
Common transformations:
Sources: crates/fuel-core/src/schema/tx.rs719-737
Certain subscriptions have configuration prerequisites:
This check is performed for resource-intensive subscriptions like new_blocks to ensure the node operator has explicitly enabled these features. The configuration flag prevents accidental resource exhaustion on public nodes.
Sources: crates/fuel-core/src/schema/tx.rs832-833
Subscription streams close under these conditions:
| Condition | Behavior | Recovery |
|---|---|---|
| Final transaction status reached | Stream ends normally | None needed |
| Network connection lost | io::Error returned | Client can resubscribe |
| Node shutdown | Stream terminates | Failover to next URL |
| GraphQL error | Error item in stream | Stream continues |
| Transaction not found | Error immediately | Client should verify TX ID |
When subscribing to statusChange after a transaction is already finalized:
TxStatusManagerThis ensures clients always receive at least one status update even for already-completed transactions.
Sources: crates/fuel-core/src/schema/tx.rs693-737
The documentation explicitly warns about missed updates:
"It is possible for the stream to miss an update if it is polled slower than the updates arrive. In such a case the stream will close without a status. If this occurs the stream can simply be restarted to return the latest status."
This is an inherent limitation of the tokio::sync::watch channel implementation - slow consumers may miss intermediate updates but can always query the current state.
Refresh this wiki