|
| 1 | +--- |
| 2 | +section: cre |
| 3 | +title: "Finality and Confidence Levels" |
| 4 | +date: Last Modified |
| 5 | +sdkLang: "go" |
| 6 | +pageId: "concepts-finality" |
| 7 | +metadata: |
| 8 | + description: "Understand how CRE handles blockchain finality across different chains, including confidence levels, finality tags, and block depth configurations." |
| 9 | + datePublished: "2025-12-04" |
| 10 | + lastModified: "2025-12-04" |
| 11 | +--- |
| 12 | + |
| 13 | +import { Aside, CopyText } from "@components" |
| 14 | + |
| 15 | +Finality determines when a blockchain transaction is considered irreversible. Until a block is finalized, it could be reorganized (replaced by a different block if the chain temporarily forks), which means any data you read from it might change. |
| 16 | + |
| 17 | +Different blockchains achieve finality in different ways and at different speeds. CRE abstracts these differences through **confidence levels**, allowing you to specify your finality requirements without needing to know the underlying chain-specific implementation. |
| 18 | + |
| 19 | +You specify confidence levels in two places: |
| 20 | + |
| 21 | +- **[EVM Log Triggers](/cre/reference/sdk/triggers/evm-log-trigger-go)** — The `confidence` parameter determines when the trigger fires based on block finality. |
| 22 | +- **[EVM Client contract reads](/cre/reference/sdk/evm-client-go)** — The `blockNumber` parameter lets you query data from `LATEST` or `FINALIZED` blocks, or any specific block number. |
| 23 | + |
| 24 | +## Confidence levels |
| 25 | + |
| 26 | +CRE provides three **abstraction levels** that work consistently across all chains. When you specify `FINALIZED` in your workflow, CRE automatically maps this to a chain-specific implementation—whether that's a native finality tag or a block depth threshold. |
| 27 | + |
| 28 | +When reading from the blockchain or setting up triggers, you can specify one of three confidence levels: |
| 29 | + |
| 30 | +| Confidence Level | Description | Use Case | |
| 31 | +| ---------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | |
| 32 | +| **`LATEST`** | The most recent block. No finality guarantees—the block could still be reorganized. | Non-critical, time-sensitive operations where speed matters more than certainty. | |
| 33 | +| **`SAFE`** | A block that is unlikely to be reorganized, but not yet fully finalized. | A balance between speed and security for most operations. | |
| 34 | +| **`FINALIZED`** | A block that is considered irreversible. This is the safest option. | Critical operations where you need absolute certainty the data won't change. | |
| 35 | + |
| 36 | +<Aside type="note" title="Default behavior"> |
| 37 | + If you don't specify a confidence level, CRE defaults to `SAFE` for triggers and `LATEST` for contract reads. |
| 38 | +</Aside> |
| 39 | + |
| 40 | +### Choosing the right level |
| 41 | + |
| 42 | +- **Use `FINALIZED`** when: Processing financial transactions, updating critical state, or when incorrect data could cause significant issues. |
| 43 | +- **Use `SAFE`** when: You need reasonable confidence without waiting for full finality. Good for most monitoring and alerting use cases. |
| 44 | +- **Use `LATEST`** when: Building real-time dashboards, price displays, or other applications where showing the most current data is more important than guaranteed accuracy. |
| 45 | + |
| 46 | +### How CRE confidence levels map to chains |
| 47 | + |
| 48 | +Here's how CRE determines which blocks to use for each confidence level: |
| 49 | + |
| 50 | +#### SAFE and LATEST |
| 51 | + |
| 52 | +When you specify `SAFE` or `LATEST` in your workflows, CRE uses the chain's native `safe` and `latest` block tags respectively for all supported chains. |
| 53 | + |
| 54 | +#### FINALIZED |
| 55 | + |
| 56 | +- **Finality tag**: Uses the chain's native `finalized` block tag |
| 57 | +- **Block depth**: Waits for a specified number of blocks to pass |
| 58 | + |
| 59 | +| Chain | Finality Method | Block Depth | |
| 60 | +| ------------------------------- | --------------- | ----------- | |
| 61 | +| Arbitrum One / Arbitrum Sepolia | Finality tag | — | |
| 62 | +| Avalanche / Avalanche Fuji | Finality tag | — | |
| 63 | +| Base / Base Sepolia | Finality tag | — | |
| 64 | +| BNB Chain / BNB Testnet | Finality tag | — | |
| 65 | +| Ethereum / Ethereum Sepolia | Finality tag | — | |
| 66 | +| OP Mainnet / OP Sepolia | Finality tag | — | |
| 67 | +| Polygon / Polygon Amoy | Block depth | 500 | |
| 68 | + |
| 69 | +## Custom block depths for chain reads |
| 70 | + |
| 71 | +For chain reads, you're not limited to the three predefined confidence levels. The EVM Client also accepts **any explicit block number**, enabling you to: |
| 72 | + |
| 73 | +- **Implement custom finality rules** tailored to your risk profile (e.g., "always wait 1,000 blocks") |
| 74 | +- **Meet regulatory requirements** that mandate fixed, auditable confirmation thresholds |
| 75 | +- **Query historical state** at specific past block heights for analysis or verification |
| 76 | + |
| 77 | +This flexibility is available for all EVM read methods ([`CallContract`](/cre/reference/sdk/evm-client-go#callcontract), [`BalanceAt`](/cre/reference/sdk/evm-client-go#balanceat), [`FilterLogs`](/cre/reference/sdk/evm-client-go#filterlogs), etc.). |
| 78 | + |
| 79 | +### When to use custom block depths |
| 80 | + |
| 81 | +Use explicit block numbers when: |
| 82 | + |
| 83 | +- **Regulatory compliance**: Your smart contract interactions require provable, fixed confirmation thresholds that must be documented for auditors |
| 84 | +- **Changing chain parameters**: The chain's finality definition may change over time, but your security model must remain constant |
| 85 | +- **Historical verification**: You need to verify state at a specific moment (e.g., for dispute resolution or forensic analysis) |
| 86 | + |
| 87 | +### Implementation |
| 88 | + |
| 89 | +You can pass any `*big.Int` directly as the `BlockNumber` parameter. The SDK accepts both special values (like `-2` for latest, `-3` for finalized) and positive integers for explicit block heights. See [Onchain Read](/cre/guides/workflow/using-evm-client/onchain-read-go#custom-block-depths) for examples. |
| 90 | + |
| 91 | +<Aside type="note" title="Limitation: Chain reads only"> |
| 92 | + Custom block numbers are **only available for EVM chain reads**. EVM Log Triggers must use the three confidence levels |
| 93 | + (`LATEST`, `SAFE`, `FINALIZED`). |
| 94 | +</Aside> |
0 commit comments