import hashlib, time, json, struct, urllib.request, secrets, random, os, sys, re # Single instance lock _LOCK_FILE = os.path.join(os.path.expanduser("~"), ".polm_miner.lock") try: _lock_fd = open(_LOCK_FILE, "w") if os.name == "nt": import msvcrt msvcrt.locking(_lock_fd.fileno(), msvcrt.LK_NBLCK, 1) else: import fcntl fcntl.flock(_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) except (IOError, OSError): print(" [!] PoLM Miner is already running. Only one instance allowed.") sys.exit(1) NODE_URL = "https://polm.com.br/api" MINER_URL = "https://raw.githubusercontent.com/proof-of-legacy/Proof-of-Legacy-Memory/main/polm_miner_cli.py" VERSION = "1.5.6" def check_update(): """Auto-update: checks GitHub for newer version and restarts if found""" try: import urllib.request, os, sys r = urllib.request.urlopen(MINER_URL + "?nocache=" + str(int(time.time())), timeout=5) new_code = r.read().decode() # Check version in remote file for line in new_code.splitlines(): if line.strip().startswith("VERSION"): remote_ver = line.split("=")[1].strip().strip('"').strip("'") if remote_ver != VERSION: print(f" [Update] New version {remote_ver} found! Updating...") this_file = os.path.abspath(__file__) open(this_file, "w", encoding="utf-8").write(new_code) print(f" [Update] Updated! Restarting...") os.execv(sys.executable, [sys.executable] + sys.argv) else: print(f" [OK] Version {VERSION} is up to date.") return except Exception as e: print(f" [Update] Could not check for updates: {e}") def detect_ram(): import platform, subprocess try: if platform.system() == "Windows": # Method 1: SMBIOSMemoryType try: out = subprocess.check_output( ["wmic","memorychip","get","SMBIOSMemoryType,Speed"], stderr=subprocess.PIPE, text=True, timeout=5, creationflags=0x08000000 ) # Parse line by line — first column is SMBIOSMemoryType lines = [l.strip() for l in out.splitlines() if l.strip() and not l.strip().startswith("S")] for line in lines: parts = line.split() if parts: try: smbios = int(parts[0]) if smbios == 34: return "DDR5" if smbios in [26,27,28,29,30]: return "DDR4" if smbios in [24,25]: return "DDR3" if smbios in [21,22]: return "DDR2" except ValueError: pass except Exception: pass # Method 2: Speed only try: out = subprocess.check_output( ["wmic","memorychip","get","Speed"], stderr=subprocess.PIPE, text=True, timeout=5, creationflags=0x08000000 ) speeds = [int(x) for x in out.split() if x.isdigit() and int(x) > 100] if speeds: avg = sum(speeds)/len(speeds) if avg >= 4800: return "DDR5" if avg >= 2133: return "DDR4" if avg >= 800: return "DDR3" return "DDR2" except Exception: pass elif platform.system() == "Linux": try: out = subprocess.check_output( ["sudo","dmidecode","-t","memory"], capture_output=True, text=True, timeout=5 ) for line in out.splitlines(): if "Type:" in line and "DDR" in line: for t in ["DDR5","DDR4","DDR3","DDR2"]: if t in line: return t except Exception: pass # Linux fallback: /sys try: import glob for path in glob.glob("/sys/bus/i2c/drivers/ee1004/*/eeprom"): data = open(path,"rb").read() if len(data) > 2: t = data[2] if t == 0x1e: return "DDR5" if t == 0x0c: return "DDR4" if t == 0x0b: return "DDR3" if t == 0x08: return "DDR2" except Exception: pass except Exception: pass return "DDR4" def detect_os(): import platform try: s = platform.system() if s == "Windows": v = platform.version() r = platform.release() return f"Windows {r} ({v[:10]})" elif s == "Linux": try: for line in open("/etc/os-release"): if line.startswith("PRETTY_NAME="): return line.split("=")[1].strip().strip('"')[:40] except: pass return f"Linux {platform.release()[:20]}" elif s == "Darwin": return f"macOS {platform.mac_ver()[0]}" return s except: return "unknown" def detect_cpu(): import platform, subprocess try: if platform.system() == "Windows": # Try registry first try: import winreg key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"HARDWARE\DESCRIPTION\System\CentralProcessor\0") name = winreg.QueryValueEx(key, "ProcessorNameString")[0].strip() if name: return name[:40] except Exception: pass # Fallback WMIC try: out = subprocess.check_output( ["wmic","cpu","get","name"], stderr=subprocess.PIPE, text=True, timeout=5, creationflags=0x08000000 ) lines = [l.strip() for l in out.splitlines() if l.strip() and l.strip() != "Name"] if lines: return lines[0][:40] except Exception: pass elif platform.system() == "Linux": with open("/proc/cpuinfo") as f: for line in f: if "model name" in line: return line.split(":")[1].strip()[:40] elif platform.system() == "Darwin": out = subprocess.check_output( ["sysctl","-n","machdep.cpu.brand_string"], capture_output=True, text=True, timeout=5 ) if out: return out.strip()[:40] except Exception: pass return "" def detect_ram_speed(): """Get RAM speed in MHz to determine DDR type""" import platform, subprocess try: if platform.system() == "Windows": out = subprocess.check_output( ["wmic","memorychip","get","Speed"], stderr=subprocess.PIPE, text=True, timeout=5, creationflags=0x08000000 ) speeds = [int(x) for x in out.split() if x.isdigit() and int(x) > 100] if speeds: return sum(speeds)//len(speeds) except: pass return 0 def measure_latency(buf, steps=5000): size = len(buf); idx = 0 t0 = time.perf_counter_ns() for _ in range(steps): idx = struct.unpack_from(' 0 else 0 ts = int(time.time()) header = (f"{height}|{prev_hash}|{ts}|{nonce}|{polm_addr}|" f"{RAM_TYPE}|1|{epoch}|{diff}|{lat:.4f}|{mem_proof}|" f"{score:.8f}|{reward}|") block_hash = hashlib.sha3_256(header.encode()).hexdigest() if block_hash.startswith("0" * diff): # Verify height is still current before submitting try: current = json.loads(urllib.request.urlopen(f"{NODE_URL}/getwork", timeout=3).read()) if int(current.get("height", height)) != height: print(f"\n Block found but chain moved — discarding") break except Exception: pass print(f"\n Block found! nonce={nonce} hash={block_hash[:16]}...") bd = { "height": height, "prev_hash": prev_hash, "timestamp": ts, "nonce": nonce, "miner_id": polm_addr, "ram_type": RAM_TYPE, "threads": 1, "epoch": epoch, "difficulty": diff, "latency_ns": lat, "mem_proof": mem_proof, "score": score, "reward": reward, "cpu_name": CPU_NAME, "os_name": OS_NAME, "tx_ids": [], "block_hash": block_hash } try: resp = submit_block(bd) if resp.get("accepted"): blocks += 1; earned += reward print(f" ACCEPTED! Blocks={blocks} Earned={earned} POLM") prev_hash = block_hash else: print(f" Rejected: {resp.get('reason','?')}") except Exception as e: print(f" Submit error: {e}") break nonce += 1 if nonce % 10000 == 0: print(f"\r nonce={nonce:,} lat={lat:.0f}ns diff={diff} ", end="", flush=True) except KeyboardInterrupt: print(f"\n Stopped. Blocks={blocks} Earned={earned} POLM") break except Exception as e: print(f" Error: {e}"); time.sleep(5)