-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Bug Description
JD-Client's vardiff continuously increases difficulty even when miners fail to submit valid shares due to difficulty being too high. This creates a runaway loop where difficulty spirals upward.
Root Cause
In miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs at line 972, the vardiff share counter is incremented before share validation:
vardiff.increment_shares_since_last_update(); // Line 972 - BEFORE validation
let res = standard_channel.validate_share(msg.clone()); // Line 973
match res {
Ok(ShareValidationResult::Valid(share_hash)) => { ... }
Ok(ShareValidationResult::Invalid(e)) => { ... }
Err(e) => { ... }
}This means:
- Miner submits a share (even if difficulty is too low to meet the target)
- Vardiff counter increments unconditionally
- Share validation happens
- Share is rejected (doesn't meet target)
- Vardiff thinks the share was successful
- On next vardiff cycle (60s), it calculates: high share rate → hashrate must be high → increase difficulty
- Difficulty increases further, making the problem worse
Expected Behavior
The share counter should only increment for valid shares that pass validation. The increment should move inside the Ok(ShareValidationResult::Valid(...)) block (line 976).
Observed Behavior
- Vardiff continuously increases difficulty
- Miner fails to submit shares (difficulty too high)
- Failed shares still count toward vardiff share rate
- Difficulty increases further
- Loop continues until difficulty is impossibly high
Reproduction
- Connect a miner to jd-client
- Wait for vardiff to increase difficulty beyond miner's capability
- Observe miner failing to submit valid shares
- Watch vardiff continue to increase difficulty instead of reducing it
Affected Code
File: miner-apps/jd-client/src/lib/channel_manager/downstream_message_handler.rs
Lines: 972 (standard channel), 1188 (extended channel - same issue)
Vardiff logic: stratum/sv2/channels-sv2/src/vardiff/classic.rs
Line 170: When realized_share_per_min == 0.0, it reduces hashrate estimate (easier difficulty), but this never triggers because failed shares still increment the counter.
Suggested Fix
Move vardiff.increment_shares_since_last_update() to after validation succeeds:
let res = standard_channel.validate_share(msg.clone());
let mut is_downstream_share_valid = false;
match res {
Ok(ShareValidationResult::Valid(share_hash)) => {
vardiff.increment_shares_since_last_update(); // Only count valid shares
// ... rest of success handling
}
// ... error cases
}Same fix needed for extended channels at line 1188.
Impact
This bug makes jd-client's vardiff unusable for miners with variable hashrate or when difficulty temporarily exceeds miner capability. Once difficulty gets too high, it never corrects downward.