Allow LSQ clients to connect during initial LedgerDB replay (EarlyN2C)
Allow the local node-to-client socket to bind within seconds of node
startup rather than after the multi-hour LedgerDB replay completes. n2c
ChainSync clients (cardano-db-sync, ogmios, wallet) can begin streaming
blocks during replay; LSQ / TxSubmit / TxMonitor handlers naturally block
on the LedgerDB until ready, relying on the property that NtC has no
client-side timeouts.
Phase 1 (ChainDB):
- New 'LedgerDBStatus' type + 'awaitLedgerDB' STM helper
- 'openDBInternal' returns once Immutable+Volatile are open; LedgerDB
replay and initial chain selection run on a registry-linked background
thread (new 'runInitLedgerDB')
- LedgerDB-touching queries wrapped in 'awaitLedgerDB'
- New 'OpenedDBImmutableReady' trace event; existing 'OpenedDB' preserved
- 'closeDB' cancels the background initialiser and only closes the
LedgerDB if 'cdbLedgerDBStatus' has reached 'LdbReady'
Phase 2 (NodeKernel + runWith):
- 'mkPendingMempool', 'mkPendingBlockchainTime', 'mkPendingDurationUntilTooOld'
forwarding wrappers that block on a TMVar until populated
- 'initInternalState' split into 'initInternalStateEarly' +
'completeInternalState'
- 'initNodeKernel' split into 'initNodeKernelEarly' returning
'(NodeKernel, m ())'; the deferred action opens the real mempool,
computes the real GsmState, and spawns the four ledger-touching
background threads (GSM, GDD watcher, blockForging, blockFetchLogic,
decisionLogicThreads)
- 'runWith' allocates the BlockchainTime / WrapDurationUntilTooOld TMVars,
builds the kernel synchronously with pending wrappers, calls
'llrnRunDataDiffusion' immediately, and forks a 'Node.lateInit' thread
that runs 'hardForkBlockchainTime' and 'realDurationUntilTooOld' once
the LedgerDB is ready, populates the TMVars, and runs the completer
Verified: 'cabal build all' clean and 'cabal test storage-test' passes
69/69 on the 3.0.1.0 release tag.