diff --git a/MINE/rin/README.md b/MINE/rin/README.md index 6233b9f..e32da9a 100644 --- a/MINE/rin/README.md +++ b/MINE/rin/README.md @@ -19,7 +19,7 @@ cd /mnt/shared/DEV/repos/d-popov.com/scripts /mnt/shared/DEV/repos/d-popov.com/mines/rin/miner/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://eu.rplant.xyz:17148 -u bc1qjn4m6rmrveuxhk02a5qhe4r6kdcsvvt3vhdn9j -p c=BTC,mc=RIN,m=solo /mnt/shared/DEV/repos/d-popov.com/mines/rin/miner/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://eu.rplant.xyz:17148 -u rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q -p m=solo cpuminer-sse2 -a rinhash -o stratum+tcps://eu.rplant.xyz:17148 -u wallet -p m=solo - +??? rin1qvj0yyt9phvled9kxflju3p687a4s7kareglpk5 ??? ``` **Result**: 100% of block rewards go to your wallet diff --git a/MINE/rin/kill_stratum_proxy.sh b/MINE/rin/kill_stratum_proxy.sh index 136f5c6..cfba4f3 100644 --- a/MINE/rin/kill_stratum_proxy.sh +++ b/MINE/rin/kill_stratum_proxy.sh @@ -1,40 +1,40 @@ -#!/bin/bash +# #!/bin/bash -# Kill RinCoin Stratum Proxy processes +# # Kill RinCoin Stratum Proxy processes -echo "=== Killing RinCoin Stratum Proxy ===" -echo "" +# echo "=== Killing RinCoin Stratum Proxy ===" +# echo "" -# Find and kill Python processes running stratum_proxy.py -PIDS=$(ps aux | grep "stratum_proxy.py" | grep -v grep | awk '{print $2}') +# # Find and kill Python processes running stratum_proxy.py +# PIDS=$(ps aux | grep "stratum_proxy.py" | grep -v grep | awk '{print $2}') -if [ -n "$PIDS" ]; then - echo "Found Stratum Proxy processes: $PIDS" - echo "Killing processes..." - for pid in $PIDS; do - kill -9 "$pid" 2>/dev/null && echo "Killed PID: $pid" || echo "Failed to kill PID: $pid" - done -else - echo "No Stratum Proxy processes found" -fi +# if [ -n "$PIDS" ]; then +# echo "Found Stratum Proxy processes: $PIDS" +# echo "Killing processes..." +# for pid in $PIDS; do +# kill -9 "$pid" 2>/dev/null && echo "Killed PID: $pid" || echo "Failed to kill PID: $pid" +# done +# else +# echo "No Stratum Proxy processes found" +# fi -# Also kill any process using port 3333 -echo "" -echo "Checking port 3333..." -PORT_PIDS=$(sudo lsof -ti:3333 2>/dev/null) +# # Also kill any process using port 3333 +# echo "" +# echo "Checking port 3333..." +# PORT_PIDS=$(sudo lsof -ti:3333 2>/dev/null) -if [ -n "$PORT_PIDS" ]; then - echo "Found processes using port 3333: $PORT_PIDS" - echo "Killing processes..." - for pid in $PORT_PIDS; do - sudo kill -9 "$pid" 2>/dev/null && echo "Killed PID: $pid" || echo "Failed to kill PID: $pid" - done -else - echo "No processes using port 3333" -fi +# if [ -n "$PORT_PIDS" ]; then +# echo "Found processes using port 3333: $PORT_PIDS" +# echo "Killing processes..." +# for pid in $PORT_PIDS; do +# sudo kill -9 "$pid" 2>/dev/null && echo "Killed PID: $pid" || echo "Failed to kill PID: $pid" +# done +# else +# echo "No processes using port 3333" +# fi -echo "" -echo "โœ… Cleanup complete!" -echo "" -echo "Port 3333 status:" -netstat -tln | grep ":3333 " || echo "Port 3333 is free" +# echo "" +# echo "โœ… Cleanup complete!" +# echo "" +# echo "Port 3333 status:" +# netstat -tln | grep ":3333 " || echo "Port 3333 is free" diff --git a/MINE/rin/mining_log.txt b/MINE/rin/mining_log.txt index f0c0d3c..0d4d460 100644 --- a/MINE/rin/mining_log.txt +++ b/MINE/rin/mining_log.txt @@ -1 +1,2 @@ [2025-09-29 20:11:03] ๐Ÿ’ฐ Wallet Balance: 0.00000000 RIN +[2025-09-29 22:31:04] ๐Ÿ’ฐ Wallet Balance: 0.00000000 RIN diff --git a/MINE/rin/pool_web_interface.py b/MINE/rin/pool_web_interface.py index 80ca03b..1577778 100644 --- a/MINE/rin/pool_web_interface.py +++ b/MINE/rin/pool_web_interface.py @@ -1,529 +1,529 @@ -#!/usr/bin/env python3 -""" -RinCoin Mining Pool Web Interface -Provides web dashboard for pool statistics and miner management -""" +# #!/usr/bin/env python3 +# """ +# RinCoin Mining Pool Web Interface +# Provides web dashboard for pool statistics and miner management +# """ -import json -import sqlite3 -import requests -from datetime import datetime, timedelta -from http.server import HTTPServer, BaseHTTPRequestHandler -import threading -import time -from requests.auth import HTTPBasicAuth +# import json +# import sqlite3 +# import requests +# from datetime import datetime, timedelta +# from http.server import HTTPServer, BaseHTTPRequestHandler +# import threading +# import time +# from requests.auth import HTTPBasicAuth -class PoolWebInterface: - def __init__(self, pool_db, host='0.0.0.0', port=8080, rpc_host='127.0.0.1', rpc_port=9556, - rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90'): - self.pool_db = pool_db - self.host = host - self.port = port - self.rpc_host = rpc_host - self.rpc_port = rpc_port - self.rpc_user = rpc_user - self.rpc_password = rpc_password - self.chart_time_window = 3600 # 1 hour default, adjustable +# class PoolWebInterface: +# def __init__(self, pool_db, host='0.0.0.0', port=8080, rpc_host='127.0.0.1', rpc_port=9556, +# rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90'): +# self.pool_db = pool_db +# self.host = host +# self.port = port +# self.rpc_host = rpc_host +# self.rpc_port = rpc_port +# self.rpc_user = rpc_user +# self.rpc_password = rpc_password +# self.chart_time_window = 3600 # 1 hour default, adjustable - def set_chart_time_window(self, seconds): - """Set the chart time window""" - self.chart_time_window = seconds +# def set_chart_time_window(self, seconds): +# """Set the chart time window""" +# self.chart_time_window = seconds - def format_hashrate(self, hashrate): - """Format hashrate in human readable format""" - if hashrate >= 1e12: - return f"{hashrate/1e12:.2f} TH/s" - elif hashrate >= 1e9: - return f"{hashrate/1e9:.2f} GH/s" - elif hashrate >= 1e6: - return f"{hashrate/1e6:.2f} MH/s" - elif hashrate >= 1e3: - return f"{hashrate/1e3:.2f} KH/s" - elif hashrate >= 0.01: - return f"{hashrate:.2f} H/s" - elif hashrate > 0: - return f"{hashrate*1000:.2f} mH/s" - else: - return "0.00 H/s" +# def format_hashrate(self, hashrate): +# """Format hashrate in human readable format""" +# if hashrate >= 1e12: +# return f"{hashrate/1e12:.2f} TH/s" +# elif hashrate >= 1e9: +# return f"{hashrate/1e9:.2f} GH/s" +# elif hashrate >= 1e6: +# return f"{hashrate/1e6:.2f} MH/s" +# elif hashrate >= 1e3: +# return f"{hashrate/1e3:.2f} KH/s" +# elif hashrate >= 0.01: +# return f"{hashrate:.2f} H/s" +# elif hashrate > 0: +# return f"{hashrate*1000:.2f} mH/s" +# else: +# return "0.00 H/s" - def get_pool_balance(self): - """Get pool wallet balance via RPC""" - try: - url = f"http://{self.rpc_host}:{self.rpc_port}/" - headers = {'content-type': 'text/plain'} - auth = HTTPBasicAuth(self.rpc_user, self.rpc_password) +# def get_pool_balance(self): +# """Get pool wallet balance via RPC""" +# try: +# url = f"http://{self.rpc_host}:{self.rpc_port}/" +# headers = {'content-type': 'text/plain'} +# auth = HTTPBasicAuth(self.rpc_user, self.rpc_password) - payload = { - "jsonrpc": "1.0", - "id": "pool_balance", - "method": "getbalance", - "params": [] - } +# payload = { +# "jsonrpc": "1.0", +# "id": "pool_balance", +# "method": "getbalance", +# "params": [] +# } - response = requests.post(url, json=payload, headers=headers, auth=auth, timeout=10) +# response = requests.post(url, json=payload, headers=headers, auth=auth, timeout=10) - if response.status_code == 200: - result = response.json() - if 'error' in result and result['error'] is not None: - print(f"RPC Error getting balance: {result['error']}") - return 0.0 - balance = result.get('result', 0) - return float(balance) / 100000000 # Convert from satoshis to RIN - else: - print(f"HTTP Error getting balance: {response.status_code}") - return 0.0 +# if response.status_code == 200: +# result = response.json() +# if 'error' in result and result['error'] is not None: +# print(f"RPC Error getting balance: {result['error']}") +# return 0.0 +# balance = result.get('result', 0) +# return float(balance) / 100000000 # Convert from satoshis to RIN +# else: +# print(f"HTTP Error getting balance: {response.status_code}") +# return 0.0 - except Exception as e: - print(f"Error getting pool balance: {e}") - return 0.0 +# except Exception as e: +# print(f"Error getting pool balance: {e}") +# return 0.0 - def get_pool_stats(self): - """Get current pool statistics""" - try: - cursor = self.pool_db.cursor() +# def get_pool_stats(self): +# """Get current pool statistics""" +# try: +# cursor = self.pool_db.cursor() - # Total miners (ever registered) - cursor.execute('SELECT COUNT(DISTINCT id) FROM miners') - total_miners = cursor.fetchone()[0] +# # Total miners (ever registered) +# cursor.execute('SELECT COUNT(DISTINCT id) FROM miners') +# total_miners = cursor.fetchone()[0] - # Active miners (last 5 minutes) - cursor.execute(''' - SELECT COUNT(DISTINCT m.id) FROM miners m - JOIN shares s ON m.id = s.miner_id - WHERE s.submitted > datetime('now', '-5 minutes') - ''') - active_miners = cursor.fetchone()[0] +# # Active miners (last 5 minutes) +# cursor.execute(''' +# SELECT COUNT(DISTINCT m.id) FROM miners m +# JOIN shares s ON m.id = s.miner_id +# WHERE s.submitted > datetime('now', '-5 minutes') +# ''') +# active_miners = cursor.fetchone()[0] - # Total shares (last 24 hours) - cursor.execute(''' - SELECT COUNT(*) FROM shares - WHERE submitted > datetime('now', '-24 hours') - ''') - total_shares_24h = cursor.fetchone()[0] +# # Total shares (last 24 hours) +# cursor.execute(''' +# SELECT COUNT(*) FROM shares +# WHERE submitted > datetime('now', '-24 hours') +# ''') +# total_shares_24h = cursor.fetchone()[0] - # Pool hashrate: sum of miners.last_hashrate (instantaneous) - cursor.execute('SELECT COALESCE(SUM(last_hashrate), 0) FROM miners') - hashrate = cursor.fetchone()[0] or 0.0 +# # Pool hashrate: sum of miners.last_hashrate (instantaneous) +# cursor.execute('SELECT COALESCE(SUM(last_hashrate), 0) FROM miners') +# hashrate = cursor.fetchone()[0] or 0.0 - # Debug stats - cursor.execute(''' - SELECT SUM(difficulty), COUNT(*) FROM shares - WHERE submitted > datetime('now', '-5 minutes') - ''') - rd = cursor.fetchone() - recent_difficulty = rd[0] if rd and rd[0] else 0 - recent_share_count = rd[1] if rd and rd[1] else 0 +# # Debug stats +# cursor.execute(''' +# SELECT SUM(difficulty), COUNT(*) FROM shares +# WHERE submitted > datetime('now', '-5 minutes') +# ''') +# rd = cursor.fetchone() +# recent_difficulty = rd[0] if rd and rd[0] else 0 +# recent_share_count = rd[1] if rd and rd[1] else 0 - # Get historical hashrate data for chart - cursor.execute(''' - SELECT - strftime('%H:%M', submitted) as time, - COUNT(*) as shares, - SUM(difficulty) as total_difficulty - FROM shares - WHERE submitted > datetime('now', '-{} seconds') - GROUP BY strftime('%Y-%m-%d %H:%M', submitted) - ORDER BY submitted DESC - LIMIT 60 - '''.format(self.chart_time_window)) - historical_data = cursor.fetchall() +# # Get historical hashrate data for chart +# cursor.execute(''' +# SELECT +# strftime('%H:%M', submitted) as time, +# COUNT(*) as shares, +# SUM(difficulty) as total_difficulty +# FROM shares +# WHERE submitted > datetime('now', '-{} seconds') +# GROUP BY strftime('%Y-%m-%d %H:%M', submitted) +# ORDER BY submitted DESC +# LIMIT 60 +# '''.format(self.chart_time_window)) +# historical_data = cursor.fetchall() - # Calculate individual miner hashrates - cursor.execute(''' - SELECT - m.user, m.worker, - COUNT(s.id) as shares, - SUM(s.difficulty) as total_difficulty, - m.last_share - FROM miners m - LEFT JOIN shares s ON m.id = s.miner_id - AND s.submitted > datetime('now', '-5 minutes') - GROUP BY m.id, m.user, m.worker - ORDER BY shares DESC - ''') - miner_stats = cursor.fetchall() +# # Calculate individual miner hashrates +# cursor.execute(''' +# SELECT +# m.user, m.worker, +# COUNT(s.id) as shares, +# SUM(s.difficulty) as total_difficulty, +# m.last_share +# FROM miners m +# LEFT JOIN shares s ON m.id = s.miner_id +# AND s.submitted > datetime('now', '-5 minutes') +# GROUP BY m.id, m.user, m.worker +# ORDER BY shares DESC +# ''') +# miner_stats = cursor.fetchall() - # Calculate individual hashrates (use miners.last_hashrate) - miner_hashrates = [] - for user, worker, shares, difficulty, last_share in miner_stats: - cursor.execute('SELECT last_hashrate FROM miners WHERE user = ? AND worker = ? LIMIT 1', (user, worker)) - row = cursor.fetchone() - miner_hashrate = row[0] if row and row[0] else 0.0 - miner_hashrates.append((user, worker, shares, miner_hashrate, last_share)) +# # Calculate individual hashrates (use miners.last_hashrate) +# miner_hashrates = [] +# for user, worker, shares, difficulty, last_share in miner_stats: +# cursor.execute('SELECT last_hashrate FROM miners WHERE user = ? AND worker = ? LIMIT 1', (user, worker)) +# row = cursor.fetchone() +# miner_hashrate = row[0] if row and row[0] else 0.0 +# miner_hashrates.append((user, worker, shares, miner_hashrate, last_share)) - # Total blocks found - cursor.execute('SELECT COUNT(*) FROM blocks') - total_blocks = cursor.fetchone()[0] +# # Total blocks found +# cursor.execute('SELECT COUNT(*) FROM blocks') +# total_blocks = cursor.fetchone()[0] - # Recent blocks - cursor.execute(''' - SELECT block_hash, height, reward, found_at - FROM blocks - ORDER BY found_at DESC - LIMIT 10 - ''') - recent_blocks = cursor.fetchall() +# # Recent blocks +# cursor.execute(''' +# SELECT block_hash, height, reward, found_at +# FROM blocks +# ORDER BY found_at DESC +# LIMIT 10 +# ''') +# recent_blocks = cursor.fetchall() - # Top miners (last 24 hours) - show all miners, even without shares - cursor.execute(''' - SELECT m.user, m.worker, - COALESCE(COUNT(s.id), 0) as shares, - m.last_share, - m.created - FROM miners m - LEFT JOIN shares s ON m.id = s.miner_id - AND s.submitted > datetime('now', '-24 hours') - GROUP BY m.id, m.user, m.worker - ORDER BY shares DESC, m.created DESC - LIMIT 20 - ''') - top_miners = cursor.fetchall() +# # Top miners (last 24 hours) - show all miners, even without shares +# cursor.execute(''' +# SELECT m.user, m.worker, +# COALESCE(COUNT(s.id), 0) as shares, +# m.last_share, +# m.created +# FROM miners m +# LEFT JOIN shares s ON m.id = s.miner_id +# AND s.submitted > datetime('now', '-24 hours') +# GROUP BY m.id, m.user, m.worker +# ORDER BY shares DESC, m.created DESC +# LIMIT 20 +# ''') +# top_miners = cursor.fetchall() - # All active miners (for better visibility) - cursor.execute(''' - SELECT user, worker, created, last_share - FROM miners - ORDER BY created DESC - LIMIT 10 - ''') - all_miners = cursor.fetchall() +# # All active miners (for better visibility) +# cursor.execute(''' +# SELECT user, worker, created, last_share +# FROM miners +# ORDER BY created DESC +# LIMIT 10 +# ''') +# all_miners = cursor.fetchall() - # Get pool balance - pool_balance = self.get_pool_balance() +# # Get pool balance +# pool_balance = self.get_pool_balance() - return { - 'total_miners': total_miners, - 'active_miners': active_miners, - 'total_shares_24h': total_shares_24h, - 'hashrate': hashrate, - 'total_blocks': total_blocks, - 'recent_blocks': recent_blocks, - 'top_miners': top_miners, - 'all_miners': all_miners, - 'miner_hashrates': miner_hashrates, - 'historical_data': historical_data, - 'pool_balance': pool_balance, - 'debug': { - 'recent_difficulty': recent_difficulty, - 'recent_share_count': recent_share_count, - 'total_shares_24h': total_shares_24h - } - } - except Exception as e: - print(f"Error getting pool stats: {e}") - return {} +# return { +# 'total_miners': total_miners, +# 'active_miners': active_miners, +# 'total_shares_24h': total_shares_24h, +# 'hashrate': hashrate, +# 'total_blocks': total_blocks, +# 'recent_blocks': recent_blocks, +# 'top_miners': top_miners, +# 'all_miners': all_miners, +# 'miner_hashrates': miner_hashrates, +# 'historical_data': historical_data, +# 'pool_balance': pool_balance, +# 'debug': { +# 'recent_difficulty': recent_difficulty, +# 'recent_share_count': recent_share_count, +# 'total_shares_24h': total_shares_24h +# } +# } +# except Exception as e: +# print(f"Error getting pool stats: {e}") +# return {} - def generate_html(self, stats): - """Generate HTML dashboard""" - html = f""" - - - - RinCoin Mining Pool - - - - - -
-
-

๐ŸŠโ€โ™‚๏ธ RinCoin Mining Pool

-

Distribute block rewards among multiple miners

-
+# def generate_html(self, stats): +# """Generate HTML dashboard""" +# html = f""" +# +# +# +# RinCoin Mining Pool +# +# +# +# +# +#
+#
+#

๐ŸŠโ€โ™‚๏ธ RinCoin Mining Pool

+#

Distribute block rewards among multiple miners

+#
- +# -
-
-
{stats.get('total_miners', 0)}
-
Total Miners
-
-
-
{stats.get('active_miners', 0)}
-
Active Miners
-
-
-
{self.format_hashrate(stats.get('hashrate', 0))}
-
Hashrate
-
-
-
{stats.get('total_blocks', 0)}
-
Blocks Found
-
-
-
{stats.get('pool_balance', 0):.2f}
-
Pool Balance (RIN)
-
-
+#
+#
+#
{stats.get('total_miners', 0)}
+#
Total Miners
+#
+#
+#
{stats.get('active_miners', 0)}
+#
Active Miners
+#
+#
+#
{self.format_hashrate(stats.get('hashrate', 0))}
+#
Hashrate
+#
+#
+#
{stats.get('total_blocks', 0)}
+#
Blocks Found
+#
+#
+#
{stats.get('pool_balance', 0):.2f}
+#
Pool Balance (RIN)
+#
+#
-
-

๐Ÿ“Š Pool Statistics

-

24h Shares: {stats.get('total_shares_24h', 0):,}

-

Pool Fee: 1%

-

Pool Balance: {stats.get('pool_balance', 0):.8f} RIN

-

Connection String: stratum+tcp://YOUR_IP:3333

+#
+#

๐Ÿ“Š Pool Statistics

+#

24h Shares: {stats.get('total_shares_24h', 0):,}

+#

Pool Fee: 1%

+#

Pool Balance: {stats.get('pool_balance', 0):.8f} RIN

+#

Connection String: stratum+tcp://YOUR_IP:3333

- -
- ๐Ÿ” Debug Info -

Recent Difficulty (5min): {stats.get('debug', {}).get('recent_difficulty', 0):.6f}

-

Recent Share Count (5min): {stats.get('debug', {}).get('recent_share_count', 0)}

-

Total Shares (24h): {stats.get('debug', {}).get('total_shares_24h', 0):,}

-

Active Miners: {stats.get('active_miners', 0)} (last 5 minutes)

-

Total Miners: {stats.get('total_miners', 0)} (ever registered)

-
-
+# +#
+# ๐Ÿ” Debug Info +#

Recent Difficulty (5min): {stats.get('debug', {}).get('recent_difficulty', 0):.6f}

+#

Recent Share Count (5min): {stats.get('debug', {}).get('recent_share_count', 0)}

+#

Total Shares (24h): {stats.get('debug', {}).get('total_shares_24h', 0):,}

+#

Active Miners: {stats.get('active_miners', 0)} (last 5 minutes)

+#

Total Miners: {stats.get('total_miners', 0)} (ever registered)

+#
+#
-
-

๐Ÿ“ˆ Hashrate Chart

-
- - -
-
- -
-
+#
+#

๐Ÿ“ˆ Hashrate Chart

+#
+# +# +#
+#
+# +#
+#
-
-

๐Ÿ‘ฅ Connected Miners

- - - - - - - - """ +#
+#

๐Ÿ‘ฅ Connected Miners

+#
UserWorkerConnectedLast Share
+# +# +# +# +# +# +# """ - for miner in stats.get('all_miners', []): - user, worker, created, last_share = miner - html += f""" - - - - - - - """ +# for miner in stats.get('all_miners', []): +# user, worker, created, last_share = miner +# html += f""" +# +# +# +# +# +# +# """ - if not stats.get('all_miners', []): - html += """ - - - - """ +# if not stats.get('all_miners', []): +# html += """ +# +# +# +# """ - html += """ -
UserWorkerConnectedLast Share
{user}{worker}{created}{last_share or 'Never'}
{user}{worker}{created}{last_share or 'Never'}
No miners connected
No miners connected
-
+# html += """ +# +#
-
-

๐Ÿ† Top Miners (24h Shares)

- - - - - - - - - """ +#
+#

๐Ÿ† Top Miners (24h Shares)

+#
UserWorkerSharesHashrateLast Share
+# +# +# +# +# +# +# +# """ - for miner in stats.get('miner_hashrates', []): - user, worker, shares, hashrate, last_share = miner - html += f""" - - - - - - - - """ +# for miner in stats.get('miner_hashrates', []): +# user, worker, shares, hashrate, last_share = miner +# html += f""" +# +# +# +# +# +# +# +# """ - if not stats.get('top_miners', []): - html += """ - - - - """ +# if not stats.get('top_miners', []): +# html += """ +# +# +# +# """ - html += """ -
UserWorkerSharesHashrateLast Share
{user}{worker}{shares:,}{self.format_hashrate(hashrate)}{last_share or 'Never'}
{user}{worker}{shares:,}{self.format_hashrate(hashrate)}{last_share or 'Never'}
No shares submitted yet
No shares submitted yet
-
+# html += """ +# +#
-
-

๐Ÿ† Recent Blocks

- - - - - - - - """ +#
+#

๐Ÿ† Recent Blocks

+#
HeightHashRewardFound At
+# +# +# +# +# +# +# """ - for block in stats.get('recent_blocks', []): - block_hash, height, reward, found_at = block - html += f""" - - - - - - - """ +# for block in stats.get('recent_blocks', []): +# block_hash, height, reward, found_at = block +# html += f""" +# +# +# +# +# +# +# """ - html += """ -
HeightHashRewardFound At
{height}{block_hash[:16]}...{reward:.8f} RIN{found_at}
{height}{block_hash[:16]}...{reward:.8f} RIN{found_at}
-
+# html += """ +# +# -
-

๐Ÿ”— Connect to Pool

-

Use any RinHash-compatible miner:

-
./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u username.workername -p x
-

Replace YOUR_IP with your server's public IP address

-
- +#
+#

๐Ÿ”— Connect to Pool

+#

Use any RinHash-compatible miner:

+#
./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u username.workername -p x
+#

Replace YOUR_IP with your server's public IP address

