Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 136 additions & 1 deletion miners/clawrtc/pow_miners.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,22 @@
"display": "Monero (RandomX)",
"algo": "randomx",
"node_ports": [18081, 18082],
"process_names": ["xmrig", "monerod", "p2pool", "xmr-stak"],
"process_names": [
"xmrig", "xmrig-notls", "xmrig-cuda", "xmrig-amd",
"monerod", "p2pool", "xmr-stak", "xmr-stak-cpu",
],
"node_info_path": "/json_rpc",
"pool_api_templates": {
"p2pool": "http://localhost:18083/local/stats",
"herominers": "https://monero.herominers.com/api/stats_address?address={address}",
"nanopool": "https://api.nanopool.org/v1/xmr/user/{address}",
"supportxmr": "https://api.supportxmr.com/api/accounts/{address}",
"moneroocean": "https://moneroocean.stream/api/stats?address={address}",
},
"miner_commands": {
"xmrig": ["xmrig", "-o", "{pool}", "-u", "{wallet}", "-p", "x", "--donate-level", "1"],
"xmrig-p2pool": ["xmrig", "-o", "localhost:3333", "-u", "{wallet}", "-p", "x"],
"monerod": ["monerod", "--start-mining", "{wallet}", "--mine-local", "--threads", "0"],
},
},
"zephyr": {
Expand Down Expand Up @@ -547,6 +557,131 @@ def _verify_pool_account(
return None


# ============================================================
# Subprocess Launch (Managed Mining)
# ============================================================

def launch_miner_subprocess(
chain: str,
wallet: str,
pool_url: Optional[str] = None,
miner_name: Optional[str] = None,
dry_run: bool = False,
) -> Tuple[bool, Optional[subprocess.Popen], str]:
"""Launch a PoW miner as a managed subprocess.

Args:
chain: Chain name (warthog, ergo, monero, etc.)
wallet: Wallet address for mining
pool_url: Pool stratum URL (e.g., stratum+tcp://pool.woolypooly.com:3140)
miner_name: Specific miner to use (bzminer, janusminer, xmrig, etc.)
dry_run: If True, don't actually launch, just return command

Returns:
Tuple of (success, process_or_None, message)
"""
if chain not in KNOWN_MINERS:
return False, None, f"Unknown chain: {chain}"

info = KNOWN_MINERS[chain]
miner_commands = info.get("miner_commands", {})

if not miner_commands:
return False, None, f"No miner commands configured for {chain}"

# Auto-detect miner if not specified
if not miner_name:
# Check which miners are available
for name in miner_commands.keys():
if _check_command_exists(name):
miner_name = name
break

if not miner_name or miner_name not in miner_commands:
available = list(miner_commands.keys())
return False, None, f"No available miner found for {chain}. Available: {available}"

# Build command
cmd_template = miner_commands[miner_name]
cmd = []
for arg in cmd_template:
if arg == "{wallet}":
cmd.append(wallet)
elif arg == "{pool}":
cmd.append(pool_url or "")
else:
cmd.append(arg)

if dry_run:
return True, None, f"Would execute: {' '.join(cmd)}"

# Launch the miner
try:
# Check if miner is already running
running_procs = _get_running_processes()
for proc_name in info["process_names"]:
if proc_name.lower() in running_procs:
return False, None, f"Miner {proc_name} already running"

# Start the miner
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=os.setsid if platform.system() != "Windows" else None,
)
return True, proc, f"Launched {miner_name} for {chain} (PID: {proc.pid})"
except FileNotFoundError:
return False, None, f"Miner executable not found: {miner_name}"
except Exception as e:
return False, None, f"Failed to launch miner: {e}"


def _check_command_exists(cmd_name: str) -> bool:
"""Check if a command exists in PATH."""
return subprocess.call(
["which", cmd_name] if platform.system() != "Windows" else ["where", cmd_name],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
) == 0


def stop_miner_subprocess(chain: str) -> Tuple[bool, str]:
"""Stop a running miner for the specified chain.

Args:
chain: Chain name (warthog, ergo, monero, etc.)

Returns:
Tuple of (success, message)
"""
if chain not in KNOWN_MINERS:
return False, f"Unknown chain: {chain}"

info = KNOWN_MINERS[chain]
running_procs = _get_running_processes()

stopped = []
for proc_name in info["process_names"]:
if proc_name.lower() in running_procs:
try:
# Try to find and kill the process
result = subprocess.run(
["pkill", "-f", proc_name],
capture_output=True,
text=True,
timeout=5,
)
stopped.append(proc_name)
except Exception as e:
return False, f"Failed to stop {proc_name}: {e}"

if stopped:
return True, f"Stopped miners: {', '.join(stopped)}"
else:
return False, f"No running miners found for {chain}"


# ============================================================
# CLI Display Helpers
# ============================================================
Expand Down
Loading
Loading