Files
mines/rin/proxy/node-stratum-proxy/test-client.js
Dobromir Popov e22f776e43 wip-broken
2025-09-21 21:22:18 +03:00

184 lines
5.5 KiB
JavaScript

#!/usr/bin/env node
/**
* Test Client for RIN Stratum Proxy
* This simulates a miner connecting to the stratum server
*/
const net = require('net');
const readline = require('readline');
class StratumTestClient {
constructor(host = '127.0.0.1', port = 3333) {
this.host = host;
this.port = port;
this.socket = null;
this.messageId = 1;
this.subscribed = false;
this.authorized = false;
this.currentJob = null;
console.log('🧪 RIN Stratum Test Client');
console.log(`🔗 Connecting to ${host}:${port}`);
}
connect() {
return new Promise((resolve, reject) => {
this.socket = new net.Socket();
this.socket.connect(this.port, this.host, () => {
console.log('✅ Connected to stratum server');
resolve();
});
this.socket.on('data', (data) => {
this.handleMessage(data.toString());
});
this.socket.on('close', () => {
console.log('🔌 Connection closed');
});
this.socket.on('error', (error) => {
console.error(`❌ Connection error: ${error.message}`);
reject(error);
});
});
}
handleMessage(message) {
try {
const lines = message.trim().split('\n');
for (const line of lines) {
if (line) {
const data = JSON.parse(line);
console.log('📨 Received:', JSON.stringify(data, null, 2));
if (data.method === 'mining.notify') {
this.handleMiningNotify(data.params);
} else if (data.method === 'mining.set_difficulty') {
this.handleSetDifficulty(data.params);
}
}
}
} catch (error) {
console.error(`❌ Message parsing error: ${error.message}`);
}
}
handleMiningNotify(params) {
if (params.length >= 8) {
this.currentJob = {
jobId: params[0],
prevhash: params[1],
coinb1: params[2],
coinb2: params[3],
merkleBranch: params[4],
version: params[5],
bits: params[6],
ntime: params[7],
cleanJobs: params[8]
};
console.log(`🆕 New job received: ${this.currentJob.jobId}`);
console.log(` Height: ${this.currentJob.version} | Bits: ${this.currentJob.bits}`);
// Simulate mining by submitting a test share
setTimeout(() => {
this.submitTestShare();
}, 1000);
}
}
handleSetDifficulty(params) {
if (params.length > 0) {
console.log(`🎯 Difficulty set to: ${params[0]}`);
}
}
sendMessage(method, params = [], id = null) {
const message = {
id: id || this.messageId++,
method: method,
params: params
};
const jsonMessage = JSON.stringify(message) + '\n';
console.log('📤 Sending:', JSON.stringify(message, null, 2));
this.socket.write(jsonMessage);
}
async subscribe() {
console.log('📝 Subscribing to stratum server...');
this.sendMessage('mining.subscribe', ['TestMiner/1.0']);
this.subscribed = true;
}
async authorize(username = 'testworker', password = 'x') {
console.log(`🔐 Authorizing as ${username}...`);
this.sendMessage('mining.authorize', [username, password]);
this.authorized = true;
}
submitTestShare() {
if (!this.currentJob) {
console.log('❌ No current job to submit share for');
return;
}
console.log('📊 Submitting test share...');
// Generate test values
const extranonce2 = Math.floor(Math.random() * 0xffffffff).toString(16).padStart(8, '0');
const ntime = this.currentJob.ntime;
const nonce = Math.floor(Math.random() * 0xffffffff).toString(16).padStart(8, '0');
this.sendMessage('mining.submit', [
'testworker',
this.currentJob.jobId,
extranonce2,
ntime,
nonce
]);
}
async run() {
try {
await this.connect();
await this.subscribe();
// Wait a bit for subscription response
await new Promise(resolve => setTimeout(resolve, 1000));
await this.authorize();
// Keep connection alive
console.log('🔄 Test client running. Press Ctrl+C to exit.');
// Simulate periodic share submissions
setInterval(() => {
if (this.currentJob && this.authorized) {
this.submitTestShare();
}
}, 5000);
} catch (error) {
console.error(`❌ Test client error: ${error.message}`);
process.exit(1);
}
}
}
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('\n🛑 Shutting down test client...');
process.exit(0);
});
// Start test client
const client = new StratumTestClient();
client.run().catch(error => {
console.error(`❌ Failed to start test client: ${error.message}`);
process.exit(1);
});