Reorganization Progress (submodules)
commit
6b42407d97
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# SharpMining
|
||||
Mono/.NET Implementation of Monero Mining Pool
|
||||
|
||||
more information to come...
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
namespace SharpMining
|
||||
{
|
||||
public class daemon
|
||||
{
|
||||
public daemon()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net47" />
|
||||
</packages>
|
|
@ -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" ] }
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue