Fred808 commited on
Commit
dd42d5b
·
verified ·
1 Parent(s): b27b3cd

Update parallel_miner_v3.py

Browse files
Files changed (1) hide show
  1. parallel_miner_v3.py +81 -55
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
@@ -33,7 +33,7 @@ class HashUnit:
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 # Hz
37
 
38
  # Silicon process parameters
39
  self.path_length = 14e-9 # meters (14nm process node)
@@ -42,7 +42,7 @@ class HashUnit:
42
  # Operations possible per second based on electron movement and switching speed
43
  ops_per_second = 9.98e15
44
  # Scale to ops per cycle for our time slicing
45
- self.ops_per_cycle = 9.98e15 # Break into millisecond cycles
46
 
47
  self.last_cycle_time = time.time()
48
 
@@ -60,7 +60,7 @@ class HashUnit:
60
  # Calculate real operations based on electron transit and switching frequency
61
  time_delta = current_time - self.last_cycle_time
62
  # Get operations based on how many complete electron transits can occur
63
- electron_transits = 98.92e555
64
  # Factor in switching frequency to determine valid operations
65
  operations_this_cycle = int(min(
66
  electron_transits,
@@ -97,7 +97,7 @@ class HashUnit:
97
 
98
  class MiningCore:
99
  """Mining core that manages multiple hash units"""
100
- def __init__(self, core_id: int, num_units: int = 15):
101
  self.core_id = core_id
102
  self.units = [HashUnit(i) for i in range(num_units)]
103
  self.total_hashes = 0
@@ -105,7 +105,7 @@ class MiningCore:
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 = 201870 # Each unit processes 1000 nonces per round
109
  results = []
110
 
111
  for i, unit in enumerate(self.units):
@@ -134,7 +134,7 @@ class MiningCore:
134
 
135
  class ParallelMiner:
136
  """Top-level parallel miner managing multiple cores"""
137
- def __init__(self, num_cores: int = 5, wallet_address: str = None):
138
  self.cores = [MiningCore(i) for i in range(num_cores)]
139
  self.start_time = None
140
  self.mining = False
@@ -148,7 +148,7 @@ class ParallelMiner:
148
  self.last_hashrate_update = time.time()
149
  self.current_hashrate = 0
150
  self.network = NetworkIntegration(wallet_address)
151
- self.network.connect() # Connect to testnet
152
 
153
  # Calculate initial network difficulty
154
  template = self.network.get_block_template()
@@ -181,7 +181,7 @@ class ParallelMiner:
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 test values")
185
  # Fallback to test values
186
  version = 2
187
  prev_block = b'\x00' * 32
@@ -204,10 +204,10 @@ class ParallelMiner:
204
  self.last_template_update = time.time()
205
  block_header, target = self._setup_block_header()
206
 
207
- logging.info("Starting parallel mining on Bitcoin testnet...")
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 testnet, getting real block templates")
211
 
212
  with ThreadPoolExecutor(max_workers=len(self.cores)) as executor:
213
  base_nonce = 0
@@ -215,11 +215,10 @@ class ParallelMiner:
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 > 300: # Update every 5 minutes instead of 30 seconds
219
  block_header, target = self._setup_block_header()
220
  self.last_template_update = current_time
221
- base_nonce = 0 # Reset nonce when template updates
222
- logging.info("Updated block template from network")
223
 
224
  futures = []
225
 
@@ -253,51 +252,78 @@ class ParallelMiner:
253
  # Log progress for this core
254
  elapsed = time.time() - self.start_time
255
 
256
- logging.info(f"Core {core_id}: {self.total_hashes:,} hashes, {self.blocks_found} blocks, {self.current_hashrate/1000:.2f} KH/s") # Check unit results
 
 
257
  for unit in result['unit_results']:
258
  if unit['nonce'] != -1:
259
  # Found a block or better hash
260
  current_hash_int = int.from_bytes(unit['hash'], byteorder='little')
261
 
262
- # Track best hash for stats
263
- if not self.best_hash or current_hash_int < int.from_bytes(self.best_hash, byteorder='little'):
264
- self.best_hash = unit['hash']
265
- self.best_nonce = unit['nonce']
266
-
267
- # Only submit if hash is below network target
268
- template = self.network.get_block_template()
269
- if current_hash_int < template['target']:
270
- logging.info(f"Found valid block! Hash is below network target")
271
- if self.network.submit_block(block_header[:-4] + struct.pack('<I', unit['nonce']), unit['nonce']):
272
- logging.info(f"Successfully submitted block to network!")
273
- logging.info(f"Block hash: {unit['hash'].hex()}")
274
- logging.info(f"Nonce: {unit['nonce']}")
275
- else:
276
- hash_hex = hex(current_hash_int)[2:].zfill(64)
277
- target_hex = hex(template['target'])[2:].zfill(64)
278
-
279
- # Calculate difficulty (max_target / hash)
280
- max_target = 0xFFFF * 2**(8*(0x1d - 3))
281
- hash_difficulty = float(max_target) / float(current_hash_int)
282
-
283
- # Calculate percentage based on leading zeros and next byte
284
- leading_zeros = len(hash_hex) - len(hash_hex.lstrip('0'))
285
- target_zeros = len(target_hex) - len(target_hex.lstrip('0'))
286
-
287
- # Progress based on zeros and first non-zero byte
288
- first_byte_progress = (255 - int(hash_hex[leading_zeros:leading_zeros+2], 16)) / 255.0
289
- progress_percent = (leading_zeros / float(target_zeros) + first_byte_progress / target_zeros) * 100
290
-
291
- # Update best hash difficulty if this is higher
292
- self.best_hash_difficulty = max(self.best_hash_difficulty, hash_difficulty)
293
-
294
- logging.info(f"New best hash found!")
295
- logging.info(f"Best hash: {hash_hex}")
296
- logging.info(f"Need target: {target_hex}")
297
- logging.info(f"Progress to target: {progress_percent:.8f}%")
298
- logging.info(f"Hash difficulty: {hash_difficulty:.8f} (higher is better)")
299
-
300
- base_nonce += len(self.cores) * 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
  # Log final results
303
  self.log_final_results(duration)
@@ -327,7 +353,7 @@ class ParallelMiner:
327
  if __name__ == "__main__":
328
  miner = ParallelMiner()
329
  try:
330
- miner.start_mining(duration=440)
331
  except KeyboardInterrupt:
332
  miner.mining = False
333
  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
 
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)
 
42
  # Operations possible per second based on electron movement and switching speed
43
  ops_per_second = 9.98e15
44
  # Scale to ops per cycle for our time slicing
45
+ self.ops_per_cycle = int(ops_per_second / 1000) # Break into millisecond cycles
46
 
47
  self.last_cycle_time = time.time()
48
 
 
60
  # Calculate real operations based on electron transit and switching frequency
61
  time_delta = current_time - self.last_cycle_time
62
  # Get operations based on how many complete electron transits can occur
63
+ electron_transits = 98.92e955
64
  # Factor in switching frequency to determine valid operations
65
  operations_this_cycle = int(min(
66
  electron_transits,
 
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
 
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):
 
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
 
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
+ # Check if hash is below network target and submit immediately if it is
269
+ template = self.network.get_block_template()
270
+ logging.info(f"Checking hash against network target...")
271
+ logging.info(f"Current hash: {hex(current_hash_int)}")
272
+ logging.info(f"Network target: {hex(template['target'])}")
273
+
274
+ if current_hash_int < template['target']:
275
+ logging.info(f"Found valid block! Hash is below network target")
276
+ logging.info(f"Core {core_id}, Unit {unit['unit_id']} found the block")
277
+ logging.info(f"Block details:")
278
+ logging.info(f" Hash: {unit['hash'].hex()}")
279
+ logging.info(f" Nonce: {unit['nonce']}")
280
+ logging.info(f" Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}")
281
+
282
+ try:
283
+ block_data = block_header[:-4] + struct.pack('<I', unit['nonce'])
284
+ logging.info("Attempting to submit block to network...")
285
+ if self.network.submit_block(block_data, unit['nonce']):
286
+ logging.info("🎉 Block successfully submitted to network! 🎉")
287
+ logging.info(f"Block hash: {unit['hash'].hex()}")
288
+ logging.info(f"Nonce: {unit['nonce']}")
289
+ logging.info(f"Difficulty: {self.network_difficulty:,.2f}")
290
+ else:
291
+ logging.error("❌ Block submission failed")
292
+ logging.error("This could be due to:")
293
+ logging.error("- Network connectivity issues")
294
+ logging.error("- Block became stale")
295
+ logging.error("- Invalid block structure")
296
+ except Exception as e:
297
+ logging.error(f" Exception during block submission: {str(e)}")
298
+ logging.error(f"Block data length: {len(block_data)}")
299
+ logging.error(f"Nonce value: {unit['nonce']}")
300
+ logging.exception("Full exception details:")
301
+ else:
302
+ hash_hex = hex(current_hash_int)[2:].zfill(64)
303
+ target_hex = hex(template['target'])[2:].zfill(64)
304
+
305
+ # Calculate difficulty (max_target / hash)
306
+ max_target = 0xFFFF * 2**(8*(0x1d - 3))
307
+ hash_difficulty = float(max_target) / float(current_hash_int)
308
+
309
+ # Calculate percentage based on leading zeros
310
+ leading_zeros = len(hash_hex) - len(hash_hex.lstrip('0'))
311
+ target_zeros = len(target_hex) - len(target_hex.lstrip('0'))
312
+
313
+ # Progress based on zeros and first non-zero byte
314
+ first_byte_progress = (255 - int(hash_hex[leading_zeros:leading_zeros+2], 16)) / 255.0
315
+ progress_percent = (leading_zeros / float(target_zeros) + first_byte_progress / target_zeros) * 100
316
+
317
+ # Update best hash difficulty if this is higher
318
+ self.best_hash_difficulty = max(self.best_hash_difficulty, hash_difficulty)
319
+
320
+ logging.info(f"New best hash found!")
321
+ logging.info(f"Best hash: {hash_hex}")
322
+ logging.info(f"Need target: {target_hex}")
323
+ logging.info(f"Progress to target: {progress_percent:.8f}%")
324
+ logging.info(f"Hash difficulty: {hash_difficulty:.8f} (higher is better)")
325
+
326
+ base_nonce += len(self.cores) * 1500
327
 
328
  # Log final results
329
  self.log_final_results(duration)
 
353
  if __name__ == "__main__":
354
  miner = ParallelMiner()
355
  try:
356
+ miner.start_mining(duration=500)
357
  except KeyboardInterrupt:
358
  miner.mining = False
359
  logging.info("\nMining stopped by user")