finaly working difficulty!
This commit is contained in:
@@ -49,7 +49,10 @@ class RinCoinStratumProxy:
|
||||
'rejected_shares': 0,
|
||||
'blocks_found': 0,
|
||||
'total_hashrate': 0,
|
||||
'connections': 0
|
||||
'connections': 0,
|
||||
'last_share_time': time.time(),
|
||||
'shares_last_minute': [],
|
||||
'current_share_rate': 0.0
|
||||
}
|
||||
self.max_connections = 50 # Production limit
|
||||
|
||||
@@ -397,35 +400,18 @@ class RinCoinStratumProxy:
|
||||
network_diff = self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 1.0
|
||||
|
||||
if is_new_client:
|
||||
# For new clients, start with a conservative estimate
|
||||
# Assuming typical CPU miner does 500kH/s, aim for 1 share per 30 seconds
|
||||
# Difficulty calculation: target_shares_per_second = hashrate / (difficulty * 2^32 / 65535)
|
||||
# Rearranged: difficulty = hashrate / (target_shares_per_second * 2^32 / 65535)
|
||||
estimated_hashrate = 500000 # 500 kH/s conservative estimate
|
||||
target_shares_per_second = 1.0 / self.target_share_interval
|
||||
# Start new clients at 0.5% of network difficulty
|
||||
initial_difficulty = network_diff * 0.005 # 0.5% of network difficulty
|
||||
|
||||
# Bitcoin-style difficulty calculation
|
||||
diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
|
||||
optimal_difficulty = (estimated_hashrate * diff1_target) / (target_shares_per_second * (2**256))
|
||||
# Ensure reasonable bounds
|
||||
min_difficulty = 0.000001 # Absolute minimum
|
||||
max_difficulty = network_diff * 0.05 # Maximum 5% of network
|
||||
initial_difficulty = max(min_difficulty, min(max_difficulty, initial_difficulty))
|
||||
|
||||
# Calculate proper difficulty based on expected hashrate for solo mining
|
||||
# Target: 1 share every 2 minutes (120 seconds)
|
||||
# Conservative estimate: 500 kH/s for CPU mining
|
||||
estimated_hashrate = 500000 # 500 kH/s
|
||||
target_shares_per_second = 1.0 / self.target_share_interval
|
||||
|
||||
# Calculate difficulty to achieve target share rate
|
||||
# Formula: difficulty = hashrate / (target_shares_per_second * 2^32 / max_target)
|
||||
max_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
|
||||
optimal_difficulty = (estimated_hashrate * target_shares_per_second) / (max_target / (2**32))
|
||||
|
||||
# Ensure it's not too low or too high
|
||||
optimal_difficulty = max(0.0000001, min(optimal_difficulty, network_diff * 0.01))
|
||||
|
||||
print(f" 📊 New client {addr}: Network diff {network_diff:.6f}, starting with {optimal_difficulty:.6f}")
|
||||
return optimal_difficulty
|
||||
print(f" 📊 NEW CLIENT {addr}: Network diff {network_diff:.6f}, starting with {initial_difficulty:.6f} (0.5% of network)")
|
||||
return initial_difficulty
|
||||
|
||||
# For existing clients, adjust based on actual performance
|
||||
# For existing clients, adjust based on actual hashrate performance
|
||||
client_data = self.clients.get(addr, {})
|
||||
if not client_data:
|
||||
return self.calculate_optimal_difficulty(addr, is_new_client=True)
|
||||
@@ -433,34 +419,30 @@ class RinCoinStratumProxy:
|
||||
current_time = time.time()
|
||||
connect_time = client_data.get('connect_time', current_time)
|
||||
share_count = client_data.get('share_count', 0)
|
||||
current_difficulty = client_data.get('stratum_difficulty', 0.001)
|
||||
current_difficulty = client_data.get('stratum_difficulty', network_diff * 0.005)
|
||||
estimated_hashrate = client_data.get('estimated_hashrate', 0)
|
||||
|
||||
# Calculate actual share rate
|
||||
mining_duration = current_time - connect_time
|
||||
if mining_duration < 60: # Need at least 1 minute of data
|
||||
# Need at least 3 shares to make adjustments
|
||||
if share_count < 3:
|
||||
return current_difficulty
|
||||
|
||||
actual_share_rate = share_count / mining_duration # shares per second
|
||||
target_share_rate = 1.0 / self.target_share_interval
|
||||
|
||||
# Adjust difficulty to hit target share rate
|
||||
if actual_share_rate > 0:
|
||||
difficulty_multiplier = actual_share_rate / target_share_rate
|
||||
new_difficulty = current_difficulty * difficulty_multiplier
|
||||
# Calculate target difficulty based on hashrate and desired share interval
|
||||
# Target: 1 share every 60 seconds (self.target_share_interval)
|
||||
if estimated_hashrate > 0:
|
||||
# Formula: difficulty = (hashrate * target_time) / (2^32)
|
||||
diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
|
||||
target_difficulty = (estimated_hashrate * self.target_share_interval) / (2**32)
|
||||
|
||||
# Apply conservative adjustment (don't change too dramatically)
|
||||
max_change = 2.0 # Don't change by more than 2x in one adjustment
|
||||
if difficulty_multiplier > max_change:
|
||||
new_difficulty = current_difficulty * max_change
|
||||
elif difficulty_multiplier < (1.0 / max_change):
|
||||
new_difficulty = current_difficulty / max_change
|
||||
# Bounds checking
|
||||
min_difficulty = network_diff * 0.0001 # 0.01% of network
|
||||
max_difficulty = network_diff * 0.02 # 2% of network
|
||||
target_difficulty = max(min_difficulty, min(max_difficulty, target_difficulty))
|
||||
|
||||
# Bounds checking for solo mining
|
||||
min_difficulty = 0.00000001 # Extremely low minimum for CPU mining
|
||||
max_difficulty = 0.0001 # Maximum 0.01% of typical network diff
|
||||
new_difficulty = max(min_difficulty, min(max_difficulty, new_difficulty))
|
||||
# Conservative adjustment - move only 50% towards target each time
|
||||
adjustment_factor = 0.5
|
||||
new_difficulty = current_difficulty + (target_difficulty - current_difficulty) * adjustment_factor
|
||||
|
||||
print(f" 📊 {addr}: {share_count} shares in {mining_duration:.0f}s ({actual_share_rate:.4f}/s), adjusting {current_difficulty:.6f} → {new_difficulty:.6f}")
|
||||
print(f" 📊 {addr}: {estimated_hashrate:.0f} H/s, {share_count} shares, adjusting {current_difficulty:.6f} → {new_difficulty:.6f}")
|
||||
return new_difficulty
|
||||
|
||||
return current_difficulty
|
||||
@@ -470,6 +452,38 @@ class RinCoinStratumProxy:
|
||||
# Fallback to conservative difficulty
|
||||
network_diff = self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 1.0
|
||||
return max(network_diff * 0.001, 0.0001)
|
||||
|
||||
def adjust_global_difficulty_if_needed(self):
|
||||
"""Adjust difficulty globally if share rate is too high/low"""
|
||||
try:
|
||||
current_rate = self.stats['current_share_rate']
|
||||
|
||||
# Target: 0.5-2 shares per second (30-120 second intervals)
|
||||
target_min_rate = 0.008 # ~1 share per 2 minutes
|
||||
target_max_rate = 0.033 # ~1 share per 30 seconds
|
||||
|
||||
if current_rate > target_max_rate:
|
||||
# Too many shares - increase difficulty for all clients
|
||||
multiplier = min(2.0, current_rate / target_max_rate)
|
||||
print(f" 🚨 HIGH SHARE RATE: {current_rate:.3f}/s > {target_max_rate:.3f}/s - increasing difficulty by {multiplier:.2f}x")
|
||||
for addr in self.clients:
|
||||
current_diff = self.clients[addr].get('stratum_difficulty', 0.001)
|
||||
new_diff = min(0.001, current_diff * multiplier)
|
||||
self.clients[addr]['stratum_difficulty'] = new_diff
|
||||
print(f" 📈 {addr}: {current_diff:.6f} → {new_diff:.6f}")
|
||||
|
||||
elif current_rate < target_min_rate and current_rate > 0:
|
||||
# Too few shares - decrease difficulty for all clients
|
||||
multiplier = max(0.5, target_min_rate / current_rate)
|
||||
print(f" 🐌 LOW SHARE RATE: {current_rate:.3f}/s < {target_min_rate:.3f}/s - decreasing difficulty by {multiplier:.2f}x")
|
||||
for addr in self.clients:
|
||||
current_diff = self.clients[addr].get('stratum_difficulty', 0.001)
|
||||
new_diff = max(0.000001, current_diff / multiplier)
|
||||
self.clients[addr]['stratum_difficulty'] = new_diff
|
||||
print(f" 📉 {addr}: {current_diff:.6f} → {new_diff:.6f}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Global difficulty adjustment error: {e}")
|
||||
|
||||
def adjust_client_difficulty(self, addr):
|
||||
"""Adjust difficulty for a specific client if needed"""
|
||||
@@ -549,6 +563,13 @@ class RinCoinStratumProxy:
|
||||
meets_stratum_difficulty = share_difficulty >= client_stratum_diff
|
||||
meets_network_difficulty = share_difficulty >= network_difficulty
|
||||
|
||||
# Track share rate
|
||||
current_time = time.time()
|
||||
self.stats['shares_last_minute'].append(current_time)
|
||||
# Remove shares older than 60 seconds
|
||||
self.stats['shares_last_minute'] = [t for t in self.stats['shares_last_minute'] if current_time - t <= 60]
|
||||
self.stats['current_share_rate'] = len(self.stats['shares_last_minute']) / 60.0
|
||||
|
||||
# Enhanced logging
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
network_percentage = (share_difficulty / network_difficulty) * 100 if network_difficulty > 0 else 0
|
||||
@@ -571,6 +592,7 @@ class RinCoinStratumProxy:
|
||||
print(f"[{timestamp}] {progress_icon} SHARE: job={job['job_id']} | nonce={nonce} | hash={block_hash_hex[:16]}...")
|
||||
print(f" 🎯 Share Diff: {share_difficulty:.2e} | Stratum Diff: {client_stratum_diff:.6f} | Network Diff: {network_difficulty:.6f}")
|
||||
print(f" 📈 Progress: {network_percentage:.4f}% of network, {stratum_percentage:.1f}% of stratum")
|
||||
print(f" 📊 Share Rate: {self.stats['current_share_rate']:.2f}/s | Total: {len(self.stats['shares_last_minute'])}/min")
|
||||
print(f" 📍 Target: {job['target'][:16]}... | Height: {job['height']}")
|
||||
print(f" ⏰ Time: {ntime} | Extranonce: {extranonce1}:{extranonce2}")
|
||||
print(f" 🔍 Difficulty Check: Share {share_difficulty:.2e} vs Stratum {client_stratum_diff:.6f} = {'✅' if meets_stratum_difficulty else '❌'}")
|
||||
@@ -596,8 +618,34 @@ class RinCoinStratumProxy:
|
||||
|
||||
# Valid stratum share! Update client stats
|
||||
if addr and addr in self.clients:
|
||||
current_time = time.time()
|
||||
self.clients[addr]['share_count'] = self.clients[addr].get('share_count', 0) + 1
|
||||
self.clients[addr]['last_share_time'] = time.time()
|
||||
self.clients[addr]['last_share_time'] = current_time
|
||||
|
||||
# Calculate hashrate from this share
|
||||
# Hashrate = difficulty * 2^32 / time_to_find_share
|
||||
client_difficulty = self.clients[addr].get('stratum_difficulty', 0.001)
|
||||
last_share_time = self.clients[addr].get('last_share_time', current_time - 60)
|
||||
time_since_last = max(1, current_time - last_share_time) # Avoid division by zero
|
||||
|
||||
# Calculate instantaneous hashrate for this share
|
||||
diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
|
||||
instant_hashrate = (client_difficulty * (2**32)) / time_since_last
|
||||
|
||||
# Store hashrate sample (keep last 10 samples)
|
||||
if 'hashrate_samples' not in self.clients[addr]:
|
||||
self.clients[addr]['hashrate_samples'] = []
|
||||
self.clients[addr]['hashrate_samples'].append((current_time, instant_hashrate))
|
||||
# Keep only last 10 samples
|
||||
if len(self.clients[addr]['hashrate_samples']) > 10:
|
||||
self.clients[addr]['hashrate_samples'] = self.clients[addr]['hashrate_samples'][-10:]
|
||||
|
||||
# Calculate average hashrate from recent samples
|
||||
if self.clients[addr]['hashrate_samples']:
|
||||
total_hashrate = sum(hr for _, hr in self.clients[addr]['hashrate_samples'])
|
||||
self.clients[addr]['estimated_hashrate'] = total_hashrate / len(self.clients[addr]['hashrate_samples'])
|
||||
|
||||
print(f" ⛏️ Miner {addr}: {self.clients[addr]['estimated_hashrate']:.0f} H/s (avg of {len(self.clients[addr]['hashrate_samples'])} samples)")
|
||||
|
||||
# Update global stats
|
||||
self.stats['total_shares'] += 1
|
||||
@@ -605,6 +653,9 @@ class RinCoinStratumProxy:
|
||||
|
||||
# Check if we should adjust difficulty
|
||||
self.adjust_client_difficulty(addr)
|
||||
|
||||
# Global difficulty adjustment based on share rate
|
||||
self.adjust_global_difficulty_if_needed()
|
||||
|
||||
# Only submit if it meets network difficulty in normal mode
|
||||
should_submit = meets_network_difficulty
|
||||
@@ -727,6 +778,8 @@ class RinCoinStratumProxy:
|
||||
self.clients[addr]['last_share_time'] = time.time()
|
||||
self.clients[addr]['share_count'] = 0
|
||||
self.clients[addr]['connect_time'] = time.time()
|
||||
self.clients[addr]['hashrate_samples'] = [] # Store recent hashrate measurements
|
||||
self.clients[addr]['estimated_hashrate'] = 0 # Current estimated hashrate
|
||||
|
||||
self.send_stratum_notification(client, "mining.set_difficulty", [initial_difficulty])
|
||||
print(f" 🎯 Set initial difficulty {initial_difficulty:.6f} for {addr}")
|
||||
|
Reference in New Issue
Block a user