Status: Accepted · Phase: 3 · Supersedes: none · Superseded by: none
Context
Arc settles in stablecoin and must not be wedded to one chain: cost, speed and liquidity differ per corridor and change over time. Settlement code also has to handle reorgs, stuck transactions, dropped transactions and reverts — none of which occur on demand against a real network.Decision
AChainDriver interface — broadcast, getTransaction, getConfirmations, estimateFee, head, subscribe — with a deterministic simulator as the default implementation.
Five chains are modelled with genuinely different characteristics: block time, finality depth, reorg depth, fee model and failure rates. forceReorg(depth) injects a reorg at an exact moment.
Consequences
Good. The saga is written against finality, not against a vendor SDK. Failure paths are testable: a seeded run reproduces the same blocks, reorgs and transaction outcomes every time, so a reorg test is deterministic rather than flaky. Chain selection becomes a per-transfer decision instead of a deployment-time one. The modelling surfaces things a naive abstraction hides. Polygon has 2-second blocks but needs 128 confirmations, so it settles slowest despite looking fastest. Andfailed and dropped are different terminal states — a failed transaction was mined and consumed a fee; a dropped one never made it into a block and cost nothing. Compensation differs for each.
Costs. The simulator is a model, and a model is wrong in ways you have not thought of. Real RPC behaviour — rate limits, inconsistent nodes, mempool visibility — is not represented at all.