Processed, safe, finalized: what "final" means on Solana, Ethereum, Stellar, TON and sequencer L2s
Every chain has a word for "this won't change any more", and the words do not line up. A mapping of the five models, what each API lets you ask for, and how to pick a threshold for a deposit versus a UI.
Multichain code tends to grow a helper called something like waitForConfirmation(tx). On the first chain it wraps one concept. By the third chain it wraps three different concepts behind one name, and the bugs live in the gap. This post lays the five models side by side — Solana, Ethereum, Stellar, TON and a sequencer-based L2 (Robinhood Chain) — and ends with a way to choose thresholds that does not pretend they are the same.
It deliberately says nothing about how long each level takes. The question here is what each level means, and what you are entitled to conclude when you read data at it.
Why "confirmed" is not portable
Three different things get called "confirmed" in practice:
- Seen by a node. The transaction is in a block the node has processed, but the block could still be dropped.
- Agreed by the network under its fork-choice rule. Very unlikely to be dropped, but the protocol still allows it.
- Irreversible under the protocol's own rules. Reverting it would require the protocol's safety assumptions to fail.
Solana names all three. Ethereum names the second and third with block tags. Stellar is built so that the first answer its API gives you is already the third. TON makes the step from the first to the third an explicit reference you can check. A sequencer L2 adds a fourth, earlier thing — "the sequencer currently shows it" — that is not any of the above.
Solana: processed, confirmed, finalized
Solana read methods take a commitment parameter with three values; getTransaction, for example, accepts processed, confirmed or finalized.
- processed: in Solana's RPC documentation, "the node's most recent processed block. This is the newest view, but it can still be rolled back." Triport's streaming reference calls this level revertible.
- confirmed: "a block directly voted on by a supermajority of stake, meaning more than two-thirds of the network's active stake." It is the default commitment on Triport's Solana streams.
- finalized: "a block the cluster recognizes as finalized with maximum lockout." Triport's
rootSubscribereference describes a rooted slot as one "finalized by supermajority vote" that "can never be rolled back", and the stream reference labelsfinalizedirreversible.
The commitment you pass changes the answer, not only its reliability. getTransaction for a signature that exists but has not reached the requested commitment returns null, which is a successful response, not an error. The method's own notes suggest polling at confirmed (or processed) for early visibility and re-reading at finalized once settled. Code that treats null at finalized as "this transaction does not exist" will mis-classify every recent payment.
Ethereum: latest, safe, finalized
Ethereum JSON-RPC reads take a block parameter, which is either a block number or a named tag. eth_getBlockByNumber accepts five:
| Tag | Meaning |
|---|---|
latest | The most recent block the node has imported |
earliest | The genesis block |
pending | The pending state and transactions not yet in a block |
safe | The latest block considered safe by the fork-choice rule |
finalized | The latest block that has reached finality |
So Ethereum's three rungs are latest (seen), safe (agreed under fork choice), and finalized (irreversible under the protocol). There is no tag spelled "confirmed", and "N confirmations" — counting blocks on top of yours — is a policy you apply to latest, not something the node reports.
Two practical consequences. A balance read at latest and a balance read at finalized can legitimately differ, and both are correct answers to different questions. And pending is not a rung on this ladder at all: it is the node's view of what might go into the next block.
Stellar: a ledger closes, or it doesn't
Stellar has no commitment parameter and no block tags, because it has one relevant state. In every Stellar Consensus Protocol round, the network reaches consensus on which transaction set to apply to the last closed ledger; a transaction is either in a closed ledger or it is not. SCP, in Stellar's own words, "prioritizes fault tolerance and safety over liveness" — the protocol is designed to stop closing ledgers rather than close conflicting ones.
For an application this simplifies the ladder to one rung, with one trap: included is not the same as succeeded. A transaction can be included in a closed ledger and still have failed, which is why Horizon transaction records carry a successful flag and why Triport's guide to monitoring Stellar payments tells you never to credit without checking it. The same guide adds the other half: successful: true means the transaction succeeded, not that your business rules are satisfied.
TON: the masterchain reference
TON splits work across a masterchain and shardchains, and finality is defined by the link between them. TON's glossary describes the masterchain as "the main chain that references shard and workchain blocks; a shard block is finalized once a Masterchain block references it." Its payment-processing guide says the same from the application side: once a transaction from a shardchain appears in a masterchain block, it becomes irreversible, and when monitoring payments you should verify masterchain inclusion rather than trusting the shardchain alone.
On Triport's TON surface (product overview: TON RPC) this is something you check, not something you pass: the 13 read-only methods take seqno, shard and logical-time parameters, and there is no commitment argument. A deposit flow therefore reads the account's transactions and confirms that the shard block holding each one is referenced by a masterchain block before crediting.
L2 sequencers: pending is not a stage
Sequencer-based L2s add a view that the other chains do not have: what the sequencer shows right now. Triport's Robinhood Chain docs are blunt about it: pending "is a snapshot of what the sequencer presents right now. It is not a durable stage, public mempool, or finality signal." A pending block or transaction can disappear, be replaced or move into another block; its hash may be null and may later change.
The second difference is what the API lets you ask for. On Triport's Robinhood Chain contract, the supported block tags are latest, earliest and pending; safe and finalized are not part of the contract. The wallet backend guide draws the conclusion: confirmation has to be depth-based — record the receipt's blockNumber, compare it with the head from eth_blockNumber, treat the transaction as settled only after the number of blocks your product requires, and reconcile by hash against later canonical blocks. A shared "read at finalized" helper carried over from Ethereum will fail on this contract, and the guide calls that failure the good outcome; the bad one is a silent fallback to latest while the UI claims finality.
Mapping table
| Earliest signal | Network-agreed | Irreversible | How you ask | |
|---|---|---|---|---|
| Solana | processed (can be rolled back) | confirmed (supermajority of stake voted) | finalized (rooted, maximum lockout) | commitment parameter |
| Ethereum | latest | safe (fork-choice rule) | finalized | Block tag |
| Stellar | — | — | In a closed ledger (check successful) | Read the ledger or transaction record |
| TON | In a shard block | — | Shard block referenced by a masterchain block | Check masterchain inclusion yourself |
| Robinhood Chain on Triport | pending (a sequencer snapshot, not a stage) | latest plus your block-depth rule | Not exposed as a tag | latest / pending tags; depth policy |
Read the table by column, not by row. The "Irreversible" column is the only one where the chains agree on intent, and even there the mechanism differs: a tag you request, a commitment you pass, a record you read, a reference you verify, or a rule you apply.
Picking thresholds for deposits vs UI
A useful policy separates showing from acting:
- UI feedback can use the earliest signal each chain offers: Solana
processedorconfirmed, Ethereumlatest, a Robinhood Chain receipt. Label it as unconfirmed if your product cares about the difference. - Crediting a deposit should wait for the level you could defend if the chain reorganised: Solana
finalized, Ethereumfinalized(orsafe, if your risk policy says so), a Stellar transaction in a closed ledger withsuccessful: true, a TON transaction whose shard block the masterchain references, and on Robinhood Chain a depth you chose and wrote down. - Store the level with the data. Every balance or transaction you persist should record the commitment, tag or depth it was read at, so a later audit can tell a finalized record from an early one.
- Never convert one chain's level into another's name. A
status: "confirmed"column that meansfinalizedon one chain andlateston another is the bug this post is about.
When this is the wrong approach
- You need settlement guarantees across a bridge. Finality of the destination chain says nothing about the source chain or the bridge contract; that is a separate trust analysis.
- You treat L1 finality as L2 finality. How and when an L2's state becomes final on its L1 is defined by that rollup's own design and is outside the scope of the tags covered here.
- You rely on time instead of state. "Wait N seconds" is not a finality rule on any of these chains; read the level.
Sources
- Triport,
getTransactionon Solana: commitment values,nullbelow the requested commitment, re-read atfinalized. Triport streaming reference (/ws/sol-stream):processedrevertible,confirmeddefault,finalizedirreversible. TriportrootSubscribereference: rooted = finalized, never rolled back. Solana RPC documentation, commitment levels — https://solana.com/docs/rpc, read 2026-09-22. - Triport,
eth_getBlockByNumberon Ethereum: the five block tags and their meanings. - Stellar Docs, Ledgers — https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/ledgers; Stellar Consensus Protocol — https://developers.stellar.org/docs/learn/fundamentals/stellar-consensus-protocol; both read 2026-09-22.
- Triport, Monitoring Stellar payments with Horizon SSE:
successful, included vs succeeded. - TON Docs, Glossary — https://docs.ton.org/foundations/glossary; Payment processing overview — https://docs.ton.org/applications/payments/overview; both read 2026-09-22.
- Triport, TON overview: 13 read-only methods, parameter shapes.
- Triport, Robinhood Chain pending data and wallet backend guide:
pendingis not a stage;safeandfinalizedare not part of the contract; depth-based confirmation.