Reorganization Progress (submodules)

master
Harald Wolff 2017-10-17 22:07:00 +02:00
commit 6b42407d97
15 changed files with 936 additions and 0 deletions

40
.gitignore vendored 100644
View File

@ -0,0 +1,40 @@
# Autosave files
*~
# build
[Oo]bj/
[Bb]in/
packages/
TestResults/
# globs
Makefile.in
*.DS_Store
*.sln.cache
*.suo
*.cache
*.pidb
*.userprefs
*.usertasks
config.log
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.user
*.tar.gz
tarballs/
test-results/
Thumbs.db
# Mac bundle stuff
*.dmg
*.app
# resharper
*_Resharper.*
*.Resharper
# dotCover
*.dotCover

6
.gitmodules vendored 100644
View File

@ -0,0 +1,6 @@
[submodule "sharp-crypto"]
path = sharp-crypto
url = git@schwann.lnvpn.de:LupusNobilis/sharp-crypto.git
[submodule "sharp-biginteger"]
path = sharp-biginteger
url = git@schwann.lnvpn.de:haraldwolff/sharp-biginteger.git

73
SharpMining.sln 100644
View File

@ -0,0 +1,73 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpMining", "SharpMining\SharpMining.csproj", "{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleLogger", "SimpleLogger\SimpleLogger.csproj", "{991FEB35-A35C-460D-A215-B8A29842E37B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharp.cryptonote", "sharp-cryptonote-tool\sharp.cryptonote.csproj", "{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharp.jsonrpc", "sharp-jsonrpc\sharp.jsonrpc.csproj", "{DCE6066E-9709-4D12-8994-F7879C3557D6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharp.hashing", "sharp-hashing\sharp.hashing.csproj", "{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sharp.extensions", "sharp-extensions\sharp.extensions.csproj", "{97CA3CA9-98B3-4492-B072-D7A5995B68E9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BigInt", "BigInteger\BigInt.csproj", "{E745E261-9E3E-4401-B3BA-78B38753A82E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BigIntegerTest", "BigIntegerTest\BigIntegerTest.csproj", "{9596C70F-9CCD-4821-A82B-501B97544D52}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crypto", "Crypto\Crypto.csproj", "{15D8398F-01EB-4280-8E2E-B03417DD3215}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}.Debug|x86.ActiveCfg = Debug|x86
{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}.Debug|x86.Build.0 = Debug|x86
{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}.Release|x86.ActiveCfg = Release|x86
{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}.Release|x86.Build.0 = Release|x86
{991FEB35-A35C-460D-A215-B8A29842E37B}.Debug|x86.ActiveCfg = Debug|Any CPU
{991FEB35-A35C-460D-A215-B8A29842E37B}.Debug|x86.Build.0 = Debug|Any CPU
{991FEB35-A35C-460D-A215-B8A29842E37B}.Release|x86.ActiveCfg = Release|Any CPU
{991FEB35-A35C-460D-A215-B8A29842E37B}.Release|x86.Build.0 = Release|Any CPU
{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}.Debug|x86.ActiveCfg = Debug|Any CPU
{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}.Debug|x86.Build.0 = Debug|Any CPU
{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}.Release|x86.ActiveCfg = Release|Any CPU
{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}.Release|x86.Build.0 = Release|Any CPU
{DCE6066E-9709-4D12-8994-F7879C3557D6}.Debug|x86.ActiveCfg = Debug|Any CPU
{DCE6066E-9709-4D12-8994-F7879C3557D6}.Debug|x86.Build.0 = Debug|Any CPU
{DCE6066E-9709-4D12-8994-F7879C3557D6}.Release|x86.ActiveCfg = Release|Any CPU
{DCE6066E-9709-4D12-8994-F7879C3557D6}.Release|x86.Build.0 = Release|Any CPU
{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}.Debug|x86.ActiveCfg = Debug|Any CPU
{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}.Debug|x86.Build.0 = Debug|Any CPU
{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}.Release|x86.ActiveCfg = Release|Any CPU
{CCD7C196-B079-4AA7-98AF-5BECAD089CE4}.Release|x86.Build.0 = Release|Any CPU
{97CA3CA9-98B3-4492-B072-D7A5995B68E9}.Debug|x86.ActiveCfg = Debug|Any CPU
{97CA3CA9-98B3-4492-B072-D7A5995B68E9}.Debug|x86.Build.0 = Debug|Any CPU
{97CA3CA9-98B3-4492-B072-D7A5995B68E9}.Release|x86.ActiveCfg = Release|Any CPU
{97CA3CA9-98B3-4492-B072-D7A5995B68E9}.Release|x86.Build.0 = Release|Any CPU
{E745E261-9E3E-4401-B3BA-78B38753A82E}.Debug|x86.ActiveCfg = Debug|Any CPU
{E745E261-9E3E-4401-B3BA-78B38753A82E}.Debug|x86.Build.0 = Debug|Any CPU
{E745E261-9E3E-4401-B3BA-78B38753A82E}.Release|x86.ActiveCfg = Release|Any CPU
{E745E261-9E3E-4401-B3BA-78B38753A82E}.Release|x86.Build.0 = Release|Any CPU
{9596C70F-9CCD-4821-A82B-501B97544D52}.Debug|x86.ActiveCfg = Debug|x86
{9596C70F-9CCD-4821-A82B-501B97544D52}.Debug|x86.Build.0 = Debug|x86
{9596C70F-9CCD-4821-A82B-501B97544D52}.Release|x86.ActiveCfg = Release|x86
{9596C70F-9CCD-4821-A82B-501B97544D52}.Release|x86.Build.0 = Release|x86
{15D8398F-01EB-4280-8E2E-B03417DD3215}.Debug|x86.ActiveCfg = Debug|Any CPU
{15D8398F-01EB-4280-8E2E-B03417DD3215}.Debug|x86.Build.0 = Debug|Any CPU
{15D8398F-01EB-4280-8E2E-B03417DD3215}.Release|x86.ActiveCfg = Release|Any CPU
{15D8398F-01EB-4280-8E2E-B03417DD3215}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.DotNetNamingPolicy = $1
$1.DirectoryNamespaceAssociation = PrefixedHierarchical
$1.ResourceNamePolicy = FileFormatDefault
$0.VersionControlPolicy = $2
$2.inheritsSet = Mono
EndGlobalSection
EndGlobal

40
SharpMining/.gitignore vendored 100644
View File

@ -0,0 +1,40 @@
# Autosave files
*~
# build
[Oo]bj/
[Bb]in/
packages/
TestResults/
# globs
Makefile.in
*.DS_Store
*.sln.cache
*.suo
*.cache
*.pidb
*.userprefs
*.usertasks
config.log
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.user
*.tar.gz
tarballs/
test-results/
Thumbs.db
# Mac bundle stuff
*.dmg
*.app
# resharper
*_Resharper.*
*.Resharper
# dotCover
*.dotCover

View File

@ -0,0 +1,50 @@
using System;
using Newtonsoft.Json.Linq;
using sharp.extensions;
using sharp.cryptonote;
namespace SharpMining
{
public class MiningJob
{
public MiningJob(byte[] blob, UInt64 jobid, UInt64 height, UInt64 target)
{
this.Blob = blob;
this.JobID = jobid;
this.Height = height;
this.Target = target;
Block block = new Block(blob);
Console.WriteLine( block.ToString() );
}
public byte[] Blob { get; private set; }
public UInt64 JobID { get; private set; }
public UInt64 Height { get; private set; }
public UInt64 Target { get; private set; }
public StratumConnection Miner { get; set; }
public JToken toJSON()
{
JToken job = new JObject(
new JProperty("blob", HexString.toString(Blob)),
new JProperty("job_id", HexString.toString(JobID.GetBytes())),
new JProperty("target", HexString.toString(Target.GetBytes()))
);
return job;
}
public JToken toJSON(UInt64 diff)
{
UInt64 target = (((UInt64)1<<32)-1) / diff;
JToken job = new JObject(
new JProperty("blob", Blob.Segment(0,76).toHexString()),
new JProperty("job_id", JobID.GetBytes().toHexString()),
new JProperty("target", target.GetBytes(Endianess.LittleEndian).toHexString().Substring(0,8))
);
return job;
}
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using sharp.cryptonote.rpc;
using sharp.cryptonote;
using Newtonsoft.Json.Linq;
namespace SharpMining
{
public class MiningPool
{
JToken poolConfig;
List<Daemon> daemons;
public Daemon[] Daemons { get { return this.daemons.ToArray(); } }
public WorkManager WorkManager { get; private set; }
public CryptoNoteAddress PoolWallet { get; private set; }
public Dictionary<CryptoNoteCoin, StratumListener> assignedStratums;
public MiningPool(JToken poolConfig)
{
this.poolConfig = poolConfig;
this.daemons = new List<Daemon>();
this.assignedStratums = new Dictionary<CryptoNoteCoin, StratumListener>();
this.Coin = (CryptoNoteCoin)Enum.Parse(typeof(CryptoNoteCoin), poolConfig["pool"]["coin"].ToObject<string>());
this.PoolWallet = new CryptoNoteAddress(poolConfig["pool"]["wallet"].ToObject<string>());
this.WorkManager = new WorkManager(this);
CreateDaemonRPC();
}
public CryptoNoteCoin Coin { get; private set; }
public void CreateDaemonRPC()
{
foreach (JToken dc in poolConfig["daemons"])
{
Daemon daemon = new Daemon(dc["host"].ToString(), dc["port"].ToObject<int>());
daemons.Add(daemon);
}
}
public Daemon getCheckedDaemon()
{
foreach (Daemon daemon in this.daemons)
{
if (daemon.check())
{
return daemon;
}
}
return null;
}
public override string ToString()
{
return string.Format("[MiningPool: Coin={0}, PoolWallet={1}]", Coin, PoolWallet);
}
}
}

View File

@ -0,0 +1,5 @@
# SharpMining
Mono/.NET Implementation of Monero Mining Pool
more information to come...

View File

@ -0,0 +1,102 @@
using System;
using sharp.cryptonote.rpc;
using sharp.cryptonote;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Collections.Generic;
using System.Linq;
namespace SharpMining
{
public class SharpMining
{
public static void Main(String[] args)
{
if (args.Length > 1){
Console.WriteLine("usage: SharpMining.exe <config.json>");
return;
}
SharpMining sm = new SharpMining(args);
sm.Run();
}
private String configFileName;
private JToken config;
private List<MiningPool> pools;
private List<StratumListener> stratums;
public SharpMining(String[] args){
if (args.Length == 0){
configFileName = "sharpmining.json";
} else if (args.Length == 1){
configFileName = args[0];
};
this.config = JToken.Parse(File.ReadAllText(configFileName));
this.pools = new List<MiningPool>();
this.stratums = new List<StratumListener>();
}
public void Run(){
CreatePools();
CreateStratums();
foreach (MiningPool pool in this.pools){
Console.WriteLine("Running Pool for {0} with Pool-Wallet {1}",pool.Coin,pool.PoolWallet.ToString());
}
foreach (StratumListener l in this.stratums){
Console.WriteLine("Started Stratum Listener [{0}] for Pools:",l.LocalEndpoint.ToString());
foreach(MiningPool pool in l.AssociatedPools){
Console.WriteLine(" -> {0}", pool.ToString());
}
}
}
public StratumListener[] Stratums { get { return this.stratums.ToArray(); } }
public void CreatePools(){
foreach (JToken pool in config["pools"])
{
this.pools.Add(new MiningPool(pool));
}
}
public void CreateStratums(){
foreach (JToken dc in config["stratums"]){
StratumListener stratum = new StratumListener(dc);
if (dc["coins"].Equals(JValue.CreateNull())){
foreach (MiningPool p in this.pools){
stratum.associatePool(p);
}
} else {
foreach (JToken c in dc["coins"]){
CryptoNoteCoin coin = c.ToObject<CryptoNoteCoin>();
stratum.associatePool( findPool(coin) );
}
}
stratums.Add(stratum);
stratum.Start();
}
}
public MiningPool findPool(CryptoNoteCoin coin){
foreach (MiningPool p in this.pools){
if (p.Coin.Equals(coin)){
return p;
}
}
return null;
}
}
}

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{5AE4E72A-253B-4FBD-AD5E-C038D57571D0}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>SharpMining</RootNamespace>
<AssemblyName>SharpMining</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Compile Include="SharpMining.cs" />
<Compile Include="WorkManager.cs" />
<Compile Include="StratumListener.cs" />
<Compile Include="StratumConnection.cs" />
<Compile Include="MiningPool.cs" />
<Compile Include="MiningJob.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="sharpmining.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-jsonrpc\sharp.jsonrpc.csproj">
<Project>{DCE6066E-9709-4D12-8994-F7879C3557D6}</Project>
<Name>sharp.jsonrpc</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-cryptonote-tool\sharp.cryptonote.csproj">
<Project>{52C68C13-2DC2-438A-9EC1-E8C4953B07DF}</Project>
<Name>sharp.cryptonote</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Policies>
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="FileFormatDefault" />
</Policies>
</Properties>
</MonoDevelop>
</ProjectExtensions>
</Project>

View File

@ -0,0 +1,188 @@
using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using sharp.jsonrpc.net;
using Newtonsoft.Json.Linq;
using sharp.cryptonote;
namespace SharpMining
{
public class StratumConnection : JSONClient
{
delegate void threadsyncdelegate();
StratumListener listener;
Thread thread;
bool shouldExit;
public Guid UID { get; } = Guid.NewGuid();
public CryptoNoteAddress Wallet { get; set; }
public string WorkerID { get; set; }
public int FixedDiff { get; set; }
public string Agent { get; set; }
public MiningPool Pool { get; private set; }
public MiningJob CurrentJob { get; private set; }
public MiningJob LastJob { get; private set; }
public StratumConnection(StratumListener listener,Socket socket)
:base(socket)
{
this.listener = listener;
this.thread = new Thread(()=>run());
this.thread.Start();
}
public new void Close(){
Monitor.Enter(this);
if (shouldExit){
return;
}
shouldExit = true;
Monitor.Wait(this);
base.Close();
Monitor.Exit(this);
}
private void run(){
while (!ShouldExit){
try
{
JToken token = readJSON();
if (token["method"] != null)
{
methodCalled(token["method"].ToObject<string>(), token["id"].ToObject<UInt64>(), token["params"]);
}
} catch (IOException ioe){
Close();
} catch (Exception e){
Console.WriteLine("StratumConnection: [{0}] Exception: {1}",UID.ToString(),e.ToString());
}
}
if (Pool != null){
Pool.WorkManager.OnNewBlockAvailable -= WorkManager_OnNewBlockAvailable;
}
Monitor.Enter(this);
Monitor.PulseAll(this);
Monitor.Exit(this);
}
private bool ShouldExit { get { Monitor.Enter(this); bool se = this.shouldExit; Monitor.Exit(this); return se; } }
private new void writeJSON(JToken token){
Monitor.Enter(this);
base.writeJSON(token);
Monitor.Exit(this);
}
private void methodCalled(string method,UInt64 id,JToken args){
switch (method){
case "login":
rpcLogin(id,args);
break;
case "submit":
rpcSubmit(id, args);
break;
default:
writeJSONRPC(id, null, new JValue(String.Format("Method not implemented: {0}", method)));
break;
}
}
private string splitSuffix(char deli, ref string line)
{
return splitSuffix(deli, ref line, "");
}
private string splitSuffix(char deli, ref string line, string def){
string result = def;
int i = line.IndexOf(deli);
if (i >= 0){
result = line.Substring(i + 1);
line = line.Substring(0, i);
};
return result;
}
private void rpcLogin(UInt64 id,JToken args){
string username, passwd;
Agent = args["agent"].ToObject<string>();
username = args["login"].ToObject<string>();
passwd = args["pass"].ToObject<string>();
try {
FixedDiff = int.Parse(splitSuffix('@', ref username,"0"));
WorkerID = splitSuffix('.', ref username);
Wallet = new CryptoNoteAddress(username);
Pool = this.listener.getAssociatedPool(Wallet.CryptoNoteCoin);
if (Pool == null){
throw new Exception("No Pool for that coin available!");
}
MiningJob job = Pool.WorkManager.createJob();
assignJob(job, false);
Pool.WorkManager.OnNewBlockAvailable += WorkManager_OnNewBlockAvailable;
} catch (Exception e){
writeJSONRPC(id,null,new JValue(String.Format("An Exception occured ({0}: {1})",e.ToString(),e.Message)));
Close();
}
Console.WriteLine("Miner connected: [{3}] Wallet: {0} WorkerID: {1} FixedDiff: {2}", Wallet, WorkerID, FixedDiff, UID.ToString());
writeJSONRPC(id, new JObject(
new JProperty("id", "555"),
new JProperty("job", CurrentJob.toJSON(100))
), null);
}
private void rpcSubmit(UInt64 id,JToken args)
{
}
private bool assignJob(MiningJob job,bool transmit){
LastJob = CurrentJob;
CurrentJob = job;
if (transmit){
transmitCurrentJob();
}
return true;
}
public void transmitCurrentJob(){
writeJSON(new JObject(
new JProperty("jsonrpc", "2.0"),
new JProperty("method","job"),
new JProperty("params", CurrentJob.toJSON())
));
}
void WorkManager_OnNewBlockAvailable(WorkManager workmanager)
{
assignJob( this.Pool.WorkManager.createJob(), true );
}
public override string ToString()
{
return string.Format("[StratumConnection: [{4}] MinerWallet={0}, WorkerID={1}, FixedDiff={2}, Agent={3}]", Wallet, WorkerID, FixedDiff, Agent, UID.ToString());
}
}
}

View File

@ -0,0 +1,130 @@
using System;
using System.Net;
using System.Collections.Generic;
using System.Threading;
using System.Net.Sockets;
using sharp.cryptonote;
using Newtonsoft.Json.Linq;
namespace SharpMining
{
public delegate void StratumConnectionAccepted(StratumListener listener, StratumConnection stratumConnection);
public class StratumListener : TcpListener
{
bool shouldExit;
List<StratumConnection> connections;
Thread thread;
Dictionary<CryptoNoteCoin, MiningPool> associatedPools;
public event StratumConnectionAccepted OnConnectionAccepted;
public StratumListener(IPEndPoint endpoint)
:base(endpoint)
{
this.initialize();
}
public StratumListener(IPAddress bind,int port)
:base(bind,port)
{
this.initialize();
}
public StratumListener(string bind, int port)
:base(IPAddress.Parse(bind),port)
{
this.initialize();
}
public StratumListener(JToken stratumConfig)
:base(IPAddress.Parse(stratumConfig["bind"].ToString()),stratumConfig["port"].ToObject<int>())
{
this.initialize();
}
private void initialize(){
this.associatedPools = new Dictionary<CryptoNoteCoin, MiningPool>();
this.connections = new List<StratumConnection>();
}
public new void Start(){
if (thread == null){
thread = new Thread(() => run());
thread.Start();
}
}
public new void Stop(){
Monitor.Enter(this);
shouldExit = true;
Monitor.Wait(this);
Monitor.Exit(this);
}
protected void ConnectionAccepted(StratumConnection connection){
if (OnConnectionAccepted != null){
OnConnectionAccepted(this,connection);
}
}
private void run(){
base.Start(5);
while (!ShouldExit){
StratumConnection connection = AcceptStratumConnection();
connection.OnConnectionClosed += (sender) => { removeConnection(connection); };
this.connections.Add(connection);
ConnectionAccepted(connection);
}
base.Stop();
Monitor.Enter(this);
this.thread = null;
foreach (StratumConnection c in this.connections){
c.Close();
}
Monitor.PulseAll(this);
Monitor.Exit(this);
}
public StratumConnection AcceptStratumConnection(){
return new StratumConnection(this,this.AcceptSocket());
}
private void removeConnection(StratumConnection connection){
this.connections.Remove(connection);
Console.WriteLine("StratumConnection lost: {0}",connection);
}
private bool ShouldExit { get { Monitor.Enter(this); bool se = this.shouldExit; Monitor.Exit(this); return se; } }
public StratumConnection[] Connections { get { return this.connections.ToArray(); } }
public MiningPool[] AssociatedPools {
get {
MiningPool[] pools = new MiningPool[this.associatedPools.Count];
this.associatedPools.Values.CopyTo(pools,0);
return pools;
}
}
public MiningPool getAssociatedPool(CryptoNoteCoin coin){
if (!this.associatedPools.ContainsKey(coin)){
return null;
}
return this.associatedPools[coin];
}
public void associatePool(MiningPool pool){
this.associatedPools[pool.Coin] = pool;
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using System.Threading;
using sharp.cryptonote;
using sharp.cryptonote.rpc;
using System.Collections.Generic;
using sharp.extensions;
using Newtonsoft.Json.Linq;
namespace SharpMining
{
public delegate void NewBlockAvailable(WorkManager workmanager);
public class WorkManager
{
Thread thread;
BlockTemplate currentTemplate;
UInt64 nextJobID;
Dictionary<UInt64, MiningJob> currentJobs;
public event NewBlockAvailable OnNewBlockAvailable;
public MiningPool MiningPool { get; private set; }
public WorkManager(MiningPool pool)
{
this.MiningPool = pool;
this.nextJobID = 1;
this.currentJobs = new Dictionary<ulong, MiningJob>();
this.thread = new Thread(() => Run());
this.thread.Start();
}
private void Run(){
while (true){
Thread.Sleep(2000);
Daemon daemon = MiningPool.getCheckedDaemon();
if (daemon == null){
Console.WriteLine("WorkManager: no Daemon available");
} else {
BlockTemplate newTemplate = daemon.getBlockTemplate(MiningPool.PoolWallet, 8);
Console.WriteLine("current target height is {0}",newTemplate.Height);
if ((currentTemplate == null) || (currentTemplate.Height != newTemplate.Height)){
changeCurrentBlock(newTemplate);
}
}
}
}
private void fireNewBlockAvailable(){
if (OnNewBlockAvailable != null){
OnNewBlockAvailable.Invoke(this);
}
}
public void changeCurrentBlock(BlockTemplate blockTemplate){
Monitor.Enter(this);
currentTemplate = blockTemplate;
Console.WriteLine("new block target height: {0} target difficulty: {1} [0x{1:x}]",blockTemplate.Height,blockTemplate.Difficulty);
fireNewBlockAvailable();
Monitor.Exit(this);
}
public MiningJob createJob()
{
Monitor.Enter(this);
if (this.currentTemplate == null){
return null;
}
UInt64 jobid = this.nextJobID++;
MiningJob job = new MiningJob(this.currentTemplate.generateJobTemplate(jobid.GetBytes()), jobid, this.currentTemplate.Height, this.currentTemplate.Difficulty);
this.currentJobs.Add(jobid, job);
Monitor.Exit(this);
return job;
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace SharpMining
{
public class daemon
{
public daemon()
{
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net47" />
</packages>

View File

@ -0,0 +1,52 @@
{
pools : [
{
pool: {
coin: "XMR",
wallet: "45YKUs6Lr8562D1vwUfVGPZR7RZp4vqnL95XMvZJEnjREiwEjs8RscC8Djxg5jRzbDAnbK6A9Z9M9VTeMjn9EG1D4Ly7U4i"
},
daemons: [
{ host: "10.0.0.1", port: 18081 }
],
wallets: [
{ host: "10.0.0.1", port: 8082 },
],
rpc: {
bind: "127.0.0.1",
port: "8880"
},
contact: "info@lupus-nobilis.de"
},
{
pool: {
coin: "AEON",
wallet: "WmtVdqr4fqH3YuwoasjChqhmF3pv8pQ3JgQTKSaA2Bog5zFkporDmyK59fAgbdZjCMcv38wzBk4ZogMYkwyKwH1337FBF2AaQ"
},
daemons: [
{ host: "10.0.0.1", port: 11181 }
],
wallets: [
{ host: "10.0.0.1", port: 8082 },
],
rpc: {
bind: "127.0.0.1",
port: "8881"
},
contact: "info@lupus-nobilis.de"
}
],
stratums: [
{ bind: "127.0.0.1", port: 3333, diff: 100, description: "Stratum Port for Low-End Miner", coins: null },
{ bind: "127.0.0.1", port: 5555, diff: 1000, description: "Stratum Port for Mid-Range Miner", coins: null },
{ bind: "127.0.0.1", port: 7777, diff: 10000, description: "Stratum Port for High-End Miner", coins: [ "XMR" ] }
]
}