Skip to content

Refactor(jd-client): replace monolithic start loop with JdcRuntime typestate machine - #633

Merged
plebhash merged 1 commit into
stratum-mining:mainfrom
nulllpc:npc/refactor-jdc-start
Aug 7, 2026
Merged

Refactor(jd-client): replace monolithic start loop with JdcRuntime typestate machine#633
plebhash merged 1 commit into
stratum-mining:mainfrom
nulllpc:npc/refactor-jdc-start

Conversation

@nulllpc

@nulllpc nulllpc commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Refactors the monolithic start function inside the Pool (miner-apps/jd-client) into a structured, typestate-based state machine (JdcRuntime) to manage bootstrap, component lifecycles, and graceful shutdown.

This PR also properly handles errors instead of calling unwrap or expect

Fixes #526

@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 3 times, most recently from 27713eb to 45f79e5 Compare July 20, 2026 20:22
@nulllpc

nulllpc commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

A note: in the initial sketch, ChannelManagerReady was put after SoloMiningReady and UpstreamReady but then I realized we need the ChannelManager to start first so we could send CoinbaseOutputConstraints to the template provider so I changed the order. Conceptually, I think there's no major problem there, just want to highlight this just in case.

@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 2 times, most recently from 7dcc7ee to 5dd1782 Compare July 20, 2026 20:35
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs Outdated
@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch from 5dd1782 to ec4544a Compare July 22, 2026 17:15
Comment thread miner-apps/jd-client/src/lib/mod.rs Outdated
Comment thread miner-apps/jd-client/src/lib/error.rs Outdated
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs Outdated
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs Outdated
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs
@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 2 times, most recently from 537c0ef to 2f72d3f Compare July 25, 2026 16:21
Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs Outdated
Comment thread miner-apps/jd-client/src/main.rs Outdated
Comment thread miner-apps/jd-client/src/lib/mod.rs Outdated
Comment thread miner-apps/jd-client/src/lib/mod.rs Outdated
Comment thread miner-apps/jd-client/src/lib/error.rs Outdated
@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 2 times, most recently from cd17528 to 94901fa Compare July 30, 2026 19:04
@plebhash

Copy link
Copy Markdown
Member

@nulllpc looks like fmt CI is broken, likely due to the fact that #651 was just merged

@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 2 times, most recently from 58c6041 to 76461a0 Compare July 31, 2026 18:31

@plebhash plebhash left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@nulllpc can you please squash all commits into 1?

@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch from 50b7941 to 93be0b3 Compare August 1, 2026 04:31

@bit-aloo bit-aloo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some suggestions, we are pretty close.

