Skip to content

Conversation

@gauravahuja
Copy link
Contributor

@gauravahuja gauravahuja commented Nov 14, 2025

Note

Switches services to async start/stop and shared timer/polling abstractions, propagating through app, API, consensus/sync, P2P, and tests with optional Vertx timers and updated dependencies.

  • Core/Infra:
    • Migrate LongRunningService to async (CompletableFuture), typealias to Linea impl; update NoOpLongRunningService.
    • Introduce timer abstraction usage (TimerFactory) and PeriodicPollingService across components.
  • Consensus/Sync/Finalization:
    • Refactor ProtocolStarter to use TimerFactory (fixed-rate poller).
    • Convert ELSyncService and PeerChainTracker to PeriodicPollingService with async lifecycle.
    • Update CLSyncServiceImpl lifecycle to async futures.
    • Rework LineaFinalizationProvider to PeriodicPollingService.
  • P2P/Discovery:
    • P2PNetworkImpl: async stop flow; plumb TimerFactory.
    • MaruDiscoveryService: async lifecycle; replace Timer with TimerFactory poller; add ENR updates.
  • App/API:
    • ApiServer now extends LongRunningService; ApiServerImpl.start/stop return futures.
    • MaruApp orchestrates services via async start/stop; MaruAppCli awaits .get().
    • MaruAppFactory: wire TimerFactory (VertxTimerFactory vs JvmTimerFactory) via new config useVertxTimers; pass through to P2P/Sync/Finalization/Protocol.
  • Config:
    • Add MaruConfig.useVertxTimers flag.
  • Tests/Utils:
    • Replace synchronous calls with .start().get() / .stop().get(); add TestablePeriodicTimerFactory; update helpers and stacks accordingly.
  • Build/Deps:
    • Add build.linea.internal:long-running-service across modules; bump Linea libs version; minor gradle wiring.

Written by Cursor Bugbot for commit 16b3ef9. This will update automatically on new commits. Configure here.

# Conflicts:
#	app/src/integrationTest/kotlin/maru/app/MaruPeerScoringTest.kt
@gauravahuja gauravahuja force-pushed the gauravahuja/polling_service branch from 19ad0d4 to 1f2484d Compare November 14, 2025 06:45
@codecov-commenter
Copy link

codecov-commenter commented Nov 14, 2025

Codecov Report

❌ Patch coverage is 94.96403% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.75%. Comparing base (3305fe0) to head (16b3ef9).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../kotlin/maru/p2p/discovery/MaruDiscoveryService.kt 81.25% 3 Missing ⚠️
app/src/main/kotlin/maru/app/MaruAppFactory.kt 81.81% 1 Missing and 1 partial ⚠️
.../src/main/kotlin/maru/consensus/ProtocolStarter.kt 90.00% 1 Missing ⚠️
p2p/src/main/kotlin/maru/p2p/P2PNetworkImpl.kt 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #469      +/-   ##
============================================
+ Coverage     83.44%   83.75%   +0.30%     
- Complexity     1119     1131      +12     
============================================
  Files           227      227              
  Lines          8077     8075       -2     
  Branches        629      621       -8     
============================================
+ Hits           6740     6763      +23     
+ Misses         1001      989      -12     
+ Partials        336      323      -13     
Flag Coverage Δ
kotlin 83.75% <94.96%> (+0.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

override val period: Duration,
override val task: Runnable,
) : Timer {
override val errorHandler: (Throwable) -> Unit = { }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestablePeriodicTimer would benefit from having errorHandling lambda in the constructor defaulted to {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handler is never used inside the TestablePeriodicTimer, so it doesn't make sense to have it in the constructor. The timer task is manually invoked in this timer and it is not wrapped in any try-catch with error handling.


checkAndHandleForkTransition()

poller.start()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Timer starts uncontrolled, risking system integrity.

The start() method lacks a guard to prevent multiple invocations, allowing the timer to be started repeatedly. The previous implementation checked if poller != null before starting, but this refactoring removed that protection. Multiple calls to start() will now start the same timer multiple times, causing the pollTask() to execute at an incorrect frequency and potentially leading to race conditions in fork transition logic.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gauravahuja can you please take a look at this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks poitless comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is pointless, start is idempotent

fluentcrafter
fluentcrafter previously approved these changes Nov 14, 2025

checkAndHandleForkTransition()

poller.start()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Repeated Starts Lead To Unpredictable Behavior.

The start() method lacks idempotency protection. The old implementation checked if poller was already running before starting, but the refactored version removed this guard. Since start() can be called multiple times (e.g., via the onBeaconSyncComplete callback at line 61), calling poller.start() repeatedly may cause undefined behavior depending on the timer implementation. The method needs to track whether the poller is already started and return early on subsequent calls.

Fix in Cursor Fix in Web


poller?.cancel()
poller = null
poller.stop()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Idempotency Failure in pause() Method

The pause() method lacks idempotency protection. The old implementation checked if the poller was null before stopping it, but the refactored version removed this guard. Since pause() can be called multiple times (e.g., via the onClSyncStatusUpdate callback at line 56, or through close() which calls pause()), calling poller.stop() repeatedly may cause undefined behavior depending on the timer implementation. The method needs to track whether the poller is already stopped and return early on subsequent calls.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants