Skip to Content
0.8.0 PreviewTxFlowConfirmation & Rollback

Confirmation & Rollback

Preview — 0.8.0-preview1: APIs may change before stable release.

Confirmation Status Lifecycle

SUBMITTED -> IN_BLOCK -> CONFIRMED | ROLLED_BACK
StatusMeaningDepth Criteria
SUBMITTEDIn mempool, not yet in a blockNot found in block
IN_BLOCKIncluded in a block, waiting for depth0 <= depth < minConfirmations
CONFIRMEDReached safety thresholddepth >= minConfirmations
ROLLED_BACKWas in chain but disappeared (reorg)Previously tracked, now not found

ConfirmationConfig

ConfirmationConfig config = ConfirmationConfig.builder() .minConfirmations(10) // Blocks for CONFIRMED (default: 10) .checkInterval(Duration.ofSeconds(5)) // Polling interval (default: 5s) .timeout(Duration.ofMinutes(30)) // Max wait time (default: 30min) .maxRollbackRetries(3) // Max rebuild/restart attempts (default: 3) .waitForBackendAfterRollback(false) // Wait for node after rollback (default: false) .postRollbackWaitAttempts(5) // Backend readiness checks (default: 5) .postRollbackUtxoSyncDelay(Duration.ZERO) // Extra delay for UTXO indexer (default: 0) .build();

Presets

PresetminConfirmationscheckIntervaltimeout
defaults()105s30min
devnet()31s5min
testnet()63s10min
quick()11s2min

The devnet() and quick() presets also enable waitForBackendAfterRollback with postRollbackWaitAttempts=30 and postRollbackUtxoSyncDelay=3s, for test environments that may restart nodes during rollback simulation.

Enabling Confirmation Tracking

FlowExecutor executor = FlowExecutor.create(backendService) .withConfirmationConfig(ConfirmationConfig.devnet());

Without withConfirmationConfig, the executor uses simple polling — a transaction is considered confirmed as soon as it appears on-chain, with no depth tracking and no rollback detection.

Rollback Strategies

Chain reorganizations (rollbacks/reorgs) occur when the network switches to a longer competing chain, removing previously included transactions. Rollback strategies determine how the executor responds.

FAIL_IMMEDIATELY (Default)

Rollback detected -> onTransactionRolledBack callback -> Step fails with rollback error -> Flow fails

The safest option. The application decides how to handle the failure externally.

NOTIFY_ONLY

Rollback detected -> onTransactionRolledBack callback -> Continue monitoring (re-enter polling) -> If re-included: monitoring continues normally -> If not re-included: eventually times out

Useful when you expect shallow reorgs where the transaction may be re-included.

REBUILD_FROM_FAILED

Rollback detected -> onTransactionRolledBack callback -> onStepRebuilding callback -> Clear step result -> Rebuild with fresh UTXOs -> Submit and monitor rebuilt transaction

Auto-escalation: If the rolled-back step has downstream dependents (other steps depend on its outputs), REBUILD_FROM_FAILED automatically escalates to a full flow restart, since downstream steps would reference invalid UTXOs.

In PIPELINED and BATCH modes, REBUILD_FROM_FAILED behaves identically to REBUILD_ENTIRE_FLOW.

REBUILD_ENTIRE_FLOW

Rollback detected -> onTransactionRolledBack callback -> onFlowRestarting callback -> Clear all step results -> Re-execute entire flow from step 1

In PIPELINED and BATCH modes, the executor checks which transactions are still confirmed on-chain and skips those steps during re-execution.

maxRollbackRetries

Controls how many times rebuild/restart is attempted before failing:

  • REBUILD_FROM_FAILED: max times a single step can be rebuilt
  • REBUILD_ENTIRE_FLOW: max times the entire flow can be restarted

Configured via ConfirmationConfig.builder().maxRollbackRetries(3).

Decision Guide

ScenarioRecommended Strategy
Production, high-value transactionsFAIL_IMMEDIATELY
Simple flows, independent stepsREBUILD_FROM_FAILED
Complex flows with UTXO dependenciesREBUILD_ENTIRE_FLOW
Custom rollback logic / external coordinationNOTIFY_ONLY
Development / testingREBUILD_ENTIRE_FLOW

Usage

FlowExecutor executor = FlowExecutor.create(backendService) .withConfirmationConfig(ConfirmationConfig.devnet()) .withRollbackStrategy(RollbackStrategy.REBUILD_ENTIRE_FLOW);

Rollback strategies only take effect when confirmation tracking is enabled via withConfirmationConfig().

Last updated on