Comment thread miner-apps/jd-client/src/lib/mod.rs Outdated
Comment on lines +198 to +204
if let Some(monitoring_addr) = self.jd_client.config.monitoring_address() {
info!("Initializing monitoring server on http://{monitoring_addr}");
if let Err(e) = self.start_monitoring_tasks(&channel_manager, monitoring_addr) {
error!("Failed to initialize monitoring tasks: {e}");
self.jd_client.cancellation_token.cancel();
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are we not propagating error here, in case the monitoring services doesn't spawn?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Nice, we can also remove the cancellation token call here because we already call mark_stopped on fail state

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did some checks and found a related issue in connect_to_bitcoin_core and I tagged you in the issue

#679

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for reporting

for now I think we should treat #679 as orthogonal and deal with it later

Comment thread miner-apps/jd-client/src/lib/jdc_runtime.rs Outdated
@plebhash

plebhash commented Aug 5, 2026

Copy link
Copy Markdown
Member

trying to expedite this PR, here's a few commit suggestions to be cherry-picked (on this specific order, otherwise won't apply) and squashed:

  • a2e2482: addressing this suggestion: Refactor(jd-client): replace monolithic start loop with JdcRuntime typestate machine #633 (comment)
  • eeb1aec: addresses ChannelManager::start return signature deviating from pattern established on #582 plus state transition gap on failure of CoinbaseOutputConstraints
  • 858dc34: moved the start call out of bootstrap_channel_manager into start_services_inner, ahead of start_downstream_server, restoring Pool's "bootstrap constructs, start_services activates" split pattern established on #582
  • 06e82b4
    • restored #[must_use] + private fields + into_parts() on BootstrapError (following #582)
    • normalized pubpub(super) (following #582)
    • dropped the mark_stopped() calls that duplicated what shutdown() already does

moreover, #685 is aligning Pool with some patterns that are being established here, and also addressing some bugs found here

@plebhash

plebhash commented Aug 5, 2026

Copy link
Copy Markdown
Member

also needs rebasing against main

@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 3 times, most recently from eb5e808 to 66f4587 Compare August 5, 2026 19:52
@nulllpc

nulllpc commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author
  • Cherry picked the commits from @plebhash
  • Squashed into 1 commit and edited the commit message
  • Rebased main

@plebhash @bit-aloo please review again. Just a reminder that I'm contributing on my free time so things might not move very fast. I'll try my best though. Thanks guys!

@nulllpc

nulllpc commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

trying to expedite this PR, here's a few commit suggestions to be cherry-picked (on this specific order, otherwise won't apply) and squashed:

  • a2e2482: addressing this suggestion: Refactor(jd-client): replace monolithic start loop with JdcRuntime typestate machine #633 (comment)

  • eeb1aec: addresses ChannelManager::start return signature deviating from pattern established on #582 plus state transition gap on failure of CoinbaseOutputConstraints

  • 858dc34: moved the start call out of bootstrap_channel_manager into start_services_inner, ahead of start_downstream_server, restoring Pool's "bootstrap constructs, start_services activates" split pattern established on #582

  • 06e82b4

    • restored #[must_use] + private fields + into_parts() on BootstrapError (following #582)
    • normalized pubpub(super) (following #582)
    • dropped the mark_stopped() calls that duplicated what shutdown() already does

moreover, #685 is aligning Pool with some patterns that are being established here, and also addressing some bugs found here

I'll apply the same rationale here to this PR #644 for the translator so we have consistent pattern

@plebhash

plebhash commented Aug 5, 2026

Copy link
Copy Markdown
Member

Just a reminder that I'm contributing on my free time so things might not move very fast. I'll try my best though.

no worries, your contributions are much appreciated!

whenever you have time, please have a look at #685

along with the commits suggested above, it will probably bring some important insights to #644

@plebhash

plebhash commented Aug 5, 2026

Copy link
Copy Markdown
Member

oh oops, I guess we posted at the same time

@plebhash plebhash mentioned this pull request Aug 5, 2026
@nulllpc
nulllpc force-pushed the npc/refactor-jdc-start branch 2 times, most recently from 75e9cd7 to 215a5cd Compare August 6, 2026 20:40
@nulllpc

nulllpc commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

I just added a tiny Rust doc change for mark_stopped so that it's consistent with the changes you made to PoolRuntime @plebhash

@bit-aloo bit-aloo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me. Thanks for working on this.

…pestate machine

Overhauls the JDC initialization sequence to align its API and behavior with PoolRuntime.

- Typestate Machine: Replaces the monolithic startup logic with strict Init -> TemplateProviderReady -> UpstreamReady -> Running
  state transitions.
- Separation of Concerns: Constructs ChannelManager and core services during bootstrap, but explicitly activates them later in
  start_services_inner.
- Error Propagation: Ensures all startup errors cascade cleanly via Result signatures instead of failing silently or panicking.
- Unblocking Bootstrap: Spawns the downstream IBD template wait loop into the background to prevent the JDC from freezing during
  Bitcoin Core syncs, keeping Ctrl+C functional. TcpListener::bind is preserved as a synchronous check for immediate port-in-use
  feedback.
- Cleanups: Normalizes visibilities to pub(super), restores must_use attributes, and removes redundant mark_stopped() calls.
@plebhash
plebhash force-pushed the npc/refactor-jdc-start branch from 215a5cd to d50d3a2 Compare August 7, 2026 12:02
@plebhash
plebhash merged commit f4a35c0 into stratum-mining:main Aug 7, 2026
10 checks passed
plebhash added a commit to plebhash/sv2-apps that referenced this pull request Aug 7, 2026
`PoolSv2::start` propagated a `PoolRuntime::<Init>::new` failure with
`?`, leaving `is_alive` true and never calling `notify_waiters()`. Since
`PoolSv2` is `Clone`, a concurrent holder calling `PoolSv2::shutdown`
would pass the `is_alive` check and then block forever on `notified`,
because the only `notify_waiters()` lives in `PoolRuntime::shutdown` —
and on that path no runtime was ever built.

Extract `mark_stopped()` (mirroring `JobDeclaratorClient::mark_stopped`,
per bit-aloo's review on stratum-mining#633), route `PoolRuntime::shutdown` through it,
and call it directly on the `new()` failure path.
plebhash added a commit to plebhash/sv2-apps that referenced this pull request Aug 7, 2026
`PoolSv2::start` propagated a `PoolRuntime::<Init>::new` failure with
`?`, leaving `is_alive` true and never calling `notify_waiters()`. Since
`PoolSv2` is `Clone`, a concurrent holder calling `PoolSv2::shutdown`
would pass the `is_alive` check and then block forever on `notified`,
because the only `notify_waiters()` lives in `PoolRuntime::shutdown` —
and on that path no runtime was ever built.

Extract `mark_stopped()` (mirroring `JobDeclaratorClient::mark_stopped`,
per bit-aloo's review on stratum-mining#633), route `PoolRuntime::shutdown` through it,
and call it directly on the `new()` failure path.
plebhash added a commit that referenced this pull request Aug 9, 2026
`PoolRuntime` startup and shutdown gaps, aligned with #633
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.

need to refactor JobDeclaratorClient::start

3 participants