channels_sv2: clamp target to max_target instead of erroring#2118
channels_sv2: clamp target to max_target instead of erroring#2118plebhash merged 5 commits intostratum-mining:mainfrom
Conversation
|
Tested this locally and the math checks out. Moving from an error to a clamp in I did a quick check on the f64 limits too. Since the clamp is unidirectional (target>max_target), it won't trigger for high-hashrate ASICs, so no new precision loss there. Also, good call on dropping those All 50 |
9e22e68 to
785ea6c
Compare
|
Thanks for looking at this @Alkamal01! |
|
thanks for spotting this @vnprc apologies for taking so long to review it, this is a great improvement! overall the PR is pretty solid, but there's a few things left... I'm taking the liberty of implementing them to make the review cycles a bit more agile, can you rebase against |
…tended,standard} to protect against constructor regressions with the changes introduced in stratum-mining#2118
…_channel to accurately describe the behavior introduced via stratum-mining#2118
…tended,standard} to protect against constructor regressions with the changes introduced in stratum-mining#2118
…_channel to accurately describe the behavior introduced via stratum-mining#2118
19b6c86 to
e834da2
Compare
actually nevermind @vnprc , I just realized I'm able to push here |
When a pool's vardiff computes a target easier than the client's declared max_target, update_channel() returned Err(RequestedMaxTargetOutOfRange). This silently broke vardiff: once triggered, no further difficulty adjustments succeeded for that channel. The pool logged a WARN every ~60s per affected channel while the miner stayed stuck at its last successfully-set difficulty. The max_target field in OpenExtendedMiningChannel means "the easiest difficulty I will accept." If the pool's calculation produces something easier, the correct response is to assign exactly max_target — not to error. The client explicitly declared this difficulty acceptable. Apply the same clamping logic to both ExtendedChannel and StandardChannel, in both new() (channel creation) and update_channel() (vardiff updates). Update the corresponding tests to assert clamping behavior rather than expecting an error. Also remove two stray println! debug statements from ExtendedChannel::new(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tended,standard} to protect against constructor regressions with the changes introduced in stratum-mining#2118
…_channel to accurately describe the behavior introduced via stratum-mining#2118
…2::server::error::{ExtendedChannelError,StandardChannelError}
5effe04 to
ae3741d
Compare
|
awesome! thanks for looking at it! lmk if i can help in any way. |
becomes obsolete with stratum-mining/stratum#2118
becomes obsolete with stratum-mining/stratum#2118
Problem
When a pool's vardiff computes a target easier than the client's declared
max_target,update_channel()returnsErr(RequestedMaxTargetOutOfRange).This silently breaks vardiff for the affected channel: the error is swallowed by
the caller, no difficulty update is applied, and the miner is permanently stuck
at its last successfully-set difficulty. The pool logs a
WARNroughly every60 seconds per affected channel while mining continues at the wrong difficulty.
This is not a hypothetical edge case. It triggers reliably for low-hashrate
miners whose natural vardiff target overshoots their declared
max_target.Root Cause
The
max_targetfield inOpenExtendedMiningChannelmeans "the easiestdifficulty I will accept." When vardiff computes a target easier than
max_target, the correct response is to assign exactlymax_target— theclient has already declared that difficulty acceptable. The current code errors
instead, which is both incorrect per the spec and operationally harmful.
Fix
Replace the
RequestedMaxTargetOutOfRangeerror path with a clamp in fourplaces:
ExtendedChannel::new()— channel creationExtendedChannel::update_channel()— vardiff updatesStandardChannel::new()— channel creationStandardChannel::update_channel()— vardiff updatesAlso removes two stray
println!debug statements fromExtendedChannel::new().Tests
The existing
test_update_channeltests in bothextended.rsandstandard.rsalready exercise this path (
very_small_hashrate = 0.1). They previouslyasserted
is_err()/RequestedMaxTargetOutOfRange. They now assertis_ok()and verify the channel target was clamped to
not_so_permissive_max_target.All 50 unit tests pass.
Notes
RequestedMaxTargetOutOfRangeis preserved in both error enums — it remainsreachable from the
UpdateChannelmessage handler path where the client itselfsends a bad
max_target.Pre-existing CI failure
cargo clippycurrently fails on upstreammaindue toneedless_lifetimesinbinary_sv2— unrelated to this PR.companion stratum-mining/sv2-apps#447