AuRa: move finalization manager and terminal-block disposer to DI#12036
AuRa: move finalization manager and terminal-block disposer to DI#12036asdacap wants to merge 3 commits into
Conversation
|
Claude finished @asdacap's task in 6m 0s —— View job Code Review
|
Register IAuRaBlockFinalizationManager as a container singleton in AuRaModule instead of constructing it manually in InitializeBlockchainAuRa and serving it to DI consumers via the FallbackToFieldFromApi source. The component has no construction cycle (only the deferred SetMainBlockBranchProcessor wiring is cyclic, and that stays in WireFinalizationBranchProcessor). AuRaNethermindApi.AuRaFinalizationManager becomes a computed getter resolving from the container (a settable property alongside a registration is rejected by FallbackToFieldFromApi). As a normal singleton Autofac now disposes it on shutdown; Dispose is idempotent so the early dispose from AuRaTerminalBlockDisposer remains safe. Tests that injected a substitute via the property now register it through DI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er via DI With IAuRaBlockFinalizationManager now a DI singleton, AuRaTerminalBlockDisposer's three constructor dependencies (IAuRaBlockFinalizationManager, IPoSSwitcher, IBlockTree) are all DI-resolvable, so the manual InitializeMergeFinalization lifecycle hook is pure ceremony. Register AuRaTerminalBlockDisposer as a singleton in AuRaMergeModule and resolve it in the InitializeBlockchainAuRaMerge step (after WireFinalizationBranchProcessor) to trigger its constructor side-effect. This step runs after the head is loaded and IPoSSwitcher is initialized, but before the block processor starts, so the once-only TerminalBlockReached signal cannot be missed. Autofac owns the disposer's lifetime and disposal, equivalent to the removed DisposeStack.Push; Dispose is idempotent. Remove the now-unused InitializeMergeFinalization override and _auraApi field from AuRaMergePlugin, and the base virtual hook + call site from MergePlugin (no other overriders exist). Add a DI-resolution regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the now-redundant AuRaNethermindApi.AuRaFinalizationManager accessor: its only remaining consumers resolve IAuRaBlockFinalizationManager directly from DI instead (AuraMainProcessingModule via a factory parameter, InitializeBlockchainAuRa via Api.Context.Resolve), completing the move off the api facade. Also remove two unused usings in EthereumRunnerTests left over from the earlier finalization-manager DI move, which the code-lint (IDE0005) check flagged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8129346 to
4f598da
Compare

Changes
Moves AuRa's block finalization manager and its merge-transition disposer fully into dependency injection, removing two pieces of manual lifecycle wiring.
IAuRaBlockFinalizationManager→ DI singleton. Registered inAuRaModulevia a factory (AuRaPlugin.cs) instead of beingnew-ed inInitializeBlockchainAuRa.InitBlockchain()and stashed on a mutableAuRaNethermindApi.AuRaFinalizationManager { get; set; }property served through theFallbackToFieldFromApisource.AuRaNethermindApi.AuRaFinalizationManageris now a get-only computed property resolving from the container (matchingValidatorStore,TxAuRaFilterBuilders, etc.). A settable property alongside a real registration is rejected byFallbackToFieldFromApi.SetMainBlockBranchProcessor— stays a deferred post-construction step (WireFinalizationBranchProcessor).ExternallyOwned) singleton, Autofac now disposes it on shutdown — an improvement over before, where non-merge AuRa never disposed it.Dispose()is idempotent.InitializeMergeFinalizationlifecycle hook. With the finalization manager in DI,AuRaTerminalBlockDisposer's three constructor dependencies are all DI-resolvable, so the hand-rolled hook inMergePluginwas pure ceremony.AuRaTerminalBlockDisposeris now registered as a singleton inAuRaMergeModuleand resolved in theInitializeBlockchainAuRaMergestep (afterWireFinalizationBranchProcessor) to trigger its constructor side-effect. That step runs after the head is loaded andIPoSSwitcheris initialized, but before the block processor starts, so the once-onlyTerminalBlockReachedsignal cannot be missed. Autofac owns disposal, equivalent to the removedDisposeStack.Push.AuRaMergePlugin.InitializeMergeFinalizationoverride and the now-unused_auraApifield, plus the basevirtualhook + call site inMergePlugin(no other overriders exist).Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
Builds clean (0 warnings).
Nethermind.AuRa.Test,Nethermind.Merge.AuRa.Test(incl. the new DI-resolution test),Nethermind.Merge.Plugin.Test, andNethermind.Runner.Test(EthereumRunnerTests) pass. The one intermittentgetPayloadV1_does_not_wait_for_improvement_when_block_is_not_emptyfailure is a pre-existing block-improvement timing flake (passes in isolation; unrelated to finalization).Documentation
Requires documentation update
Requires explanation in Release Notes