Lesson 4 of 4

Fetch Information About the Mempool

A transaction is "in the mempool" when a node has accepted it but not yet included it in a block. For a few seconds — sometimes longer — it's been seen but isn't settled. If you're building a service that submits transactions, you often want to confirm yours is pending rather than lost.

gOuroboros exposes this via the LocalTxMonitor mini-protocol. The starter-kit demonstrates it in cmd/tx-monitor.


What LocalTxMonitor Does

LocalTxMonitor is a Node-to-Client protocol. You connect to a local socket, acquire a mempool snapshot, then iterate the transactions in that snapshot one at a time. Two queries are common:

Query

Returns

GetSizes()

(capacity, size, numberOfTxs) — mempool capacity, current bytes used, tx count

NextTx()

The next pending transaction, or nil when the snapshot is exhausted

The program uses both: prints the sizes, then iterates the snapshot and prints each transaction's hash, fee, and CBOR.


Prerequisites

  • Completed 101.1 (starter-kit set up, CARDANO_NODE_SOCKET_PATH and CARDANO_NODE_MAGIC exported)
  • Dolos running
  • Ideally, a preprod wallet that can submit a transaction (so you have something to look at in the mempool)

Step 1: Run tx-monitor on an Empty Mempool

With nothing pending on your local view, you'll still get the sizes:

go run ./cmd/tx-monitor
Mempool size (bytes): 0          Mempool capacity (bytes): 131072    Transactions: 0

Three things to notice:

  • Capacity is fixed by the protocol. 128 KB is the standard limit for mempool size per node.
  • Size 0 with Transactions 0 is the steady state on a quiet network.
  • The program exits. It doesn't stream — each run is a single snapshot.

Step 2: Submit a Transaction, Then Re-Run

In Module 102 you'll build and submit a real transaction. For this lesson any submitted transaction will do — from a wallet, a faucet request, or an earlier course exercise.

Submit something, then immediately (within 20–40 seconds, before the next block) re-run:

go run ./cmd/tx-monitor

You should see:

Mempool size (bytes): 512        Mempool capacity (bytes): 131072    Transactions: 1

Transaction:
- Hash: 62396165deadbeef...
- Fee: 168317
- CBOR: 84a40081825820...

Once the transaction lands in a block, the next run returns to size 0. That's the window you're watching.


The Code Shape

From cmd/tx-monitor/main.go (paraphrased):

o, _ := ouroboros.NewConnection(
    ouroboros.WithNetworkMagic(cfg.Magic),
    ouroboros.WithErrorChan(errorChan),
    ouroboros.WithNodeToNode(false),   // NtC, Unix socket
)
o.Dial("unix", cfg.SocketPath)

capacity, size, numberOfTxs, _ := o.LocalTxMonitor().Client.GetSizes()

for {
    tx, _ := o.LocalTxMonitor().Client.NextTx()
    if tx == nil {
        break
    }
    // decode tx bytes, print hash/fee/CBOR
}

The NextTx() loop is a snapshot iterator, not a live subscription. You see every transaction that was pending at the moment of the acquire, then you're done. To see a newer snapshot, run the program again.


Use Cases for a Mempool Check

In a production Go service you might call LocalTxMonitor to:

  • Confirm your submission was accepted by the node — after LocalTxSubmission.SubmitTx returns success, verify the tx is visible in the mempool before telling the user "submitted."
  • Estimate network congestionsize relative to capacity tells you how full the mempool is right now. A near-full mempool may reject your submission with an overfull error.
  • Detect a stalled tx — if your tx hash keeps showing up in repeated snapshots, it's pending a long time. Worth investigating why (too low a fee, expired validity window, etc.).

Common Issues

Size is never > 0 even after you submit a transaction

Your wallet submitted through a public relay, not through Dolos. The mempool you see here is only your local node's mempool. Transactions submitted via Blockfrost or a public node won't appear unless they propagate back to Dolos before being mined.

protocol not supported on handshake

LocalTxMonitor is not enabled on every node implementation. Dolos supports it; some lightweight forks may not. If you switch to a different upstream, check its feature list.

Mempool is full and your tx is rejected elsewhere

Capacity is 128 KB and fills up during busy periods (especially on mainnet). This isn't a tx-monitor issue — it's a protocol reality you detect with tx-monitor.


You'll Know You're Successful When

  • tx-monitor prints sizes when you run it
  • You've seen your own submitted transaction appear in the mempool at least once
  • You understand this is a snapshot-and-iterate model, not a live stream

Practice Tasks

  • Submit a transaction, then run tx-monitor every 5 seconds until size returns to 0. How long did your tx spend in the mempool?
  • Compare the tx hash from your wallet's UI against the hash printed by tx-monitor. They should match exactly.
  • Read cmd/tx-monitor/main.go and find the for { NextTx() } loop. What would break if you replaced break with continue?

What's Next

Module 101 is now complete — you can connect to a node, fetch blocks, check the tip, and inspect the mempool. In Module 102 you'll build and sign transactions, and use the starter-kit's tx-submission command to submit them back to the same node you've been querying here.