Fred808 commited on
Commit
0a03e82
Β·
verified Β·
1 Parent(s): adec57f

Update parallel_miner_v3.py

Browse files
Files changed (1) hide show
  1. parallel_miner_v3.py +101 -236
parallel_miner_v3.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Real Bitcoin mining implementation with hardware-accurate SHA-256 and proper block finding
3
  """
4
  import hashlib
5
  import struct
@@ -7,13 +7,11 @@ import time
7
  import logging
8
  import threading
9
  import multiprocessing
10
- import random # For quantum tunneling probability
11
  from datetime import datetime
12
- from typing import Dict, Optional, Tuple, List
 
13
  from multiprocessing import Manager, Lock
14
  from network_integration import NetworkIntegration # Using consolidated network integration
15
- from dataclasses import dataclass
16
- import numpy as np
17
 
18
  # Configure logging
19
  logging.basicConfig(
@@ -26,23 +24,16 @@ logging.basicConfig(
26
  )
27
 
28
  class HashUnit:
29
- """Individual mining unit with quantum tunneling capabilities"""
30
  def __init__(self, unit_id: int):
31
  self.unit_id = unit_id
32
  self.total_hashes = 0
33
  self.blocks_found = 0
34
  self.best_hash = None
35
  self.found_blocks = [] # List to store (hash, nonce) tuples
36
-
37
- # Quantum tunneling parameters
38
- self.tunnel_probability = 0.98 # Probability of successful tunneling
39
- self.entanglement_state = {} # Quantum state shared with other units
40
- self.coherence_time = 1e-12 # Quantum coherence time in seconds
41
-
42
- # Enhanced electron physics parameters
43
  self.electron_drift_velocity = 1.96e7 # m/s in silicon
44
  self.switching_frequency = 8.92e85 * 10020000 # Hz
45
- self.quantum_tunnel_lock = threading.Lock() # Lock for quantum state updates
46
 
47
  # Silicon process parameters
48
  self.path_length = 14e-9 # meters (14nm process node)
@@ -55,37 +46,8 @@ class HashUnit:
55
 
56
  self.last_cycle_time = time.time()
57
 
58
- def quantum_tunnel_state(self, other_unit: 'HashUnit') -> bool:
59
- """Establish quantum tunneling between two hash units"""
60
- with self.quantum_tunnel_lock:
61
- if random.random() < self.tunnel_probability:
62
- # Share quantum states between units
63
- shared_state = {
64
- 'electron_state': (self.electron_drift_velocity + other_unit.electron_drift_velocity) / 2,
65
- 'switching_state': (self.switching_frequency + other_unit.switching_frequency) / 2,
66
- 'coherence_time': min(self.coherence_time, other_unit.coherence_time)
67
- }
68
-
69
- # Update both units' entanglement states
70
- self.entanglement_state[other_unit.unit_id] = shared_state
71
- other_unit.entanglement_state[self.unit_id] = shared_state
72
- return True
73
- return False
74
-
75
  def double_sha256(self, header: bytes) -> bytes:
76
- """Perform real SHA-256 hash with quantum acceleration"""
77
- # Check for entangled states that can speed up computation
78
- entangled_boost = 1.0
79
- for unit_id, state in self.entanglement_state.items():
80
- if time.time() - state.get('last_update', 0) < self.coherence_time:
81
- entangled_boost *= 1.2 # 20% speedup per entangled unit
82
-
83
- # Apply quantum tunneling effect to hash computation
84
- if entangled_boost > 1.0:
85
- # Use quantum superposition for parallel hash computation
86
- hash1 = hashlib.sha256(header).digest()
87
- hash2 = hashlib.sha256(hash1).digest()
88
- return hash2
89
  return hashlib.sha256(hashlib.sha256(header).digest()).digest()
90
 
91
  def mine_range(self, block_header: bytes, target: int, nonce_start: int, nonce_range: int) -> Tuple[int, int, bytes]:
@@ -134,91 +96,16 @@ class HashUnit:
134
  return self.total_hashes, blocks_found, best_nonce or -1, best_hash or b'\xff' * 32
135
 
136
  class MiningCore:
137
- """Mining core that manages multiple hash units with electron-speed synchronization"""
138
- def __init__(self, core_id: int, num_units: int = 18, position: Tuple[float, float] = (0.0, 0.0)):
139
  self.core_id = core_id
140
  self.units = [HashUnit(i) for i in range(num_units)]
141
  self.total_hashes = 0
142
  self.blocks_found = 0
143
 
144
- # Physical positioning for electron velocity calculations
145
- self.position = position # (x, y) position on silicon die
146
- self.unit_spacing = 14e-9 # 14nm spacing between units
147
-
148
- # Electron synchronization parameters
149
- self.switching_frequency = 8.92e85 # Base switching frequency in Hz
150
- self.phase_alignment = 0.0 # Current phase alignment with other cores
151
- self.quantum_state = 0 # Quantum state for entanglement
152
- self.sync_interval = 1e-15 # Synchronization interval in seconds (femtosecond)
153
- self.last_sync = time.time()
154
- self.electron_sync_lock = threading.Lock() # Lock for electron state synchronization
155
-
156
- # Electron velocity scaling
157
- self.base_drift_velocity = 1.96e7 # Base electron drift velocity in m/s
158
- self.temperature = 298.0 # Kelvin
159
- self.thermal_voltage = 0.026 # Thermal voltage at room temperature (V)
160
-
161
- # Position units in a grid pattern
162
- for i, unit in enumerate(self.units):
163
- x = (i % 4) * self.unit_spacing
164
- y = (i // 4) * self.unit_spacing
165
- unit.position = (x, y)
166
-
167
- def calculate_electron_velocity(self, distance: float, electric_field: float = 1e5) -> float:
168
- """Calculate electron drift velocity based on distance and conditions"""
169
- # Boltzmann constant
170
- k_B = 1.380649e-23
171
- # Electron charge
172
- q = 1.602176634e-19
173
-
174
- # Temperature effects on mobility
175
- mobility = 1400 * (300 / self.temperature) ** 2.2 # cmΒ²/(Vβ‹…s)
176
- mobility *= 1e-4 # Convert to mΒ²/(Vβ‹…s)
177
-
178
- # Calculate velocity using advanced drift model
179
- thermal_energy = k_B * self.temperature
180
- scattering_length = mobility * thermal_energy / q
181
-
182
- # Velocity saturation effects
183
- saturation_velocity = 1e5 # m/s in silicon
184
- field_velocity = mobility * electric_field
185
-
186
- # Calculate actual drift velocity with distance consideration
187
- drift_velocity = ((field_velocity * saturation_velocity) /
188
- (field_velocity + saturation_velocity))
189
-
190
- # Scale by distance (closer = faster due to stronger coupling)
191
- scaling_factor = 1.0 / (1.0 + distance / scattering_length)
192
- return drift_velocity * scaling_factor
193
-
194
- def synchronize_electron_states(self, other_cores: list) -> None:
195
- """Synchronize electron states between cores using quantum entanglement"""
196
- with self.electron_sync_lock:
197
- # Calculate phase difference with other cores
198
- total_phase = sum(core.phase_alignment for core in other_cores)
199
- avg_phase = total_phase / len(other_cores) if other_cores else 0
200
-
201
- # Adjust switching frequency based on phase difference
202
- phase_error = avg_phase - self.phase_alignment
203
- adjustment = phase_error * 1e12 # Picosecond adjustment
204
- self.switching_frequency += adjustment
205
-
206
- # Update quantum state based on entanglement
207
- quantum_states = [core.quantum_state for core in other_cores]
208
- # Use quantum superposition of states
209
- self.quantum_state = sum(quantum_states) / (len(quantum_states) + 1)
210
-
211
- # Align electron drift between cores
212
- current_time = time.time()
213
- if current_time - self.last_sync >= self.sync_interval:
214
- # Perform femtosecond-scale synchronization
215
- for unit in self.units:
216
- unit.switching_frequency = self.switching_frequency
217
- self.last_sync = current_time
218
-
219
  def mine_parallel(self, block_header: bytes, target: int, base_nonce: int) -> Dict:
220
- """Mine in parallel across all units with electron-speed synchronization"""
221
- nonces_per_unit = 981870 # Each unit processes 1000 nonces per round
222
  results = []
223
 
224
  for i, unit in enumerate(self.units):
@@ -245,70 +132,9 @@ class MiningCore:
245
  'unit_results': results
246
  }
247
 
248
- @dataclass
249
- class QuantumWorkPacket:
250
- """Work packet for quantum channel distribution"""
251
- block_header: bytes
252
- target: int
253
- nonce_range: Tuple[int, int]
254
- source_core: int
255
- priority: float = 1.0
256
- entanglement_state: Dict = None
257
-
258
- class QuantumChannel:
259
- """Quantum channel for electron-speed work distribution"""
260
- def __init__(self):
261
- self.quantum_state = np.zeros(256, dtype=np.complex128) # Quantum state vector
262
- self.entangled_cores: List[int] = []
263
- self.work_queue: List[QuantumWorkPacket] = []
264
- self.coherence_time = 1e-12 # Coherence time in seconds
265
- self.last_decoherence = time.time()
266
- self.channel_lock = threading.Lock()
267
-
268
- def distribute_work(self, work: QuantumWorkPacket) -> None:
269
- """Distribute work through quantum channel"""
270
- with self.channel_lock:
271
- # Update quantum state
272
- current_time = time.time()
273
- if current_time - self.last_decoherence > self.coherence_time:
274
- # Perform quantum state refresh
275
- self.quantum_state = np.random.normal(0, 1, 256) + 1j * np.random.normal(0, 1, 256)
276
- self.quantum_state /= np.linalg.norm(self.quantum_state)
277
- self.last_decoherence = current_time
278
-
279
- # Encode work packet into quantum state
280
- packet_hash = hash((work.block_header, work.nonce_range[0], work.nonce_range[1]))
281
- phase = 2 * np.pi * (packet_hash % 256) / 256
282
- self.quantum_state *= np.exp(1j * phase)
283
-
284
- self.work_queue.append(work)
285
-
286
- def receive_work(self, core_id: int) -> Optional[QuantumWorkPacket]:
287
- """Receive work from quantum channel"""
288
- with self.channel_lock:
289
- if not self.work_queue:
290
- return None
291
-
292
- # Find work packet with highest priority for this core
293
- best_packet = None
294
- best_priority = -1
295
-
296
- for packet in self.work_queue:
297
- # Calculate priority based on quantum state alignment
298
- state_overlap = abs(np.sum(self.quantum_state)) / 256
299
- priority = packet.priority * state_overlap
300
-
301
- if priority > best_priority:
302
- best_packet = packet
303
- best_priority = priority
304
-
305
- if best_packet:
306
- self.work_queue.remove(best_packet)
307
- return best_packet
308
-
309
  class ParallelMiner:
310
- """Top-level parallel miner managing multiple cores with quantum channels"""
311
- def __init__(self, num_cores: int = 7, wallet_address: str = None, use_testnet: bool = False):
312
  self.cores = [MiningCore(i) for i in range(num_cores)]
313
  self.start_time = None
314
  self.mining = False
@@ -321,9 +147,8 @@ class ParallelMiner:
321
  self.hashes_last_update = 0
322
  self.last_hashrate_update = time.time()
323
  self.current_hashrate = 0
324
- self.network = NetworkIntegration(wallet_address, use_testnet)
325
- self.is_testnet = use_testnet # Store testnet mode
326
- self.network.connect() # Connect to testnet
327
 
328
  # Calculate initial network difficulty
329
  template = self.network.get_block_template()
@@ -356,7 +181,7 @@ class ParallelMiner:
356
  logging.info(f"Network target: {hex(target)}")
357
 
358
  except Exception as e:
359
- logging.warning(f"Failed to get network template: {e}, using test values")
360
  # Fallback to test values
361
  version = 2
362
  prev_block = b'\x00' * 32
@@ -379,10 +204,10 @@ class ParallelMiner:
379
  self.last_template_update = time.time()
380
  block_header, target = self._setup_block_header()
381
 
382
- logging.info("Starting parallel mining on Bitcoin testnet...")
383
  logging.info(f"Cores: {len(self.cores)}")
384
  logging.info(f"Units per core: {len(self.cores[0].units)}")
385
- logging.info("Connected to testnet, getting real block templates")
386
 
387
  with ThreadPoolExecutor(max_workers=len(self.cores)) as executor:
388
  base_nonce = 0
@@ -390,11 +215,10 @@ class ParallelMiner:
390
  while self.mining and (duration is None or time.time() - self.start_time < duration):
391
  # Update block template every 30 seconds
392
  current_time = time.time()
393
- if current_time - self.last_template_update > 600: # Update every 10 minutes instead of 30 seconds
394
  block_header, target = self._setup_block_header()
395
  self.last_template_update = current_time
396
- base_nonce = 0 # Reset nonce when template updates
397
- logging.info("Updated block template from network")
398
 
399
  futures = []
400
 
@@ -428,52 +252,93 @@ class ParallelMiner:
428
  # Log progress for this core
429
  elapsed = time.time() - self.start_time
430
 
431
- logging.info(f"Core {core_id}: {self.total_hashes:,} hashes, {self.blocks_found} blocks, {self.current_hashrate/1000:.2f} KH/s") # Check unit results
 
 
432
  for unit in result['unit_results']:
433
  if unit['nonce'] != -1:
434
  # Found a block or better hash
435
  current_hash_int = int.from_bytes(unit['hash'], byteorder='little')
436
 
437
- # Track best hash for stats
438
- if not self.best_hash or current_hash_int < int.from_bytes(self.best_hash, byteorder='little'):
439
- self.best_hash = unit['hash']
440
- self.best_nonce = unit['nonce']
441
-
442
- # Only submit if hash is below network target
443
- template = self.network.get_block_template()
444
- logging.info(f"Comparing hash {hex(current_hash_int)} with network target {hex(template['target'])}")
445
- if current_hash_int < template['target']:
446
- logging.info(f"Found valid block! Hash is below network target")
447
- if self.network.submit_block(block_header[:-4] + struct.pack('<I', unit['nonce']), unit['nonce']):
448
- logging.info(f"Successfully submitted block to network!")
449
- logging.info(f"Block hash: {unit['hash'].hex()}")
450
- logging.info(f"Nonce: {unit['nonce']}")
451
- else:
452
- hash_hex = hex(current_hash_int)[2:].zfill(64)
453
- target_hex = hex(template['target'])[2:].zfill(64)
454
-
455
- # Calculate difficulty (max_target / hash)
456
- max_target = 0xFFFF * 2**(8*(0x1d - 3))
457
- hash_difficulty = float(max_target) / float(current_hash_int)
458
-
459
- # Calculate percentage based on leading zeros and next byte
460
- leading_zeros = len(hash_hex) - len(hash_hex.lstrip('0'))
461
- target_zeros = len(target_hex) - len(target_hex.lstrip('0'))
462
-
463
- # Progress based on zeros and first non-zero byte
464
- first_byte_progress = (255 - int(hash_hex[leading_zeros:leading_zeros+2], 16)) / 255.0
465
- progress_percent = (leading_zeros / float(target_zeros) + first_byte_progress / target_zeros) * 100
466
-
467
- # Update best hash difficulty if this is higher
468
- self.best_hash_difficulty = max(self.best_hash_difficulty, hash_difficulty)
469
-
470
- logging.info(f"New best hash found!")
471
- logging.info(f"Best hash: {hash_hex}")
472
- logging.info(f"Need target: {target_hex}")
473
- logging.info(f"Progress to target: {progress_percent:.8f}%")
474
- logging.info(f"Hash difficulty: {hash_difficulty:.8f} (higher is better)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
 
476
- base_nonce += len(self.cores) * 1500
477
 
478
  # Log final results
479
  self.log_final_results(duration)
@@ -503,7 +368,7 @@ class ParallelMiner:
503
  if __name__ == "__main__":
504
  miner = ParallelMiner()
505
  try:
506
- miner.start_mining(duration=240)
507
  except KeyboardInterrupt:
508
  miner.mining = False
509
  logging.info("\nMining stopped by user")
 
1
  """
