mirror of
https://github.com/luxfi/dex.git
synced 2026-08-07 13:41:48 +00:00
commitSeamAtomic passed the overlay's CommitBatch to sm.Apply — the in-process platformvm acceptor pattern — and had NO batch-less path. The D-Chain ships as an out-of-process plugin, so its SharedMemory is the ZAP client, and that client refuses any batch (a database.Batch cannot cross a process boundary). Every block carrying a cross-chain seam op would have failed at Accept, which is fatal: the chain stops on the first intent it ever imports. Blocks with no seam op take the plain commit path, which is why the chain runs fine right up until the seam is used. Commit the overlay state first, then Apply with no batch. Without a shared batch exactly-once is unreachable, so the choice is at-most-once (a crash between the two writes skips an op) or at-least-once (it replays one). Replay is unsound here — a duplicate put is fatal and, after the peer has consumed the object, re-creates it. A skip is survivable because neither side's replay protection depends on the shared-memory op: D's guard is the durable seamintent escrow row, written by the state commit that now happens first. Do not fix this by teaching atomiczap to take a batch. Co-authored-by: Hanzo Dev <dev@hanzo.ai>