The Transactions screen is a per-transaction ledger of the bdn.ingest → fan-out → land pipeline. It answers one question per row: this signature was handed to FirstByte — what happened to it, where did it enter, and which leader did it reach? This page explains the vocabulary on that screen. It does not cover how to submit a transaction; it covers how to read the result.

The recent window and what one row represents

The ledger is fed by a single procedure, txns.list, called with no arguments. There is no page cursor, no time-range picker, and no per-tenant selector on this screen — the server decides which transactions are recent and returns that set. The subheader states the size of the set you are currently looking at (bdn.ingest → fan-out → land · N recent), so treat N as the window, not as your lifetime transaction count. Live tail re-runs txns.list. It is a refetch, not a subscription: the table updates when you press it (or when the query otherwise refreshes), and rows that have aged out of the server’s recent window disappear on the next fetch. If you need a row to survive that, export it (see CSV export columns) or open it on chain. One row is one submitted transaction signature, carrying: Clicking any row opens the detail drawer.

State vocabulary: landed, dropped, dedup

State is derived, not stored as a single field. The screen computes it from two booleans on the row, dedup and landed, and in this order: Because dedup wins the precedence, the three states are mutually exclusive in the UI and the filter chips partition the window cleanly. The Dropped filter is defined the same way — it keeps rows that are neither landed nor dedup — so a suppressed duplicate never shows up as a drop. The summary chips above the table count against the full recent window, not against the filtered view:
  • Landed — landed / total.
  • Dedup hits — the number of suppressed duplicates.
  • Land rate — landed as a percentage of the window, to one decimal. With an empty window it renders — rather than a percentage, because there is no rate to compute.
The search box matches a case-insensitive substring against the signature and the leader only. It does not search the ingest node, cluster, or tenant.

Route column: fan-out versus direct TPU

The via field records which path the transaction took out of the ingest node. The table renders the raw value as a tag; the drawer spells it out under Route: The TPU filter chip is a route filter, not a state filter: it keeps every row whose via is tpu, whether it landed, dropped, or deduped. Combine it with the search box to isolate direct submissions to one leader. The Fan-out column (×N) is the edge count for the row. Direct TPU rows still carry a fan-out value; read it alongside the route rather than on its own.

Ingest node and landing leader attribution

These two columns describe the two ends of the pipeline and are attributed from different stages:
  • Ingest node is the node that received the transaction. The drawer’s ingest pipeline stage restates it as received @ <node> — that stage is the authority for this column.
  • Leader is the landing leader recorded on the row. For a landed transaction, the land stage pairs it with the slot (landed · slot <n>). For a dropped transaction the land stage reads no leader landed, and the latency cell shows —, so read the leader column on a dropped row as the leader the row was targeting or last associated with, not as proof of inclusion. Inclusion is established by the landed flag and the slot, or by checking the signature on chain.
Both fields are opaque identifier strings rendered verbatim. The leader is searchable; the ingest node is not.

The detail drawer and its four pipeline stages

Selecting a row opens a drawer with the full signature at the top, labelled Signature (first 64 bytes = dedup key) — that is, deduplication keys on the signature itself. A Copy signature button copies the untruncated value. Below that, a fixed grid of fields: Then the Pipeline block, four stages in order. Each stage shows a tick, a lock, or a cross: The shape of this block is the fastest diagnosis on the screen:
  • Tick, tick, tick, cross → the transaction propagated and simply was not included. Look at the leader and the route.
  • Tick, lock, skipped, cross → it was a duplicate. Nothing was fanned out, so the absence of a landing is expected; the original submission is a different row.

Verifying a signature on chain

The drawer footer has two exits:
  • View on explorer opens the signature in a block explorer in a new tab.
  • Copy as cURL copies a ready-to-run JSON-RPC request to your clipboard — a getTransaction call for the selected signature against the public mainnet-beta endpoint, with maxSupportedTransactionVersion: 0:
Use this when the ledger says dropped and you want independent confirmation, or when a row has aged out of the recent window and you still have the signature.

CSV export columns

Export downloads bdn-transactions.csv. Two things to know before you rely on it:
  • It exports the currently filtered and searched rows, not the whole recent window. Clear the filter chip and the search box first if you want everything the screen has.
  • The button is disabled when the current filter matches no rows.
The file is flat, one row per transaction, with these columns: Note the redundancy between state and dedup: a dedup state always has dedup = yes, and latency_ms is blank rather than zero whenever nothing landed. Guard for the empty string when you load this into a numeric column. Cluster, tenant, and timestamp appear in the drawer but are not in the export.

When the screen has no ledger to show

If the block-distribution module is not deployed, the screen replaces the ledger with a pending state instead of an empty table. It lists what the ledger needs before it can render:
  • mod_bdn nodes running
  • an active landed-transaction stream
Until both are in place there is no ingest, fan-out, or land data to attribute, and the summary chips have nothing to divide by.