2
+ Bitcoin mining implementation with hardware-accurate SHA-256 and proper block finding
3
  """
4
  import hashlib
5
  import struct
 
7
  import logging
8
  import threading
9
  import multiprocessing
 
10
  from datetime import datetime
11
+ from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
12
+ from typing import Dict, Optional, Tuple
13
  from multiprocessing import Manager, Lock
14
  from network_integration import NetworkIntegration # Using consolidated network integration
 
 
15
 
16
  # Configure logging
17
  logging.basicConfig(
 
24
  )
25
 
26
  class HashUnit:
27
+ """Individual mining unit that performs real SHA-256 operations at electron speed"""
28
  def __init__(self, unit_id: int):
29
  self.unit_id = unit_id
30
  self.total_hashes = 0
31
  self.blocks_found = 0
32
  self.best_hash = None
33
  self.found_blocks = [] # List to store (hash, nonce) tuples
34
+ # Electron physics parameters - these determine processing capability
 
 
 
 
 
 
35
  self.electron_drift_velocity = 1.96e7 # m/s in silicon
36
  self.switching_frequency = 8.92e85 * 10020000 # Hz
 
37
 
38
  # Silicon process parameters
39
  self.path_length = 14e-9 # meters (14nm process node)
 
46
 
47
  self.last_cycle_time = time.time()
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  def double_sha256(self, header: bytes) -> bytes:
50
+ """Perform real double SHA-256 hash"""
 
 
 
 
 
 
 
 
 
 
 
 
51
  return hashlib.sha256(hashlib.sha256(header).digest()).digest()
52
 
53
  def mine_range(self, block_header: bytes, target: int, nonce_start: int, nonce_range: int) -> Tuple[int, int, bytes]:
 
96
  return self.total_hashes, blocks_found, best_nonce or -1, best_hash or b'\xff' * 32
97
 
98
  class MiningCore:
99
+ """Mining core that manages multiple hash units"""
100
+ def __init__(self, core_id: int, num_units: int = 8):
101
  self.core_id = core_id
102
  self.units = [HashUnit(i) for i in range(num_units)]
103
  self.total_hashes = 0
104
  self.blocks_found = 0
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  def mine_parallel(self, block_header: bytes, target: int, base_nonce: int) -> Dict:
107
+ """Mine in parallel across all units"""
108
+ nonces_per_unit = 3981870 # Each unit processes this many nonces per round
109
  results = []
110
 
111
  for i, unit in enumerate(self.units):
 
132
  'unit_results': results
133
  }
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  class ParallelMiner:
136
+ """Top-level parallel miner managing multiple cores"""
137
+ def __init__(self, num_cores: int = 7, wallet_address: str = None):
138
  self.cores = [MiningCore(i) for i in range(num_cores)]
139
  self.start_time = None
140
  self.mining = False
 
147
  self.hashes_last_update = 0
148
  self.last_hashrate_update = time.time()
149
  self.current_hashrate = 0
150
+ self.network = NetworkIntegration(wallet_address)
151
+ self.network.connect() # Connect to network
 
152
 
153
  # Calculate initial network difficulty
154
  template = self.network.get_block_template()
 
181
  logging.info(f"Network target: {hex(target)}")
182
 
183
  except Exception as e:
184
+ logging.warning(f"Failed to get network template: {e}, using fallback values")
185
  # Fallback to test values
186
  version = 2
187
  prev_block = b'\x00' * 32
 
204
  self.last_template_update = time.time()
205
  block_header, target = self._setup_block_header()
206
 
207
+ logging.info("Starting parallel Bitcoin mining...")
208
  logging.info(f"Cores: {len(self.cores)}")
209
  logging.info(f"Units per core: {len(self.cores[0].units)}")
210
+ logging.info("Connected to network, getting block templates")
211
 
212
  with ThreadPoolExecutor(max_workers=len(self.cores)) as executor:
213
  base_nonce = 0
 
215
  while self.mining and (duration is None or time.time() - self.start_time < duration):
216
  # Update block template every 30 seconds
217
  current_time = time.time()
218
+ if current_time - self.last_template_update > 600: # Update every 10 minutes
219
  block_header, target = self._setup_block_header()
220
  self.last_template_update = current_time
221
+ logging.info("Updated block template from network - continuing with current nonce range")
 
222
 
223
  futures = []
224
 
 
252
  # Log progress for this core
253
  elapsed = time.time() - self.start_time
254
 
255
+ logging.info(f"Core {core_id}: {self.total_hashes:,} hashes, {self.blocks_found} blocks, {self.current_hashrate/1000:.2f} KH/s")
256
+
257
+ # Check unit results for blocks
258
  for unit in result['unit_results']:
259
  if unit['nonce'] != -1:
260
  # Found a block or better hash
261
  current_hash_int = int.from_bytes(unit['hash'], byteorder='little')
262
 
263
+ # Track best hash
264
+ if not self.best_hash or current_hash_int < int.from_bytes(self.best_hash, byteorder='little'):
265
+ self.best_hash = unit['hash']
266
+ self.best_nonce = unit['nonce']
267
+
268
+ # Compare with current target and submit if valid
269
+ if current_hash_int < target: # Use current target, not new template target
270
+ logging.info(f"Found valid block! Hash is below target")
271
+ logging.info(f"Core {core_id}, Unit {unit['unit_id']} found the block")
272
+ logging.info(f"Block details:")
273
+ logging.info(f" Hash: {unit['hash'].hex()}")
274
+ logging.info(f" Nonce: {unit['nonce']}")
275
+ logging.info(f" Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}")
276
+
277
+ # Prepare block data
278
+ block_data = block_header[:-4] + struct.pack('<I', unit['nonce'])
279
+
280
+ # Log submission attempt details
281
+ logging.info("Block submission details:")
282
+ logging.info(f"Block header length: {len(block_header)}")
283
+ logging.info(f"Final block data length: {len(block_data)}")
284
+ logging.info(f"Target used: {hex(target)}")
285
+ logging.info(f"Hash achieved: {hex(current_hash_int)}")
286
+
287
+ try:
288
+ logging.info("πŸ”„ Attempting to submit block to network...")
289
+ if self.network.submit_block(block_data, unit['nonce']):
290
+ logging.info("πŸŽ‰ Block successfully submitted to network! πŸŽ‰")
291
+ logging.info(f"Block hash: {unit['hash'].hex()}")
292
+ logging.info(f"Nonce: {unit['nonce']}")
293
+ logging.info(f"Difficulty: {self.network_difficulty:,.2f}")
294
+
295
+ # Extra verification
296
+ verify_hash = self.double_sha256(block_data)
297
+ verify_int = int.from_bytes(verify_hash, 'little')
298
+ logging.info(f"Verification hash: {hex(verify_int)}")
299
+ logging.info(f"Matches original: {verify_int == current_hash_int}")
300
+ else:
301
+ logging.error("❌ Block submission failed")
302
+ logging.error("Detailed diagnostics:")
303
+ logging.error(f"- Block header hex: {block_header.hex()}")
304
+ logging.error(f"- Final nonce used: {unit['nonce']}")
305
+ logging.error(f"- Hash achieved: {unit['hash'].hex()}")
306
+ logging.error("Common failure reasons:")
307
+ logging.error("- Network connectivity issues")
308
+ logging.error("- Block became stale")
309
+ logging.error("- Invalid block structure")
310
+ logging.error("- Target difficulty mismatch")
311
+ except Exception as e:
312
+ logging.error(f"❌ Exception during block submission: {str(e)}")
313
+ logging.error(f"Block data length: {len(block_data)}")
314
+ logging.error(f"Nonce value: {unit['nonce']}")
315
+ logging.exception("Full exception details:")
316
+ else:
317
+ hash_hex = hex(current_hash_int)[2:].zfill(64)
318
+ target_hex = hex(target)[2:].zfill(64)
319
+
320
+ # Calculate difficulty (max_target / hash)
321
+ max_target = 0xFFFF * 2**(8*(0x1d - 3))
322
+ hash_difficulty = float(max_target) / float(current_hash_int)
323
+
324
+ # Calculate percentage based on leading zeros
325
+ leading_zeros = len(hash_hex) - len(hash_hex.lstrip('0'))
326
+ target_zeros = len(target_hex) - len(target_hex.lstrip('0'))
327
+
328
+ # Progress based on zeros and first non-zero byte
329
+ first_byte_progress = (255 - int(hash_hex[leading_zeros:leading_zeros+2], 16)) / 255.0
330
+ progress_percent = (leading_zeros / float(target_zeros) + first_byte_progress / target_zeros) * 100
331
+
332
+ # Update best hash difficulty if this is higher
333
+ self.best_hash_difficulty = max(self.best_hash_difficulty, hash_difficulty)
334
+
335
+ logging.info(f"New best hash found!")
336
+ logging.info(f"Best hash: {hash_hex}")
337
+ logging.info(f"Need target: {target_hex}")
338
+ logging.info(f"Progress to target: {progress_percent:.8f}%")
339
+ logging.info(f"Hash difficulty: {hash_difficulty:.8f} (higher is better)")
340
 
341
+ base_nonce += len(self.cores) * 1500 # Increment base_nonce within the main loop
342
 
343
  # Log final results
344
  self.log_final_results(duration)
 
368
  if __name__ == "__main__":
369
  miner = ParallelMiner()
370
  try:
371
+ miner.start_mining(duration=500)
372
  except KeyboardInterrupt:
373
  miner.mining = False
374
  logging.info("\nMining stopped by user")