+#
+# - - +# +# function changeTimeWindow(seconds) {{ +# // Reload page with new time window +# const url = new URL(window.location); +# url.searchParams.set('window', seconds); +# window.location.href = url.toString(); +# }} +# - - - - """ - return html +# +# +# +# """ +# return html -class PoolWebHandler(BaseHTTPRequestHandler): - def __init__(self, *args, pool_interface=None, **kwargs): - self.pool_interface = pool_interface - super().__init__(*args, **kwargs) +# class PoolWebHandler(BaseHTTPRequestHandler): +# def __init__(self, *args, pool_interface=None, **kwargs): +# self.pool_interface = pool_interface +# super().__init__(*args, **kwargs) - def do_GET(self): - if self.path == '/': - stats = self.pool_interface.get_pool_stats() - html = self.pool_interface.generate_html(stats) +# def do_GET(self): +# if self.path == '/': +# stats = self.pool_interface.get_pool_stats() +# html = self.pool_interface.generate_html(stats) - self.send_response(200) - self.send_header('Content-type', 'text/html') - self.end_headers() - self.wfile.write(html.encode('utf-8')) - elif self.path == '/api/stats': - stats = self.pool_interface.get_pool_stats() +# self.send_response(200) +# self.send_header('Content-type', 'text/html') +# self.end_headers() +# self.wfile.write(html.encode('utf-8')) +# elif self.path == '/api/stats': +# stats = self.pool_interface.get_pool_stats() - self.send_response(200) - self.send_header('Content-type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(stats).encode('utf-8')) - else: - self.send_response(404) - self.end_headers() - self.wfile.write(b'Not Found') +# self.send_response(200) +# self.send_header('Content-type', 'application/json') +# self.end_headers() +# self.wfile.write(json.dumps(stats).encode('utf-8')) +# else: +# self.send_response(404) +# self.end_headers() +# self.wfile.write(b'Not Found') - def log_message(self, format, *args): - # Suppress access logs - pass +# def log_message(self, format, *args): +# # Suppress access logs +# pass -def start_web_interface(pool_db, host='0.0.0.0', port=8083, rpc_host='127.0.0.1', rpc_port=9556, - rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90'): - """Start the web interface server""" - interface = PoolWebInterface(pool_db, host, port, rpc_host, rpc_port, rpc_user, rpc_password) +# def start_web_interface(pool_db, host='0.0.0.0', port=8083, rpc_host='127.0.0.1', rpc_port=9556, +# rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90'): +# """Start the web interface server""" +# interface = PoolWebInterface(pool_db, host, port, rpc_host, rpc_port, rpc_user, rpc_password) - class Handler(PoolWebHandler): - def __init__(self, *args, **kwargs): - super().__init__(*args, pool_interface=interface, **kwargs) +# class Handler(PoolWebHandler): +# def __init__(self, *args, **kwargs): +# super().__init__(*args, pool_interface=interface, **kwargs) - try: - server = HTTPServer((host, port), Handler) - print(f"๐ŸŒ Web interface running on http://{host}:{port}") - print("Press Ctrl+C to stop") +# try: +# server = HTTPServer((host, port), Handler) +# print(f"๐ŸŒ Web interface running on http://{host}:{port}") +# print("Press Ctrl+C to stop") - server.serve_forever() - except OSError as e: - if "Address already in use" in str(e): - print(f"โš ๏ธ Port {port} is already in use, web interface not started") - print(f"๐Ÿ’ก Try a different port or kill the process using port {port}") - else: - print(f"โŒ Failed to start web interface: {e}") - except KeyboardInterrupt: - print("\n๐Ÿ›‘ Shutting down web interface...") - server.shutdown() +# server.serve_forever() +# except OSError as e: +# if "Address already in use" in str(e): +# print(f"โš ๏ธ Port {port} is already in use, web interface not started") +# print(f"๐Ÿ’ก Try a different port or kill the process using port {port}") +# else: +# print(f"โŒ Failed to start web interface: {e}") +# except KeyboardInterrupt: +# print("\n๐Ÿ›‘ Shutting down web interface...") +# server.shutdown() -if __name__ == "__main__": - # This would be called from the main pool server - print("Web interface module loaded") +# if __name__ == "__main__": +# # This would be called from the main pool server +# print("Web interface module loaded") diff --git a/MINE/rin/solo_mining.sh b/MINE/rin/solo_mining.sh index b0ec0ad..54001dc 100644 --- a/MINE/rin/solo_mining.sh +++ b/MINE/rin/solo_mining.sh @@ -1,47 +1,47 @@ -#!/bin/bash +# #!/bin/bash -# Solo Mining Script for RinCoin -# Uses local RinCoin node for solo mining +# # Solo Mining Script for RinCoin +# # Uses local RinCoin node for solo mining -echo "=== RinCoin Solo Mining Setup ===" -echo "" +# echo "=== RinCoin Solo Mining Setup ===" +# echo "" -# Check if rincoin-node container is running -if ! sudo docker ps | grep -q "rincoin-node"; then - echo "Error: rincoin-node container is not running!" - echo "Please start it first:" - echo "sudo docker start rincoin-node" - exit 1 -fi +# # Check if rincoin-node container is running +# if ! sudo docker ps | grep -q "rincoin-node"; then +# echo "Error: rincoin-node container is not running!" +# echo "Please start it first:" +# echo "sudo docker start rincoin-node" +# exit 1 +# fi -# Get wallet address -RIN_ADDRESS=$(sudo docker exec rincoin-node rincoin-cli -datadir=/data -conf=/data/rincoin.conf -rpcwallet=main getnewaddress 2>/dev/null) +# # Get wallet address +# RIN_ADDRESS=$(sudo docker exec rincoin-node rincoin-cli -datadir=/data -conf=/data/rincoin.conf -rpcwallet=main getnewaddress 2>/dev/null) -if [ -z "$RIN_ADDRESS" ]; then - echo "Error: Could not get RinCoin address!" - echo "Make sure the wallet is created and the node is synced." - exit 1 -fi +# if [ -z "$RIN_ADDRESS" ]; then +# echo "Error: Could not get RinCoin address!" +# echo "Make sure the wallet is created and the node is synced." +# exit 1 +# fi -echo "RinCoin Address: $RIN_ADDRESS" -echo "" +# echo "RinCoin Address: $RIN_ADDRESS" +# echo "" -# Check node sync status -SYNC_STATUS=$(sudo docker exec rincoin-node rincoin-cli -datadir=/data -conf=/data/rincoin.conf getblockchaininfo | grep -o '"initialblockdownload": [^,]*' | cut -d' ' -f2) +# # Check node sync status +# SYNC_STATUS=$(sudo docker exec rincoin-node rincoin-cli -datadir=/data -conf=/data/rincoin.conf getblockchaininfo | grep -o '"initialblockdownload": [^,]*' | cut -d' ' -f2) -if [ "$SYNC_STATUS" = "true" ]; then - echo "โš ๏ธ WARNING: Node is still syncing (initialblockdownload: true)" - echo "Solo mining may not work properly until sync is complete." - echo "" -fi +# if [ "$SYNC_STATUS" = "true" ]; then +# echo "โš ๏ธ WARNING: Node is still syncing (initialblockdownload: true)" +# echo "Solo mining may not work properly until sync is complete." +# echo "" +# fi -echo "Starting solo mining with cpuminer-opt-rin..." -echo "Algorithm: rinhash" -echo "Target: Local RinCoin node (127.0.0.1:9555)" -echo "Wallet: $RIN_ADDRESS" -echo "" -echo "Press Ctrl+C to stop mining" -echo "" +# echo "Starting solo mining with cpuminer-opt-rin..." +# echo "Algorithm: rinhash" +# echo "Target: Local RinCoin node (127.0.0.1:9555)" +# echo "Wallet: $RIN_ADDRESS" +# echo "" +# echo "Press Ctrl+C to stop mining" +# echo "" -# Start solo mining -sudo docker exec -it amd-strix-halo-llama-rocm bash -c "/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://127.0.0.1:9555 -u $RIN_ADDRESS -p x -t 32" +# # Start solo mining +# sudo docker exec -it amd-strix-halo-llama-rocm bash -c "/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://127.0.0.1:9555 -u $RIN_ADDRESS -p x -t 32" diff --git a/MINE/rin/solo_mining_core.sh b/MINE/rin/solo_mining_core.sh index 1ade71d..3a9efe5 100644 --- a/MINE/rin/solo_mining_core.sh +++ b/MINE/rin/solo_mining_core.sh @@ -1,171 +1,171 @@ -#!/bin/bash +# #!/bin/bash -# RinCoin Solo Mining using Built-in Core Mining -# Uses RinCoin Core's generatetoaddress command +# # RinCoin Solo Mining using Built-in Core Mining +# # Uses RinCoin Core's generatetoaddress command -# Default address (can be overridden with command line parameter) -DEFAULT_ADDRESS="rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q" +# # Default address (can be overridden with command line parameter) +# DEFAULT_ADDRESS="rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q" -# Get total CPU cores for default thread count -TOTAL_CORES=$(nproc) -DEFAULT_THREADS=$TOTAL_CORES +# # Get total CPU cores for default thread count +# TOTAL_CORES=$(nproc) +# DEFAULT_THREADS=$TOTAL_CORES -# Parse command line arguments -RIN_ADDRESS="" -THREAD_COUNT="" +# # Parse command line arguments +# RIN_ADDRESS="" +# THREAD_COUNT="" -# Parse arguments -while [[ $# -gt 0 ]]; do - case $1 in - -a|--address) - RIN_ADDRESS="$2" - shift 2 - ;; - -t|--threads) - THREAD_COUNT="$2" - shift 2 - ;; - -h|--help) - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " -a, --address ADDRESS RinCoin address to mine to (default: $DEFAULT_ADDRESS)" - echo " -t, --threads COUNT Number of threads to use (default: $DEFAULT_THREADS)" - echo " -h, --help Show this help message" - echo "" - echo "Examples:" - echo " $0 # Use defaults (all cores, default address)" - echo " $0 -a rin1q... -t 16 # Custom address and 16 threads" - echo " $0 --address rin1q... --threads 8 # Custom address and 8 threads" - exit 0 - ;; - *) - echo "Unknown option: $1" - echo "Use -h or --help for usage information" - exit 1 - ;; - esac -done +# # Parse arguments +# while [[ $# -gt 0 ]]; do +# case $1 in +# -a|--address) +# RIN_ADDRESS="$2" +# shift 2 +# ;; +# -t|--threads) +# THREAD_COUNT="$2" +# shift 2 +# ;; +# -h|--help) +# echo "Usage: $0 [OPTIONS]" +# echo "" +# echo "Options:" +# echo " -a, --address ADDRESS RinCoin address to mine to (default: $DEFAULT_ADDRESS)" +# echo " -t, --threads COUNT Number of threads to use (default: $DEFAULT_THREADS)" +# echo " -h, --help Show this help message" +# echo "" +# echo "Examples:" +# echo " $0 # Use defaults (all cores, default address)" +# echo " $0 -a rin1q... -t 16 # Custom address and 16 threads" +# echo " $0 --address rin1q... --threads 8 # Custom address and 8 threads" +# exit 0 +# ;; +# *) +# echo "Unknown option: $1" +# echo "Use -h or --help for usage information" +# exit 1 +# ;; +# esac +# done -# Set defaults if not provided -if [ -z "$RIN_ADDRESS" ]; then - RIN_ADDRESS="$DEFAULT_ADDRESS" - echo "No address provided, using default: $RIN_ADDRESS" -fi +# # Set defaults if not provided +# if [ -z "$RIN_ADDRESS" ]; then +# RIN_ADDRESS="$DEFAULT_ADDRESS" +# echo "No address provided, using default: $RIN_ADDRESS" +# fi -if [ -z "$THREAD_COUNT" ]; then - THREAD_COUNT="$DEFAULT_THREADS" - echo "No thread count provided, using all cores: $THREAD_COUNT" -fi +# if [ -z "$THREAD_COUNT" ]; then +# THREAD_COUNT="$DEFAULT_THREADS" +# echo "No thread count provided, using all cores: $THREAD_COUNT" +# fi -# Validate thread count -if ! [[ "$THREAD_COUNT" =~ ^[0-9]+$ ]] || [ "$THREAD_COUNT" -lt 1 ] || [ "$THREAD_COUNT" -gt "$TOTAL_CORES" ]; then - echo "โŒ Error: Invalid thread count: $THREAD_COUNT" - echo "Thread count must be between 1 and $TOTAL_CORES" - exit 1 -fi +# # Validate thread count +# if ! [[ "$THREAD_COUNT" =~ ^[0-9]+$ ]] || [ "$THREAD_COUNT" -lt 1 ] || [ "$THREAD_COUNT" -gt "$TOTAL_CORES" ]; then +# echo "โŒ Error: Invalid thread count: $THREAD_COUNT" +# echo "Thread count must be between 1 and $TOTAL_CORES" +# exit 1 +# fi -echo "=== RinCoin Solo Mining (Built-in Core Mining) ===" -echo "CPU Cores Available: $TOTAL_CORES" -echo "Threads to Use: $THREAD_COUNT" -echo "Target Address: $RIN_ADDRESS" -echo "" -echo "" +# echo "=== RinCoin Solo Mining (Built-in Core Mining) ===" +# echo "CPU Cores Available: $TOTAL_CORES" +# echo "Threads to Use: $THREAD_COUNT" +# echo "Target Address: $RIN_ADDRESS" +# echo "" +# echo "" -# Configuration -RPC_HOST="127.0.0.1" -RPC_PORT="9556" -RPC_USER="rinrpc" -RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" +# # Configuration +# RPC_HOST="127.0.0.1" +# RPC_PORT="9556" +# RPC_USER="rinrpc" +# RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" -# Function to call RPC -call_rpc() { - local method="$1" - local params="$2" +# # Function to call RPC +# call_rpc() { +# local method="$1" +# local params="$2" - curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ - "http://$RPC_HOST:$RPC_PORT/" -} +# curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ +# "http://$RPC_HOST:$RPC_PORT/" +# } -# Wait for node to be ready -echo "Waiting for RinCoin node to be ready..." -while true; do - response=$(call_rpc "getblockchaininfo" "[]") - if [[ $response != *"Loading block index"* ]]; then - break - fi - echo "Node still loading... waiting 10 seconds" - sleep 10 -done +# # Wait for node to be ready +# echo "Waiting for RinCoin node to be ready..." +# while true; do +# response=$(call_rpc "getblockchaininfo" "[]") +# if [[ $response != *"Loading block index"* ]]; then +# break +# fi +# echo "Node still loading... waiting 10 seconds" +# sleep 10 +# done -echo "โœ… Node is ready!" -echo "" +# echo "โœ… Node is ready!" +# echo "" -# Load wallet if not already loaded -echo "Loading wallet..." -wallet_response=$(call_rpc "loadwallet" "[\"main\"]") -if [[ $wallet_response == *"error"* ]] && [[ $wallet_response == *"already loaded"* ]]; then - echo "โœ… Wallet already loaded" -else - echo "โœ… Wallet loaded successfully" -fi -echo "" +# # Load wallet if not already loaded +# echo "Loading wallet..." +# wallet_response=$(call_rpc "loadwallet" "[\"main\"]") +# if [[ $wallet_response == *"error"* ]] && [[ $wallet_response == *"already loaded"* ]]; then +# echo "โœ… Wallet already loaded" +# else +# echo "โœ… Wallet loaded successfully" +# fi +# echo "" -# Validate the provided address (basic check) -if [[ ! "$RIN_ADDRESS" =~ ^rin1[a-zA-Z0-9]{25,}$ ]]; then - echo "โŒ Error: Invalid RinCoin address format: $RIN_ADDRESS" - echo "RinCoin addresses should start with 'rin1' and be ~30 characters long" - exit 1 -fi +# # Validate the provided address (basic check) +# if [[ ! "$RIN_ADDRESS" =~ ^rin1[a-zA-Z0-9]{25,}$ ]]; then +# echo "โŒ Error: Invalid RinCoin address format: $RIN_ADDRESS" +# echo "RinCoin addresses should start with 'rin1' and be ~30 characters long" +# exit 1 +# fi -echo "โœ… Using RinCoin Address: $RIN_ADDRESS" -echo "" +# echo "โœ… Using RinCoin Address: $RIN_ADDRESS" +# echo "" -# Get blockchain info -echo "Blockchain Status:" -blockchain_info=$(call_rpc "getblockchaininfo" "[]") -blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) -headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) -difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) +# # Get blockchain info +# echo "Blockchain Status:" +# blockchain_info=$(call_rpc "getblockchaininfo" "[]") +# blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) +# headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) +# difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) -echo "Blocks: $blocks" -echo "Headers: $headers" -echo "Difficulty: $difficulty" -echo "" +# echo "Blocks: $blocks" +# echo "Headers: $headers" +# echo "Difficulty: $difficulty" +# echo "" -echo "โš ๏ธ IMPORTANT: Built-in Core Mining Limitations:" -echo "1. Uses CPU only (not GPU)" -echo "2. Very low hashpower compared to specialized miners" -echo "3. Extremely low chance of finding blocks solo" -echo "4. Best for testing, not profitable mining" -echo "5. Thread count affects mining attempts per cycle" -echo "" +# echo "โš ๏ธ IMPORTANT: Built-in Core Mining Limitations:" +# echo "1. Uses CPU only (not GPU)" +# echo "2. Very low hashpower compared to specialized miners" +# echo "3. Extremely low chance of finding blocks solo" +# echo "4. Best for testing, not profitable mining" +# echo "5. Thread count affects mining attempts per cycle" +# echo "" -echo "๐Ÿš€ Starting Built-in Solo Mining..." -echo "Target Address: $RIN_ADDRESS" -echo "Threads: $THREAD_COUNT" -echo "Press Ctrl+C to stop mining" -echo "" +# echo "๐Ÿš€ Starting Built-in Solo Mining..." +# echo "Target Address: $RIN_ADDRESS" +# echo "Threads: $THREAD_COUNT" +# echo "Press Ctrl+C to stop mining" +# echo "" -# Start built-in mining with specified thread count -# Note: RinCoin Core's generatetoaddress doesn't directly support thread count -# but we can run multiple instances or adjust the maxtries parameter -while true; do - echo "Attempting to mine 1 block with $THREAD_COUNT threads..." +# # Start built-in mining with specified thread count +# # Note: RinCoin Core's generatetoaddress doesn't directly support thread count +# # but we can run multiple instances or adjust the maxtries parameter +# while true; do +# echo "Attempting to mine 1 block with $THREAD_COUNT threads..." - # Adjust maxtries based on thread count for better distribution - adjusted_tries=$((1000000 * THREAD_COUNT / TOTAL_CORES)) +# # Adjust maxtries based on thread count for better distribution +# adjusted_tries=$((1000000 * THREAD_COUNT / TOTAL_CORES)) - mining_result=$(call_rpc "generatetoaddress" "[1, \"$RIN_ADDRESS\", $adjusted_tries]") +# mining_result=$(call_rpc "generatetoaddress" "[1, \"$RIN_ADDRESS\", $adjusted_tries]") - if [[ $mining_result == *"result"* ]] && [[ $mining_result != *"[]"* ]]; then - echo "๐ŸŽ‰ BLOCK FOUND!" - echo "Result: $mining_result" - break - else - echo "No block found in this attempt (tries: $adjusted_tries). Retrying..." - sleep 5 - fi -done +# if [[ $mining_result == *"result"* ]] && [[ $mining_result != *"[]"* ]]; then +# echo "๐ŸŽ‰ BLOCK FOUND!" +# echo "Result: $mining_result" +# break +# else +# echo "No block found in this attempt (tries: $adjusted_tries). Retrying..." +# sleep 5 +# fi +# done diff --git a/MINE/rin/solo_mining_remote.sh b/MINE/rin/solo_mining_remote.sh index 6b1ef9a..843df89 100644 --- a/MINE/rin/solo_mining_remote.sh +++ b/MINE/rin/solo_mining_remote.sh @@ -1,81 +1,81 @@ -#!/bin/bash +# #!/bin/bash -# Remote Solo Mining Script for RinCoin -# Connects to RinCoin node over network/RPC +# # Remote Solo Mining Script for RinCoin +# # Connects to RinCoin node over network/RPC -# Configuration -RPC_HOST="127.0.0.1" # Change to your server IP for remote access -RPC_PORT="9556" -RPC_USER="rinrpc" -RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" +# # Configuration +# RPC_HOST="127.0.0.1" # Change to your server IP for remote access +# RPC_PORT="9556" +# RPC_USER="rinrpc" +# RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" -echo "=== Remote RinCoin Solo Mining Setup ===" -echo "RPC Host: $RPC_HOST:$RPC_PORT" -echo "" +# echo "=== Remote RinCoin Solo Mining Setup ===" +# echo "RPC Host: $RPC_HOST:$RPC_PORT" +# echo "" -# Test RPC connection -echo "Testing RPC connection..." -RPC_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ - "http://$RPC_HOST:$RPC_PORT/") +# # Test RPC connection +# echo "Testing RPC connection..." +# RPC_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ +# "http://$RPC_HOST:$RPC_PORT/") -if [[ $RPC_RESPONSE == *"error"* ]]; then - echo "โŒ Error: Could not connect to RinCoin RPC!" - echo "Response: $RPC_RESPONSE" - echo "" - echo "Check:" - echo "1. RinCoin node is running" - echo "2. RPC port $RPC_PORT is accessible" - echo "3. Firewall allows connections to port $RPC_PORT" - exit 1 -fi +# if [[ $RPC_RESPONSE == *"error"* ]]; then +# echo "โŒ Error: Could not connect to RinCoin RPC!" +# echo "Response: $RPC_RESPONSE" +# echo "" +# echo "Check:" +# echo "1. RinCoin node is running" +# echo "2. RPC port $RPC_PORT is accessible" +# echo "3. Firewall allows connections to port $RPC_PORT" +# exit 1 +# fi -echo "โœ… RPC connection successful!" -echo "" +# echo "โœ… RPC connection successful!" +# echo "" -# Get wallet address via RPC -echo "Getting wallet address..." -WALLET_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data '{"jsonrpc":"1.0","id":"curl","method":"getnewaddress","params":[]}' \ - "http://$RPC_HOST:$RPC_PORT/") +# # Get wallet address via RPC +# echo "Getting wallet address..." +# WALLET_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data '{"jsonrpc":"1.0","id":"curl","method":"getnewaddress","params":[]}' \ +# "http://$RPC_HOST:$RPC_PORT/") -RIN_ADDRESS=$(echo "$WALLET_RESPONSE" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) +# RIN_ADDRESS=$(echo "$WALLET_RESPONSE" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) -if [ -z "$RIN_ADDRESS" ]; then - echo "โŒ Error: Could not get RinCoin address!" - echo "Response: $WALLET_RESPONSE" - echo "" - echo "Make sure wallet 'main' exists:" - echo "curl --user $RPC_USER:$RPC_PASS -H 'content-type: text/plain' --data '{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"createwallet\",\"params\":[\"main\"]}' http://$RPC_HOST:$RPC_PORT/" - exit 1 -fi +# if [ -z "$RIN_ADDRESS" ]; then +# echo "โŒ Error: Could not get RinCoin address!" +# echo "Response: $WALLET_RESPONSE" +# echo "" +# echo "Make sure wallet 'main' exists:" +# echo "curl --user $RPC_USER:$RPC_PASS -H 'content-type: text/plain' --data '{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"createwallet\",\"params\":[\"main\"]}' http://$RPC_HOST:$RPC_PORT/" +# exit 1 +# fi -echo "โœ… RinCoin Address: $RIN_ADDRESS" -echo "" +# echo "โœ… RinCoin Address: $RIN_ADDRESS" +# echo "" -# Check node sync status -SYNC_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ - "http://$RPC_HOST:$RPC_PORT/") +# # Check node sync status +# SYNC_RESPONSE=$(curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ +# "http://$RPC_HOST:$RPC_PORT/") -SYNC_STATUS=$(echo "$SYNC_RESPONSE" | grep -o '"initialblockdownload":[^,]*' | cut -d':' -f2 | tr -d ' ') +# SYNC_STATUS=$(echo "$SYNC_RESPONSE" | grep -o '"initialblockdownload":[^,]*' | cut -d':' -f2 | tr -d ' ') -if [ "$SYNC_STATUS" = "true" ]; then - echo "โš ๏ธ WARNING: Node is still syncing (initialblockdownload: true)" - echo "Solo mining may not work properly until sync is complete." - echo "" -fi +# if [ "$SYNC_STATUS" = "true" ]; then +# echo "โš ๏ธ WARNING: Node is still syncing (initialblockdownload: true)" +# echo "Solo mining may not work properly until sync is complete." +# echo "" +# fi -echo "Starting remote solo mining with cpuminer-opt-rin..." -echo "Algorithm: rinhash" -echo "Target: RinCoin node at $RPC_HOST:9555" -echo "Wallet: $RIN_ADDRESS" -echo "" -echo "Press Ctrl+C to stop mining" -echo "" +# echo "Starting remote solo mining with cpuminer-opt-rin..." +# echo "Algorithm: rinhash" +# echo "Target: RinCoin node at $RPC_HOST:9555" +# echo "Wallet: $RIN_ADDRESS" +# echo "" +# echo "Press Ctrl+C to stop mining" +# echo "" -# Start solo mining (connect to P2P port, not RPC) -sudo docker exec -it amd-strix-halo-llama-rocm bash -c "/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://$RPC_HOST:9555 -u $RIN_ADDRESS -p x -t 32" +# # Start solo mining (connect to P2P port, not RPC) +# sudo docker exec -it amd-strix-halo-llama-rocm bash -c "/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://$RPC_HOST:9555 -u $RIN_ADDRESS -p x -t 32" diff --git a/MINE/rin/solo_mining_rpc.sh b/MINE/rin/solo_mining_rpc.sh index 7f44f5d..220e641 100644 --- a/MINE/rin/solo_mining_rpc.sh +++ b/MINE/rin/solo_mining_rpc.sh @@ -1,76 +1,76 @@ -#!/bin/bash +# #!/bin/bash -# RinCoin Solo Mining via RPC -# This script uses RinCoin's RPC interface for solo mining +# # RinCoin Solo Mining via RPC +# # This script uses RinCoin's RPC interface for solo mining -echo "=== RinCoin Solo Mining via RPC ===" -echo "" +# echo "=== RinCoin Solo Mining via RPC ===" +# echo "" -# Configuration -RPC_HOST="127.0.0.1" -RPC_PORT="9556" -RPC_USER="rinrpc" -RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" +# # Configuration +# RPC_HOST="127.0.0.1" +# RPC_PORT="9556" +# RPC_USER="rinrpc" +# RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" -# Function to call RPC -call_rpc() { - local method="$1" - local params="$2" +# # Function to call RPC +# call_rpc() { +# local method="$1" +# local params="$2" - curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ - "http://$RPC_HOST:$RPC_PORT/" -} +# curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ +# "http://$RPC_HOST:$RPC_PORT/" +# } -# Wait for node to be ready -echo "Waiting for RinCoin node to be ready..." -while true; do - response=$(call_rpc "getblockchaininfo" "[]") - if [[ $response != *"Loading block index"* ]]; then - break - fi - echo "Node still loading... waiting 10 seconds" - sleep 10 -done +# # Wait for node to be ready +# echo "Waiting for RinCoin node to be ready..." +# while true; do +# response=$(call_rpc "getblockchaininfo" "[]") +# if [[ $response != *"Loading block index"* ]]; then +# break +# fi +# echo "Node still loading... waiting 10 seconds" +# sleep 10 +# done -echo "โœ… Node is ready!" -echo "" +# echo "โœ… Node is ready!" +# echo "" -# Get wallet address -echo "Getting wallet address..." -wallet_response=$(call_rpc "getnewaddress" "[]") -rin_address=$(echo "$wallet_response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) +# # Get wallet address +# echo "Getting wallet address..." +# wallet_response=$(call_rpc "getnewaddress" "[]") +# rin_address=$(echo "$wallet_response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) -if [ -z "$rin_address" ]; then - echo "โŒ Error: Could not get RinCoin address!" - echo "Response: $wallet_response" - exit 1 -fi +# if [ -z "$rin_address" ]; then +# echo "โŒ Error: Could not get RinCoin address!" +# echo "Response: $wallet_response" +# exit 1 +# fi -echo "โœ… RinCoin Address: $rin_address" -echo "" +# echo "โœ… RinCoin Address: $rin_address" +# echo "" -# Get blockchain info -echo "Blockchain Status:" -blockchain_info=$(call_rpc "getblockchaininfo" "[]") -blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) -headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) -difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) +# # Get blockchain info +# echo "Blockchain Status:" +# blockchain_info=$(call_rpc "getblockchaininfo" "[]") +# blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) +# headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) +# difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) -echo "Blocks: $blocks" -echo "Headers: $headers" -echo "Difficulty: $difficulty" -echo "" +# echo "Blocks: $blocks" +# echo "Headers: $headers" +# echo "Difficulty: $difficulty" +# echo "" -echo "โš ๏ธ IMPORTANT: RinCoin solo mining requires:" -echo "1. A fully synced node (currently at block $blocks of $headers)" -echo "2. Mining software that supports RinCoin's RPC mining protocol" -echo "3. Very high hashpower to find blocks solo" -echo "" -echo "For now, we recommend pool mining for consistent rewards:" -echo "" -echo "Pool Mining Command:" -echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://rinhash.mine.zergpool.com:7148 -u bc1qjn4m6rmrveuxhk02a5qhe4r6kdcsvvt3vhdn9j -p c=BTC,mc=RIN,ID=StrixHalo -t 32\"" -echo "" -echo "Your RinCoin address for solo mining: $rin_address" +# echo "โš ๏ธ IMPORTANT: RinCoin solo mining requires:" +# echo "1. A fully synced node (currently at block $blocks of $headers)" +# echo "2. Mining software that supports RinCoin's RPC mining protocol" +# echo "3. Very high hashpower to find blocks solo" +# echo "" +# echo "For now, we recommend pool mining for consistent rewards:" +# echo "" +# echo "Pool Mining Command:" +# echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://rinhash.mine.zergpool.com:7148 -u bc1qjn4m6rmrveuxhk02a5qhe4r6kdcsvvt3vhdn9j -p c=BTC,mc=RIN,ID=StrixHalo -t 32\"" +# echo "" +# echo "Your RinCoin address for solo mining: $rin_address" diff --git a/MINE/rin/solo_mining_zergpool.sh b/MINE/rin/solo_mining_zergpool.sh index 7f44f5d..220e641 100644 --- a/MINE/rin/solo_mining_zergpool.sh +++ b/MINE/rin/solo_mining_zergpool.sh @@ -1,76 +1,76 @@ -#!/bin/bash +# #!/bin/bash -# RinCoin Solo Mining via RPC -# This script uses RinCoin's RPC interface for solo mining +# # RinCoin Solo Mining via RPC +# # This script uses RinCoin's RPC interface for solo mining -echo "=== RinCoin Solo Mining via RPC ===" -echo "" +# echo "=== RinCoin Solo Mining via RPC ===" +# echo "" -# Configuration -RPC_HOST="127.0.0.1" -RPC_PORT="9556" -RPC_USER="rinrpc" -RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" +# # Configuration +# RPC_HOST="127.0.0.1" +# RPC_PORT="9556" +# RPC_USER="rinrpc" +# RPC_PASS="745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90" -# Function to call RPC -call_rpc() { - local method="$1" - local params="$2" +# # Function to call RPC +# call_rpc() { +# local method="$1" +# local params="$2" - curl -s --user "$RPC_USER:$RPC_PASS" \ - -H 'content-type: text/plain' \ - --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ - "http://$RPC_HOST:$RPC_PORT/" -} +# curl -s --user "$RPC_USER:$RPC_PASS" \ +# -H 'content-type: text/plain' \ +# --data "{\"jsonrpc\":\"1.0\",\"id\":\"curl\",\"method\":\"$method\",\"params\":$params}" \ +# "http://$RPC_HOST:$RPC_PORT/" +# } -# Wait for node to be ready -echo "Waiting for RinCoin node to be ready..." -while true; do - response=$(call_rpc "getblockchaininfo" "[]") - if [[ $response != *"Loading block index"* ]]; then - break - fi - echo "Node still loading... waiting 10 seconds" - sleep 10 -done +# # Wait for node to be ready +# echo "Waiting for RinCoin node to be ready..." +# while true; do +# response=$(call_rpc "getblockchaininfo" "[]") +# if [[ $response != *"Loading block index"* ]]; then +# break +# fi +# echo "Node still loading... waiting 10 seconds" +# sleep 10 +# done -echo "โœ… Node is ready!" -echo "" +# echo "โœ… Node is ready!" +# echo "" -# Get wallet address -echo "Getting wallet address..." -wallet_response=$(call_rpc "getnewaddress" "[]") -rin_address=$(echo "$wallet_response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) +# # Get wallet address +# echo "Getting wallet address..." +# wallet_response=$(call_rpc "getnewaddress" "[]") +# rin_address=$(echo "$wallet_response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4) -if [ -z "$rin_address" ]; then - echo "โŒ Error: Could not get RinCoin address!" - echo "Response: $wallet_response" - exit 1 -fi +# if [ -z "$rin_address" ]; then +# echo "โŒ Error: Could not get RinCoin address!" +# echo "Response: $wallet_response" +# exit 1 +# fi -echo "โœ… RinCoin Address: $rin_address" -echo "" +# echo "โœ… RinCoin Address: $rin_address" +# echo "" -# Get blockchain info -echo "Blockchain Status:" -blockchain_info=$(call_rpc "getblockchaininfo" "[]") -blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) -headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) -difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) +# # Get blockchain info +# echo "Blockchain Status:" +# blockchain_info=$(call_rpc "getblockchaininfo" "[]") +# blocks=$(echo "$blockchain_info" | grep -o '"blocks":[^,]*' | cut -d':' -f2) +# headers=$(echo "$blockchain_info" | grep -o '"headers":[^,]*' | cut -d':' -f2) +# difficulty=$(echo "$blockchain_info" | grep -o '"difficulty":[^,]*' | cut -d':' -f2) -echo "Blocks: $blocks" -echo "Headers: $headers" -echo "Difficulty: $difficulty" -echo "" +# echo "Blocks: $blocks" +# echo "Headers: $headers" +# echo "Difficulty: $difficulty" +# echo "" -echo "โš ๏ธ IMPORTANT: RinCoin solo mining requires:" -echo "1. A fully synced node (currently at block $blocks of $headers)" -echo "2. Mining software that supports RinCoin's RPC mining protocol" -echo "3. Very high hashpower to find blocks solo" -echo "" -echo "For now, we recommend pool mining for consistent rewards:" -echo "" -echo "Pool Mining Command:" -echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://rinhash.mine.zergpool.com:7148 -u bc1qjn4m6rmrveuxhk02a5qhe4r6kdcsvvt3vhdn9j -p c=BTC,mc=RIN,ID=StrixHalo -t 32\"" -echo "" -echo "Your RinCoin address for solo mining: $rin_address" +# echo "โš ๏ธ IMPORTANT: RinCoin solo mining requires:" +# echo "1. A fully synced node (currently at block $blocks of $headers)" +# echo "2. Mining software that supports RinCoin's RPC mining protocol" +# echo "3. Very high hashpower to find blocks solo" +# echo "" +# echo "For now, we recommend pool mining for consistent rewards:" +# echo "" +# echo "Pool Mining Command:" +# echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://rinhash.mine.zergpool.com:7148 -u bc1qjn4m6rmrveuxhk02a5qhe4r6kdcsvvt3vhdn9j -p c=BTC,mc=RIN,ID=StrixHalo -t 32\"" +# echo "" +# echo "Your RinCoin address for solo mining: $rin_address" diff --git a/MINE/rin/start_mining_pool.sh b/MINE/rin/start_mining_pool.sh index 9f95eb8..ec4c828 100644 --- a/MINE/rin/start_mining_pool.sh +++ b/MINE/rin/start_mining_pool.sh @@ -1,83 +1,83 @@ -#!/bin/bash +# #!/bin/bash -# RinCoin Mining Pool Server Startup Script -# Distributes block rewards among multiple miners +# # RinCoin Mining Pool Server Startup Script +# # Distributes block rewards among multiple miners -echo "=== RinCoin Mining Pool Server ===" -echo "" +# echo "=== RinCoin Mining Pool Server ===" +# echo "" -# Check if RinCoin node is running -echo "Checking RinCoin node status..." -if ! curl -s -u rinrpc:745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90 \ - -H 'content-type: text/plain' \ - --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ - http://127.0.0.1:9556/ > /dev/null; then - echo "โŒ RinCoin node is not running!" - echo "Start it first with: docker start rincoin-node" - exit 1 -fi +# # Check if RinCoin node is running +# echo "Checking RinCoin node status..." +# if ! curl -s -u rinrpc:745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90 \ +# -H 'content-type: text/plain' \ +# --data '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' \ +# http://127.0.0.1:9556/ > /dev/null; then +# echo "โŒ RinCoin node is not running!" +# echo "Start it first with: docker start rincoin-node" +# exit 1 +# fi -echo "โœ… RinCoin node is running" +# echo "โœ… RinCoin node is running" -# Check Python dependencies -echo "Checking Python dependencies..." -python3 -c "import requests, sqlite3" 2>/dev/null || { - echo "Installing python3-requests..." - sudo apt-get update && sudo apt-get install -y python3-requests -} +# # Check Python dependencies +# echo "Checking Python dependencies..." +# python3 -c "import requests, sqlite3" 2>/dev/null || { +# echo "Installing python3-requests..." +# sudo apt-get update && sudo apt-get install -y python3-requests +# } -echo "โœ… Python dependencies ready" +# echo "โœ… Python dependencies ready" -# Check if port 3333 is already in use -if netstat -tln | grep -q ":3333 "; then - echo "" - echo "โš ๏ธ Port 3333 is already in use!" - echo "" - echo "๐Ÿ” Process using port 3333:" - sudo netstat -tlnp | grep ":3333 " || echo "Could not determine process" - echo "" - echo "๐Ÿ›‘ To kill existing process:" - echo "sudo lsof -ti:3333 | xargs sudo kill -9" - echo "" - read -p "Kill existing process and continue? (y/N): " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Killing processes using port 3333..." - sudo lsof -ti:3333 | xargs sudo kill -9 2>/dev/null || echo "No processes to kill" - sleep 2 - else - echo "Exiting..." - exit 1 - fi -fi +# # Check if port 3333 is already in use +# if netstat -tln | grep -q ":3333 "; then +# echo "" +# echo "โš ๏ธ Port 3333 is already in use!" +# echo "" +# echo "๐Ÿ” Process using port 3333:" +# sudo netstat -tlnp | grep ":3333 " || echo "Could not determine process" +# echo "" +# echo "๐Ÿ›‘ To kill existing process:" +# echo "sudo lsof -ti:3333 | xargs sudo kill -9" +# echo "" +# read -p "Kill existing process and continue? (y/N): " -n 1 -r +# echo +# if [[ $REPLY =~ ^[Yy]$ ]]; then +# echo "Killing processes using port 3333..." +# sudo lsof -ti:3333 | xargs sudo kill -9 2>/dev/null || echo "No processes to kill" +# sleep 2 +# else +# echo "Exiting..." +# exit 1 +# fi +# fi -echo "" -echo "๐Ÿš€ Starting Mining Pool Server..." -echo "This will distribute block rewards among multiple miners" -echo "" -echo "Pool Features:" -echo "- Multiple miner support" -echo "- Share-based reward distribution" -echo "- Pool fee: 1%" -echo "- Real-time statistics" -echo "- Web dashboard on port 8083" -echo "" +# echo "" +# echo "๐Ÿš€ Starting Mining Pool Server..." +# echo "This will distribute block rewards among multiple miners" +# echo "" +# echo "Pool Features:" +# echo "- Multiple miner support" +# echo "- Share-based reward distribution" +# echo "- Pool fee: 1%" +# echo "- Real-time statistics" +# echo "- Web dashboard on port 8083" +# echo "" -echo "After it starts, miners can connect with:" -echo "" -echo "Option 1: Address as username" -echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q -p x" -echo "" -echo "Option 2: Address.workername format" -echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q.worker1 -p x" -echo "" -echo "Option 3: Traditional username (rewards to pool address)" -echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u username.workername -p x" -echo "" -echo "๐ŸŒ Web Dashboard: http://YOUR_IP:8083" -echo "๐Ÿ“Š View real-time pool statistics, miners, and blocks" -echo "" -echo "Press Ctrl+C to stop the pool" +# echo "After it starts, miners can connect with:" +# echo "" +# echo "Option 1: Address as username" +# echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q -p x" +# echo "" +# echo "Option 2: Address.workername format" +# echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q.worker1 -p x" +# echo "" +# echo "Option 3: Traditional username (rewards to pool address)" +# echo "./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u username.workername -p x" +# echo "" +# echo "๐ŸŒ Web Dashboard: http://YOUR_IP:8083" +# echo "๐Ÿ“Š View real-time pool statistics, miners, and blocks" +# echo "" +# echo "Press Ctrl+C to stop the pool" -# Start the mining pool -python3 MINE/rin/stratum_pool.py +# # Start the mining pool +# python3 MINE/rin/stratum_pool.py diff --git a/MINE/rin/start_stratum_proxy.sh b/MINE/rin/start_stratum_proxy.sh index 0d9c82f..1e317f1 100644 --- a/MINE/rin/start_stratum_proxy.sh +++ b/MINE/rin/start_stratum_proxy.sh @@ -1,68 +1,68 @@ -#!/bin/bash +# #!/bin/bash -# Start RinCoin Stratum Proxy Server -# Bridges cpuminer-opt-rin to RinCoin node +# # Start RinCoin Stratum Proxy Server +# # Bridges cpuminer-opt-rin to RinCoin node -echo "=== RinCoin Stratum Proxy Server ===" -echo "" +# echo "=== RinCoin Stratum Proxy Server ===" +# echo "" -# Check if RinCoin node is running -if ! sudo docker ps | grep -q "rincoin-node"; then - echo "โŒ Error: rincoin-node container is not running!" - echo "Please start it first:" - echo "sudo docker start rincoin-node" - exit 1 -fi +# # Check if RinCoin node is running +# if ! sudo docker ps | grep -q "rincoin-node"; then +# echo "โŒ Error: rincoin-node container is not running!" +# echo "Please start it first:" +# echo "sudo docker start rincoin-node" +# exit 1 +# fi -echo "โœ… RinCoin node is running" +# echo "โœ… RinCoin node is running" -# Check if Python3 and requests are available -if ! command -v python3 &> /dev/null; then - echo "โŒ Error: python3 is not installed!" - echo "Please install it: sudo apt-get install python3" - exit 1 -fi +# # Check if Python3 and requests are available +# if ! command -v python3 &> /dev/null; then +# echo "โŒ Error: python3 is not installed!" +# echo "Please install it: sudo apt-get install python3" +# exit 1 +# fi -# Install requests if not available -python3 -c "import requests" 2>/dev/null || { - echo "Installing python3-requests..." - sudo apt-get update && sudo apt-get install -y python3-requests -} +# # Install requests if not available +# python3 -c "import requests" 2>/dev/null || { +# echo "Installing python3-requests..." +# sudo apt-get update && sudo apt-get install -y python3-requests +# } -echo "โœ… Python dependencies ready" +# echo "โœ… Python dependencies ready" -# Check if port 3334 is already in use -if netstat -tln | grep -q ":3334 "; then - echo "" - echo "โš ๏ธ Port 3334 is already in use!" - echo "" - echo "๐Ÿ” Process using port 3334:" - sudo netstat -tlnp | grep ":3334 " || echo "Could not determine process" - echo "" - echo "๐Ÿ›‘ To kill existing process:" - echo "sudo lsof -ti:3334 | xargs sudo kill -9" - echo "" - read -p "Kill existing process and continue? (y/N): " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Killing processes using port 3334..." - sudo lsof -ti:3334 | xargs sudo kill -9 2>/dev/null || echo "No processes to kill" - sleep 2 - else - echo "Exiting..." - exit 1 - fi -fi +# # Check if port 3334 is already in use +# if netstat -tln | grep -q ":3334 "; then +# echo "" +# echo "โš ๏ธ Port 3334 is already in use!" +# echo "" +# echo "๐Ÿ” Process using port 3334:" +# sudo netstat -tlnp | grep ":3334 " || echo "Could not determine process" +# echo "" +# echo "๐Ÿ›‘ To kill existing process:" +# echo "sudo lsof -ti:3334 | xargs sudo kill -9" +# echo "" +# read -p "Kill existing process and continue? (y/N): " -n 1 -r +# echo +# if [[ $REPLY =~ ^[Yy]$ ]]; then +# echo "Killing processes using port 3334..." +# sudo lsof -ti:3334 | xargs sudo kill -9 2>/dev/null || echo "No processes to kill" +# sleep 2 +# else +# echo "Exiting..." +# exit 1 +# fi +# fi -echo "" -echo "๐Ÿš€ Starting Stratum Proxy Server..." -echo "" -echo "After it starts, connect your miner with:" -echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://127.0.0.1:3334 -u user -p pass -t 28\"" -echo "" -echo "Press Ctrl+C to stop the proxy" -echo "" +# echo "" +# echo "๐Ÿš€ Starting Stratum Proxy Server..." +# echo "" +# echo "After it starts, connect your miner with:" +# echo "sudo docker exec -it amd-strix-halo-llama-rocm bash -c \"/mnt/dl/rinhash/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://127.0.0.1:3334 -u user -p pass -t 28\"" +# echo "" +# echo "Press Ctrl+C to stop the proxy" +# echo "" -# Start the proxy -cd "$(dirname "$0")" -python3 stratum_proxy.py --submit-all-blocks +# # Start the proxy +# cd "$(dirname "$0")" +# python3 stratum_proxy.py --submit-all-blocks diff --git a/MINE/rin/start_web_wallet.sh b/MINE/rin/start_web_wallet.sh index 930ee98..9de5c6f 100644 --- a/MINE/rin/start_web_wallet.sh +++ b/MINE/rin/start_web_wallet.sh @@ -1,14 +1,14 @@ -#!/bin/bash +# #!/bin/bash -set -euo pipefail +# set -euo pipefail -SCRIPT_DIR="/mnt/shared/DEV/repos/d-popov.com/scripts/MINE/rin/web_wallet" +# SCRIPT_DIR="/mnt/shared/DEV/repos/d-popov.com/scripts/MINE/rin/web_wallet" -if ! command -v python3 >/dev/null 2>&1; then - echo "python3 is required" - exit 1 -fi +# if ! command -v python3 >/dev/null 2>&1; then +# echo "python3 is required" +# exit 1 +# fi -python3 "${SCRIPT_DIR}/server.py" +# python3 "${SCRIPT_DIR}/server.py" diff --git a/MINE/rin/stratum_pool.py b/MINE/rin/stratum_pool.py index cba81a2..5ef3e8a 100644 --- a/MINE/rin/stratum_pool.py +++ b/MINE/rin/stratum_pool.py @@ -1,602 +1,602 @@ -#!/usr/bin/env python3 -""" -RinCoin Mining Pool Server -Distributes block rewards among multiple miners based on share contributions -""" +# #!/usr/bin/env python3 +# """ +# RinCoin Mining Pool Server +# Distributes block rewards among multiple miners based on share contributions +# """ -import socket -import threading -import json -import time -import requests -import hashlib -import struct -import sqlite3 -from datetime import datetime -from requests.auth import HTTPBasicAuth +# import socket +# import threading +# import json +# import time +# import requests +# import hashlib +# import struct +# import sqlite3 +# from datetime import datetime +# from requests.auth import HTTPBasicAuth -# Import web interface -from pool_web_interface import start_web_interface +# # Import web interface +# from pool_web_interface import start_web_interface -# Import stratum base class -from stratum_proxy import RinCoinStratumBase +# # Import stratum base class +# from stratum_proxy import RinCoinStratumBase -class RinCoinMiningPool(RinCoinStratumBase): - def __init__(self, stratum_host='0.0.0.0', stratum_port=3333, - rpc_host='127.0.0.1', rpc_port=9556, - rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90', - pool_address='rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q', - pool_fee_percent=1.0): +# class RinCoinMiningPool(RinCoinStratumBase): +# def __init__(self, stratum_host='0.0.0.0', stratum_port=3333, +# rpc_host='127.0.0.1', rpc_port=9556, +# rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90', +# pool_address='rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q', +# pool_fee_percent=1.0): - # Initialize base class - super().__init__(stratum_host, stratum_port, rpc_host, rpc_port, rpc_user, rpc_password, pool_address) +# # Initialize base class +# super().__init__(stratum_host, stratum_port, rpc_host, rpc_port, rpc_user, rpc_password, pool_address) - self.pool_address = pool_address - self.pool_fee_percent = pool_fee_percent +# self.pool_address = pool_address +# self.pool_fee_percent = pool_fee_percent - # Pool statistics - self.total_shares = 0 - self.total_blocks = 0 - self.pool_hashrate = 0 +# # Pool statistics +# self.total_shares = 0 +# self.total_blocks = 0 +# self.pool_hashrate = 0 - # Database for persistent storage - self.init_database() +# # Database for persistent storage +# self.init_database() - print(f"=== RinCoin Mining Pool Server ===") - print(f"Stratum: {stratum_host}:{stratum_port}") - print(f"RPC: {rpc_host}:{rpc_port}") - print(f"Pool Address: {pool_address}") - print(f"Pool Fee: {pool_fee_percent}%") +# print(f"=== RinCoin Mining Pool Server ===") +# print(f"Stratum: {stratum_host}:{stratum_port}") +# print(f"RPC: {rpc_host}:{rpc_port}") +# print(f"Pool Address: {pool_address}") +# print(f"Pool Fee: {pool_fee_percent}%") - def init_database(self): - """Initialize SQLite database for miner tracking""" - self.db = sqlite3.connect(':memory:', check_same_thread=False) - cursor = self.db.cursor() +# def init_database(self): +# """Initialize SQLite database for miner tracking""" +# self.db = sqlite3.connect(':memory:', check_same_thread=False) +# cursor = self.db.cursor() - # Create tables - cursor.execute(''' - CREATE TABLE IF NOT EXISTS miners ( - id INTEGER PRIMARY KEY, - user TEXT NOT NULL, - worker TEXT NOT NULL, - address TEXT, - shares INTEGER DEFAULT 0, - last_share TIMESTAMP, - last_hashrate REAL DEFAULT 0, - created TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ) - ''') +# # Create tables +# cursor.execute(''' +# CREATE TABLE IF NOT EXISTS miners ( +# id INTEGER PRIMARY KEY, +# user TEXT NOT NULL, +# worker TEXT NOT NULL, +# address TEXT, +# shares INTEGER DEFAULT 0, +# last_share TIMESTAMP, +# last_hashrate REAL DEFAULT 0, +# created TIMESTAMP DEFAULT CURRENT_TIMESTAMP +# ) +# ''') - cursor.execute(''' - CREATE TABLE IF NOT EXISTS shares ( - id INTEGER PRIMARY KEY, - miner_id INTEGER, - job_id TEXT, - difficulty REAL, - submitted TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (miner_id) REFERENCES miners (id) - ) - ''') +# cursor.execute(''' +# CREATE TABLE IF NOT EXISTS shares ( +# id INTEGER PRIMARY KEY, +# miner_id INTEGER, +# job_id TEXT, +# difficulty REAL, +# submitted TIMESTAMP DEFAULT CURRENT_TIMESTAMP, +# FOREIGN KEY (miner_id) REFERENCES miners (id) +# ) +# ''') - cursor.execute(''' - CREATE TABLE IF NOT EXISTS blocks ( - id INTEGER PRIMARY KEY, - block_hash TEXT, - height INTEGER, - reward REAL, - pool_fee REAL, - miner_rewards TEXT, -- JSON of {address: amount} - found_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ) - ''') +# cursor.execute(''' +# CREATE TABLE IF NOT EXISTS blocks ( +# id INTEGER PRIMARY KEY, +# block_hash TEXT, +# height INTEGER, +# reward REAL, +# pool_fee REAL, +# miner_rewards TEXT, -- JSON of {address: amount} +# found_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +# ) +# ''') - # Samples for pool hashrate chart - cursor.execute(''' - CREATE TABLE IF NOT EXISTS hashrate_samples ( - id INTEGER PRIMARY KEY, - ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - hashrate REAL - ) - ''') +# # Samples for pool hashrate chart +# cursor.execute(''' +# CREATE TABLE IF NOT EXISTS hashrate_samples ( +# id INTEGER PRIMARY KEY, +# ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, +# hashrate REAL +# ) +# ''') - self.db.commit() +# self.db.commit() - def get_pool_block_template(self): - """Get new block template and create pool-style job""" - template = super().get_block_template() - if template: - # Convert to pool-style job format if needed - job = self.current_job - if job: - # Add pool-specific fields - job["coinb1"] = "01000000" + "0" * 60 - job["coinb2"] = "ffffffff" - job["merkle_branch"] = [] - job["clean_jobs"] = True - return job - return None +# def get_pool_block_template(self): +# """Get new block template and create pool-style job""" +# template = super().get_block_template() +# if template: +# # Convert to pool-style job format if needed +# job = self.current_job +# if job: +# # Add pool-specific fields +# job["coinb1"] = "01000000" + "0" * 60 +# job["coinb2"] = "ffffffff" +# job["merkle_branch"] = [] +# job["clean_jobs"] = True +# return job +# return None - def validate_rincoin_address(self, address): - """Validate if an address is a valid RinCoin address""" - try: - return self.decode_bech32_address(address) is not None - except: - return False +# def validate_rincoin_address(self, address): +# """Validate if an address is a valid RinCoin address""" +# try: +# return self.decode_bech32_address(address) is not None +# except: +# return False - def register_miner(self, user, worker, address=None): - """Register or update miner in database""" - cursor = self.db.cursor() +# def register_miner(self, user, worker, address=None): +# """Register or update miner in database""" +# cursor = self.db.cursor() - # Check if miner exists - cursor.execute('SELECT id, address FROM miners WHERE user = ? AND worker = ?', (user, worker)) - result = cursor.fetchone() +# # Check if miner exists +# cursor.execute('SELECT id, address FROM miners WHERE user = ? AND worker = ?', (user, worker)) +# result = cursor.fetchone() - if result: - miner_id, existing_address = result - if address and not existing_address: - cursor.execute('UPDATE miners SET address = ? WHERE id = ?', (address, miner_id)) - self.db.commit() - return miner_id - else: - # Create new miner - cursor.execute('INSERT INTO miners (user, worker, address) VALUES (?, ?, ?)', (user, worker, address)) - self.db.commit() - return cursor.lastrowid +# if result: +# miner_id, existing_address = result +# if address and not existing_address: +# cursor.execute('UPDATE miners SET address = ? WHERE id = ?', (address, miner_id)) +# self.db.commit() +# return miner_id +# else: +# # Create new miner +# cursor.execute('INSERT INTO miners (user, worker, address) VALUES (?, ?, ?)', (user, worker, address)) +# self.db.commit() +# return cursor.lastrowid - def record_share(self, miner_id, job_id, difficulty): - """Record a share submission""" - cursor = self.db.cursor() +# def record_share(self, miner_id, job_id, difficulty): +# """Record a share submission""" +# cursor = self.db.cursor() - # Record share - cursor.execute('INSERT INTO shares (miner_id, job_id, difficulty) VALUES (?, ?, ?)', - (miner_id, job_id, difficulty)) +# # Record share +# cursor.execute('INSERT INTO shares (miner_id, job_id, difficulty) VALUES (?, ?, ?)', +# (miner_id, job_id, difficulty)) - # Update miner stats - cursor.execute('UPDATE miners SET shares = shares + 1, last_share = CURRENT_TIMESTAMP WHERE id = ?', (miner_id,)) +# # Update miner stats +# cursor.execute('UPDATE miners SET shares = shares + 1, last_share = CURRENT_TIMESTAMP WHERE id = ?', (miner_id,)) - self.db.commit() - self.total_shares += 1 +# self.db.commit() +# self.total_shares += 1 - def distribute_block_reward(self, block_hash, block_height, total_reward): - """Distribute block reward among miners based on their shares""" - cursor = self.db.cursor() +# def distribute_block_reward(self, block_hash, block_height, total_reward): +# """Distribute block reward among miners based on their shares""" +# cursor = self.db.cursor() - # Calculate pool fee - pool_fee = total_reward * (self.pool_fee_percent / 100.0) - miner_reward = total_reward - pool_fee +# # Calculate pool fee +# pool_fee = total_reward * (self.pool_fee_percent / 100.0) +# miner_reward = total_reward - pool_fee - # Get shares from last 24 hours - cursor.execute(''' - SELECT m.address, COUNT(s.id) as share_count, SUM(s.difficulty) as total_difficulty - FROM miners m - JOIN shares s ON m.id = s.miner_id - WHERE s.submitted > datetime('now', '-1 day') - GROUP BY m.id, m.address - HAVING share_count > 0 - ''') +# # Get shares from last 24 hours +# cursor.execute(''' +# SELECT m.address, COUNT(s.id) as share_count, SUM(s.difficulty) as total_difficulty +# FROM miners m +# JOIN shares s ON m.id = s.miner_id +# WHERE s.submitted > datetime('now', '-1 day') +# GROUP BY m.id, m.address +# HAVING share_count > 0 +# ''') - miners = cursor.fetchall() +# miners = cursor.fetchall() - if not miners: - print("No miners with shares in last 24 hours") - return +# if not miners: +# print("No miners with shares in last 24 hours") +# return - # Calculate total difficulty - total_difficulty = sum(row[2] for row in miners) +# # Calculate total difficulty +# total_difficulty = sum(row[2] for row in miners) - # Separate miners with and without addresses - miners_with_addresses = [] - miners_without_addresses = [] - total_difficulty_with_addresses = 0 - total_difficulty_without_addresses = 0 +# # Separate miners with and without addresses +# miners_with_addresses = [] +# miners_without_addresses = [] +# total_difficulty_with_addresses = 0 +# total_difficulty_without_addresses = 0 - for address, share_count, difficulty in miners: - if address: - miners_with_addresses.append((address, share_count, difficulty)) - total_difficulty_with_addresses += difficulty - else: - miners_without_addresses.append((address, share_count, difficulty)) - total_difficulty_without_addresses += difficulty +# for address, share_count, difficulty in miners: +# if address: +# miners_with_addresses.append((address, share_count, difficulty)) +# total_difficulty_with_addresses += difficulty +# else: +# miners_without_addresses.append((address, share_count, difficulty)) +# total_difficulty_without_addresses += difficulty - # Calculate total difficulty - total_difficulty = total_difficulty_with_addresses + total_difficulty_without_addresses +# # Calculate total difficulty +# total_difficulty = total_difficulty_with_addresses + total_difficulty_without_addresses - if total_difficulty == 0: - print("No valid difficulty found") - return +# if total_difficulty == 0: +# print("No valid difficulty found") +# return - # Distribute rewards - miner_rewards = {} +# # Distribute rewards +# miner_rewards = {} - # First, distribute to miners with valid addresses - if miners_with_addresses: - for address, share_count, difficulty in miners_with_addresses: - reward_share = (difficulty / total_difficulty) * miner_reward - miner_rewards[address] = reward_share - print(f"๐Ÿ’ฐ Miner {address}: {reward_share:.8f} RIN ({difficulty} difficulty)") +# # First, distribute to miners with valid addresses +# if miners_with_addresses: +# for address, share_count, difficulty in miners_with_addresses: +# reward_share = (difficulty / total_difficulty) * miner_reward +# miner_rewards[address] = reward_share +# print(f"๐Ÿ’ฐ Miner {address}: {reward_share:.8f} RIN ({difficulty} difficulty)") - # Calculate undistributed rewards (from miners without addresses) - if miners_without_addresses: - undistributed_reward = 0 - for address, share_count, difficulty in miners_without_addresses: - undistributed_reward += (difficulty / total_difficulty) * miner_reward - print(f"โš ๏ธ Miner without address: {difficulty} difficulty -> {undistributed_reward:.8f} RIN to pool") +# # Calculate undistributed rewards (from miners without addresses) +# if miners_without_addresses: +# undistributed_reward = 0 +# for address, share_count, difficulty in miners_without_addresses: +# undistributed_reward += (difficulty / total_difficulty) * miner_reward +# print(f"โš ๏ธ Miner without address: {difficulty} difficulty -> {undistributed_reward:.8f} RIN to pool") - # Keep undistributed rewards for pool (no redistribution) - print(f"๐Ÿ’ฐ Pool keeps {undistributed_reward:.8f} RIN from miners without addresses") +# # Keep undistributed rewards for pool (no redistribution) +# print(f"๐Ÿ’ฐ Pool keeps {undistributed_reward:.8f} RIN from miners without addresses") - # Record block - cursor.execute(''' - INSERT INTO blocks (block_hash, height, reward, pool_fee, miner_rewards) - VALUES (?, ?, ?, ?, ?) - ''', (block_hash, block_height, total_reward, pool_fee, json.dumps(miner_rewards))) +# # Record block +# cursor.execute(''' +# INSERT INTO blocks (block_hash, height, reward, pool_fee, miner_rewards) +# VALUES (?, ?, ?, ?, ?) +# ''', (block_hash, block_height, total_reward, pool_fee, json.dumps(miner_rewards))) - self.db.commit() - self.total_blocks += 1 +# self.db.commit() +# self.total_blocks += 1 - print(f"๐ŸŽ‰ Block {block_height} reward distributed!") - print(f"๐Ÿ’ฐ Pool fee: {pool_fee:.8f} RIN") - print(f"๐Ÿ’ฐ Total distributed: {sum(miner_rewards.values()):.8f} RIN") +# print(f"๐ŸŽ‰ Block {block_height} reward distributed!") +# print(f"๐Ÿ’ฐ Pool fee: {pool_fee:.8f} RIN") +# print(f"๐Ÿ’ฐ Total distributed: {sum(miner_rewards.values()):.8f} RIN") - # Summary - if miners_without_addresses: - print(f"๐Ÿ“Š Summary: {len(miners_with_addresses)} miners with addresses, {len(miners_without_addresses)} without (rewards to pool)") +# # Summary +# if miners_without_addresses: +# print(f"๐Ÿ“Š Summary: {len(miners_with_addresses)} miners with addresses, {len(miners_without_addresses)} without (rewards to pool)") - # Use inherited send_stratum_response and send_stratum_notification from base class +# # Use inherited send_stratum_response and send_stratum_notification from base class - def handle_stratum_message(self, client, addr, message): - """Handle incoming Stratum message from miner""" - try: - data = json.loads(message.strip()) - method = data.get("method") - msg_id = data.get("id") - params = data.get("params", []) +# def handle_stratum_message(self, client, addr, message): +# """Handle incoming Stratum message from miner""" +# try: +# data = json.loads(message.strip()) +# method = data.get("method") +# msg_id = data.get("id") +# params = data.get("params", []) - print(f"[{addr}] {method}: {params}") +# print(f"[{addr}] {method}: {params}") - if method == "mining.subscribe": - # Subscribe response - self.send_stratum_response(client, msg_id, [ - [["mining.set_difficulty", "subscription_id"], ["mining.notify", "subscription_id"]], - "extranonce1", - 4 - ]) +# if method == "mining.subscribe": +# # Subscribe response +# self.send_stratum_response(client, msg_id, [ +# [["mining.set_difficulty", "subscription_id"], ["mining.notify", "subscription_id"]], +# "extranonce1", +# 4 +# ]) - # Send difficulty (lower for CPU mining) - self.send_stratum_notification(client, "mining.set_difficulty", [0.0001]) +# # Send difficulty (lower for CPU mining) +# self.send_stratum_notification(client, "mining.set_difficulty", [0.0001]) - # Send initial job - if self.get_pool_block_template(): - job = self.current_job - self.send_stratum_notification(client, "mining.notify", [ - job["job_id"], - job["prevhash"], - job["coinb1"], - job["coinb2"], - job["merkle_branch"], - f"{job['version']:08x}", - job["bits"], - job["ntime"], - job["clean_jobs"] - ]) +# # Send initial job +# if self.get_pool_block_template(): +# job = self.current_job +# self.send_stratum_notification(client, "mining.notify", [ +# job["job_id"], +# job["prevhash"], +# job["coinb1"], +# job["coinb2"], +# job["merkle_branch"], +# f"{job['version']:08x}", +# job["bits"], +# job["ntime"], +# job["clean_jobs"] +# ]) - elif method == "mining.extranonce.subscribe": - # Handle extranonce subscription - print(f"[{addr}] Extranonce subscription requested") - self.send_stratum_response(client, msg_id, True) +# elif method == "mining.extranonce.subscribe": +# # Handle extranonce subscription +# print(f"[{addr}] Extranonce subscription requested") +# self.send_stratum_response(client, msg_id, True) - elif method == "mining.authorize": - # Parse user.worker format - if len(params) >= 2: - user_worker = params[0] - password = params[1] if len(params) > 1 else "" +# elif method == "mining.authorize": +# # Parse user.worker format +# if len(params) >= 2: +# user_worker = params[0] +# password = params[1] if len(params) > 1 else "" - # Extract user and worker - if '.' in user_worker: - user, worker = user_worker.split('.', 1) - else: - user = user_worker - worker = "default" +# # Extract user and worker +# if '.' in user_worker: +# user, worker = user_worker.split('.', 1) +# else: +# user = user_worker +# worker = "default" - # Check if user contains a RinCoin address (starts with 'rin') - miner_address = None - if user.startswith('rin'): - # User is a RinCoin address - if self.validate_rincoin_address(user): - miner_address = user - user = f"miner_{miner_address[:8]}" # Create a user ID from address - print(f"[{addr}] โœ… Miner using valid RinCoin address: {miner_address}") - else: - print(f"[{addr}] โŒ Invalid RinCoin address: {user}") - self.send_stratum_response(client, msg_id, False, "Invalid RinCoin address") - return - elif '.' in user and user.split('.')[0].startswith('rin'): - # Format: rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q.workername - address_part, worker_part = user.split('.', 1) - if address_part.startswith('rin'): - if self.validate_rincoin_address(address_part): - miner_address = address_part - user = f"miner_{miner_address[:8]}" - worker = worker_part - print(f"[{addr}] โœ… Miner using valid RinCoin address format: {miner_address}.{worker}") - else: - print(f"[{addr}] โŒ Invalid RinCoin address: {address_part}") - self.send_stratum_response(client, msg_id, False, "Invalid RinCoin address") - return +# # Check if user contains a RinCoin address (starts with 'rin') +# miner_address = None +# if user.startswith('rin'): +# # User is a RinCoin address +# if self.validate_rincoin_address(user): +# miner_address = user +# user = f"miner_{miner_address[:8]}" # Create a user ID from address +# print(f"[{addr}] โœ… Miner using valid RinCoin address: {miner_address}") +# else: +# print(f"[{addr}] โŒ Invalid RinCoin address: {user}") +# self.send_stratum_response(client, msg_id, False, "Invalid RinCoin address") +# return +# elif '.' in user and user.split('.')[0].startswith('rin'): +# # Format: rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q.workername +# address_part, worker_part = user.split('.', 1) +# if address_part.startswith('rin'): +# if self.validate_rincoin_address(address_part): +# miner_address = address_part +# user = f"miner_{miner_address[:8]}" +# worker = worker_part +# print(f"[{addr}] โœ… Miner using valid RinCoin address format: {miner_address}.{worker}") +# else: +# print(f"[{addr}] โŒ Invalid RinCoin address: {address_part}") +# self.send_stratum_response(client, msg_id, False, "Invalid RinCoin address") +# return - # Register miner with address - miner_id = self.register_miner(user, worker, miner_address) +# # Register miner with address +# miner_id = self.register_miner(user, worker, miner_address) - # Store client info - self.clients[addr] = { - 'client': client, - 'user': user, - 'worker': worker, - 'miner_id': miner_id, - 'address': miner_address, - 'shares': 0, - 'last_share': time.time(), - 'extranonce1': '00000000' # Default extranonce1 - } +# # Store client info +# self.clients[addr] = { +# 'client': client, +# 'user': user, +# 'worker': worker, +# 'miner_id': miner_id, +# 'address': miner_address, +# 'shares': 0, +# 'last_share': time.time(), +# 'extranonce1': '00000000' # Default extranonce1 +# } - if miner_address: - print(f"[{addr}] โœ… Authorized: {user}.{worker} -> {miner_address}") - else: - print(f"[{addr}] โš ๏ธ Authorized: {user}.{worker} (rewards will go to pool address)") - self.send_stratum_response(client, msg_id, True) - else: - self.send_stratum_response(client, msg_id, False, "Invalid authorization") +# if miner_address: +# print(f"[{addr}] โœ… Authorized: {user}.{worker} -> {miner_address}") +# else: +# print(f"[{addr}] โš ๏ธ Authorized: {user}.{worker} (rewards will go to pool address)") +# self.send_stratum_response(client, msg_id, True) +# else: +# self.send_stratum_response(client, msg_id, False, "Invalid authorization") - elif method == "mining.submit": - # Submit share - if addr not in self.clients: - self.send_stratum_response(client, msg_id, False, "Not authorized") - return +# elif method == "mining.submit": +# # Submit share +# if addr not in self.clients: +# self.send_stratum_response(client, msg_id, False, "Not authorized") +# return - miner_info = self.clients[addr] +# miner_info = self.clients[addr] - try: - if self.current_job and len(params) >= 5: - username = params[0] - job_id = params[1] - extranonce2 = params[2] - ntime = params[3] - nonce = params[4] +# try: +# if self.current_job and len(params) >= 5: +# username = params[0] +# job_id = params[1] +# extranonce2 = params[2] +# ntime = params[3] +# nonce = params[4] - # Use base class to validate and submit share - extranonce1 = miner_info.get('extranonce1', '00000000') - miner_address = miner_info.get('address') +# # Use base class to validate and submit share +# extranonce1 = miner_info.get('extranonce1', '00000000') +# miner_address = miner_info.get('address') - # For pool mining, always mine to pool address - success, message = self.submit_share( - self.current_job, extranonce1, extranonce2, ntime, nonce, - target_address=self.pool_address - ) +# # For pool mining, always mine to pool address +# success, message = self.submit_share( +# self.current_job, extranonce1, extranonce2, ntime, nonce, +# target_address=self.pool_address +# ) - if success: - # Record share with estimated difficulty - actual_difficulty = 0.00133 # Estimated for ~381 kH/s - self.record_share(miner_info['miner_id'], job_id, actual_difficulty) +# if success: +# # Record share with estimated difficulty +# actual_difficulty = 0.00133 # Estimated for ~381 kH/s +# self.record_share(miner_info['miner_id'], job_id, actual_difficulty) - # Update miner stats - now_ts = time.time() - prev_ts = miner_info.get('last_share') or now_ts - dt = max(now_ts - prev_ts, 1e-3) - miner_hashrate = actual_difficulty * (2**32) / dt +# # Update miner stats +# now_ts = time.time() +# prev_ts = miner_info.get('last_share') or now_ts +# dt = max(now_ts - prev_ts, 1e-3) +# miner_hashrate = actual_difficulty * (2**32) / dt - if miner_info['shares'] == 0: - miner_hashrate = 381000 # Default estimate - miner_info['shares'] += 1 - miner_info['last_share'] = now_ts +# if miner_info['shares'] == 0: +# miner_hashrate = 381000 # Default estimate +# miner_info['shares'] += 1 +# miner_info['last_share'] = now_ts - # Update database - try: - cursor = self.db.cursor() - cursor.execute('UPDATE miners SET last_share = CURRENT_TIMESTAMP, last_hashrate = ? WHERE id = ?', - (miner_hashrate, miner_info['miner_id'])) - self.db.commit() - except Exception as e: - print(f"DB update error: {e}") +# # Update database +# try: +# cursor = self.db.cursor() +# cursor.execute('UPDATE miners SET last_share = CURRENT_TIMESTAMP, last_hashrate = ? WHERE id = ?', +# (miner_hashrate, miner_info['miner_id'])) +# self.db.commit() +# except Exception as e: +# print(f"DB update error: {e}") - print(f"[{addr}] โœ… Share accepted from {miner_info['user']}.{miner_info['worker']} (Total: {miner_info['shares']})") - self.send_stratum_response(client, msg_id, True) +# print(f"[{addr}] โœ… Share accepted from {miner_info['user']}.{miner_info['worker']} (Total: {miner_info['shares']})") +# self.send_stratum_response(client, msg_id, True) - # If block was found, distribute rewards - if "Block found" in message: - print(f"๐ŸŽ‰ [{addr}] BLOCK FOUND!") - # Get block info and distribute rewards - total_reward = self.current_job['coinbasevalue'] / 100000000 if self.current_job else 25.0 - self.distribute_block_reward("pending", self.current_job['height'] if self.current_job else 0, total_reward) - else: - # Accept as share for pool statistics even if block validation fails - self.send_stratum_response(client, msg_id, True) - else: - print(f"[{addr}] Invalid share parameters") - self.send_stratum_response(client, msg_id, False, "Invalid parameters") +# # If block was found, distribute rewards +# if "Block found" in message: +# print(f"๐ŸŽ‰ [{addr}] BLOCK FOUND!") +# # Get block info and distribute rewards +# total_reward = self.current_job['coinbasevalue'] / 100000000 if self.current_job else 25.0 +# self.distribute_block_reward("pending", self.current_job['height'] if self.current_job else 0, total_reward) +# else: +# # Accept as share for pool statistics even if block validation fails +# self.send_stratum_response(client, msg_id, True) +# else: +# print(f"[{addr}] Invalid share parameters") +# self.send_stratum_response(client, msg_id, False, "Invalid parameters") - except Exception as e: - print(f"[{addr}] Share processing error: {e}") - # Still accept the share for mining statistics - self.send_stratum_response(client, msg_id, True) +# except Exception as e: +# print(f"[{addr}] Share processing error: {e}") +# # Still accept the share for mining statistics +# self.send_stratum_response(client, msg_id, True) - else: - print(f"[{addr}] โš ๏ธ Unknown method: {method}") - # Send null result for unknown methods (standard Stratum behavior) - self.send_stratum_response(client, msg_id, None, None) +# else: +# print(f"[{addr}] โš ๏ธ Unknown method: {method}") +# # Send null result for unknown methods (standard Stratum behavior) +# self.send_stratum_response(client, msg_id, None, None) - except json.JSONDecodeError: - print(f"[{addr}] Invalid JSON: {message}") - except Exception as e: - print(f"[{addr}] Message handling error: {e}") +# except json.JSONDecodeError: +# print(f"[{addr}] Invalid JSON: {message}") +# except Exception as e: +# print(f"[{addr}] Message handling error: {e}") - def handle_client(self, client, addr): - """Handle individual client connection""" - print(f"[{addr}] Connected") +# def handle_client(self, client, addr): +# """Handle individual client connection""" +# print(f"[{addr}] Connected") - try: - while self.running: - data = client.recv(4096) - if not data: - break +# try: +# while self.running: +# data = client.recv(4096) +# if not data: +# break - # Handle multiple messages in one packet - messages = data.decode('utf-8').strip().split('\n') - for message in messages: - if message: - self.handle_stratum_message(client, addr, message) +# # Handle multiple messages in one packet +# messages = data.decode('utf-8').strip().split('\n') +# for message in messages: +# if message: +# self.handle_stratum_message(client, addr, message) - except Exception as e: - print(f"[{addr}] Client error: {e}") - finally: - client.close() - if addr in self.clients: - del self.clients[addr] - print(f"[{addr}] Disconnected") +# except Exception as e: +# print(f"[{addr}] Client error: {e}") +# finally: +# client.close() +# if addr in self.clients: +# del self.clients[addr] +# print(f"[{addr}] Disconnected") - def job_updater(self): - """Periodically update mining jobs""" - last_job_time = 0 - last_block_height = 0 +# def job_updater(self): +# """Periodically update mining jobs""" +# last_job_time = 0 +# last_block_height = 0 - while self.running: - try: - # Check for new blocks every 10 seconds - time.sleep(10) +# while self.running: +# try: +# # Check for new blocks every 10 seconds +# time.sleep(10) - # Get current blockchain info - blockchain_info = self.rpc_call("getblockchaininfo") - if blockchain_info: - current_height = blockchain_info.get('blocks', 0) +# # Get current blockchain info +# blockchain_info = self.rpc_call("getblockchaininfo") +# if blockchain_info: +# current_height = blockchain_info.get('blocks', 0) - # Create new job if: - # 1. New block detected - # 2. 30+ seconds since last job - # 3. No current job exists - should_create_job = ( - current_height != last_block_height or - time.time() - last_job_time > 30 or - not self.current_job - ) +# # Create new job if: +# # 1. New block detected +# # 2. 30+ seconds since last job +# # 3. No current job exists +# should_create_job = ( +# current_height != last_block_height or +# time.time() - last_job_time > 30 or +# not self.current_job +# ) - if should_create_job: - if self.get_pool_block_template(): - job = self.current_job - last_job_time = time.time() - last_block_height = current_height +# if should_create_job: +# if self.get_pool_block_template(): +# job = self.current_job +# last_job_time = time.time() +# last_block_height = current_height - print(f"๐Ÿ“ฆ New job created: {job['job_id']} (block {current_height})") +# print(f"๐Ÿ“ฆ New job created: {job['job_id']} (block {current_height})") - # Send to all connected clients - for addr, miner_info in list(self.clients.items()): - try: - self.send_stratum_notification(miner_info['client'], "mining.notify", [ - job["job_id"], - job["prevhash"], - job["coinb1"], - job["coinb2"], - job["merkle_branch"], - f"{job['version']:08x}", - job["bits"], - job["ntime"], - job["clean_jobs"] - ]) - except Exception as e: - print(f"Failed to send job to {addr}: {e}") +# # Send to all connected clients +# for addr, miner_info in list(self.clients.items()): +# try: +# self.send_stratum_notification(miner_info['client'], "mining.notify", [ +# job["job_id"], +# job["prevhash"], +# job["coinb1"], +# job["coinb2"], +# job["merkle_branch"], +# f"{job['version']:08x}", +# job["bits"], +# job["ntime"], +# job["clean_jobs"] +# ]) +# except Exception as e: +# print(f"Failed to send job to {addr}: {e}") - except Exception as e: - print(f"Job updater error: {e}") +# except Exception as e: +# print(f"Job updater error: {e}") - def stats_updater(self): - """Periodically update pool statistics""" - while self.running: - try: - time.sleep(60) # Update every minute - cursor = self.db.cursor() - # Pool hashrate is the sum of miners' last hashrates - cursor.execute('SELECT COALESCE(SUM(last_hashrate), 0) FROM miners') - self.pool_hashrate = cursor.fetchone()[0] or 0.0 - # Sample for chart - cursor.execute('INSERT INTO hashrate_samples (hashrate) VALUES (?)', (self.pool_hashrate,)) - self.db.commit() - print(f"๐Ÿ“Š Pool Stats: {len(self.clients)} miners, {self.total_shares} shares, {self.pool_hashrate/1000:.2f} kH/s") +# def stats_updater(self): +# """Periodically update pool statistics""" +# while self.running: +# try: +# time.sleep(60) # Update every minute +# cursor = self.db.cursor() +# # Pool hashrate is the sum of miners' last hashrates +# cursor.execute('SELECT COALESCE(SUM(last_hashrate), 0) FROM miners') +# self.pool_hashrate = cursor.fetchone()[0] or 0.0 +# # Sample for chart +# cursor.execute('INSERT INTO hashrate_samples (hashrate) VALUES (?)', (self.pool_hashrate,)) +# self.db.commit() +# print(f"๐Ÿ“Š Pool Stats: {len(self.clients)} miners, {self.total_shares} shares, {self.pool_hashrate/1000:.2f} kH/s") - except Exception as e: - print(f"Stats updater error: {e}") +# except Exception as e: +# print(f"Stats updater error: {e}") - def start(self): - """Start the mining pool server""" - try: - # Test RPC connection - blockchain_info = self.rpc_call("getblockchaininfo") - if not blockchain_info: - print("โŒ Failed to connect to RinCoin node!") - return +# def start(self): +# """Start the mining pool server""" +# try: +# # Test RPC connection +# blockchain_info = self.rpc_call("getblockchaininfo") +# if not blockchain_info: +# print("โŒ Failed to connect to RinCoin node!") +# return - print(f"โœ… Connected to RinCoin node (block {blockchain_info.get('blocks', 'unknown')})") +# print(f"โœ… Connected to RinCoin node (block {blockchain_info.get('blocks', 'unknown')})") - # Start background threads - job_thread = threading.Thread(target=self.job_updater, daemon=True) - job_thread.start() +# # Start background threads +# job_thread = threading.Thread(target=self.job_updater, daemon=True) +# job_thread.start() - stats_thread = threading.Thread(target=self.stats_updater, daemon=True) - stats_thread.start() +# stats_thread = threading.Thread(target=self.stats_updater, daemon=True) +# stats_thread.start() - # Start web interface in background - web_thread = threading.Thread(target=start_web_interface, - args=(self.db, '0.0.0.0', 8083, - self.rpc_host, self.rpc_port, - self.rpc_user, self.rpc_password), - daemon=True) - web_thread.start() +# # Start web interface in background +# web_thread = threading.Thread(target=start_web_interface, +# args=(self.db, '0.0.0.0', 8083, +# self.rpc_host, self.rpc_port, +# self.rpc_user, self.rpc_password), +# daemon=True) +# web_thread.start() - print(f"๐ŸŒ Web dashboard started on http://0.0.0.0:8083") +# print(f"๐ŸŒ Web dashboard started on http://0.0.0.0:8083") - # Start Stratum server - server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - server_socket.bind((self.stratum_host, self.stratum_port)) - server_socket.listen(10) +# # Start Stratum server +# server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +# server_socket.bind((self.stratum_host, self.stratum_port)) +# server_socket.listen(10) - print(f"๐Ÿš€ Mining pool listening on {self.stratum_host}:{self.stratum_port}") - print("Ready for multiple miners...") - print("") - print(f"๐Ÿ’ฐ Pool address: {self.pool_address}") - print(f"๐Ÿ’ฐ Pool fee: {self.pool_fee_percent}%") - print("") - print("Connect miners with:") - print(f"./cpuminer -a rinhash -o stratum+tcp://{self.stratum_host}:{self.stratum_port} -u username.workername -p x") - print("") +# print(f"๐Ÿš€ Mining pool listening on {self.stratum_host}:{self.stratum_port}") +# print("Ready for multiple miners...") +# print("") +# print(f"๐Ÿ’ฐ Pool address: {self.pool_address}") +# print(f"๐Ÿ’ฐ Pool fee: {self.pool_fee_percent}%") +# print("") +# print("Connect miners with:") +# print(f"./cpuminer -a rinhash -o stratum+tcp://{self.stratum_host}:{self.stratum_port} -u username.workername -p x") +# print("") - while self.running: - try: - client, addr = server_socket.accept() - client_thread = threading.Thread(target=self.handle_client, args=(client, addr), daemon=True) - client_thread.start() - except KeyboardInterrupt: - print("\n๐Ÿ›‘ Shutting down pool...") - self.running = False - break - except Exception as e: - print(f"Server error: {e}") +# while self.running: +# try: +# client, addr = server_socket.accept() +# client_thread = threading.Thread(target=self.handle_client, args=(client, addr), daemon=True) +# client_thread.start() +# except KeyboardInterrupt: +# print("\n๐Ÿ›‘ Shutting down pool...") +# self.running = False +# break +# except Exception as e: +# print(f"Server error: {e}") - except OSError as e: - if "Address already in use" in str(e): - print(f"โŒ Port {self.stratum_port} is already in use!") - print("") - print("๐Ÿ” Check what's using the port:") - print(f"sudo netstat -tlnp | grep :{self.stratum_port}") - print("") - print("๐Ÿ›‘ Kill existing process:") - print(f"sudo lsof -ti:{self.stratum_port} | xargs sudo kill -9") - print("") - print("๐Ÿ”„ Or use a different port by editing the script") - else: - print(f"Failed to start server: {e}") - except Exception as e: - print(f"Failed to start server: {e}") - finally: - print("Pool server stopped") +# except OSError as e: +# if "Address already in use" in str(e): +# print(f"โŒ Port {self.stratum_port} is already in use!") +# print("") +# print("๐Ÿ” Check what's using the port:") +# print(f"sudo netstat -tlnp | grep :{self.stratum_port}") +# print("") +# print("๐Ÿ›‘ Kill existing process:") +# print(f"sudo lsof -ti:{self.stratum_port} | xargs sudo kill -9") +# print("") +# print("๐Ÿ”„ Or use a different port by editing the script") +# else: +# print(f"Failed to start server: {e}") +# except Exception as e: +# print(f"Failed to start server: {e}") +# finally: +# print("Pool server stopped") -if __name__ == "__main__": - pool = RinCoinMiningPool() - pool.start() +# if __name__ == "__main__": +# pool = RinCoinMiningPool() +# pool.start() diff --git a/MINE/rin/stratum_proxy.py b/MINE/rin/stratum_proxy.py index 5ce89b3..3833e9d 100644 --- a/MINE/rin/stratum_proxy.py +++ b/MINE/rin/stratum_proxy.py @@ -1,1350 +1,1350 @@ -#!/usr/bin/env python3 -""" -stratum_proxy.py -RinCoin Stratum Proxy Server -DEBUG RPC: we get node logs with 'docker logs --tail=200 rincoin-node' -MINE: /mnt/shared/DEV/repos/d-popov.com/mines/rin/miner/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://localhost:3334 -u x -p x -t 32 -""" +# #!/usr/bin/env python3 +# """ +# stratum_proxy.py +# RinCoin Stratum Proxy Server +# DEBUG RPC: we get node logs with 'docker logs --tail=200 rincoin-node' +# MINE: /mnt/shared/DEV/repos/d-popov.com/mines/rin/miner/cpuminer-opt-rin/cpuminer -a rinhash -o stratum+tcp://localhost:3334 -u x -p x -t 32 +# """ -import socket -import threading -import json -import time -import requests -import hashlib -import struct -from requests.auth import HTTPBasicAuth +# import socket +# import threading +# import json +# import time +# import requests +# import hashlib +# import struct +# from requests.auth import HTTPBasicAuth -class RinCoinStratumProxy: - def __init__(self, stratum_host='0.0.0.0', stratum_port=3334, - rpc_host='127.0.0.1', rpc_port=9556, - rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90', - target_address='rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q', - submit_all_blocks=False, submit_threshold=0.1): +# class RinCoinStratumProxy: +# def __init__(self, stratum_host='0.0.0.0', stratum_port=3334, +# rpc_host='127.0.0.1', rpc_port=9556, +# rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90', +# target_address='rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q', +# submit_all_blocks=False, submit_threshold=0.1): - self.stratum_host = stratum_host - self.stratum_port = stratum_port - self.rpc_host = rpc_host - self.rpc_port = rpc_port - self.rpc_user = rpc_user - self.rpc_password = rpc_password - self.target_address = target_address - self.submit_all_blocks = submit_all_blocks - # For debugging: submit blocks that meet this fraction of network difficulty - self.submit_threshold = submit_threshold # Configurable percentage of network difficulty +# self.stratum_host = stratum_host +# self.stratum_port = stratum_port +# self.rpc_host = rpc_host +# self.rpc_port = rpc_port +# self.rpc_user = rpc_user +# self.rpc_password = rpc_password +# self.target_address = target_address +# self.submit_all_blocks = submit_all_blocks +# # For debugging: submit blocks that meet this fraction of network difficulty +# self.submit_threshold = submit_threshold # Configurable percentage of network difficulty - self.clients = {} - self.job_counter = 0 - self.current_job = None - self.running = True - self.extranonce1_counter = 0 +# self.clients = {} +# self.job_counter = 0 +# self.current_job = None +# self.running = True +# self.extranonce1_counter = 0 - # Dynamic difficulty adjustment - self.share_stats = {} # Track shares per client - self.last_difficulty_adjustment = time.time() - self.target_share_interval = 15 # Target: 1 share every 15 seconds (optimal for 1-min blocks) +# # Dynamic difficulty adjustment +# self.share_stats = {} # Track shares per client +# self.last_difficulty_adjustment = time.time() +# self.target_share_interval = 15 # Target: 1 share every 15 seconds (optimal for 1-min blocks) - # Production monitoring - self.stats = { - 'start_time': time.time(), - 'total_shares': 0, - 'accepted_shares': 0, - 'rejected_shares': 0, - 'blocks_found': 0, - 'total_hashrate': 0, - 'connections': 0, - 'last_share_time': time.time(), - 'shares_last_minute': [], - 'current_share_rate': 0.0 - } - self.max_connections = 50 # Production limit +# # Production monitoring +# self.stats = { +# 'start_time': time.time(), +# 'total_shares': 0, +# 'accepted_shares': 0, +# 'rejected_shares': 0, +# 'blocks_found': 0, +# 'total_hashrate': 0, +# 'connections': 0, +# 'last_share_time': time.time(), +# 'shares_last_minute': [], +# 'current_share_rate': 0.0 +# } +# self.max_connections = 50 # Production limit - # Logging setup - self.log_file = "mining_log.txt" - self.init_log_file() +# # Logging setup +# self.log_file = "mining_log.txt" +# self.init_log_file() - print(f"RinCoin Stratum Proxy Server") - print(f"Stratum: {stratum_host}:{stratum_port}") - print(f"RPC: {rpc_host}:{rpc_port}") - print(f"Target: {target_address}") +# print(f"RinCoin Stratum Proxy Server") +# print(f"Stratum: {stratum_host}:{stratum_port}") +# print(f"RPC: {rpc_host}:{rpc_port}") +# print(f"Target: {target_address}") - def init_log_file(self): - """Initialize mining log file with header""" - try: - with open(self.log_file, 'w') as f: - f.write("=" * 80 + "\n") - f.write("RinCoin Mining Log\n") - f.write("=" * 80 + "\n") - f.write(f"Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n") - f.write(f"Target Address: {self.target_address}\n") - f.write(f"Stratum: {self.stratum_host}:{self.stratum_port}\n") - f.write(f"RPC: {self.rpc_host}:{self.rpc_port}\n") - f.write("=" * 80 + "\n\n") - except Exception as e: - print(f"Failed to initialize log file: {e}") +# def init_log_file(self): +# """Initialize mining log file with header""" +# try: +# with open(self.log_file, 'w') as f: +# f.write("=" * 80 + "\n") +# f.write("RinCoin Mining Log\n") +# f.write("=" * 80 + "\n") +# f.write(f"Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n") +# f.write(f"Target Address: {self.target_address}\n") +# f.write(f"Stratum: {self.stratum_host}:{self.stratum_port}\n") +# f.write(f"RPC: {self.rpc_host}:{self.rpc_port}\n") +# f.write("=" * 80 + "\n\n") +# except Exception as e: +# print(f"Failed to initialize log file: {e}") - def log_hash_found(self, hash_hex, difficulty, height, reward, nonce, ntime): - """Log found hash to file""" - try: - timestamp = time.strftime('%Y-%m-%d %H:%M:%S') - with open(self.log_file, 'a') as f: - f.write(f"[{timestamp}] ๐ŸŽ‰ HASH FOUND!\n") - f.write(f" Hash: {hash_hex}\n") - f.write(f" Difficulty: {difficulty:.6f}\n") - f.write(f" Height: {height}\n") - f.write(f" Reward: {reward:.8f} RIN\n") - f.write(f" Nonce: {nonce}\n") - f.write(f" Time: {ntime}\n") - f.write("-" * 40 + "\n") - except Exception as e: - print(f"Failed to log hash: {e}") +# def log_hash_found(self, hash_hex, difficulty, height, reward, nonce, ntime): +# """Log found hash to file""" +# try: +# timestamp = time.strftime('%Y-%m-%d %H:%M:%S') +# with open(self.log_file, 'a') as f: +# f.write(f"[{timestamp}] ๐ŸŽ‰ HASH FOUND!\n") +# f.write(f" Hash: {hash_hex}\n") +# f.write(f" Difficulty: {difficulty:.6f}\n") +# f.write(f" Height: {height}\n") +# f.write(f" Reward: {reward:.8f} RIN\n") +# f.write(f" Nonce: {nonce}\n") +# f.write(f" Time: {ntime}\n") +# f.write("-" * 40 + "\n") +# except Exception as e: +# print(f"Failed to log hash: {e}") - def log_wallet_balance(self): - """Log current wallet balance to file""" - try: - balance = self.rpc_call("getbalance") - if balance is not None: - timestamp = time.strftime('%Y-%m-%d %H:%M:%S') - with open(self.log_file, 'a') as f: - f.write(f"[{timestamp}] ๐Ÿ’ฐ Wallet Balance: {balance:.8f} RIN\n") - except Exception as e: - print(f"Failed to log wallet balance: {e}") +# def log_wallet_balance(self): +# """Log current wallet balance to file""" +# try: +# balance = self.rpc_call("getbalance") +# if balance is not None: +# timestamp = time.strftime('%Y-%m-%d %H:%M:%S') +# with open(self.log_file, 'a') as f: +# f.write(f"[{timestamp}] ๐Ÿ’ฐ Wallet Balance: {balance:.8f} RIN\n") +# except Exception as e: +# print(f"Failed to log wallet balance: {e}") - def rpc_call(self, method, params=[]): - """Make RPC call to RinCoin node""" - try: - url = f"http://{self.rpc_host}:{self.rpc_port}/" - headers = {'content-type': 'text/plain'} - auth = HTTPBasicAuth(self.rpc_user, self.rpc_password) +# def rpc_call(self, method, params=[]): +# """Make RPC call to RinCoin node""" +# try: +# url = f"http://{self.rpc_host}:{self.rpc_port}/" +# headers = {'content-type': 'text/plain'} +# auth = HTTPBasicAuth(self.rpc_user, self.rpc_password) - payload = { - "jsonrpc": "1.0", - "id": "stratum_proxy", - "method": method, - "params": params - } +# payload = { +# "jsonrpc": "1.0", +# "id": "stratum_proxy", +# "method": method, +# "params": params +# } - response = requests.post(url, json=payload, headers=headers, auth=auth, timeout=30) +# response = requests.post(url, json=payload, headers=headers, auth=auth, timeout=30) - if response.status_code == 200: - result = response.json() - if 'error' in result and result['error'] is not None: - print(f"RPC Error: {result['error']}") - return None - return result.get('result') - else: - print(f"HTTP Error: {response.status_code}") - return None +# if response.status_code == 200: +# result = response.json() +# if 'error' in result and result['error'] is not None: +# print(f"RPC Error: {result['error']}") +# return None +# return result.get('result') +# else: +# print(f"HTTP Error: {response.status_code}") +# return None - except Exception as e: - print(f"RPC Call Error: {e}") - return None +# except Exception as e: +# print(f"RPC Call Error: {e}") +# return None - def encode_varint(self, n): - """Encode integer as Bitcoin-style varint""" - if n < 0xfd: - return bytes([n]) - elif n <= 0xffff: - return b"\xfd" + struct.pack(' bytes: - outputs_blob = b'' - outputs_list = [] - # Main output - outputs_list.append(struct.pack(' bytes: +# outputs_blob = b'' +# outputs_list = [] +# # Main output +# outputs_list.append(struct.pack(' 1: - if len(hashes) % 2 == 1: - hashes.append(hashes[-1]) # Duplicate last hash if odd +# # Build merkle tree +# while len(hashes) > 1: +# if len(hashes) % 2 == 1: +# hashes.append(hashes[-1]) # Duplicate last hash if odd - next_level = [] - for i in range(0, len(hashes), 2): - combined = hashes[i] + hashes[i + 1] - next_level.append(hashlib.sha256(hashlib.sha256(combined).digest()).digest()) +# next_level = [] +# for i in range(0, len(hashes), 2): +# combined = hashes[i] + hashes[i + 1] +# next_level.append(hashlib.sha256(hashlib.sha256(combined).digest()).digest()) - hashes = next_level +# hashes = next_level - return hashes[0] if hashes else b'\x00' * 32 +# return hashes[0] if hashes else b'\x00' * 32 - except Exception as e: - print(f"Merkle root calculation error: {e}") - return b'\x00' * 32 +# except Exception as e: +# print(f"Merkle root calculation error: {e}") +# return b'\x00' * 32 - def calculate_merkle_branches(self, tx_hashes, tx_index): - """Calculate merkle branches for a specific transaction index""" - try: - if not tx_hashes or tx_index >= len(tx_hashes): - return [] +# def calculate_merkle_branches(self, tx_hashes, tx_index): +# """Calculate merkle branches for a specific transaction index""" +# try: +# if not tx_hashes or tx_index >= len(tx_hashes): +# return [] - branches = [] - current_index = tx_index +# branches = [] +# current_index = tx_index - # Start with the full list of transaction hashes - hashes = tx_hashes[:] +# # Start with the full list of transaction hashes +# hashes = tx_hashes[:] - while len(hashes) > 1: - if len(hashes) % 2 == 1: - hashes.append(hashes[-1]) # Duplicate last hash if odd +# while len(hashes) > 1: +# if len(hashes) % 2 == 1: +# hashes.append(hashes[-1]) # Duplicate last hash if odd - # Find the partner for current_index - partner_index = current_index ^ 1 # Flip the least significant bit +# # Find the partner for current_index +# partner_index = current_index ^ 1 # Flip the least significant bit - if partner_index < len(hashes): - # Add the partner hash to branches (in big-endian for stratum) - branches.append(hashes[partner_index][::-1].hex()) - else: - # This shouldn't happen, but add the duplicate if it does - branches.append(hashes[current_index][::-1].hex()) +# if partner_index < len(hashes): +# # Add the partner hash to branches (in big-endian for stratum) +# branches.append(hashes[partner_index][::-1].hex()) +# else: +# # This shouldn't happen, but add the duplicate if it does +# branches.append(hashes[current_index][::-1].hex()) - # Move to next level - next_level = [] - for i in range(0, len(hashes), 2): - combined = hashes[i] + hashes[i + 1] - next_level.append(hashlib.sha256(hashlib.sha256(combined).digest()).digest()) +# # Move to next level +# next_level = [] +# for i in range(0, len(hashes), 2): +# combined = hashes[i] + hashes[i + 1] +# next_level.append(hashlib.sha256(hashlib.sha256(combined).digest()).digest()) - hashes = next_level - current_index //= 2 +# hashes = next_level +# current_index //= 2 - return branches +# return branches - except Exception as e: - print(f"Merkle branches calculation error: {e}") - return [] +# except Exception as e: +# print(f"Merkle branches calculation error: {e}") +# return [] - def bits_to_target(self, bits_hex): - """Convert bits to target - FIXED VERSION""" - try: - bits = int(bits_hex, 16) - exponent = bits >> 24 - mantissa = bits & 0xffffff +# def bits_to_target(self, bits_hex): +# """Convert bits to target - FIXED VERSION""" +# try: +# bits = int(bits_hex, 16) +# exponent = bits >> 24 +# mantissa = bits & 0xffffff - # Bitcoin target calculation - if exponent <= 3: - target = mantissa >> (8 * (3 - exponent)) - else: - target = mantissa << (8 * (exponent - 3)) +# # Bitcoin target calculation +# if exponent <= 3: +# target = mantissa >> (8 * (3 - exponent)) +# else: +# target = mantissa << (8 * (exponent - 3)) - return f"{target:064x}" - except Exception as e: - print(f"Bits to target error: {e}") - return "0000ffff00000000000000000000000000000000000000000000000000000000" +# return f"{target:064x}" +# except Exception as e: +# print(f"Bits to target error: {e}") +# return "0000ffff00000000000000000000000000000000000000000000000000000000" - def get_block_template(self): - """Get new block template and create Stratum job""" - try: - template = self.rpc_call("getblocktemplate", [{"rules": ["segwit", "mweb"]}]) - if not template: - return None +# def get_block_template(self): +# """Get new block template and create Stratum job""" +# try: +# template = self.rpc_call("getblocktemplate", [{"rules": ["segwit", "mweb"]}]) +# if not template: +# return None - self.job_counter += 1 +# self.job_counter += 1 - job = { - "job_id": f"job_{self.job_counter:08x}", - "template": template, - "prevhash": template.get("previousblockhash", "0" * 64), - "version": template.get('version', 1), - "bits": template.get('bits', '1d00ffff'), - "ntime": f"{int(time.time()):08x}", - "target": self.bits_to_target(template.get('bits', '1d00ffff')), - "height": template.get('height', 0), - "coinbasevalue": template.get('coinbasevalue', 0), - "transactions": template.get('transactions', []) - } +# job = { +# "job_id": f"job_{self.job_counter:08x}", +# "template": template, +# "prevhash": template.get("previousblockhash", "0" * 64), +# "version": template.get('version', 1), +# "bits": template.get('bits', '1d00ffff'), +# "ntime": f"{int(time.time()):08x}", +# "target": self.bits_to_target(template.get('bits', '1d00ffff')), +# "height": template.get('height', 0), +# "coinbasevalue": template.get('coinbasevalue', 0), +# "transactions": template.get('transactions', []) +# } - self.current_job = job - timestamp = time.strftime("%Y-%m-%d %H:%M:%S") - network_difficulty = self.calculate_network_difficulty(job['target']) - print(f"[{timestamp}] ๐Ÿ†• NEW JOB: {job['job_id']} | Height: {job['height']} | Reward: {job['coinbasevalue']/100000000:.2f} RIN") - print(f" ๐ŸŽฏ Network Difficulty: {network_difficulty:.6f} | Bits: {job['bits']}") - print(f" ๐Ÿ“ Target: {job['target'][:16]}... | Transactions: {len(job['transactions'])}") - return job +# self.current_job = job +# timestamp = time.strftime("%Y-%m-%d %H:%M:%S") +# network_difficulty = self.calculate_network_difficulty(job['target']) +# print(f"[{timestamp}] ๐Ÿ†• NEW JOB: {job['job_id']} | Height: {job['height']} | Reward: {job['coinbasevalue']/100000000:.2f} RIN") +# print(f" ๐ŸŽฏ Network Difficulty: {network_difficulty:.6f} | Bits: {job['bits']}") +# print(f" ๐Ÿ“ Target: {job['target'][:16]}... | Transactions: {len(job['transactions'])}") +# return job - except Exception as e: - print(f"Get block template error: {e}") - return None +# except Exception as e: +# print(f"Get block template error: {e}") +# return None - def calculate_share_difficulty(self, hash_hex, target_hex): - """Calculate actual share difficulty from hash - FIXED""" - try: - hash_int = int(hash_hex, 16) +# def calculate_share_difficulty(self, hash_hex, target_hex): +# """Calculate actual share difficulty from hash - FIXED""" +# try: +# hash_int = int(hash_hex, 16) - if hash_int == 0: - return float('inf') # Perfect hash +# if hash_int == 0: +# return float('inf') # Perfect hash - # Bitcoin-style difficulty calculation using difficulty 1 target - # Difficulty 1 target for mainnet - diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 +# # Bitcoin-style difficulty calculation using difficulty 1 target +# # Difficulty 1 target for mainnet +# diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 - # Share difficulty = how much harder this hash was compared to diff 1 - difficulty = diff1_target / hash_int +# # Share difficulty = how much harder this hash was compared to diff 1 +# difficulty = diff1_target / hash_int - return difficulty - except Exception as e: - print(f"Difficulty calculation error: {e}") - return 0.0 +# return difficulty +# except Exception as e: +# print(f"Difficulty calculation error: {e}") +# return 0.0 - def calculate_network_difficulty(self, target_hex): - """Calculate network difficulty from target - FIXED""" - try: - target_int = int(target_hex, 16) +# def calculate_network_difficulty(self, target_hex): +# """Calculate network difficulty from target - FIXED""" +# try: +# target_int = int(target_hex, 16) - # Bitcoin difficulty 1.0 target - diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 +# # Bitcoin difficulty 1.0 target +# diff1_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 - # Network difficulty = how much harder than difficulty 1.0 - network_difficulty = diff1_target / target_int +# # Network difficulty = how much harder than difficulty 1.0 +# network_difficulty = diff1_target / target_int - return network_difficulty - except Exception as e: - print(f"Network difficulty calculation error: {e}") - return 1.0 +# return network_difficulty +# except Exception as e: +# print(f"Network difficulty calculation error: {e}") +# return 1.0 - def calculate_optimal_difficulty(self, addr, is_new_client=False): - """Calculate optimal stratum difficulty for a client based on hashrate and network conditions""" - try: - # Get current network difficulty - network_diff = self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 1.0 +# def calculate_optimal_difficulty(self, addr, is_new_client=False): +# """Calculate optimal stratum difficulty for a client based on hashrate and network conditions""" +# try: +# # Get current network difficulty +# network_diff = self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 1.0 - if is_new_client: - # Calculate difficulty for 4 shares per minute (15 second intervals) - # Formula: difficulty = (shares_per_second * 2^32) / hashrate - target_shares_per_second = 4 / 60 # 4 shares per minute - assumed_hashrate = 680000 # H/s (conservative estimate) - calculated_difficulty = (target_shares_per_second * (2**32)) / assumed_hashrate +# if is_new_client: +# # Calculate difficulty for 4 shares per minute (15 second intervals) +# # Formula: difficulty = (shares_per_second * 2^32) / hashrate +# target_shares_per_second = 4 / 60 # 4 shares per minute +# assumed_hashrate = 680000 # H/s (conservative estimate) +# calculated_difficulty = (target_shares_per_second * (2**32)) / assumed_hashrate - # Scale based on network difficulty to maintain relative percentage - target_percentage = calculated_difficulty / network_diff if network_diff > 0 else 0.32 - scaled_difficulty = network_diff * target_percentage +# # Scale based on network difficulty to maintain relative percentage +# target_percentage = calculated_difficulty / network_diff if network_diff > 0 else 0.32 +# scaled_difficulty = network_diff * target_percentage - # Use the calculated difficulty (should be around 421 for 680kH/s) - initial_difficulty = calculated_difficulty +# # Use the calculated difficulty (should be around 421 for 680kH/s) +# initial_difficulty = calculated_difficulty - # Ensure reasonable bounds - min_difficulty = 0.0001 # Absolute minimum - # IMPORTANT: DO NOT CHANGE THIS VALUE. our pool may grow big in the future, so we need to be able to handle it. - max_difficulty = network_diff * 0.1 # Maximum 10% of network - initial_difficulty = max(min_difficulty, min(max_difficulty, initial_difficulty)) +# # Ensure reasonable bounds +# min_difficulty = 0.0001 # Absolute minimum +# # IMPORTANT: DO NOT CHANGE THIS VALUE. our pool may grow big in the future, so we need to be able to handle it. +# max_difficulty = network_diff * 0.1 # Maximum 10% of network +# initial_difficulty = max(min_difficulty, min(max_difficulty, initial_difficulty)) - percentage = (initial_difficulty / network_diff) * 100 - print(f" ๐Ÿ“Š NEW CLIENT {addr}: Network diff {network_diff:.6f}") - print(f" ๐ŸŽฏ Starting difficulty: {initial_difficulty:.6f} ({percentage:.4f}% of network)") - miner_hashrate = self.clients.get(addr, {}).get('estimated_hashrate', 0) - if miner_hashrate > 0: - print(f" Target: 1 share every {self.target_share_interval}s @ {miner_hashrate:.0f} H/s") - else: - print(f" Target: 1 share every {self.target_share_interval}s (miner hashrate unknown)") - print(f" ๐Ÿ”ง Per-miner adjustment: Difficulty will adapt to each device's actual hashrate") - return initial_difficulty +# percentage = (initial_difficulty / network_diff) * 100 +# print(f" ๐Ÿ“Š NEW CLIENT {addr}: Network diff {network_diff:.6f}") +# print(f" ๐ŸŽฏ Starting difficulty: {initial_difficulty:.6f} ({percentage:.4f}% of network)") +# miner_hashrate = self.clients.get(addr, {}).get('estimated_hashrate', 0) +# if miner_hashrate > 0: +# print(f" Target: 1 share every {self.target_share_interval}s @ {miner_hashrate:.0f} H/s") +# else: +# print(f" Target: 1 share every {self.target_share_interval}s (miner hashrate unknown)") +# print(f" ๐Ÿ”ง Per-miner adjustment: Difficulty will adapt to each device's actual hashrate") +# return initial_difficulty - # 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) +# # 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) - 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', network_diff * 0.005) - estimated_hashrate = client_data.get('estimated_hashrate', 0) +# 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', network_diff * 0.005) +# estimated_hashrate = client_data.get('estimated_hashrate', 0) - # Need at least 3 shares to make adjustments - if share_count < 3: - return current_difficulty +# # Need at least 3 shares to make adjustments +# if share_count < 3: +# return current_difficulty - # Calculate target difficulty based on hashrate and desired share interval - # Target: 1 share every 15 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) +# # Calculate target difficulty based on hashrate and desired share interval +# # Target: 1 share every 15 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) - # 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 +# 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)) - # Conservative adjustment - move only 50% towards target each time - adjustment_factor = 0.5 - new_difficulty = current_difficulty + (target_difficulty - current_difficulty) * adjustment_factor +# # 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}: {estimated_hashrate:.0f} H/s, {share_count} shares, adjusting {current_difficulty:.6f} โ†’ {new_difficulty:.6f}") - return new_difficulty +# print(f" ๐Ÿ“Š {addr}: {estimated_hashrate:.0f} H/s, {share_count} shares, adjusting {current_difficulty:.6f} โ†’ {new_difficulty:.6f}") +# return new_difficulty - return current_difficulty +# return current_difficulty - except Exception as e: - print(f"Difficulty calculation error: {e}") - # 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) +# except Exception as e: +# print(f"Difficulty calculation error: {e}") +# # 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'] +# 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 +# # 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}") +# 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}") +# 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}") +# 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""" - try: - current_time = time.time() +# def adjust_client_difficulty(self, addr): +# """Adjust difficulty for a specific client if needed""" +# try: +# current_time = time.time() - # Only adjust every 2 minutes minimum - last_adjustment = self.clients[addr].get('last_difficulty_adjustment', 0) - if current_time - last_adjustment < 120: - return +# # Only adjust every 2 minutes minimum +# last_adjustment = self.clients[addr].get('last_difficulty_adjustment', 0) +# if current_time - last_adjustment < 120: +# return - new_difficulty = self.calculate_optimal_difficulty(addr, is_new_client=False) - current_difficulty = self.clients[addr].get('stratum_difficulty', 0.001) +# new_difficulty = self.calculate_optimal_difficulty(addr, is_new_client=False) +# current_difficulty = self.clients[addr].get('stratum_difficulty', 0.001) - # Only send update if difficulty changed significantly (>20%) - if abs(new_difficulty - current_difficulty) / current_difficulty > 0.2: - self.clients[addr]['stratum_difficulty'] = new_difficulty - self.clients[addr]['last_difficulty_adjustment'] = current_time +# # Only send update if difficulty changed significantly (>20%) +# if abs(new_difficulty - current_difficulty) / current_difficulty > 0.2: +# self.clients[addr]['stratum_difficulty'] = new_difficulty +# self.clients[addr]['last_difficulty_adjustment'] = current_time - # Send new difficulty to client - if 'socket' in self.clients[addr]: - self.send_stratum_notification(self.clients[addr]['socket'], "mining.set_difficulty", [new_difficulty]) - print(f" ๐ŸŽฏ Updated difficulty for {addr}: {current_difficulty:.6f} โ†’ {new_difficulty:.6f}") +# # Send new difficulty to client +# if 'socket' in self.clients[addr]: +# self.send_stratum_notification(self.clients[addr]['socket'], "mining.set_difficulty", [new_difficulty]) +# print(f" ๐ŸŽฏ Updated difficulty for {addr}: {current_difficulty:.6f} โ†’ {new_difficulty:.6f}") - except Exception as e: - print(f"Difficulty adjustment error for {addr}: {e}") +# except Exception as e: +# print(f"Difficulty adjustment error for {addr}: {e}") - def submit_share(self, job, extranonce1, extranonce2, ntime, nonce, addr=None, target_address=None): - """Validate share and submit block if valid - FIXED VERSION""" - try: - # Use provided address or default - address = target_address or self.target_address +# def submit_share(self, job, extranonce1, extranonce2, ntime, nonce, addr=None, target_address=None): +# """Validate share and submit block if valid - FIXED VERSION""" +# try: +# # Use provided address or default +# address = target_address or self.target_address - # Build coinbase (with and without witness) - coinbase_wit, coinbase_nowit = self.build_coinbase_transaction_for_address( - job['template'], extranonce1, extranonce2, address) - if not coinbase_wit or not coinbase_nowit: - return False, "Coinbase construction failed" +# # Build coinbase (with and without witness) +# coinbase_wit, coinbase_nowit = self.build_coinbase_transaction_for_address( +# job['template'], extranonce1, extranonce2, address) +# if not coinbase_wit or not coinbase_nowit: +# return False, "Coinbase construction failed" - # Calculate coinbase txid (non-witness serialization) - coinbase_txid = hashlib.sha256(hashlib.sha256(coinbase_nowit).digest()).digest()[::-1] +# # Calculate coinbase txid (non-witness serialization) +# coinbase_txid = hashlib.sha256(hashlib.sha256(coinbase_nowit).digest()).digest()[::-1] - # Calculate merkle root - merkle_root = self.calculate_merkle_root(coinbase_txid, job['transactions']) +# # Calculate merkle root +# merkle_root = self.calculate_merkle_root(coinbase_txid, job['transactions']) - # Build block header - FIXED ENDIANNESS - header = b'' - header += struct.pack('= client_stratum_diff - meets_network_difficulty = share_difficulty >= network_difficulty +# # CRITICAL FIX: Check if share difficulty meets minimum requirements +# 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 +# # 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 - stratum_percentage = (share_difficulty / client_stratum_diff) * 100 if client_stratum_diff > 0 else 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 +# stratum_percentage = (share_difficulty / client_stratum_diff) * 100 if client_stratum_diff > 0 else 0 - # Progress indicator based on difficulty comparison - if meets_network_difficulty: - progress_icon = "๐ŸŽ‰" # Block found! - elif meets_stratum_difficulty: - progress_icon = "โœ…" # Valid share for stratum - elif network_percentage >= 50: - progress_icon = "๐Ÿ”ฅ" # Very close to network - elif network_percentage >= 10: - progress_icon = "โšก" # Getting warm - elif network_percentage >= 1: - progress_icon = "๐Ÿ’ซ" # Some progress - else: - progress_icon = "๐Ÿ“Š" # Low progress +# # Progress indicator based on difficulty comparison +# if meets_network_difficulty: +# progress_icon = "๐ŸŽ‰" # Block found! +# elif meets_stratum_difficulty: +# progress_icon = "โœ…" # Valid share for stratum +# elif network_percentage >= 50: +# progress_icon = "๐Ÿ”ฅ" # Very close to network +# elif network_percentage >= 10: +# progress_icon = "โšก" # Getting warm +# elif network_percentage >= 1: +# progress_icon = "๐Ÿ’ซ" # Some progress +# else: +# progress_icon = "๐Ÿ“Š" # Low progress - # Calculate network and pool hashrates - block_time = 60 # RinCoin 1-minute blocks - network_hashrate = (network_difficulty * (2**32)) / block_time - network_mhs = network_hashrate / 1e6 +# # Calculate network and pool hashrates +# block_time = 60 # RinCoin 1-minute blocks +# network_hashrate = (network_difficulty * (2**32)) / block_time +# network_mhs = network_hashrate / 1e6 - # Calculate pool hashrate (sum of all connected miners) - pool_hashrate = 0 - for client_addr, client_data in self.clients.items(): - pool_hashrate += client_data.get('estimated_hashrate', 0) - pool_mhs = pool_hashrate / 1e6 +# # Calculate pool hashrate (sum of all connected miners) +# pool_hashrate = 0 +# for client_addr, client_data in self.clients.items(): +# pool_hashrate += client_data.get('estimated_hashrate', 0) +# pool_mhs = pool_hashrate / 1e6 - # Calculate percentages - pool_network_percentage = (pool_mhs / network_mhs) * 100 if network_mhs > 0 else 0 - miner_pool_percentage = (0.87 / pool_mhs) * 100 if pool_mhs > 0 else 0 # Assuming 870kH/s miner +# # Calculate percentages +# pool_network_percentage = (pool_mhs / network_mhs) * 100 if network_mhs > 0 else 0 +# miner_pool_percentage = (0.87 / pool_mhs) * 100 if pool_mhs > 0 else 0 # Assuming 870kH/s miner - 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" ๐ŸŒ Network: {network_mhs:.1f} MH/s | Pool: {pool_mhs:.1f} MH/s ({pool_network_percentage:.2f}% of network)") - print(f" โ›๏ธ Miner: 0.87 MH/s ({miner_pool_percentage:.1f}% of pool) | Expected solo: {network_mhs/0.87:.0f}h") - 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 'โŒ'}") - print(f" ๐Ÿ” Difficulty Check: Share {share_difficulty:.2e} vs Network {network_difficulty:.6f} = {'โœ…' if meets_network_difficulty else 'โŒ'}") +# 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" ๐ŸŒ Network: {network_mhs:.1f} MH/s | Pool: {pool_mhs:.1f} MH/s ({pool_network_percentage:.2f}% of network)") +# print(f" โ›๏ธ Miner: 0.87 MH/s ({miner_pool_percentage:.1f}% of pool) | Expected solo: {network_mhs/0.87:.0f}h") +# 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 'โŒ'}") +# print(f" ๐Ÿ” Difficulty Check: Share {share_difficulty:.2e} vs Network {network_difficulty:.6f} = {'โœ…' if meets_network_difficulty else 'โŒ'}") - # Initialize submission variables - submit_network_difficulty = meets_network_difficulty - submit_debug_threshold = share_difficulty >= (network_difficulty * self.submit_threshold) +# # Initialize submission variables +# submit_network_difficulty = meets_network_difficulty +# submit_debug_threshold = share_difficulty >= (network_difficulty * self.submit_threshold) - if submit_network_difficulty: - submit_reason = "meets network difficulty" - elif submit_debug_threshold: - submit_reason = f"meets debug threshold ({self.submit_threshold*100:.0f}% of network)" - else: - submit_reason = "does not meet minimum requirements" +# if submit_network_difficulty: +# submit_reason = "meets network difficulty" +# elif submit_debug_threshold: +# submit_reason = f"meets debug threshold ({self.submit_threshold*100:.0f}% of network)" +# else: +# submit_reason = "does not meet minimum requirements" - # Handle submit_all_blocks mode - bypass all difficulty checks - if self.submit_all_blocks: - print(f" ๐Ÿงช TEST MODE: Submitting ALL shares to node for validation") - # Update stats for test mode - self.stats['total_shares'] += 1 - self.stats['accepted_shares'] += 1 +# # Handle submit_all_blocks mode - bypass all difficulty checks +# if self.submit_all_blocks: +# print(f" ๐Ÿงช TEST MODE: Submitting ALL shares to node for validation") +# # Update stats for test mode +# self.stats['total_shares'] += 1 +# self.stats['accepted_shares'] += 1 - # Always submit in test mode - should_submit = True - else: - # Normal mode - check stratum difficulty properly - if not meets_stratum_difficulty: - # Share doesn't meet minimum stratum difficulty - reject - print(f" โŒ Share rejected (difficulty too low: {share_difficulty:.2e} < {client_stratum_diff:.6f})") - self.stats['total_shares'] += 1 - self.stats['rejected_shares'] += 1 - return False, "Share does not meet stratum difficulty" +# # Always submit in test mode +# should_submit = True +# else: +# # Normal mode - check stratum difficulty properly +# if not meets_stratum_difficulty: +# # Share doesn't meet minimum stratum difficulty - reject +# print(f" โŒ Share rejected (difficulty too low: {share_difficulty:.2e} < {client_stratum_diff:.6f})") +# self.stats['total_shares'] += 1 +# self.stats['rejected_shares'] += 1 +# return False, "Share does not meet stratum difficulty" - # 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'] = current_time +# # 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'] = 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 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 +# # 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:] +# # 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']) +# # 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)") +# 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 - self.stats['accepted_shares'] += 1 +# # Update global stats +# self.stats['total_shares'] += 1 +# self.stats['accepted_shares'] += 1 - # Check if we should adjust difficulty - self.adjust_client_difficulty(addr) +# # Check if we should adjust difficulty +# self.adjust_client_difficulty(addr) - # Global difficulty adjustment based on share rate - self.adjust_global_difficulty_if_needed() +# # Global difficulty adjustment based on share rate +# self.adjust_global_difficulty_if_needed() - should_submit = submit_network_difficulty or submit_debug_threshold +# should_submit = submit_network_difficulty or submit_debug_threshold - # Submit block if conditions are met - if should_submit: - if submit_network_difficulty: - print(f" ๐ŸŽ‰ VALID BLOCK FOUND! Hash: {block_hash_hex}") - print(f" ๐Ÿ’ฐ Reward: {job['coinbasevalue']/100000000:.2f} RIN -> {address}") - print(f" ๐Ÿ“Š Block height: {job['height']}") - print(f" ๐Ÿ” Difficulty: {share_difficulty:.6f} (target: {network_difficulty:.6f})") - print(f" ๐Ÿ“‹ Submit reason: {submit_reason}") +# # Submit block if conditions are met +# if should_submit: +# if submit_network_difficulty: +# print(f" ๐ŸŽ‰ VALID BLOCK FOUND! Hash: {block_hash_hex}") +# print(f" ๐Ÿ’ฐ Reward: {job['coinbasevalue']/100000000:.2f} RIN -> {address}") +# print(f" ๐Ÿ“Š Block height: {job['height']}") +# print(f" ๐Ÿ” Difficulty: {share_difficulty:.6f} (target: {network_difficulty:.6f})") +# print(f" ๐Ÿ“‹ Submit reason: {submit_reason}") - # Log the found hash - ONLY for actual network-valid blocks - reward_rin = job['coinbasevalue'] / 100000000 - self.log_hash_found(block_hash_hex, share_difficulty, job['height'], reward_rin, nonce, ntime) - elif submit_debug_threshold: - print(f" ๐Ÿงช DEBUG SUBMISSION! Hash: {block_hash_hex} ({submit_reason})") - print(f" ๐Ÿ“Š Block height: {job['height']} | Difficulty: {share_difficulty:.6f}") - print(f" ๐Ÿ’ก This is a test submission - not a real block") - else: - print(f" ๐Ÿงช TEST BLOCK SUBMISSION! Hash: {block_hash_hex} (submit_all_blocks=True)") - print(f" ๐Ÿ“Š Block height: {job['height']} | Difficulty: {share_difficulty:.6f}") - print(f" ๐Ÿ’ก This is a test submission - not a real block") +# # Log the found hash - ONLY for actual network-valid blocks +# reward_rin = job['coinbasevalue'] / 100000000 +# self.log_hash_found(block_hash_hex, share_difficulty, job['height'], reward_rin, nonce, ntime) +# elif submit_debug_threshold: +# print(f" ๐Ÿงช DEBUG SUBMISSION! Hash: {block_hash_hex} ({submit_reason})") +# print(f" ๐Ÿ“Š Block height: {job['height']} | Difficulty: {share_difficulty:.6f}") +# print(f" ๐Ÿ’ก This is a test submission - not a real block") +# else: +# print(f" ๐Ÿงช TEST BLOCK SUBMISSION! Hash: {block_hash_hex} (submit_all_blocks=True)") +# print(f" ๐Ÿ“Š Block height: {job['height']} | Difficulty: {share_difficulty:.6f}") +# print(f" ๐Ÿ’ก This is a test submission - not a real block") - # Build complete block - block = header +# # Build complete block +# block = header - # Transaction count - tx_count = 1 + len(job['transactions']) - block += self.encode_varint(tx_count) +# # Transaction count +# tx_count = 1 + len(job['transactions']) +# block += self.encode_varint(tx_count) - # Add coinbase transaction (witness variant for block body) - block += coinbase_wit +# # Add coinbase transaction (witness variant for block body) +# block += coinbase_wit - # Add other transactions - for tx in job['transactions']: - block += bytes.fromhex(tx['data']) +# # Add other transactions +# for tx in job['transactions']: +# block += bytes.fromhex(tx['data']) - # Submit block - block_hex = block.hex() - print(f" ๐Ÿ“ฆ Submitting block of size {len(block_hex)//2} bytes...") - print(f" ๐Ÿš€ Calling RPC: submitblock([block_hex={len(block_hex)//2}_bytes])") +# # Submit block +# block_hex = block.hex() +# print(f" ๐Ÿ“ฆ Submitting block of size {len(block_hex)//2} bytes...") +# print(f" ๐Ÿš€ Calling RPC: submitblock([block_hex={len(block_hex)//2}_bytes])") - result = self.rpc_call("submitblock", [block_hex]) - print(f" ๐Ÿ“ก RPC RESPONSE: {result}") # Log the actual RPC response +# result = self.rpc_call("submitblock", [block_hex]) +# print(f" ๐Ÿ“ก RPC RESPONSE: {result}") # Log the actual RPC response - if result is None: - print(f" โœ… Block accepted by network!") - print(f" ๐ŸŽŠ SUCCESS: Block {job['height']} submitted successfully!") - print(f" ๐Ÿ’ฐ Reward earned: {job['coinbasevalue']/100000000:.8f} RIN") - # Update block stats - self.stats['blocks_found'] += 1 - # Log wallet balance after successful block submission - self.log_wallet_balance() - return True, "Block found and submitted" - else: - print(f" โŒ Block rejected: {result}") - print(f" ๐Ÿ” Debug: Block size {len(block_hex)//2} bytes, {len(job['transactions'])} transactions") - print(f" ๐Ÿ“‹ Full RPC error details: {result}") - return False, f"Block rejected: {result}" - else: - # Valid stratum share but not network-valid block (normal mode only) - if not self.submit_all_blocks: - print(f" โœ… Valid stratum share accepted") - return True, "Valid stratum share" - else: - # This shouldn't happen in test mode since should_submit would be True - return True, "Test mode share processed" +# if result is None: +# print(f" โœ… Block accepted by network!") +# print(f" ๐ŸŽŠ SUCCESS: Block {job['height']} submitted successfully!") +# print(f" ๐Ÿ’ฐ Reward earned: {job['coinbasevalue']/100000000:.8f} RIN") +# # Update block stats +# self.stats['blocks_found'] += 1 +# # Log wallet balance after successful block submission +# self.log_wallet_balance() +# return True, "Block found and submitted" +# else: +# print(f" โŒ Block rejected: {result}") +# print(f" ๐Ÿ” Debug: Block size {len(block_hex)//2} bytes, {len(job['transactions'])} transactions") +# print(f" ๐Ÿ“‹ Full RPC error details: {result}") +# return False, f"Block rejected: {result}" +# else: +# # Valid stratum share but not network-valid block (normal mode only) +# if not self.submit_all_blocks: +# print(f" โœ… Valid stratum share accepted") +# return True, "Valid stratum share" +# else: +# # This shouldn't happen in test mode since should_submit would be True +# return True, "Test mode share processed" - except Exception as e: - print(f"Share submission error: {e}") - return False, f"Submission error: {e}" +# except Exception as e: +# print(f"Share submission error: {e}") +# return False, f"Submission error: {e}" - def send_stratum_response(self, client, msg_id, result, error=None): - """Send Stratum response to client""" - try: - response = { - "id": msg_id, - "result": result, - "error": error - } - message = json.dumps(response) + "\n" - client.send(message.encode('utf-8')) - except Exception as e: - print(f"Send response error: {e}") +# def send_stratum_response(self, client, msg_id, result, error=None): +# """Send Stratum response to client""" +# try: +# response = { +# "id": msg_id, +# "result": result, +# "error": error +# } +# message = json.dumps(response) + "\n" +# client.send(message.encode('utf-8')) +# except Exception as e: +# print(f"Send response error: {e}") - def send_stratum_notification(self, client, method, params): - """Send Stratum notification to client""" - try: - notification = { - "id": None, - "method": method, - "params": params - } - message = json.dumps(notification) + "\n" - client.send(message.encode('utf-8')) - except Exception as e: - print(f"Send notification error: {e}") +# def send_stratum_notification(self, client, method, params): +# """Send Stratum notification to client""" +# try: +# notification = { +# "id": None, +# "method": method, +# "params": params +# } +# message = json.dumps(notification) + "\n" +# client.send(message.encode('utf-8')) +# except Exception as e: +# print(f"Send notification error: {e}") - def handle_stratum_message(self, client, addr, message): - """Handle incoming Stratum message from miner""" - try: - # Debug: log raw message - print(f"[{addr}] Raw message: {repr(message)}") +# def handle_stratum_message(self, client, addr, message): +# """Handle incoming Stratum message from miner""" +# try: +# # Debug: log raw message +# print(f"[{addr}] Raw message: {repr(message)}") - data = json.loads(message.strip()) - method = data.get("method") - msg_id = data.get("id") - params = data.get("params", []) +# data = json.loads(message.strip()) +# method = data.get("method") +# msg_id = data.get("id") +# params = data.get("params", []) - print(f"[{addr}] Parsed: method={method}, id={msg_id}, params={params}") +# print(f"[{addr}] Parsed: method={method}, id={msg_id}, params={params}") - if method == "mining.subscribe": - # Generate unique extranonce1 for this connection - self.extranonce1_counter += 1 - extranonce1 = f"{self.extranonce1_counter:08x}" +# if method == "mining.subscribe": +# # Generate unique extranonce1 for this connection +# self.extranonce1_counter += 1 +# extranonce1 = f"{self.extranonce1_counter:08x}" - # Store extranonce1 for this client - if addr not in self.clients: - self.clients[addr] = {} - self.clients[addr]['extranonce1'] = extranonce1 +# # Store extranonce1 for this client +# if addr not in self.clients: +# self.clients[addr] = {} +# self.clients[addr]['extranonce1'] = extranonce1 - # Subscribe response - self.send_stratum_response(client, msg_id, [ - [["mining.set_difficulty", "subscription_id"], ["mining.notify", "subscription_id"]], - extranonce1, - 4 # extranonce2 size - ]) +# # Subscribe response +# self.send_stratum_response(client, msg_id, [ +# [["mining.set_difficulty", "subscription_id"], ["mining.notify", "subscription_id"]], +# extranonce1, +# 4 # extranonce2 size +# ]) - # Calculate optimal stratum difficulty for this client - initial_difficulty = self.calculate_optimal_difficulty(addr, is_new_client=True) - # Store stratum difficulty for this client - if addr not in self.clients: - self.clients[addr] = {} - self.clients[addr]['stratum_difficulty'] = initial_difficulty - 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 +# # Calculate optimal stratum difficulty for this client +# initial_difficulty = self.calculate_optimal_difficulty(addr, is_new_client=True) +# # Store stratum difficulty for this client +# if addr not in self.clients: +# self.clients[addr] = {} +# self.clients[addr]['stratum_difficulty'] = initial_difficulty +# 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}") +# self.send_stratum_notification(client, "mining.set_difficulty", [initial_difficulty]) +# print(f" ๐ŸŽฏ Set initial difficulty {initial_difficulty:.6f} for {addr}") - # Send initial job - if self.current_job: - self.send_job_to_client(client, self.current_job) - else: - if self.get_block_template(): - self.send_job_to_client(client, self.current_job) +# # Send initial job +# if self.current_job: +# self.send_job_to_client(client, self.current_job) +# else: +# if self.get_block_template(): +# self.send_job_to_client(client, self.current_job) - elif method == "mining.authorize": - username = params[0] if params else "anonymous" - self.clients[addr]['username'] = username - self.send_stratum_response(client, msg_id, True) - timestamp = time.strftime("%Y-%m-%d %H:%M:%S") - print(f"[{timestamp}] ๐Ÿ” [{addr}] Authorized as {username}") +# elif method == "mining.authorize": +# username = params[0] if params else "anonymous" +# self.clients[addr]['username'] = username +# self.send_stratum_response(client, msg_id, True) +# timestamp = time.strftime("%Y-%m-%d %H:%M:%S") +# print(f"[{timestamp}] ๐Ÿ” [{addr}] Authorized as {username}") - elif method == "login": - # Handle xmrig's login method (JSON-RPC format with object params) - if isinstance(params, dict): - # xmrig format: {"login": "username", "pass": "password", "agent": "...", "algo": [...]} - username = params.get('login', 'anonymous') - password = params.get('pass', 'x') - agent = params.get('agent', 'unknown') - algorithms = params.get('algo', []) - else: - # Standard stratum format: ["username", "password"] - username = params[0] if params else "anonymous" - password = params[1] if len(params) > 1 else "x" - agent = "unknown" - algorithms = [] +# elif method == "login": +# # Handle xmrig's login method (JSON-RPC format with object params) +# if isinstance(params, dict): +# # xmrig format: {"login": "username", "pass": "password", "agent": "...", "algo": [...]} +# username = params.get('login', 'anonymous') +# password = params.get('pass', 'x') +# agent = params.get('agent', 'unknown') +# algorithms = params.get('algo', []) +# else: +# # Standard stratum format: ["username", "password"] +# username = params[0] if params else "anonymous" +# password = params[1] if len(params) > 1 else "x" +# agent = "unknown" +# algorithms = [] - self.clients[addr]['username'] = username - self.clients[addr]['password'] = password - self.clients[addr]['agent'] = agent - self.clients[addr]['algorithms'] = algorithms +# self.clients[addr]['username'] = username +# self.clients[addr]['password'] = password +# self.clients[addr]['agent'] = agent +# self.clients[addr]['algorithms'] = algorithms - # Check if rinhash is supported - rinhash_supported = any('rinhash' in algo.lower() or 'rin' in algo.lower() for algo in algorithms) - if not rinhash_supported: - print(f"[{addr}] Warning: rinhash not in supported algorithms: {algorithms}") +# # Check if rinhash is supported +# rinhash_supported = any('rinhash' in algo.lower() or 'rin' in algo.lower() for algo in algorithms) +# if not rinhash_supported: +# print(f"[{addr}] Warning: rinhash not in supported algorithms: {algorithms}") - self.send_stratum_response(client, msg_id, True) - timestamp = time.strftime("%Y-%m-%d %H:%M:%S") - print(f"[{timestamp}] ๐Ÿ” [{addr}] xmrig Login as {username} (agent: {agent})") - print(f"[{addr}] Supported algorithms: {algorithms}") +# self.send_stratum_response(client, msg_id, True) +# timestamp = time.strftime("%Y-%m-%d %H:%M:%S") +# print(f"[{timestamp}] ๐Ÿ” [{addr}] xmrig Login as {username} (agent: {agent})") +# print(f"[{addr}] Supported algorithms: {algorithms}") - # Send initial job after login - if self.current_job: - self.send_job_to_client(client, self.current_job) - else: - if self.get_block_template(): - self.send_job_to_client(client, self.current_job) +# # Send initial job after login +# if self.current_job: +# self.send_job_to_client(client, self.current_job) +# else: +# if self.get_block_template(): +# self.send_job_to_client(client, self.current_job) - elif method == "mining.extranonce.subscribe": - self.send_stratum_response(client, msg_id, True) +# elif method == "mining.extranonce.subscribe": +# self.send_stratum_response(client, msg_id, True) - elif method == "mining.submit": - if len(params) >= 5: - username = params[0] - job_id = params[1] - extranonce2 = params[2] - ntime = params[3] - nonce = params[4] +# elif method == "mining.submit": +# if len(params) >= 5: +# username = params[0] +# job_id = params[1] +# extranonce2 = params[2] +# ntime = params[3] +# nonce = params[4] - print(f"[{addr}] Submit: {username} | job={job_id} | nonce={nonce}") +# print(f"[{addr}] Submit: {username} | job={job_id} | nonce={nonce}") - # Always validate against current job - if self.current_job: - extranonce1 = self.clients[addr].get('extranonce1', '00000000') +# # Always validate against current job +# if self.current_job: +# extranonce1 = self.clients[addr].get('extranonce1', '00000000') - # Submit share - success, message = self.submit_share(self.current_job, extranonce1, extranonce2, ntime, nonce, addr) +# # Submit share +# success, message = self.submit_share(self.current_job, extranonce1, extranonce2, ntime, nonce, addr) - # Always accept shares for debugging, even if they don't meet target - self.send_stratum_response(client, msg_id, True) +# # Always accept shares for debugging, even if they don't meet target +# self.send_stratum_response(client, msg_id, True) - if success and "Block found" in message: - # Get new job after block found - threading.Thread(target=self.update_job_after_block, daemon=True).start() - else: - self.send_stratum_response(client, msg_id, True) - else: - self.send_stratum_response(client, msg_id, False, "Invalid parameters") +# if success and "Block found" in message: +# # Get new job after block found +# threading.Thread(target=self.update_job_after_block, daemon=True).start() +# else: +# self.send_stratum_response(client, msg_id, True) +# else: +# self.send_stratum_response(client, msg_id, False, "Invalid parameters") - else: - print(f"[{addr}] Unknown method: {method}") - self.send_stratum_response(client, msg_id, None, "Unknown method") +# else: +# print(f"[{addr}] Unknown method: {method}") +# self.send_stratum_response(client, msg_id, None, "Unknown method") - except json.JSONDecodeError as e: - print(f"[{addr}] Invalid JSON: {message}") - print(f"[{addr}] JSON Error: {e}") - except Exception as e: - print(f"[{addr}] Message handling error: {e}") - print(f"[{addr}] Error type: {type(e).__name__}") +# except json.JSONDecodeError as e: +# print(f"[{addr}] Invalid JSON: {message}") +# print(f"[{addr}] JSON Error: {e}") +# except Exception as e: +# print(f"[{addr}] Message handling error: {e}") +# print(f"[{addr}] Error type: {type(e).__name__}") - def send_job_to_client(self, client, job): - """Send mining job to specific client with proper stratum parameters""" - try: - # Get network difficulty for display - network_difficulty = self.calculate_network_difficulty(job['target']) +# def send_job_to_client(self, client, job): +# """Send mining job to specific client with proper stratum parameters""" +# try: +# # Get network difficulty for display +# network_difficulty = self.calculate_network_difficulty(job['target']) - # Build proper coinbase transaction parts for stratum protocol - template = job.get('template', {}) - height = job.get('height', 0) +# # Build proper coinbase transaction parts for stratum protocol +# template = job.get('template', {}) +# height = job.get('height', 0) - # Encode height as minimal push (BIP34 compliance) - if height == 0: - height_push = b'' - else: - height_bytes = struct.pack(' 1 and height_bytes[-1] == 0: - height_bytes = height_bytes[:-1] - height_push = bytes([len(height_bytes)]) + height_bytes +# # Encode height as minimal push (BIP34 compliance) +# if height == 0: +# height_push = b'' +# else: +# height_bytes = struct.pack(' 1 and height_bytes[-1] == 0: +# height_bytes = height_bytes[:-1] +# height_push = bytes([len(height_bytes)]) + height_bytes - # Build coinbase input script: height + arbitrary data + extranonces - coinb1_script = height_push + b'/RinCoin/' +# # Build coinbase input script: height + arbitrary data + extranonces +# coinb1_script = height_push + b'/RinCoin/' - # Build coinbase transaction structure - # Version (4 bytes) - coinb1 = struct.pack('= self.max_connections: - print(f"[{addr}] Connection rejected - max connections ({self.max_connections}) reached") - client.close() - return +# def handle_client(self, client, addr): +# """Handle individual client connection""" +# # Check connection limits +# if len(self.clients) >= self.max_connections: +# print(f"[{addr}] Connection rejected - max connections ({self.max_connections}) reached") +# client.close() +# return - print(f"[{addr}] Connected (clients: {len(self.clients) + 1}/{self.max_connections})") - if addr not in self.clients: - self.clients[addr] = {} - self.clients[addr]['socket'] = client - self.stats['connections'] = len(self.clients) +# print(f"[{addr}] Connected (clients: {len(self.clients) + 1}/{self.max_connections})") +# if addr not in self.clients: +# self.clients[addr] = {} +# self.clients[addr]['socket'] = client +# self.stats['connections'] = len(self.clients) - try: - while self.running: - data = client.recv(4096) - if not data: - break +# try: +# while self.running: +# data = client.recv(4096) +# if not data: +# break - # Handle multiple messages in one packet - messages = data.decode('utf-8').strip().split('\n') - for message in messages: - if message: - self.handle_stratum_message(client, addr, message) +# # Handle multiple messages in one packet +# messages = data.decode('utf-8').strip().split('\n') +# for message in messages: +# if message: +# self.handle_stratum_message(client, addr, message) - except Exception as e: - print(f"[{addr}] Client error: {e}") - finally: - client.close() - if addr in self.clients: - del self.clients[addr] - self.stats['connections'] = len(self.clients) - print(f"[{addr}] Disconnected (clients: {len(self.clients)}/{self.max_connections})") +# except Exception as e: +# print(f"[{addr}] Client error: {e}") +# finally: +# client.close() +# if addr in self.clients: +# del self.clients[addr] +# self.stats['connections'] = len(self.clients) +# print(f"[{addr}] Disconnected (clients: {len(self.clients)}/{self.max_connections})") - def print_stats(self): - """Print pool statistics""" - try: - uptime = time.time() - self.stats['start_time'] - uptime_str = f"{int(uptime//3600)}h {int((uptime%3600)//60)}m" +# def print_stats(self): +# """Print pool statistics""" +# try: +# uptime = time.time() - self.stats['start_time'] +# uptime_str = f"{int(uptime//3600)}h {int((uptime%3600)//60)}m" - accept_rate = 0 - if self.stats['total_shares'] > 0: - accept_rate = (self.stats['accepted_shares'] / self.stats['total_shares']) * 100 +# accept_rate = 0 +# if self.stats['total_shares'] > 0: +# accept_rate = (self.stats['accepted_shares'] / self.stats['total_shares']) * 100 - print(f"\n๐Ÿ“Š POOL STATISTICS:") - print(f" โฐ Uptime: {uptime_str}") - print(f" ๐Ÿ‘ฅ Connected miners: {self.stats['connections']}") - print(f" ๐Ÿ“ˆ Shares: {self.stats['accepted_shares']}/{self.stats['total_shares']} ({accept_rate:.1f}% accepted)") - print(f" ๐ŸŽ‰ Blocks found: {self.stats['blocks_found']}") - print(f" ๐ŸŽฏ Network difficulty: {self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 'unknown':.6f}") +# print(f"\n๐Ÿ“Š POOL STATISTICS:") +# print(f" โฐ Uptime: {uptime_str}") +# print(f" ๐Ÿ‘ฅ Connected miners: {self.stats['connections']}") +# print(f" ๐Ÿ“ˆ Shares: {self.stats['accepted_shares']}/{self.stats['total_shares']} ({accept_rate:.1f}% accepted)") +# print(f" ๐ŸŽ‰ Blocks found: {self.stats['blocks_found']}") +# print(f" ๐ŸŽฏ Network difficulty: {self.calculate_network_difficulty(self.current_job['target']) if self.current_job else 'unknown':.6f}") - # Calculate hashrate estimate from connected clients - total_hashrate = 0 - for addr, client_data in self.clients.items(): - share_count = client_data.get('share_count', 0) - connect_time = client_data.get('connect_time', time.time()) - mining_duration = time.time() - connect_time - if mining_duration > 60 and share_count > 0: - stratum_diff = client_data.get('stratum_difficulty', 0.001) - # Rough hashrate estimate: shares * difficulty * 2^32 / time - hashrate = (share_count * stratum_diff * 4294967296) / mining_duration - total_hashrate += hashrate - print(f" ๐Ÿ”ฅ {addr}: ~{hashrate/1000:.0f} kH/s") +# # Calculate hashrate estimate from connected clients +# total_hashrate = 0 +# for addr, client_data in self.clients.items(): +# share_count = client_data.get('share_count', 0) +# connect_time = client_data.get('connect_time', time.time()) +# mining_duration = time.time() - connect_time +# if mining_duration > 60 and share_count > 0: +# stratum_diff = client_data.get('stratum_difficulty', 0.001) +# # Rough hashrate estimate: shares * difficulty * 2^32 / time +# hashrate = (share_count * stratum_diff * 4294967296) / mining_duration +# total_hashrate += hashrate +# print(f" ๐Ÿ”ฅ {addr}: ~{hashrate/1000:.0f} kH/s") - if total_hashrate > 0: - print(f" ๐Ÿš€ Total pool hashrate: ~{total_hashrate/1000:.0f} kH/s") - print() +# if total_hashrate > 0: +# print(f" ๐Ÿš€ Total pool hashrate: ~{total_hashrate/1000:.0f} kH/s") +# print() - except Exception as e: - print(f"Stats error: {e}") +# except Exception as e: +# print(f"Stats error: {e}") - def job_updater(self): - """Periodically update mining jobs""" - balance_log_counter = 0 - stats_counter = 0 +# def job_updater(self): +# """Periodically update mining jobs""" +# balance_log_counter = 0 +# stats_counter = 0 - while self.running: - try: - time.sleep(30) # Update every 30 seconds +# while self.running: +# try: +# time.sleep(30) # Update every 30 seconds - old_height = self.current_job['height'] if self.current_job else 0 +# old_height = self.current_job['height'] if self.current_job else 0 - if self.get_block_template(): - new_height = self.current_job['height'] - if new_height > old_height: - print(f"New block detected! Broadcasting new job...") - self.broadcast_new_job() +# if self.get_block_template(): +# new_height = self.current_job['height'] +# if new_height > old_height: +# print(f"New block detected! Broadcasting new job...") +# self.broadcast_new_job() - # Log wallet balance every 10 minutes (20 cycles of 30 seconds) - balance_log_counter += 1 - if balance_log_counter >= 20: - self.log_wallet_balance() - balance_log_counter = 0 +# # Log wallet balance every 10 minutes (20 cycles of 30 seconds) +# balance_log_counter += 1 +# if balance_log_counter >= 20: +# self.log_wallet_balance() +# balance_log_counter = 0 - # Print stats every 5 minutes (10 cycles of 30 seconds) - stats_counter += 1 - if stats_counter >= 10: - self.print_stats() - stats_counter = 0 +# # Print stats every 5 minutes (10 cycles of 30 seconds) +# stats_counter += 1 +# if stats_counter >= 10: +# self.print_stats() +# stats_counter = 0 - except Exception as e: - print(f"Job updater error: {e}") +# except Exception as e: +# print(f"Job updater error: {e}") - def validate_mining_capability(self): - """Validate that we can mine valid blocks against the RinCoin node""" - try: - print("๐Ÿ” Validating mining capability...") +# def validate_mining_capability(self): +# """Validate that we can mine valid blocks against the RinCoin node""" +# try: +# print("๐Ÿ” Validating mining capability...") - # Get block template - template = self.rpc_call("getblocktemplate", [{"rules": ["segwit", "mweb"]}]) - if not template: - print("โŒ Cannot get block template") - return False +# # Get block template +# template = self.rpc_call("getblocktemplate", [{"rules": ["segwit", "mweb"]}]) +# if not template: +# print("โŒ Cannot get block template") +# return False - # Test address validation - result = self.rpc_call("validateaddress", [self.target_address]) - if not result or not result.get('isvalid'): - print(f"โŒ Target address {self.target_address} is invalid") - return False +# # Test address validation +# result = self.rpc_call("validateaddress", [self.target_address]) +# if not result or not result.get('isvalid'): +# print(f"โŒ Target address {self.target_address} is invalid") +# return False - print(f"โœ… Target address {self.target_address} is valid") +# print(f"โœ… Target address {self.target_address} is valid") - # Test coinbase construction - coinbase_wit, coinbase_nowit = self.build_coinbase_transaction_for_address( - template, "00000001", "01000000", self.target_address) +# # Test coinbase construction +# coinbase_wit, coinbase_nowit = self.build_coinbase_transaction_for_address( +# template, "00000001", "01000000", self.target_address) - if not coinbase_wit or not coinbase_nowit: - print("โŒ Cannot construct coinbase transaction") - return False +# if not coinbase_wit or not coinbase_nowit: +# print("โŒ Cannot construct coinbase transaction") +# return False - print(f"โœ… Coinbase construction works") +# print(f"โœ… Coinbase construction works") - # Test block header construction with dummy values - test_nonce = "12345678" - test_ntime = f"{int(time.time()):08x}" +# # Test block header construction with dummy values +# test_nonce = "12345678" +# test_ntime = f"{int(time.time()):08x}" - # Calculate merkle root - coinbase_txid = hashlib.sha256(hashlib.sha256(coinbase_nowit).digest()).digest()[::-1] - merkle_root = self.calculate_merkle_root(coinbase_txid, template.get('transactions', [])) +# # Calculate merkle root +# coinbase_txid = hashlib.sha256(hashlib.sha256(coinbase_nowit).digest()).digest()[::-1] +# merkle_root = self.calculate_merkle_root(coinbase_txid, template.get('transactions', [])) - # Build test header - header = b'' - header += struct.pack(' X.XX RIN to pool' - Undistributed" -echo "3. '๐Ÿ’ฐ Pool keeps X.XX RIN from miners without addresses' - Pool keeps rewards" -echo "4. '๐Ÿ“Š Summary: X miners with addresses, Y without (rewards to pool)' - Final summary" +# echo "" +# echo "๐Ÿ“Š Pool Log Analysis:" +# echo "Look for these patterns in the logs above:" +# echo "1. '๐Ÿ’ฐ Miner rin1q...: X.XX RIN (difficulty)' - Base rewards" +# echo "2. 'โš ๏ธ Miner without address: X difficulty -> X.XX RIN to pool' - Undistributed" +# echo "3. '๐Ÿ’ฐ Pool keeps X.XX RIN from miners without addresses' - Pool keeps rewards" +# echo "4. '๐Ÿ“Š Summary: X miners with addresses, Y without (rewards to pool)' - Final summary" -echo "" -echo "๐Ÿงน Cleaning up..." -kill $POOL_PID 2>/dev/null -./MINE/rin/kill_stratum_proxy.sh +# echo "" +# echo "๐Ÿงน Cleaning up..." +# kill $POOL_PID 2>/dev/null +# ./MINE/rin/kill_stratum_proxy.sh -echo "" -echo "๐Ÿ“‹ Reward Distribution Logic Summary:" -echo "" -echo "โœ… Miners with valid RinCoin addresses:" -echo " - Get reward based on their difficulty" -echo " - Rewards sent directly to their addresses" -echo "" -echo "โš ๏ธ Miners without addresses:" -echo " - Contribute to total difficulty" -echo " - Their reward share goes to pool address" -echo " - No direct rewards received" -echo "" -echo "๐Ÿ’ฐ Pool fee: Always 1% of total block reward" -echo "๐Ÿ’ฐ Pool bonus: Additional rewards from miners without addresses" +# echo "" +# echo "๐Ÿ“‹ Reward Distribution Logic Summary:" +# echo "" +# echo "โœ… Miners with valid RinCoin addresses:" +# echo " - Get reward based on their difficulty" +# echo " - Rewards sent directly to their addresses" +# echo "" +# echo "โš ๏ธ Miners without addresses:" +# echo " - Contribute to total difficulty" +# echo " - Their reward share goes to pool address" +# echo " - No direct rewards received" +# echo "" +# echo "๐Ÿ’ฐ Pool fee: Always 1% of total block reward" +# echo "๐Ÿ’ฐ Pool bonus: Additional rewards from miners without addresses"