Skip to content

Instantly share code, notes, and snippets.

@Timonchegs
Last active December 30, 2025 02:48
Show Gist options
  • Select an option

  • Save Timonchegs/9d8ac1920f2737ecbfa6e8c183cc0d23 to your computer and use it in GitHub Desktop.

Select an option

Save Timonchegs/9d8ac1920f2737ecbfa6e8c183cc0d23 to your computer and use it in GitHub Desktop.
deepseek_proxy
const net = require('net');
const http = require('http');
const crypto = require('crypto');
// КОНФИГУРАЦИЯ
const CONFIG = {
STRATUM_PORT: 3333,
NODE_RPC_HOST: '127.0.0.1',
NODE_GETWORK_PORT: 8668,
RPC_USER: 'tteFTlJ7YOfGDA2KBMHKqnDnXeE=',
RPC_PASS: 'SOkvF8sxay8ViOxpgbraHmqJmSU=',
INITIAL_DIFFICULTY: 0.5
};
class SmartAbelianProxy {
constructor() {
this.currentJob = null;
this.jobs = new Map();
this.miners = new Map();
this.sessionId = 1;
this.server = net.createServer((socket) => this.handleConnection(socket));
// Кеширование результатов тестов
this.testedCombinations = new Set();
this.successfulCombo = null;
}
async start() {
console.log('🧠 Умный Abelian Proxy');
console.log('====================\n');
// Проверка ноды
try {
await this.updateWork();
console.log('✅ Нода подключена\n');
} catch (error) {
console.error('❌ Ошибка ноды:', error.message);
process.exit(1);
}
this.server.listen(CONFIG.STRATUM_PORT, '0.0.0.0', () => {
console.log(`📡 Прокси слушает :${CONFIG.STRATUM_PORT}\n`);
});
// Обновление работы каждые 30 сек
setInterval(() => this.updateWork(), 30000);
}
// ---------- RPC ВЗАИМОДЕЙСТВИЕ ----------
async rpcCall(method, params) {
const data = JSON.stringify({
jsonrpc: '2.0',
id: Date.now(),
method,
params
});
const auth = 'Basic ' + Buffer.from(`${CONFIG.RPC_USER}:${CONFIG.RPC_PASS}`).toString('base64');
const options = {
hostname: CONFIG.NODE_RPC_HOST,
port: CONFIG.NODE_GETWORK_PORT,
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
'Authorization': auth
},
timeout: 5000
};
return new Promise((resolve, reject) => {
const req = http.request(options, (res) => {
let response = '';
res.on('data', chunk => response += chunk);
res.on('end', () => {
try {
resolve(JSON.parse(response));
} catch {
reject(new Error('Invalid JSON response'));
}
});
});
req.on('error', reject);
req.write(data);
req.end();
});
}
async updateWork() {
try {
const result = await this.rpcCall('getwork', [""]);
if (!result.result) throw new Error('No work from node');
const work = result.result;
const jobId = Date.now().toString(36).slice(-6);
this.currentJob = {
id: jobId,
nodeJobId: work.jobid,
contentHash: work.contenthash.replace('0x', ''),
epochSeed: work.epochseed.replace('0x', ''),
epoch: work.epoch || 0,
target: work.targetboundary?.replace('0x', '') || '0'.repeat(64)
};
this.jobs.set(jobId, this.currentJob);
console.log(`🔄 Новая работа: ${jobId} (эпоха ${this.currentJob.epoch})`);
// Рассылка авторизованным майнерам
this.miners.forEach(miner => {
if (miner.authorized) this.sendJob(miner);
});
} catch (error) {
console.error('⚠️ Ошибка обновления:', error.message);
}
}
// ---------- STRATUM ОБРАБОТКА ----------
handleConnection(socket) {
const minerId = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(`\n🔌 Подключение: ${minerId}`);
const miner = {
id: minerId,
socket,
sessionId: `s${this.sessionId++}`,
extraNonce: crypto.randomBytes(2).toString('hex'),
authorized: false,
workerName: null
};
this.miners.set(minerId, miner);
socket.on('data', (data) => {
const lines = data.toString().trim().split('\n');
lines.forEach(line => line && this.processMessage(miner, line));
});
socket.on('close', () => {
console.log(`🔌 Отключение: ${minerId}`);
this.miners.delete(minerId);
});
}
processMessage(miner, message) {
try {
const msg = JSON.parse(message);
if (msg.method === 'mining.hello') {
this.send(miner.socket, {
id: msg.id,
result: {
proto: "AbelianStratum",
encoding: "utf-8",
extranonce: miner.extraNonce,
version: "1.0.0",
algo: "abelhash",
resume: "0",
timeout: "300"
},
error: null
});
}
else if (msg.method === 'mining.subscribe') {
this.send(miner.socket, {
id: msg.id,
result: {
session_id: miner.sessionId,
extra_nonce1: miner.extraNonce
},
error: null
});
}
else if (msg.method === 'mining.authorize') {
miner.authorized = true;
miner.workerName = msg.params[0];
console.log(`✅ Авторизация: ${miner.workerName}`);
this.send(miner.socket, {
id: msg.id,
result: { worker: miner.id, registered: "0" },
error: null
});
// Отправляем сложность и работу
setTimeout(() => {
this.send(miner.socket, {
id: null,
method: 'mining.set_difficulty',
params: [CONFIG.INITIAL_DIFFICULTY]
});
if (this.currentJob) this.sendJob(miner);
}, 100);
}
else if (msg.method === 'mining.submit') {
this.handleSubmit(miner, msg);
}
} catch (error) {
console.error('❌ Ошибка обработки:', error.message);
}
}
async handleSubmit(miner, msg) {
const [jobId, submittedNonce, workerName] = msg.params;
const job = this.jobs.get(jobId);
if (!job) {
this.send(miner.socket, { id: msg.id, result: false, error: "Stale job" });
return;
}
console.log(`\n🎯 Submit от ${miner.workerName}`);
console.log(`📦 Nonce: ${submittedNonce}, Job: ${jobId}`);
// Если уже нашли работающую комбинацию - используем её
if (this.successfulCombo) {
const result = await this.testCombination(job, submittedNonce, this.successfulCombo);
this.send(miner.socket, { id: msg.id, result: result.success, error: null });
return;
}
// Тестируем только 4 ключевые гипотезы
const hypotheses = [
// ГИПОТЕЗА 1: Ethash-like (Keccak от header + nonce)
{
name: 'Ethash-like',
prepare: (nonce) => {
const cleanNonce = nonce.slice(miner.extraNonce.length);
const mixHash = crypto.createHash('sha3-256')
.update(job.contentHash + cleanNonce, 'hex')
.digest('hex');
return {
params: [job.nodeJobId, cleanNonce, '0x' + mixHash],
desc: `nonce=${cleanNonce}, Keccak(header+nonce)`
};
}
},
// ГИПОТЕЗА 2: Nonce как mixDigest (редкий случай)
{
name: 'Nonce-as-mix',
prepare: (nonce) => ({
params: [job.nodeJobId, job.contentHash, '0x' + nonce],
desc: `nonce как mixDigest`
})
},
// ГИПОТЕЗА 3: Epoch-based (используем epochSeed)
{
name: 'Epoch-based',
prepare: (nonce) => {
const cleanNonce = nonce.slice(miner.extraNonce.length);
const mixHash = crypto.createHash('sha3-256')
.update(job.epochSeed + cleanNonce, 'hex')
.digest('hex');
return {
params: [job.nodeJobId, cleanNonce, '0x' + mixHash],
desc: `nonce=${cleanNonce}, Keccak(epochSeed+nonce)`
};
}
},
// ГИПОТЕЗА 4: Простой contentHash как mixDigest
{
name: 'Simple-header',
prepare: (nonce) => ({
params: [job.nodeJobId, nonce.slice(miner.extraNonce.length), '0x' + job.contentHash],
desc: `contentHash как mixDigest`
})
}
];
let shareAccepted = false;
for (const hypothesis of hypotheses) {
const comboKey = hypothesis.name;
// Пропускаем если уже тестировали
if (this.testedCombinations.has(comboKey)) continue;
console.log(`🔍 Тестируем: ${hypothesis.name}`);
const prepared = hypothesis.prepare(submittedNonce);
console.log(` ${prepared.desc}`);
const result = await this.rpcCall('submitwork', prepared.params);
if (result.result === true) {
console.log(`🎉🎉🎉 РАБОЧАЯ КОМБИНАЦИЯ: ${hypothesis.name}`);
this.successfulCombo = hypothesis;
shareAccepted = true;
break;
} else if (result.error) {
console.log(` ❌ ${result.error.code}: ${result.error.message}`);
this.testedCombinations.add(comboKey);
}
// Пауза между запросами
await new Promise(r => setTimeout(r, 100));
}
// Если ни одна гипотеза не сработала
if (!shareAccepted && this.testedCombinations.size === hypotheses.length) {
console.log('🚫 Все гипотезы проверены, ни одна не работает');
console.log('💡 Возможные причины:');
console.log(' 1. Неверный алгоритм хеширования mixDigest');
console.log(' 2. Неверный порядок параметров submitwork');
console.log(' 3. Нужен 4-й параметр (epoch или что-то ещё)');
}
this.send(miner.socket, {
id: msg.id,
result: shareAccepted,
error: shareAccepted ? null : "Share rejected"
});
}
sendJob(miner) {
if (!this.currentJob) return;
// mining.set
this.send(miner.socket, {
id: null,
method: 'mining.set',
params: {
epoch: "65",
target: "00000001ffff0000000000000000000000000000000000000000000000000000",
algo: "abelhash",
extranonce: miner.extraNonce,
extra_nonce_bits_num: "10"
}
});
// mining.notify
this.send(miner.socket, {
id: null,
method: 'mining.notify',
params: {
job_id: this.currentJob.id,
height: this.currentJob.epoch.toString(16),
content_hash: this.currentJob.contentHash,
clean_job: "0"
}
});
console.log(`📤 Работа ${this.currentJob.id} → ${miner.workerName}`);
}
send(socket, data) {
socket.write(JSON.stringify(data) + '\n');
}
async testCombination(job, submittedNonce, hypothesis) {
const prepared = hypothesis.prepare(submittedNonce);
const result = await this.rpcCall('submitwork', prepared.params);
return { success: result.result === true };
}
}
// Запуск
const proxy = new SmartAbelianProxy();
proxy.start().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment