diff --git a/.gitmodules b/.gitmodules index 052b103cd..8fdebd0c2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "deps/gibbed.io"] - path = deps/gibbed.io - url = https://github.com/CoiniumServ/Gibbed.IO.git -[submodule "deps/jsonconfig"] - path = deps/jsonconfig - url = https://github.com/CoiniumServ/JsonConfig.git [submodule "deps/csredis"] path = deps/csredis url = https://github.com/CoiniumServ/csredis.git diff --git a/Changelog.md b/Changelog.md index 219f49c62..40397b3ce 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,28 @@ +##### [v0.1.3 alpha - Piri Reis](https://github.com/CoiniumServ/CoiniumServ/releases/tag/v0.1.3-alpha) - 03.09.2014 + +**Storage** +* Implemented storage layers support; hybrid-storage (redis+mysql) and mpos compatibility (mysql). +* Major changes in storage configuration - you need to update per-pool configuration files. +* Added migration support, CoiniumServ will manage required tables on it's own in hybrid-storage mode. + +**Coin** +* Fixed a bug with coin's that was returning non-standard version reply in getinfo(). +* Added initial proof-of-stake coin support. +* Added automatic detection support for proof-of-stake coins. + +**Statistics & API** +* Re-developed statistics & api sub-system from stratch. +* Pool api now can expose more details. +* Fixed a bug where authenticated miner count was reported incorrectly. + +**Web** +* Improved index page layout. + +**Misc** +* Updated dependency packages. +* File path handling improvements. +* Fixed app.config. + ##### [v0.1.2 alpha - Piri Reis](https://github.com/CoiniumServ/CoiniumServ/releases/tag/v0.1.2-alpha) - 14.08.2014 **Payments** diff --git a/README.md b/README.md index 4b12762db..4361a8ffd 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # ![Screenshot](http://coinium.org/assets/images/logo/coinium-icon-48.png) CoiniumServ [![Build Status](https://travis-ci.org/CoiniumServ/CoiniumServ.svg?branch=develop)](https://travis-ci.org/CoiniumServ/CoiniumServ) [![Build status](https://ci.appveyor.com/api/projects/status/3x349ig9dt14943t)](https://ci.appveyor.com/project/raistlinthewiz/coiniumserv) -[CoiniumServ](https://github.com/CoiniumServ/CoiniumServ) is an high performance, extremely efficient, platform-agnostic, easy to setup pool server implementation. It features a stratum and vanilla services, reward / payment / share processors, user-friendly front-end website and a full-stack API. +[CoiniumServ](https://github.com/CoiniumServ/CoiniumServ) is a high performance, extremely efficient, platform-agnostic, easy to setup pool server implementation. It features stratum and vanilla services, reward, payment, share processors, vardiff & ban managers, user-friendly embedded web-server & front-end and a full-stack API. CoiniumServ was created to be used for [Coinium.org](http://www.coinium.org) mining pool network at first hand. You can check [some of pools](https://github.com/CoiniumServ/CoiniumServ/wiki/Pools) of the pools running CoiniumServ. * Official pools: [coinium.org](http://www.coinium.org) -![CoiniumServ running over mono & ubuntu](http://i.imgur.com/izIB5nq.png) +![CoiniumServ running over mono & ubuntu](http://i.imgur.com/HvaPVrZ.png) ### Support @@ -15,6 +15,7 @@ Start by reading our [FAQ](https://github.com/CoiniumServ/CoiniumServ/wiki/FAQ) You can also use our [issues](https://github.com/CoiniumServ/CoiniumServ/issues) page to report bugs. * Official site: [coiniumserv.com](http://www.coiniumserv.com) +* [Paid support & consulting options](https://github.com/CoiniumServ/CoiniumServ#consulting) * [Support forums](http://forum.coinium.org/forum/19-support/) * IRC (**irc.freenode.net**): - **#coiniumserv** [user support](http://webchat.freenode.net/?channels=%23coiniumserv&prompt=1&uio=OT10cnVlde) @@ -68,19 +69,20 @@ Can run on these platforms; ###### Multiplexed Structure * Multiple pools & ports. * Multiple coin daemon connection support. -* Multiple database layers. +* Multiple storage layers. ###### Functionality * Stratum server (over TCP sockets). * Stratum show_message support (MOTD & messages). * Vanilla server (getwork over http server). [experimental] * Daemon RPC interface. +* Storage layers support * Block template / job managment. * Generation transaction builder. * Share processor. * Payment processor. -* Proof of Work (PoW) and Proof of Stake (PoS) [in-development] support. -* Transaction messages support [in-development]. +* Proof of Work (PoW) and Proof of Stake (PoS) support. +* Transaction messages support. * Vardiff support. * Ban manager support that can handles miners flooding with invalid shares. * Embedded web-server & front-end @@ -111,6 +113,13 @@ _Under Development_ * ✓ __NIST5__ * ✓ __Qubit__ * ✓ __Hefty1__ + +###### Persistance & Storage Layers + +CoiniumServ supports storage layer interfaces that you can extend to implement your own persistance logic. By default, it supports two layers; a high performance hybrid layer and mpos compatibility layer. + +* __Hybrid Layer__: a custom hybrid layer that utilizes redis + mysql together that is carefully designed for high performance persistance support. +* __MPOS Layer__: a compatibility layer based on mysql that supports MPOS whenever you want payments to be handled by MPOS. ###### Development Model * Strictly [follows](https://github.com/CoiniumServ/CoiniumServ/tree/develop/src/Tests) the [Test Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) model. We have implemented extensive [tests](https://github.com/CoiniumServ/CoiniumServ/tree/develop/src/Tests) for all important functionality and never merge in code that breaks tests and stuff. Yet again, when a new functionality is introduced we also expect proper tests to be implemented within the PR. In simple words, most probably you won't notice any functionality-breaking changes within the repository. @@ -140,10 +149,14 @@ Start reading by these; * [Developer's Guide](https://github.com/CoiniumServ/CoiniumServ/wiki/Developer's-Guide) * [Technical Documentation](https://github.com/CoiniumServ/CoiniumServ/wiki/Technical-Documentation) +### Consulting + +Additional to free [support](https://github.com/CoiniumServ/CoiniumServ#support) methods, we offer paid remote support & consulting services for whom would like to get professional support. Contact us over [here](http://blog.coinium.org/coiniumserv/consulting/) and we will get back to you to discuss your needs. + ### License Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org - -http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +http://www.coiniumserv.com This software is dual-licensed: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/build/CoiniumServ.sln b/build/CoiniumServ.sln index 11212bbd0..b7a5f8a64 100644 --- a/build/CoiniumServ.sln +++ b/build/CoiniumServ.sln @@ -14,10 +14,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoiniumServ", "..\src\Coini EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "..\src\Tests\Tests.csproj", "{73CE2C0A-12E6-42FD-8021-C75827D014E3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gibbed.IO", "..\deps\gibbed.io\Gibbed.IO.csproj", "{047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JsonConfig", "..\deps\jsonconfig\JsonConfig\JsonConfig.csproj", "{10095092-E1E5-441F-9380-B6329F3CFEB4}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoiniumServGui", "..\src\CoiniumServGui\CoiniumServGui.csproj", "{1E2AF218-156A-40A0-8DA3-95DD13D93810}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSRedis", "..\deps\csredis\CSRedis\CSRedis.csproj", "{D35E185E-A7E1-41E1-846C-21944F56074F}" @@ -71,42 +67,6 @@ Global {73CE2C0A-12E6-42FD-8021-C75827D014E3}.Testing|Mixed Platforms.Build.0 = Release|Any CPU {73CE2C0A-12E6-42FD-8021-C75827D014E3}.Testing|x86.ActiveCfg = Release|Any CPU {73CE2C0A-12E6-42FD-8021-C75827D014E3}.Testing|x86.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|x86.ActiveCfg = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Debug|x86.Build.0 = Debug|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|Any CPU.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|x86.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Release|x86.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|Any CPU.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|Any CPU.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|Mixed Platforms.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|Mixed Platforms.Build.0 = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|x86.ActiveCfg = Release|Any CPU - {047857BA-DAA3-4CA7-AFB8-A1B082B28C6A}.Testing|x86.Build.0 = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|x86.ActiveCfg = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Debug|x86.Build.0 = Debug|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|Any CPU.Build.0 = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|x86.ActiveCfg = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Release|x86.Build.0 = Release|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|Any CPU.ActiveCfg = Testing|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|Any CPU.Build.0 = Testing|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|Mixed Platforms.ActiveCfg = Testing|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|Mixed Platforms.Build.0 = Testing|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|x86.ActiveCfg = Testing|Any CPU - {10095092-E1E5-441F-9380-B6329F3CFEB4}.Testing|x86.Build.0 = Testing|Any CPU {1E2AF218-156A-40A0-8DA3-95DD13D93810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1E2AF218-156A-40A0-8DA3-95DD13D93810}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E2AF218-156A-40A0-8DA3-95DD13D93810}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU diff --git a/deps/csredis b/deps/csredis index 6667063d1..63528f315 160000 --- a/deps/csredis +++ b/deps/csredis @@ -1 +1 @@ -Subproject commit 6667063d156bf04673449996b4f3560918631c4c +Subproject commit 63528f315dea5ebb07d1ced0809b4083a1bfeb2f diff --git a/deps/gibbed.io b/deps/gibbed.io deleted file mode 160000 index 2a0de138d..000000000 --- a/deps/gibbed.io +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2a0de138ddd9efda8d4adc2d5e61f4fb16cc9d49 diff --git a/deps/jsonconfig b/deps/jsonconfig deleted file mode 160000 index 4bfac3474..000000000 --- a/deps/jsonconfig +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4bfac34740819e2dd6ef8655a59e43f37cd01b2c diff --git a/src/CoiniumServ/App.config b/src/CoiniumServ/App.config index 2a96593e9..547ad3c5c 100644 --- a/src/CoiniumServ/App.config +++ b/src/CoiniumServ/App.config @@ -8,22 +8,6 @@ - - - - - - - - - - - - - - - - @@ -34,4 +18,12 @@ + + + + + + + + diff --git a/src/CoiniumServ/Banning/BanConfig.cs b/src/CoiniumServ/Banning/BanConfig.cs index 81df6caa1..353c48ffe 100644 --- a/src/CoiniumServ/Banning/BanConfig.cs +++ b/src/CoiniumServ/Banning/BanConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Banning/BanManager.cs b/src/CoiniumServ/Banning/BanManager.cs index bd2b94134..2b612d029 100644 --- a/src/CoiniumServ/Banning/BanManager.cs +++ b/src/CoiniumServ/Banning/BanManager.cs @@ -20,14 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; using CoiniumServ.Miners; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Stratum.Sockets; using CoiniumServ.Server.Mining.Vanilla; using CoiniumServ.Shares; diff --git a/src/CoiniumServ/Banning/IBanConfig.cs b/src/CoiniumServ/Banning/IBanConfig.cs index 2f1807f6f..7dd5d3228 100644 --- a/src/CoiniumServ/Banning/IBanConfig.cs +++ b/src/CoiniumServ/Banning/IBanConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Banning diff --git a/src/CoiniumServ/Banning/IBanManager.cs b/src/CoiniumServ/Banning/IBanManager.cs index ce70f7736..849161b89 100644 --- a/src/CoiniumServ/Banning/IBanManager.cs +++ b/src/CoiniumServ/Banning/IBanManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Net; namespace CoiniumServ.Banning diff --git a/src/CoiniumServ/Blocks/BlockProcessor.cs b/src/CoiniumServ/Blocks/BlockProcessor.cs index 9967f233d..f5efbc34b 100644 --- a/src/CoiniumServ/Blocks/BlockProcessor.cs +++ b/src/CoiniumServ/Blocks/BlockProcessor.cs @@ -20,12 +20,11 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Linq; using CoiniumServ.Daemon; using CoiniumServ.Daemon.Exceptions; using CoiniumServ.Daemon.Responses; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using Serilog; namespace CoiniumServ.Blocks diff --git a/src/CoiniumServ/Blocks/IBlockProcessor.cs b/src/CoiniumServ/Blocks/IBlockProcessor.cs index fdd8a308d..e4f3e9ab7 100644 --- a/src/CoiniumServ/Blocks/IBlockProcessor.cs +++ b/src/CoiniumServ/Blocks/IBlockProcessor.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Daemon.Responses; namespace CoiniumServ.Blocks diff --git a/src/CoiniumServ/Coin/Address/Base58.cs b/src/CoiniumServ/Coin/Address/Base58.cs index b7abf5cbe..a230c72d4 100644 --- a/src/CoiniumServ/Coin/Address/Base58.cs +++ b/src/CoiniumServ/Coin/Address/Base58.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Linq; using System.Text; diff --git a/src/CoiniumServ/Coin/Address/Exceptions/AddressFormatException.cs b/src/CoiniumServ/Coin/Address/Exceptions/AddressFormatException.cs index 2ba7c1e5f..832cc7906 100644 --- a/src/CoiniumServ/Coin/Address/Exceptions/AddressFormatException.cs +++ b/src/CoiniumServ/Coin/Address/Exceptions/AddressFormatException.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Coin.Address.Exceptions diff --git a/src/CoiniumServ/Coin/Address/Exceptions/InvalidWalletAddressException.cs b/src/CoiniumServ/Coin/Address/Exceptions/InvalidWalletAddressException.cs index 9086fce28..4898089a8 100644 --- a/src/CoiniumServ/Coin/Address/Exceptions/InvalidWalletAddressException.cs +++ b/src/CoiniumServ/Coin/Address/Exceptions/InvalidWalletAddressException.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Coin.Address.Exceptions diff --git a/src/CoiniumServ/Coin/Coinbase/Serializers.cs b/src/CoiniumServ/Coin/Coinbase/Serializers.cs index 72136583c..506769dbd 100644 --- a/src/CoiniumServ/Coin/Coinbase/Serializers.cs +++ b/src/CoiniumServ/Coin/Coinbase/Serializers.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Text; @@ -42,8 +41,9 @@ public static class Serializers /// /// /// + /// Are we serializing a proof-of-stake coin block /// - public static byte[] SerializeBlock(IJob job, byte[] header, byte[] coinbase) + public static byte[] SerializeBlock(IJob job, byte[] header, byte[] coinbase, bool IsPOSCoin = false) { byte[] result; @@ -58,7 +58,8 @@ public static byte[] SerializeBlock(IJob job, byte[] header, byte[] coinbase) stream.WriteBytes(transaction.Data.HexToByteArray()); } - // need to implement POS support too. + if (IsPOSCoin) // check if we are serializing a block for proof-of-stake coin. + stream.WriteByte(0); // proof-of-stake coins require a zero byte appended to block which the daemon replaces with signature. result = stream.ToArray(); } diff --git a/src/CoiniumServ/Coin/Coinbase/Utils.cs b/src/CoiniumServ/Coin/Coinbase/Utils.cs index 1511d4b8e..60242d2d2 100644 --- a/src/CoiniumServ/Coin/Coinbase/Utils.cs +++ b/src/CoiniumServ/Coin/Coinbase/Utils.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Linq; diff --git a/src/CoiniumServ/Coin/Config/CoinConfig.cs b/src/CoiniumServ/Coin/Config/CoinConfig.cs index 1d4486b75..388b9738c 100644 --- a/src/CoiniumServ/Coin/Config/CoinConfig.cs +++ b/src/CoiniumServ/Coin/Config/CoinConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; @@ -33,6 +32,7 @@ public class CoinConfig : ICoinConfig public string Symbol { get; private set; } public string Algorithm { get; private set; } public bool SupportsTxMessages { get; private set; } + public bool IsPOS { get; set; } public string BlockExplorer { get; private set; } public dynamic Options { get; private set; } @@ -40,10 +40,18 @@ public CoinConfig(dynamic config) { try { + // set the coin data. Name = config.name; Symbol = config.symbol; Algorithm = config.algorithm; SupportsTxMessages = config.txMessages; + + // check the coin type. + if (string.IsNullOrEmpty(config.reward)) // if no value is set, behave it as a proof-of-work coin by default. + IsPOS = false; + else // if we have a reward value set. + IsPOS = config.reward.ToString().ToLower() == "pos"; // see if it's a proof-of-stake coin or proof-of-work coin. + BlockExplorer = string.IsNullOrEmpty(config.blockExplorer) ? "https://altexplorer.net" : config.blockExplorer; Options = config; diff --git a/src/CoiniumServ/Coin/Config/ICoinConfig.cs b/src/CoiniumServ/Coin/Config/ICoinConfig.cs index 2c2f2224c..616b343d4 100644 --- a/src/CoiniumServ/Coin/Config/ICoinConfig.cs +++ b/src/CoiniumServ/Coin/Config/ICoinConfig.cs @@ -20,26 +20,30 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; +using Newtonsoft.Json; namespace CoiniumServ.Coin.Config { + [JsonObject(MemberSerialization.OptIn)] public interface ICoinConfig:IConfig { /// /// name of the coin /// + [JsonProperty("name")] string Name { get; } /// /// 3 or 4 letter symbol for the coin /// + [JsonProperty("symbol")] string Symbol { get; } /// /// The algorithm used by the coin. /// + [JsonProperty("algorithm")] string Algorithm { get; } /// @@ -47,9 +51,16 @@ public interface ICoinConfig:IConfig /// bool SupportsTxMessages { get; } + /// + /// Is the coin a proof-of-stake coin? + /// + [JsonProperty("pos")] + bool IsPOS { get; set; } + /// /// Block explorer for the coin. /// + string BlockExplorer { get; } /// diff --git a/src/CoiniumServ/Coin/Helpers/Hashrate.cs b/src/CoiniumServ/Coin/Helpers/Hashrate.cs index 6113b588e..2ce2ae599 100644 --- a/src/CoiniumServ/Coin/Helpers/Hashrate.cs +++ b/src/CoiniumServ/Coin/Helpers/Hashrate.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Coin.Helpers diff --git a/src/CoiniumServ/CoiniumServ.csproj b/src/CoiniumServ/CoiniumServ.csproj index 77a31b136..4a2a75fcf 100644 --- a/src/CoiniumServ/CoiniumServ.csproj +++ b/src/CoiniumServ/CoiniumServ.csproj @@ -58,29 +58,57 @@ False ..\..\build\packages\CryptSharpOfficial.2.0.0.0\lib\CryptSharp.dll + + False + ..\..\build\packages\Dapper.1.34\lib\net45\Dapper.dll + + + False + ..\..\build\packages\FluentMigrator.1.3.0.0\lib\40\FluentMigrator.dll + + + False + ..\..\build\packages\FluentMigrator.Runner.1.3.0.0\lib\40\FluentMigrator.Runner.dll + + + False + ..\..\build\packages\Gibbed.IO.1.0.0\lib\Gibbed.IO.dll + False ..\..\build\packages\HashLib.2.0.1\lib\net40\HashLib.dll - + False - ..\..\build\packages\Metrics.NET.0.1.10\lib\net45\Metrics.dll + ..\..\build\packages\JsonConfig.1.0.0\lib\JsonConfig.dll + + + False + ..\..\build\packages\JsonFx.2.0.1209.2802\lib\net40\JsonFx.dll + + + False + ..\..\build\packages\Metrics.NET.0.1.11\lib\net45\Metrics.dll + + + False + ..\..\build\packages\MySql.Data.6.8.3\lib\net45\MySql.Data.dll False ..\..\build\packages\Nancy.0.23.2\lib\net40\Nancy.dll - + False - ..\..\build\packages\Nancy.CustomErrors.1.0.5.0\lib\net40\Nancy.CustomErrors.dll + ..\..\build\packages\Nancy.CustomErrors.1.0.6.0\lib\net40\Nancy.CustomErrors.dll False ..\..\build\packages\Nancy.Hosting.Self.0.23.2\lib\net40\Nancy.Hosting.Self.dll - + False - ..\..\build\packages\NancyFx.Metrics.0.1.10\lib\net45\Nancy.Metrics.dll + ..\..\build\packages\NancyFx.Metrics.0.1.11\lib\net45\Nancy.Metrics.dll False @@ -90,23 +118,28 @@ False ..\..\build\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll - + False - ..\..\build\packages\Serilog.1.3.43\lib\net45\Serilog.dll + ..\..\build\packages\Serilog.1.4.7\lib\net45\Serilog.dll - + False - ..\..\build\packages\Serilog.1.3.43\lib\net45\Serilog.FullNetFx.dll + ..\..\build\packages\Serilog.1.4.7\lib\net45\Serilog.FullNetFx.dll + + + False - ..\..\build\packages\Microsoft.AspNet.Razor.3.2.0\lib\net45\System.Web.Razor.dll + ..\..\build\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll + + @@ -118,6 +151,8 @@ + + @@ -147,10 +182,39 @@ + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -158,15 +222,10 @@ - - - - + + + - - - - @@ -174,16 +233,7 @@ - - - - - - - - - - + @@ -206,15 +256,12 @@ - - - + - @@ -227,8 +274,7 @@ - - + @@ -237,7 +283,6 @@ - @@ -246,7 +291,7 @@ - + @@ -267,7 +312,7 @@ - + @@ -282,18 +327,18 @@ - + - - - - - + + + + + - + @@ -305,7 +350,6 @@ - @@ -316,7 +360,7 @@ - + @@ -331,7 +375,7 @@ - + @@ -804,7 +848,6 @@ PreserveNewest - PreserveNewest @@ -922,14 +965,6 @@ {d35e185e-a7e1-41e1-846c-21944f56074f} CSRedis - - {047857ba-daa3-4ca7-afb8-a1b082b28c6a} - Gibbed.IO - - - {10095092-e1e5-441f-9380-b6329f3cfeb4} - JsonConfig - @@ -994,7 +1029,6 @@ PreserveNewest - diff --git a/src/CoiniumServ/Configuration/ConfigManager.cs b/src/CoiniumServ/Configuration/ConfigManager.cs index c56435169..db33d1ca7 100644 --- a/src/CoiniumServ/Configuration/ConfigManager.cs +++ b/src/CoiniumServ/Configuration/ConfigManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.IO; @@ -28,7 +27,7 @@ using CoiniumServ.Coin.Config; using CoiniumServ.Factories; using CoiniumServ.Logging; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Server.Web; using CoiniumServ.Utils.Helpers.IO; using Serilog; @@ -122,7 +121,7 @@ private void LoadPoolConfigs() if (!coinConfig.Valid) // make sure the configuration for referenced coin is valid. { - _logger.Error("coins/{0:l}.json doesnt't contain a valid configuration, skipping pool configuration: pools/{1:l}.json", coinName, filename); + _logger.Error("coins/{0:l}.json doesnt't contain a valid coin configuration, skipping pool configuration: pools/{1:l}.json", coinName, filename); continue; } diff --git a/src/CoiniumServ/Configuration/IConfigManager.cs b/src/CoiniumServ/Configuration/IConfigManager.cs index d9ff85e19..98fa4f1e2 100644 --- a/src/CoiniumServ/Configuration/IConfigManager.cs +++ b/src/CoiniumServ/Configuration/IConfigManager.cs @@ -20,10 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using CoiniumServ.Logging; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Server.Web; namespace CoiniumServ.Configuration diff --git a/src/CoiniumServ/Configuration/IJsonConfigReader.cs b/src/CoiniumServ/Configuration/IJsonConfigReader.cs index dcde48f01..12cdb9dba 100644 --- a/src/CoiniumServ/Configuration/IJsonConfigReader.cs +++ b/src/CoiniumServ/Configuration/IJsonConfigReader.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Configuration { public interface IJsonConfigReader diff --git a/src/CoiniumServ/Configuration/IStackConfig.cs b/src/CoiniumServ/Configuration/IStackConfig.cs index 7f51a9afb..b5ee23c23 100644 --- a/src/CoiniumServ/Configuration/IStackConfig.cs +++ b/src/CoiniumServ/Configuration/IStackConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Configuration { public interface IStackConfig : IConfig diff --git a/src/CoiniumServ/Configuration/JsonConfigReader.cs b/src/CoiniumServ/Configuration/JsonConfigReader.cs index 38bf262dd..d6572d3a3 100644 --- a/src/CoiniumServ/Configuration/JsonConfigReader.cs +++ b/src/CoiniumServ/Configuration/JsonConfigReader.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Text.RegularExpressions; @@ -59,8 +58,7 @@ private bool ValidateJson(string json, string fileName) try { // try to validate the json. - var @object = JsonConvert.DeserializeObject(json); - + JsonConvert.DeserializeObject(json); return true; } catch (JsonReaderException e) diff --git a/src/CoiniumServ/Configuration/StackConfig.cs b/src/CoiniumServ/Configuration/StackConfig.cs index bb9cda9e3..455f74ded 100644 --- a/src/CoiniumServ/Configuration/StackConfig.cs +++ b/src/CoiniumServ/Configuration/StackConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Repository/Bootstrapper.cs b/src/CoiniumServ/Container/Bootstrapper.cs similarity index 95% rename from src/CoiniumServ/Repository/Bootstrapper.cs rename to src/CoiniumServ/Container/Bootstrapper.cs index b41b277ae..4eaf3ad8d 100644 --- a/src/CoiniumServ/Repository/Bootstrapper.cs +++ b/src/CoiniumServ/Container/Bootstrapper.cs @@ -20,11 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - -using CoiniumServ.Repository.Registries; +using CoiniumServ.Container.Registries; using Nancy.TinyIoc; -namespace CoiniumServ.Repository +namespace CoiniumServ.Container { /// /// IOC & DI registry. diff --git a/src/CoiniumServ/Repository/Context/ApplicationContext.cs b/src/CoiniumServ/Container/Context/ApplicationContext.cs similarity index 96% rename from src/CoiniumServ/Repository/Context/ApplicationContext.cs rename to src/CoiniumServ/Container/Context/ApplicationContext.cs index 34b230e05..edc16c4f0 100644 --- a/src/CoiniumServ/Repository/Context/ApplicationContext.cs +++ b/src/CoiniumServ/Container/Context/ApplicationContext.cs @@ -20,10 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Nancy.TinyIoc; -namespace CoiniumServ.Repository.Context +namespace CoiniumServ.Container.Context { public class ApplicationContext : IApplicationContext { diff --git a/src/CoiniumServ/Repository/Context/IApplicationContext.cs b/src/CoiniumServ/Container/Context/IApplicationContext.cs similarity index 96% rename from src/CoiniumServ/Repository/Context/IApplicationContext.cs rename to src/CoiniumServ/Container/Context/IApplicationContext.cs index cb697fb30..55d28e37a 100644 --- a/src/CoiniumServ/Repository/Context/IApplicationContext.cs +++ b/src/CoiniumServ/Container/Context/IApplicationContext.cs @@ -20,10 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Nancy.TinyIoc; -namespace CoiniumServ.Repository.Context +namespace CoiniumServ.Container.Context { public interface IApplicationContext { diff --git a/src/CoiniumServ/Repository/Registries/AlgorithmRegistry.cs b/src/CoiniumServ/Container/Registries/AlgorithmRegistry.cs similarity index 73% rename from src/CoiniumServ/Repository/Registries/AlgorithmRegistry.cs rename to src/CoiniumServ/Container/Registries/AlgorithmRegistry.cs index 41bd64b61..b2b84802f 100644 --- a/src/CoiniumServ/Repository/Registries/AlgorithmRegistry.cs +++ b/src/CoiniumServ/Container/Registries/AlgorithmRegistry.cs @@ -20,11 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using CoiniumServ.Container.Context; using CoiniumServ.Cryptology.Algorithms; -using CoiniumServ.Repository.Context; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class AlgorithmRegistry : IRegistry { @@ -38,19 +37,20 @@ public AlgorithmRegistry(IApplicationContext applicationContext) public void RegisterInstances() { // hash algorithms - _applicationContext.Container.Register(Algorithms.Blake).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Fugue).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Groestl).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Keccak).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Scrypt).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Sha256).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Shavite3).AsSingleton(); - _applicationContext.Container.Register(Algorithms.Skein).AsSingleton(); - _applicationContext.Container.Register(Algorithms.X11).AsSingleton(); - _applicationContext.Container.Register(Algorithms.X13).AsSingleton(); - _applicationContext.Container.Register(Algorithms.X14).AsSingleton(); - _applicationContext.Container.Register(Algorithms.X15).AsSingleton(); - _applicationContext.Container.Register(Algorithms.X17).AsSingleton(); + _applicationContext.Container.Register().AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Blake).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Fugue).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Groestl).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Keccak).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Scrypt).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Sha256).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Shavite3).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.Skein).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.X11).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.X13).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.X14).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.X15).AsSingleton(); + _applicationContext.Container.Register(AlgorithmManager.X17).AsSingleton(); } } } \ No newline at end of file diff --git a/src/CoiniumServ/Repository/Registries/ClassRegistry.cs b/src/CoiniumServ/Container/Registries/ClassRegistry.cs similarity index 72% rename from src/CoiniumServ/Repository/Registries/ClassRegistry.cs rename to src/CoiniumServ/Container/Registries/ClassRegistry.cs index 7af68b4af..41a5844a2 100644 --- a/src/CoiniumServ/Repository/Registries/ClassRegistry.cs +++ b/src/CoiniumServ/Container/Registries/ClassRegistry.cs @@ -20,23 +20,19 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Blocks; using CoiniumServ.Coin.Config; using CoiniumServ.Configuration; +using CoiniumServ.Container.Context; using CoiniumServ.Daemon; using CoiniumServ.Jobs.Tracker; using CoiniumServ.Payments; -using CoiniumServ.Persistance; -using CoiniumServ.Persistance.Redis; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; -using CoiniumServ.Repository.Context; using CoiniumServ.Server.Web; using CoiniumServ.Statistics; using Nancy.Bootstrapper; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class ClassRegistry : IRegistry { @@ -50,29 +46,22 @@ public ClassRegistry(IApplicationContext applicationContext) public void RegisterInstances() { // pool - _applicationContext.Container.Register().AsSingleton(); _applicationContext.Container.Register().AsMultiInstance(); _applicationContext.Container.Register().AsMultiInstance(); _applicationContext.Container.Register().AsMultiInstance(); _applicationContext.Container.Register().AsMultiInstance(); - _applicationContext.Container.Register().AsSingleton(); _applicationContext.Container.Register().AsMultiInstance(); + _applicationContext.Container.Register().AsMultiInstance(); + _applicationContext.Container.Register().AsMultiInstance(); // statistics - _applicationContext.Container.Register().AsSingleton(); - _applicationContext.Container.Register().AsSingleton(); - _applicationContext.Container.Register().AsMultiInstance(); - _applicationContext.Container.Register().AsMultiInstance(); - _applicationContext.Container.Register().AsMultiInstance(); + _applicationContext.Container.Register().AsSingleton(); // config _applicationContext.Container.Register().AsMultiInstance(); _applicationContext.Container.Register().AsMultiInstance(); _applicationContext.Container.Register().AsSingleton(); - // storage - _applicationContext.Container.Register(Storages.Redis).AsMultiInstance(); - // web _applicationContext.Container.Register().AsSingleton(); } diff --git a/src/CoiniumServ/Repository/Registries/FactoryRegistry.cs b/src/CoiniumServ/Container/Registries/FactoryRegistry.cs similarity index 95% rename from src/CoiniumServ/Repository/Registries/FactoryRegistry.cs rename to src/CoiniumServ/Container/Registries/FactoryRegistry.cs index 62fe1170b..41efeb636 100644 --- a/src/CoiniumServ/Repository/Registries/FactoryRegistry.cs +++ b/src/CoiniumServ/Container/Registries/FactoryRegistry.cs @@ -20,11 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using CoiniumServ.Container.Context; using CoiniumServ.Factories; -using CoiniumServ.Repository.Context; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class FactoryRegistry : IRegistry { diff --git a/src/CoiniumServ/Repository/Registries/IRegistry.cs b/src/CoiniumServ/Container/Registries/IRegistry.cs similarity index 96% rename from src/CoiniumServ/Repository/Registries/IRegistry.cs rename to src/CoiniumServ/Container/Registries/IRegistry.cs index 8141e42d4..7cd85f025 100644 --- a/src/CoiniumServ/Repository/Registries/IRegistry.cs +++ b/src/CoiniumServ/Container/Registries/IRegistry.cs @@ -20,7 +20,7 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public interface IRegistry { diff --git a/src/CoiniumServ/Repository/Registries/ManagerRegistry.cs b/src/CoiniumServ/Container/Registries/ManagerRegistry.cs similarity index 96% rename from src/CoiniumServ/Repository/Registries/ManagerRegistry.cs rename to src/CoiniumServ/Container/Registries/ManagerRegistry.cs index 437c70781..b78980786 100644 --- a/src/CoiniumServ/Repository/Registries/ManagerRegistry.cs +++ b/src/CoiniumServ/Container/Registries/ManagerRegistry.cs @@ -20,19 +20,18 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Banning; using CoiniumServ.Configuration; +using CoiniumServ.Container.Context; using CoiniumServ.Jobs.Manager; using CoiniumServ.Logging; using CoiniumServ.Metrics; using CoiniumServ.Miners; using CoiniumServ.Pools; -using CoiniumServ.Repository.Context; using CoiniumServ.Shares; using CoiniumServ.Vardiff; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class ManagerRegistry : IRegistry { diff --git a/src/CoiniumServ/Repository/Registries/Registry.cs b/src/CoiniumServ/Container/Registries/Registry.cs similarity index 93% rename from src/CoiniumServ/Repository/Registries/Registry.cs rename to src/CoiniumServ/Container/Registries/Registry.cs index 2a9335ec1..ac4275105 100644 --- a/src/CoiniumServ/Repository/Registries/Registry.cs +++ b/src/CoiniumServ/Container/Registries/Registry.cs @@ -20,13 +20,12 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; -using CoiniumServ.Repository.Context; +using CoiniumServ.Container.Context; using Nancy.TinyIoc; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class Registry : IRegistry { @@ -49,6 +48,7 @@ public void RegisterInstances() typeof(ClassRegistry), typeof(FactoryRegistry), typeof(AlgorithmRegistry), + typeof(StorageRegistry) }); } } diff --git a/src/CoiniumServ/Repository/Registries/ServerRegistry.cs b/src/CoiniumServ/Container/Registries/ServerRegistry.cs similarity index 96% rename from src/CoiniumServ/Repository/Registries/ServerRegistry.cs rename to src/CoiniumServ/Container/Registries/ServerRegistry.cs index 44a3f66ef..963bff99f 100644 --- a/src/CoiniumServ/Repository/Registries/ServerRegistry.cs +++ b/src/CoiniumServ/Container/Registries/ServerRegistry.cs @@ -20,8 +20,7 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - -using CoiniumServ.Repository.Context; +using CoiniumServ.Container.Context; using CoiniumServ.Server.Mining; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Server.Mining.Stratum; @@ -30,7 +29,7 @@ using CoiniumServ.Server.Mining.Vanilla.Service; using CoiniumServ.Server.Web; -namespace CoiniumServ.Repository.Registries +namespace CoiniumServ.Container.Registries { public class ServerRegistry : IRegistry { diff --git a/src/CoiniumServ/Container/Registries/StorageRegistry.cs b/src/CoiniumServ/Container/Registries/StorageRegistry.cs new file mode 100644 index 000000000..ffaf9a895 --- /dev/null +++ b/src/CoiniumServ/Container/Registries/StorageRegistry.cs @@ -0,0 +1,60 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using CoiniumServ.Container.Context; +using CoiniumServ.Persistance; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Empty; +using CoiniumServ.Persistance.Layers.Hybrid; +using CoiniumServ.Persistance.Layers.Hybrid.Migrations; +using CoiniumServ.Persistance.Layers.Mpos; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; +using CoiniumServ.Persistance.Providers.Redis; + +namespace CoiniumServ.Container.Registries +{ + public class StorageRegistry: IRegistry + { + private readonly IApplicationContext _applicationContext; + + public StorageRegistry(IApplicationContext applicationContext) + { + _applicationContext = applicationContext; + } + + public void RegisterInstances() + { + // providers + _applicationContext.Container.Register(StorageProviders.MySql).AsMultiInstance(); + _applicationContext.Container.Register(StorageProviders.Redis).AsMultiInstance(); + + // layers + _applicationContext.Container.Register(StorageLayers.Hybrid).AsMultiInstance(); + _applicationContext.Container.Register(StorageLayers.Mpos).AsMultiInstance(); + _applicationContext.Container.Register(StorageLayers.Empty).AsSingleton(); + + // migrators + _applicationContext.Container.Register().AsMultiInstance(); + } + } +} diff --git a/src/CoiniumServ/Cryptology/Algorithms/AlgorithmManager.cs b/src/CoiniumServ/Cryptology/Algorithms/AlgorithmManager.cs new file mode 100644 index 000000000..161c7d81c --- /dev/null +++ b/src/CoiniumServ/Cryptology/Algorithms/AlgorithmManager.cs @@ -0,0 +1,142 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using CoiniumServ.Pools; +using CoiniumServ.Utils.Numerics; +using Newtonsoft.Json; + +namespace CoiniumServ.Cryptology.Algorithms +{ + public class AlgorithmManager:IAlgorithmManager + { + public const string Blake = "blake"; + public const string Fugue = "fugue"; + public const string Groestl = "groestl"; + public const string Keccak = "keccak"; + public const string Scrypt = "scrypt"; + public const string Sha256 = "sha256"; + public const string Shavite3 = "shavite3"; + public const string Skein = "skein"; + public const string X11 = "x11"; + public const string X13 = "x13"; + public const string X14 = "x14"; + public const string X15 = "x15"; + public const string X17 = "x17"; + + // todo: add hefty1, qubit support + + /// + /// Global diff1 + /// + public static BigInteger Diff1 { get; private set; } + + static AlgorithmManager() + { + Diff1 = BigInteger.Parse("00000000ffff0000000000000000000000000000000000000000000000000000", NumberStyles.HexNumber); + } + + private readonly IList _storage; + + public AlgorithmManager(IPoolManager poolManager) + { + _storage = new List(); + + // add algorithms + foreach (var pool in poolManager.GetAll()) + { + if (_storage.Contains(pool.HashAlgorithm)) + continue; + + _storage.Add(pool.HashAlgorithm); + } + + // assign pools to hash algorithms + foreach (var item in _storage) + { + var algorithm = item; + var pools = poolManager.GetAll().Where(p => p.Config.Coin.Algorithm == algorithm.GetType().Name.ToLower()); + algorithm.AssignPools(pools); + } + } + + public IQueryable SearchFor(Expression> predicate) + { + return _storage.AsQueryable().Where(predicate); + } + + public IEnumerable GetAll() + { + return _storage; + } + + public IQueryable GetAllAsQueryable() + { + return _storage.AsQueryable(); + } + + public IReadOnlyCollection GetAllAsReadOnly() + { + return new ReadOnlyCollection(_storage); + } + + public int Count { get { return _storage.Count; }} + + public string ServiceResponse { get; private set; } + + public void Recache() + { + foreach (var algorithm in _storage) + { + if (algorithm.Count == 0) + continue; + + algorithm.Recache(); + } + + // cache the json-service response + var cache = _storage.ToDictionary(algo => algo.GetType().Name.ToLower()); + ServiceResponse = JsonConvert.SerializeObject(cache, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + } + + public IHashAlgorithm Get(string name) + { + return _storage.FirstOrDefault(p => p.GetType().Name.ToLower().Equals(name, StringComparison.OrdinalIgnoreCase)); + } + + public IEnumerator GetEnumerator() + { + return _storage.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/src/CoiniumServ/Cryptology/Algorithms/Algorithms.cs b/src/CoiniumServ/Cryptology/Algorithms/Algorithms.cs deleted file mode 100644 index cc732a105..000000000 --- a/src/CoiniumServ/Cryptology/Algorithms/Algorithms.cs +++ /dev/null @@ -1,57 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System.Globalization; -using CoiniumServ.Utils.Numerics; - -namespace CoiniumServ.Cryptology.Algorithms -{ - public static class Algorithms - { - public const string Blake = "blake"; - public const string Fugue = "fugue"; - public const string Groestl = "groestl"; - public const string Keccak = "keccak"; - public const string Scrypt = "scrypt"; - public const string Sha256 = "sha256"; - public const string Shavite3 = "shavite3"; - public const string Skein = "skein"; - public const string X11 = "x11"; - public const string X13 = "x13"; - public const string X14 = "x14"; - public const string X15 = "x15"; - public const string X17 = "x17"; - - // todo: add hefty1, qubit support - - /// - /// Global diff1 - /// - public static BigInteger Diff1 { get; private set; } - - static Algorithms() - { - Diff1 = BigInteger.Parse("00000000ffff0000000000000000000000000000000000000000000000000000", NumberStyles.HexNumber); - } - } -} diff --git a/src/CoiniumServ/Cryptology/Algorithms/Blake.cs b/src/CoiniumServ/Cryptology/Algorithms/Blake.cs index a9e038dd2..3f6966724 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Blake.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Blake.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Blake : IHashAlgorithm + public sealed class Blake : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -39,7 +38,7 @@ public Blake() Multiplier = (UInt32) Math.Pow(2, 8); } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Fugue.cs b/src/CoiniumServ/Cryptology/Algorithms/Fugue.cs index 602e45ad5..3452ba8de 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Fugue.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Fugue.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Fugue : IHashAlgorithm + public sealed class Fugue : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -39,7 +38,7 @@ public Fugue() Multiplier = (UInt32)Math.Pow(2, 8); } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Groestl.cs b/src/CoiniumServ/Cryptology/Algorithms/Groestl.cs index 88df47b15..b4c568bc0 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Groestl.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Groestl.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Groestl : IHashAlgorithm + public sealed class Groestl : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -39,7 +38,7 @@ public Groestl() Multiplier = (UInt32)Math.Pow(2, 8); } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/HashAlgorithmBase.cs b/src/CoiniumServ/Cryptology/Algorithms/HashAlgorithmBase.cs new file mode 100644 index 000000000..6c79e72a4 --- /dev/null +++ b/src/CoiniumServ/Cryptology/Algorithms/HashAlgorithmBase.cs @@ -0,0 +1,113 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using CoiniumServ.Pools; +using Newtonsoft.Json; + +namespace CoiniumServ.Cryptology.Algorithms +{ + public class HashAlgorithmBase : IHashAlgorithm + { + public string Name { get; private set; } + + public virtual uint Multiplier { get; protected set; } + + private readonly IList _storage; + + public HashAlgorithmBase() + { + Name = this.GetType().Name.ToLower(); // set the algorithm name. + _storage = new List(); // initialize the pool storage. + } + + public virtual byte[] Hash(byte[] input, dynamic config) + { + throw new NotImplementedException(); + } + + public void AssignPools(IEnumerable pools) + { + foreach (var pool in pools) + { + _storage.Add(pool); + } + } + + public IQueryable SearchFor(Expression> predicate) + { + return _storage.AsQueryable().Where(predicate); + } + + public IEnumerable GetAll() + { + return _storage; + } + + public IQueryable GetAllAsQueryable() + { + return _storage.AsQueryable(); + } + + public IReadOnlyCollection GetAllAsReadOnly() + { + return new ReadOnlyCollection(_storage); + } + + public int Count { get { return _storage.Count; } } + + public IEnumerator GetEnumerator() + { + return _storage.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public int MinerCount { get; private set; } + public ulong Hashrate { get; private set; } + + public string ServiceResponse { get; private set; } + + public void Recache() + { + MinerCount = 0; + Hashrate = 0; + + foreach (var pool in _storage) + { + MinerCount += pool.MinerManager.Count; + Hashrate += pool.Hashrate; + } + + // cache the json-service response + ServiceResponse = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + } + } +} diff --git a/src/CoiniumServ/Statistics/IAlgorithms.cs b/src/CoiniumServ/Cryptology/Algorithms/IAlgorithmManager.cs similarity index 80% rename from src/CoiniumServ/Statistics/IAlgorithms.cs rename to src/CoiniumServ/Cryptology/Algorithms/IAlgorithmManager.cs index bbb3f5a70..e9a6b4372 100644 --- a/src/CoiniumServ/Statistics/IAlgorithms.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/IAlgorithmManager.cs @@ -20,13 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using CoiniumServ.Server.Web.Service; +using CoiniumServ.Utils.Repository; +using HashLib; -using System.Collections.Generic; - -namespace CoiniumServ.Statistics +namespace CoiniumServ.Cryptology.Algorithms { - public interface IAlgorithms: IEnumerable>, IJsonResponse, IStatisticsProvider + public interface IAlgorithmManager : IRepository, IJsonService { - IPerAlgorithm GetByName(string name); + IHashAlgorithm Get(string name); } } diff --git a/src/CoiniumServ/Cryptology/Algorithms/IHashAlgorithm.cs b/src/CoiniumServ/Cryptology/Algorithms/IHashAlgorithm.cs index af7d6c6a5..1965a93a5 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/IHashAlgorithm.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/IHashAlgorithm.cs @@ -20,15 +20,30 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; +using System.Collections.Generic; +using CoiniumServ.Pools; +using CoiniumServ.Server.Web.Service; +using CoiniumServ.Utils.Repository; +using Newtonsoft.Json; namespace CoiniumServ.Cryptology.Algorithms { - public interface IHashAlgorithm + [JsonObject(MemberSerialization.OptIn)] + public interface IHashAlgorithm: IRepository, IJsonService { + string Name { get; } + UInt32 Multiplier { get; } + [JsonProperty("miners")] + Int32 MinerCount { get; } + + [JsonProperty("hashrate")] + UInt64 Hashrate { get; } + byte[] Hash(byte[] input, dynamic config); + + void AssignPools(IEnumerable pools); } } \ No newline at end of file diff --git a/src/CoiniumServ/Cryptology/Algorithms/Keccak.cs b/src/CoiniumServ/Cryptology/Algorithms/Keccak.cs index 66af8f33b..0a3a5fc94 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Keccak.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Keccak.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Keccak : IHashAlgorithm + public sealed class Keccak : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -39,7 +38,7 @@ public Keccak() Multiplier = (UInt32)Math.Pow(2, 8); } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Scrypt.cs b/src/CoiniumServ/Cryptology/Algorithms/Scrypt.cs index 17596e9be..d367c9ffe 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Scrypt.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Scrypt.cs @@ -20,13 +20,12 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CryptSharp.Utility; namespace CoiniumServ.Cryptology.Algorithms { - public class Scrypt : IHashAlgorithm + public sealed class Scrypt : HashAlgorithmBase { /// /// Gets the multiplier. @@ -34,7 +33,7 @@ public class Scrypt : IHashAlgorithm /// /// The multiplier. /// - public UInt32 Multiplier { get; private set; } + public override UInt32 Multiplier { get; protected set; } /// /// N parameter - CPU/memory cost parameter. @@ -61,7 +60,7 @@ public Scrypt() Multiplier = (UInt32) Math.Pow(2, 16); } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return SCrypt.ComputeDerivedKey(input, input, _n, _r, _p, null, 32); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Sha256.cs b/src/CoiniumServ/Cryptology/Algorithms/Sha256.cs index 99ebcc70a..a16c952c5 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Sha256.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Sha256.cs @@ -20,14 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Security.Cryptography; namespace CoiniumServ.Cryptology.Algorithms { - public class Sha256:IHashAlgorithm + public sealed class Sha256:HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly SHA256Managed _algorithm; @@ -38,7 +37,7 @@ public Sha256() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return DoubleDigest(input); // coins like bitcoin (sha256d coins) uses double-digest. } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Shavite3.cs b/src/CoiniumServ/Cryptology/Algorithms/Shavite3.cs index c08f31c2b..9b7e257a7 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Shavite3.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Shavite3.cs @@ -20,14 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Shavite3 : IHashAlgorithm + public sealed class Shavite3 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -38,7 +37,7 @@ public Shavite3() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/Skein.cs b/src/CoiniumServ/Cryptology/Algorithms/Skein.cs index a9cccd8e8..5c730cc29 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/Skein.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/Skein.cs @@ -20,14 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class Skein : IHashAlgorithm + public sealed class Skein : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly IHash _hasher; @@ -38,7 +37,7 @@ public Skein() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { return _hasher.ComputeBytes(input).GetBytes(); } diff --git a/src/CoiniumServ/Cryptology/Algorithms/X11.cs b/src/CoiniumServ/Cryptology/Algorithms/X11.cs index 57cb0f9f8..c42cd4462 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/X11.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/X11.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class X11 : IHashAlgorithm + public sealed class X11 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly List _hashers; @@ -52,7 +51,7 @@ public X11() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { var buffer = input; diff --git a/src/CoiniumServ/Cryptology/Algorithms/X13.cs b/src/CoiniumServ/Cryptology/Algorithms/X13.cs index afea0e049..95e767a45 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/X13.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/X13.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class X13 : IHashAlgorithm + public sealed class X13 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly List _hashers; @@ -54,7 +53,7 @@ public X13() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { var buffer = input; diff --git a/src/CoiniumServ/Cryptology/Algorithms/X14.cs b/src/CoiniumServ/Cryptology/Algorithms/X14.cs index 7beccb23f..17f80fbc7 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/X14.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/X14.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class X14 : IHashAlgorithm + public sealed class X14 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly List _hashers; @@ -55,7 +54,7 @@ public X14() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { var buffer = input; diff --git a/src/CoiniumServ/Cryptology/Algorithms/X15.cs b/src/CoiniumServ/Cryptology/Algorithms/X15.cs index a812817df..2881600eb 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/X15.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/X15.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class X15 : IHashAlgorithm + public sealed class X15 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly List _hashers; @@ -56,7 +55,7 @@ public X15() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { var buffer = input; diff --git a/src/CoiniumServ/Cryptology/Algorithms/X17.cs b/src/CoiniumServ/Cryptology/Algorithms/X17.cs index 102062f27..78ee5ec9c 100644 --- a/src/CoiniumServ/Cryptology/Algorithms/X17.cs +++ b/src/CoiniumServ/Cryptology/Algorithms/X17.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using HashLib; namespace CoiniumServ.Cryptology.Algorithms { - public class X17 : IHashAlgorithm + public sealed class X17 : HashAlgorithmBase { - public uint Multiplier { get; private set; } + public override uint Multiplier { get; protected set; } private readonly List _hashers; @@ -58,7 +57,7 @@ public X17() Multiplier = 1; } - public byte[] Hash(byte[] input, dynamic config) + public override byte[] Hash(byte[] input, dynamic config) { var buffer = input; diff --git a/src/CoiniumServ/Cryptology/Hash.cs b/src/CoiniumServ/Cryptology/Hash.cs index 00ca60cd7..d21d495a5 100644 --- a/src/CoiniumServ/Cryptology/Hash.cs +++ b/src/CoiniumServ/Cryptology/Hash.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Diagnostics; using System.Linq; diff --git a/src/CoiniumServ/Cryptology/Merkle/IMerkleTree.cs b/src/CoiniumServ/Cryptology/Merkle/IMerkleTree.cs index 3eb763d66..fdeafaf8c 100644 --- a/src/CoiniumServ/Cryptology/Merkle/IMerkleTree.cs +++ b/src/CoiniumServ/Cryptology/Merkle/IMerkleTree.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Cryptology.Merkle diff --git a/src/CoiniumServ/Cryptology/Merkle/MerkleTree.cs b/src/CoiniumServ/Cryptology/Merkle/MerkleTree.cs index 1a9bf73ed..9e0fd1e02 100644 --- a/src/CoiniumServ/Cryptology/Merkle/MerkleTree.cs +++ b/src/CoiniumServ/Cryptology/Merkle/MerkleTree.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; using CoiniumServ.Utils.Extensions; diff --git a/src/CoiniumServ/Cryptology/Utils.cs b/src/CoiniumServ/Cryptology/Utils.cs index 75625662e..30e700fb8 100644 --- a/src/CoiniumServ/Cryptology/Utils.cs +++ b/src/CoiniumServ/Cryptology/Utils.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Security.Cryptography; diff --git a/src/CoiniumServ/Daemon/Config/DaemonConfig.cs b/src/CoiniumServ/Daemon/Config/DaemonConfig.cs index 42ead0978..bb9fdaf71 100644 --- a/src/CoiniumServ/Daemon/Config/DaemonConfig.cs +++ b/src/CoiniumServ/Daemon/Config/DaemonConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Daemon/Config/IDaemonConfig.cs b/src/CoiniumServ/Daemon/Config/IDaemonConfig.cs index a6cbd053f..4045726a5 100644 --- a/src/CoiniumServ/Daemon/Config/IDaemonConfig.cs +++ b/src/CoiniumServ/Daemon/Config/IDaemonConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Configuration; diff --git a/src/CoiniumServ/Daemon/DaemonBase.cs b/src/CoiniumServ/Daemon/DaemonBase.cs index 191abd71b..f4fe2ea02 100644 --- a/src/CoiniumServ/Daemon/DaemonBase.cs +++ b/src/CoiniumServ/Daemon/DaemonBase.cs @@ -20,17 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Net; using System.Text; -using CoiniumServ.Daemon.Config; using CoiniumServ.Daemon.Exceptions; -using CoiniumServ.Factories; using CoiniumServ.Logging; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using CoiniumServ.Utils.Extensions; using Newtonsoft.Json; using Serilog; diff --git a/src/CoiniumServ/Daemon/DaemonClient.cs b/src/CoiniumServ/Daemon/DaemonClient.cs index 0392a34aa..ed6602be5 100644 --- a/src/CoiniumServ/Daemon/DaemonClient.cs +++ b/src/CoiniumServ/Daemon/DaemonClient.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; @@ -38,7 +37,7 @@ // Original bitcoin api call list: https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list // Rpc error codes: https://github.com/bitcoin/bitcoin/blob/master/src/rpcprotocol.h#L34 -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; namespace CoiniumServ.Daemon { diff --git a/src/CoiniumServ/Daemon/DaemonErrorResponse.cs b/src/CoiniumServ/Daemon/DaemonErrorResponse.cs index 5910ddac4..363cb1667 100644 --- a/src/CoiniumServ/Daemon/DaemonErrorResponse.cs +++ b/src/CoiniumServ/Daemon/DaemonErrorResponse.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Newtonsoft.Json; diff --git a/src/CoiniumServ/Daemon/DaemonRequest.cs b/src/CoiniumServ/Daemon/DaemonRequest.cs index f27131487..4616edc44 100644 --- a/src/CoiniumServ/Daemon/DaemonRequest.cs +++ b/src/CoiniumServ/Daemon/DaemonRequest.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/src/CoiniumServ/Daemon/DaemonResponse.cs b/src/CoiniumServ/Daemon/DaemonResponse.cs index 54d670621..e8d734899 100644 --- a/src/CoiniumServ/Daemon/DaemonResponse.cs +++ b/src/CoiniumServ/Daemon/DaemonResponse.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Newtonsoft.Json; namespace CoiniumServ.Daemon diff --git a/src/CoiniumServ/Daemon/Exceptions/RpcException.cs b/src/CoiniumServ/Daemon/Exceptions/RpcException.cs index 3e2098f5b..c893f4d8d 100644 --- a/src/CoiniumServ/Daemon/Exceptions/RpcException.cs +++ b/src/CoiniumServ/Daemon/Exceptions/RpcException.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Daemon.Exceptions diff --git a/src/CoiniumServ/Daemon/IDaemonBase.cs b/src/CoiniumServ/Daemon/IDaemonBase.cs index 8e93d37a7..008e0c269 100644 --- a/src/CoiniumServ/Daemon/IDaemonBase.cs +++ b/src/CoiniumServ/Daemon/IDaemonBase.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Daemon diff --git a/src/CoiniumServ/Daemon/IDaemonClient.cs b/src/CoiniumServ/Daemon/IDaemonClient.cs index 787ae853a..a0332c4bc 100644 --- a/src/CoiniumServ/Daemon/IDaemonClient.cs +++ b/src/CoiniumServ/Daemon/IDaemonClient.cs @@ -20,10 +20,7 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; -using CoiniumServ.Coin.Config; -using CoiniumServ.Daemon.Config; using CoiniumServ.Daemon.Responses; namespace CoiniumServ.Daemon diff --git a/src/CoiniumServ/Daemon/Requests/CreateRawTransaction.cs b/src/CoiniumServ/Daemon/Requests/CreateRawTransaction.cs index be7308761..c6a7dbb92 100644 --- a/src/CoiniumServ/Daemon/Requests/CreateRawTransaction.cs +++ b/src/CoiniumServ/Daemon/Requests/CreateRawTransaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Requests diff --git a/src/CoiniumServ/Daemon/Requests/CreateRawTransactionInput.cs b/src/CoiniumServ/Daemon/Requests/CreateRawTransactionInput.cs index 7d623967d..c262554ac 100644 --- a/src/CoiniumServ/Daemon/Requests/CreateRawTransactionInput.cs +++ b/src/CoiniumServ/Daemon/Requests/CreateRawTransactionInput.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Newtonsoft.Json; namespace CoiniumServ.Daemon.Requests diff --git a/src/CoiniumServ/Daemon/Requests/SignRawTransaction.cs b/src/CoiniumServ/Daemon/Requests/SignRawTransaction.cs index 9f94ae690..260c16049 100644 --- a/src/CoiniumServ/Daemon/Requests/SignRawTransaction.cs +++ b/src/CoiniumServ/Daemon/Requests/SignRawTransaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Requests diff --git a/src/CoiniumServ/Daemon/Requests/SignRawTransactionInput.cs b/src/CoiniumServ/Daemon/Requests/SignRawTransactionInput.cs index b4ef5f234..d56977700 100644 --- a/src/CoiniumServ/Daemon/Requests/SignRawTransactionInput.cs +++ b/src/CoiniumServ/Daemon/Requests/SignRawTransactionInput.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Newtonsoft.Json; namespace CoiniumServ.Daemon.Requests diff --git a/src/CoiniumServ/Daemon/Responses/AddedNodeInfo.cs b/src/CoiniumServ/Daemon/Responses/AddedNodeInfo.cs index e51e9b579..b6b6ac868 100644 --- a/src/CoiniumServ/Daemon/Responses/AddedNodeInfo.cs +++ b/src/CoiniumServ/Daemon/Responses/AddedNodeInfo.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Responses diff --git a/src/CoiniumServ/Daemon/Responses/Block.cs b/src/CoiniumServ/Daemon/Responses/Block.cs index 253d92314..35b8e2354 100644 --- a/src/CoiniumServ/Daemon/Responses/Block.cs +++ b/src/CoiniumServ/Daemon/Responses/Block.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; diff --git a/src/CoiniumServ/Daemon/Responses/BlockTemplate.cs b/src/CoiniumServ/Daemon/Responses/BlockTemplate.cs index 9c5330fd2..688ca8f9b 100644 --- a/src/CoiniumServ/Daemon/Responses/BlockTemplate.cs +++ b/src/CoiniumServ/Daemon/Responses/BlockTemplate.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; diff --git a/src/CoiniumServ/Daemon/Responses/DecodedRawTransaction.cs b/src/CoiniumServ/Daemon/Responses/DecodedRawTransaction.cs index b75c98081..0f898862e 100644 --- a/src/CoiniumServ/Daemon/Responses/DecodedRawTransaction.cs +++ b/src/CoiniumServ/Daemon/Responses/DecodedRawTransaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Responses diff --git a/src/CoiniumServ/Daemon/Responses/Getwork.cs b/src/CoiniumServ/Daemon/Responses/Getwork.cs index e6d517525..dff678d43 100644 --- a/src/CoiniumServ/Daemon/Responses/Getwork.cs +++ b/src/CoiniumServ/Daemon/Responses/Getwork.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Daemon.Responses { // Documentation: diff --git a/src/CoiniumServ/Daemon/Responses/IBlockTemplate.cs b/src/CoiniumServ/Daemon/Responses/IBlockTemplate.cs index ecad39baa..f8e31b118 100644 --- a/src/CoiniumServ/Daemon/Responses/IBlockTemplate.cs +++ b/src/CoiniumServ/Daemon/Responses/IBlockTemplate.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; diff --git a/src/CoiniumServ/Daemon/Responses/Info.cs b/src/CoiniumServ/Daemon/Responses/Info.cs index 2b1db3041..1e76e47e9 100644 --- a/src/CoiniumServ/Daemon/Responses/Info.cs +++ b/src/CoiniumServ/Daemon/Responses/Info.cs @@ -24,7 +24,7 @@ namespace CoiniumServ.Daemon.Responses { public class Info { - public int Version { get; set; } + public string Version { get; set; } public int ProtocolVersion { get; set; } public int WalletVersion { get; set; } public decimal Balance { get; set; } diff --git a/src/CoiniumServ/Daemon/Responses/MiningInfo.cs b/src/CoiniumServ/Daemon/Responses/MiningInfo.cs index 5b94cdc64..cb4a6ee6b 100644 --- a/src/CoiniumServ/Daemon/Responses/MiningInfo.cs +++ b/src/CoiniumServ/Daemon/Responses/MiningInfo.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Daemon.Responses diff --git a/src/CoiniumServ/Daemon/Responses/Transaction.cs b/src/CoiniumServ/Daemon/Responses/Transaction.cs index 3ad8705b5..6ebf2e81f 100644 --- a/src/CoiniumServ/Daemon/Responses/Transaction.cs +++ b/src/CoiniumServ/Daemon/Responses/Transaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Daemon/Responses/TransactionsSinceBlock.cs b/src/CoiniumServ/Daemon/Responses/TransactionsSinceBlock.cs index e633e937c..9f75d0c2c 100644 --- a/src/CoiniumServ/Daemon/Responses/TransactionsSinceBlock.cs +++ b/src/CoiniumServ/Daemon/Responses/TransactionsSinceBlock.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Responses diff --git a/src/CoiniumServ/Daemon/Responses/ValidateAddress.cs b/src/CoiniumServ/Daemon/Responses/ValidateAddress.cs index 46036810a..7471b1054 100644 --- a/src/CoiniumServ/Daemon/Responses/ValidateAddress.cs +++ b/src/CoiniumServ/Daemon/Responses/ValidateAddress.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Daemon.Responses diff --git a/src/CoiniumServ/Factories/ConfigFactory.cs b/src/CoiniumServ/Factories/ConfigFactory.cs index d4ab6013b..250e43304 100644 --- a/src/CoiniumServ/Factories/ConfigFactory.cs +++ b/src/CoiniumServ/Factories/ConfigFactory.cs @@ -20,11 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Coin.Config; using CoiniumServ.Configuration; -using CoiniumServ.Pools.Config; -using CoiniumServ.Repository.Context; +using CoiniumServ.Container.Context; +using CoiniumServ.Pools; using Nancy.TinyIoc; namespace CoiniumServ.Factories diff --git a/src/CoiniumServ/Factories/IConfigFactory.cs b/src/CoiniumServ/Factories/IConfigFactory.cs index d8c5f9929..ab746b67e 100644 --- a/src/CoiniumServ/Factories/IConfigFactory.cs +++ b/src/CoiniumServ/Factories/IConfigFactory.cs @@ -20,12 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Coin.Config; using CoiniumServ.Configuration; -using CoiniumServ.Logging; -using CoiniumServ.Pools.Config; -using CoiniumServ.Server.Web; +using CoiniumServ.Pools; namespace CoiniumServ.Factories { diff --git a/src/CoiniumServ/Factories/IObjectFactory.cs b/src/CoiniumServ/Factories/IObjectFactory.cs index 7af91c6a1..d3676f099 100644 --- a/src/CoiniumServ/Factories/IObjectFactory.cs +++ b/src/CoiniumServ/Factories/IObjectFactory.cs @@ -20,7 +20,7 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using System.Collections.Generic; using CoiniumServ.Banning; using CoiniumServ.Blocks; using CoiniumServ.Cryptology.Algorithms; @@ -31,9 +31,11 @@ using CoiniumServ.Metrics; using CoiniumServ.Miners; using CoiniumServ.Payments; -using CoiniumServ.Persistance; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Hybrid; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using CoiniumServ.Server.Mining; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Server.Web; @@ -72,16 +74,16 @@ public interface IObjectFactory /// IDaemonClient GetDaemonClient(IPoolConfig poolConfig); - IMinerManager GetMinerManager(IPoolConfig poolConfig, IDaemonClient daemonClient); + IMinerManager GetMinerManager(IPoolConfig poolConfig, IStorageLayer storageLayer); IJobManager GetJobManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IShareManager shareManager, IMinerManager minerManager, IHashAlgorithm hashAlgorithm); IJobTracker GetJobTracker(); - IShareManager GetShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorage storage, IBlockProcessor blockProcessor); + IShareManager GetShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorageLayer storageLayer, IBlockProcessor blockProcessor); - IPaymentProcessor GetPaymentProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient, IStorage storage, IBlockProcessor blockProcessor); + IPaymentProcessor GetPaymentProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient, IStorageLayer storageLayer, IBlockProcessor blockProcessor); IBlockProcessor GetBlockProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient); @@ -89,23 +91,13 @@ IJobManager GetJobManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJ IVardiffManager GetVardiffManager(IPoolConfig poolConfig, IShareManager shareManager); - #endregion - - #region pool statistics objects - - IStatistics GetStatistics(); - - IGlobal GetGlobalStatistics(); - - IAlgorithms GetAlgorithmStatistics(); - - IPools GetPoolStats(); + INetworkStats GetNetworkStats(IDaemonClient daemonClient); - IPerPool GetPerPoolStats(IPoolConfig poolConfig, IDaemonClient daemonClient, IMinerManager minerManager, IHashAlgorithm hashAlgorithm, IBlocksCount blockStatistics, IStorage storage); + IAlgorithmManager GetAlgorithmManager(IPoolManager poolManager); - IBlocksCount GetBlockStats(ILatestBlocks latestBlocks, IStorage storage); + IBlocksCache GetBlocksCache(IStorageLayer storageLayer); - ILatestBlocks GetLatestBlocks(IStorage storage); + IStatisticsManager GetStatisticsManager(); #endregion @@ -122,8 +114,17 @@ IMiningServer GetMiningServer(string type, IPoolConfig poolConfig, IPool pool, I #endregion + #region storage objects + + IStorageProvider GetStorageProvider(string type, IPoolConfig poolConfig, IStorageProviderConfig config); + + IStorageLayer GetStorageLayer(string type, IEnumerable providers, IDaemonClient daemonClient, IPoolConfig poolConfig); + + IMigrationManager GetMigrationManager(IMySqlProvider provider, IPoolConfig poolConfig); + + #endregion + #region other objects - IStorage GetStorage(string type, IPoolConfig poolConfig); ILogManager GetLogManager(); diff --git a/src/CoiniumServ/Factories/ObjectFactory.cs b/src/CoiniumServ/Factories/ObjectFactory.cs index 99fe822c4..905f61283 100644 --- a/src/CoiniumServ/Factories/ObjectFactory.cs +++ b/src/CoiniumServ/Factories/ObjectFactory.cs @@ -20,9 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using System.Collections.Generic; using CoiniumServ.Banning; using CoiniumServ.Blocks; +using CoiniumServ.Container.Context; using CoiniumServ.Cryptology.Algorithms; using CoiniumServ.Daemon; using CoiniumServ.Jobs.Manager; @@ -31,10 +32,11 @@ using CoiniumServ.Metrics; using CoiniumServ.Miners; using CoiniumServ.Payments; -using CoiniumServ.Persistance; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Hybrid; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; -using CoiniumServ.Repository.Context; using CoiniumServ.Server.Mining; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Server.Web; @@ -114,12 +116,12 @@ public IDaemonClient GetDaemonClient(IPoolConfig poolConfig) return _applicationContext.Container.Resolve(@params); } - public IMinerManager GetMinerManager(IPoolConfig poolConfig, IDaemonClient daemonClient) + public IMinerManager GetMinerManager(IPoolConfig poolConfig, IStorageLayer storageLayer) { var @params = new NamedParameterOverloads { {"poolConfig", poolConfig}, - {"daemonClient", daemonClient}, + {"storageLayer", storageLayer}, }; return _applicationContext.Container.Resolve(@params); @@ -146,27 +148,27 @@ public IJobTracker GetJobTracker() return _applicationContext.Container.Resolve(); } - public IShareManager GetShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorage storage, IBlockProcessor blockProcessor) + public IShareManager GetShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorageLayer storageLayer, IBlockProcessor blockProcessor) { var @params = new NamedParameterOverloads { {"poolConfig", poolConfig}, {"daemonClient", daemonClient}, {"jobTracker", jobTracker}, - {"storage", storage}, + {"storageLayer", storageLayer}, {"blockProcessor", blockProcessor} }; return _applicationContext.Container.Resolve(@params); } - public IPaymentProcessor GetPaymentProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient, IStorage storage, IBlockProcessor blockProcessor) + public IPaymentProcessor GetPaymentProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient, IStorageLayer storageLayer, IBlockProcessor blockProcessor) { var @params = new NamedParameterOverloads { {"poolConfig", poolConfig}, {"daemonClient", daemonClient}, - {"storage", storage}, + {"storageLayer", storageLayer}, {"blockProcessor", blockProcessor}, }; @@ -206,64 +208,34 @@ public IVardiffManager GetVardiffManager(IPoolConfig poolConfig, IShareManager s return _applicationContext.Container.Resolve(@params); } - #endregion - - #region pool statistics objects - - public IStatistics GetStatistics() - { - return _applicationContext.Container.Resolve(); - } - - public IGlobal GetGlobalStatistics() - { - return _applicationContext.Container.Resolve(); - } - - public IAlgorithms GetAlgorithmStatistics() - { - return _applicationContext.Container.Resolve(); - } - - public IPools GetPoolStats() - { - return _applicationContext.Container.Resolve(); - } - - public IPerPool GetPerPoolStats(IPoolConfig poolConfig, IDaemonClient daemonClient, IMinerManager minerManager, IHashAlgorithm hashAlgorithm, IBlocksCount blockStatistics, IStorage storage) + public INetworkStats GetNetworkStats(IDaemonClient daemonClient) { var @params = new NamedParameterOverloads { - {"poolConfig", poolConfig}, {"daemonClient", daemonClient}, - {"minerManager",minerManager}, - {"hashAlgorithm", hashAlgorithm}, - {"blockStatistics", blockStatistics}, - {"storage", storage}, }; - return _applicationContext.Container.Resolve(@params); + return _applicationContext.Container.Resolve(@params); } - public ILatestBlocks GetLatestBlocks(IStorage storage) + public IAlgorithmManager GetAlgorithmManager(IPoolManager poolManager) { - var @params = new NamedParameterOverloads - { - {"storage", storage} - }; - - return _applicationContext.Container.Resolve(@params); + return _applicationContext.Container.Resolve(); } - public IBlocksCount GetBlockStats(ILatestBlocks latestBlocks, IStorage storage) + public IBlocksCache GetBlocksCache(IStorageLayer storageLayer) { var @params = new NamedParameterOverloads { - {"latestBlocks", latestBlocks}, - {"storage", storage}, + {"storageLayer", storageLayer}, }; - return _applicationContext.Container.Resolve(@params); + return _applicationContext.Container.Resolve(@params); + } + + public IStatisticsManager GetStatisticsManager() + { + return _applicationContext.Container.Resolve(); } #endregion @@ -309,18 +281,48 @@ public INancyBootstrapper GetWebBootstrapper() #endregion - #region other objects + #region storage objects + + public IStorageProvider GetStorageProvider(string type, IPoolConfig poolConfig, IStorageProviderConfig config) + { + var @params = new NamedParameterOverloads + { + {"poolConfig", poolConfig}, + {"config", config} + }; + + return _applicationContext.Container.Resolve(type, @params); + } - public IStorage GetStorage(string type, IPoolConfig poolConfig) + public IStorageLayer GetStorageLayer(string type, IEnumerable providers, IDaemonClient daemonClient, IPoolConfig poolConfig) { var @params = new NamedParameterOverloads { + {"providers", providers}, + {"daemonClient", daemonClient}, {"poolConfig", poolConfig} }; - return _applicationContext.Container.Resolve(type, @params); + return type != StorageLayers.Empty + ? _applicationContext.Container.Resolve(type, @params) + : _applicationContext.Container.Resolve(type); } + public IMigrationManager GetMigrationManager(IMySqlProvider provider, IPoolConfig poolConfig) + { + var @params = new NamedParameterOverloads + { + {"provider", provider}, + {"poolConfig", poolConfig}, + }; + + return _applicationContext.Container.Resolve(@params); + } + + #endregion + + #region other objects + public ILogManager GetLogManager() { return _applicationContext.Container.Resolve(); diff --git a/src/CoiniumServ/Jobs/ExtraNonce.cs b/src/CoiniumServ/Jobs/ExtraNonce.cs index 7b2a03de0..09bf03eec 100644 --- a/src/CoiniumServ/Jobs/ExtraNonce.cs +++ b/src/CoiniumServ/Jobs/ExtraNonce.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Utils.Extensions; diff --git a/src/CoiniumServ/Jobs/IExtraNonce.cs b/src/CoiniumServ/Jobs/IExtraNonce.cs index 16efa0e1c..ae55bfecb 100644 --- a/src/CoiniumServ/Jobs/IExtraNonce.cs +++ b/src/CoiniumServ/Jobs/IExtraNonce.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Jobs diff --git a/src/CoiniumServ/Jobs/IJob.cs b/src/CoiniumServ/Jobs/IJob.cs index 5d228581f..cb039b3a0 100644 --- a/src/CoiniumServ/Jobs/IJob.cs +++ b/src/CoiniumServ/Jobs/IJob.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using CoiniumServ.Cryptology.Algorithms; diff --git a/src/CoiniumServ/Jobs/IJobCounter.cs b/src/CoiniumServ/Jobs/IJobCounter.cs index 37a0a3ea7..0f1570c56 100644 --- a/src/CoiniumServ/Jobs/IJobCounter.cs +++ b/src/CoiniumServ/Jobs/IJobCounter.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Jobs diff --git a/src/CoiniumServ/Jobs/Job.cs b/src/CoiniumServ/Jobs/Job.cs index f18c189d5..42268ae37 100644 --- a/src/CoiniumServ/Jobs/Job.cs +++ b/src/CoiniumServ/Jobs/Job.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections; using System.Collections.Generic; @@ -169,7 +168,7 @@ public Job(UInt64 id, IHashAlgorithm algorithm, IBlockTemplate blockTemplate, IG : BigInteger.Parse(blockTemplate.Target, NumberStyles.HexNumber); // set the block diff - Difficulty = ((double)new BigRational(Algorithms.Diff1, Target)); + Difficulty = ((double)new BigRational(AlgorithmManager.Diff1, Target)); // set the ntime nTime = BitConverter.GetBytes(blockTemplate.CurTime.BigEndian()).ToHexString(); diff --git a/src/CoiniumServ/Jobs/JobCounter.cs b/src/CoiniumServ/Jobs/JobCounter.cs index 7e2c1dfa3..d15cd73a0 100644 --- a/src/CoiniumServ/Jobs/JobCounter.cs +++ b/src/CoiniumServ/Jobs/JobCounter.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Jobs diff --git a/src/CoiniumServ/Jobs/Manager/IJobConfig.cs b/src/CoiniumServ/Jobs/Manager/IJobConfig.cs index 91d32742d..80d7f719e 100644 --- a/src/CoiniumServ/Jobs/Manager/IJobConfig.cs +++ b/src/CoiniumServ/Jobs/Manager/IJobConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Jobs.Manager diff --git a/src/CoiniumServ/Jobs/Manager/IJobManager.cs b/src/CoiniumServ/Jobs/Manager/IJobManager.cs index ffe1b0cb4..ea8cc558d 100644 --- a/src/CoiniumServ/Jobs/Manager/IJobManager.cs +++ b/src/CoiniumServ/Jobs/Manager/IJobManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Jobs.Manager diff --git a/src/CoiniumServ/Jobs/Manager/JobConfig.cs b/src/CoiniumServ/Jobs/Manager/JobConfig.cs index 9aaf46e4c..e8209ecdc 100644 --- a/src/CoiniumServ/Jobs/Manager/JobConfig.cs +++ b/src/CoiniumServ/Jobs/Manager/JobConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Jobs/Manager/JobManager.cs b/src/CoiniumServ/Jobs/Manager/JobManager.cs index 8791a946b..56004a00e 100644 --- a/src/CoiniumServ/Jobs/Manager/JobManager.cs +++ b/src/CoiniumServ/Jobs/Manager/JobManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Threading; using CoiniumServ.Cryptology.Algorithms; @@ -28,8 +27,7 @@ using CoiniumServ.Daemon.Exceptions; using CoiniumServ.Jobs.Tracker; using CoiniumServ.Miners; -using CoiniumServ.Payments; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Vanilla; using CoiniumServ.Shares; @@ -155,7 +153,7 @@ private IJob GetNewJob() var blockTemplate = _daemonClient.GetBlockTemplate(); // TODO: convert generation transaction to ioc & DI based. - var generationTransaction = new GenerationTransaction(ExtraNonce, _daemonClient, blockTemplate,_poolConfig.Wallet, _poolConfig.Rewards,_poolConfig.Meta, _poolConfig.Coin.SupportsTxMessages); + var generationTransaction = new GenerationTransaction(ExtraNonce, _daemonClient, blockTemplate, _poolConfig); generationTransaction.Create(); // create the job notification. diff --git a/src/CoiniumServ/Jobs/Tracker/IJobTracker.cs b/src/CoiniumServ/Jobs/Tracker/IJobTracker.cs index be0651faa..f458cf6cb 100644 --- a/src/CoiniumServ/Jobs/Tracker/IJobTracker.cs +++ b/src/CoiniumServ/Jobs/Tracker/IJobTracker.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Jobs.Tracker diff --git a/src/CoiniumServ/Jobs/Tracker/JobTracker.cs b/src/CoiniumServ/Jobs/Tracker/JobTracker.cs index 452329334..a3a5e8a6b 100644 --- a/src/CoiniumServ/Jobs/Tracker/JobTracker.cs +++ b/src/CoiniumServ/Jobs/Tracker/JobTracker.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; diff --git a/src/CoiniumServ/Logging/ILogConfig.cs b/src/CoiniumServ/Logging/ILogConfig.cs index 2655630c5..7f7faa981 100644 --- a/src/CoiniumServ/Logging/ILogConfig.cs +++ b/src/CoiniumServ/Logging/ILogConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using CoiniumServ.Configuration; diff --git a/src/CoiniumServ/Logging/ILogManager.cs b/src/CoiniumServ/Logging/ILogManager.cs index a135bed4e..a68a49f5a 100644 --- a/src/CoiniumServ/Logging/ILogManager.cs +++ b/src/CoiniumServ/Logging/ILogManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Logging { public interface ILogManager diff --git a/src/CoiniumServ/Logging/ILogTarget.cs b/src/CoiniumServ/Logging/ILogTarget.cs index 1bc1a4ca4..8c714bb94 100644 --- a/src/CoiniumServ/Logging/ILogTarget.cs +++ b/src/CoiniumServ/Logging/ILogTarget.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; using Serilog.Events; diff --git a/src/CoiniumServ/Logging/LogConfig.cs b/src/CoiniumServ/Logging/LogConfig.cs index c278cfde1..3ab8200d9 100644 --- a/src/CoiniumServ/Logging/LogConfig.cs +++ b/src/CoiniumServ/Logging/LogConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Dynamic; diff --git a/src/CoiniumServ/Logging/LogManager.cs b/src/CoiniumServ/Logging/LogManager.cs index 8fb549c0c..7dc1cd991 100644 --- a/src/CoiniumServ/Logging/LogManager.cs +++ b/src/CoiniumServ/Logging/LogManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Linq; diff --git a/src/CoiniumServ/Logging/LogTarget.cs b/src/CoiniumServ/Logging/LogTarget.cs index 9d9e2ee48..1d795fe70 100644 --- a/src/CoiniumServ/Logging/LogTarget.cs +++ b/src/CoiniumServ/Logging/LogTarget.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; using Serilog.Events; diff --git a/src/CoiniumServ/Metrics/IMetricsManager.cs b/src/CoiniumServ/Metrics/IMetricsManager.cs index 1768d7933..f61466836 100644 --- a/src/CoiniumServ/Metrics/IMetricsManager.cs +++ b/src/CoiniumServ/Metrics/IMetricsManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Metrics { public interface IMetricsManager diff --git a/src/CoiniumServ/Metrics/MetricsManager.cs b/src/CoiniumServ/Metrics/MetricsManager.cs index 1491d6e0d..0f9424425 100644 --- a/src/CoiniumServ/Metrics/MetricsManager.cs +++ b/src/CoiniumServ/Metrics/MetricsManager.cs @@ -20,10 +20,8 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Configuration; -using CoiniumServ.Server.Web; using CoiniumServ.Utils.Helpers.IO; using CoiniumServ.Utils.Platform; using Metrics; @@ -33,15 +31,11 @@ namespace CoiniumServ.Metrics { public class MetricsManager : IMetricsManager { - private readonly IBackendConfig _config; - private readonly ILogger _logger; public MetricsManager(IConfigManager configManager) { - _config = configManager.WebServerConfig.Backend; - - if (!_config.MetricsEnabled) + if (!configManager.WebServerConfig.Backend.MetricsEnabled) return; _logger = Log.ForContext(); diff --git a/src/CoiniumServ/Miners/IMetaConfig.cs b/src/CoiniumServ/Miners/IMetaConfig.cs index 416d231de..5e34aff37 100644 --- a/src/CoiniumServ/Miners/IMetaConfig.cs +++ b/src/CoiniumServ/Miners/IMetaConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Miners diff --git a/src/CoiniumServ/Miners/IMiner.cs b/src/CoiniumServ/Miners/IMiner.cs index 86bf9558a..757e534d8 100644 --- a/src/CoiniumServ/Miners/IMiner.cs +++ b/src/CoiniumServ/Miners/IMiner.cs @@ -20,15 +20,16 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Pools; +using Newtonsoft.Json; namespace CoiniumServ.Miners { /// /// Miner interface that any implementations should extend. /// + [JsonObject(MemberSerialization.OptIn)] public interface IMiner { /// diff --git a/src/CoiniumServ/Miners/IMinerConfig.cs b/src/CoiniumServ/Miners/IMinerConfig.cs index 1603507fa..ac8f370fd 100644 --- a/src/CoiniumServ/Miners/IMinerConfig.cs +++ b/src/CoiniumServ/Miners/IMinerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Miners diff --git a/src/CoiniumServ/Miners/IMinerManager.cs b/src/CoiniumServ/Miners/IMinerManager.cs index 6edaafdbe..b9aeb4760 100644 --- a/src/CoiniumServ/Miners/IMinerManager.cs +++ b/src/CoiniumServ/Miners/IMinerManager.cs @@ -20,20 +20,25 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Stratum.Sockets; using CoiniumServ.Server.Mining.Vanilla; +using Newtonsoft.Json; namespace CoiniumServ.Miners { + [JsonObject(MemberSerialization.OptIn)] public interface IMinerManager { event EventHandler MinerAuthenticated; + [JsonProperty("count")] + int Count { get; } + + [JsonProperty("list")] IList Miners { get; } IMiner GetMiner(Int32 id); diff --git a/src/CoiniumServ/Miners/MetaConfig.cs b/src/CoiniumServ/Miners/MetaConfig.cs index 180a98fe8..746685c4d 100644 --- a/src/CoiniumServ/Miners/MetaConfig.cs +++ b/src/CoiniumServ/Miners/MetaConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Miners/MinerConfig.cs b/src/CoiniumServ/Miners/MinerConfig.cs index 58908597d..8315a0502 100644 --- a/src/CoiniumServ/Miners/MinerConfig.cs +++ b/src/CoiniumServ/Miners/MinerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Miners/MinerEventArgs.cs b/src/CoiniumServ/Miners/MinerEventArgs.cs index 585be502c..ac57404bb 100644 --- a/src/CoiniumServ/Miners/MinerEventArgs.cs +++ b/src/CoiniumServ/Miners/MinerEventArgs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Miners diff --git a/src/CoiniumServ/Miners/MinerManager.cs b/src/CoiniumServ/Miners/MinerManager.cs index 94ad1a603..9ebe5eab3 100644 --- a/src/CoiniumServ/Miners/MinerManager.cs +++ b/src/CoiniumServ/Miners/MinerManager.cs @@ -20,14 +20,11 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; -using CoiniumServ.Daemon; -using CoiniumServ.Daemon.Exceptions; +using CoiniumServ.Persistance.Layers; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Stratum.Sockets; using CoiniumServ.Server.Mining.Vanilla; @@ -36,7 +33,8 @@ namespace CoiniumServ.Miners { public class MinerManager : IMinerManager - { + { + public int Count { get { return _miners.Count(kvp => kvp.Value.Authenticated); } } public IList Miners { get { return _miners.Values.ToList(); } } public event EventHandler MinerAuthenticated; @@ -45,22 +43,16 @@ public class MinerManager : IMinerManager private int _counter = 0; // counter for assigining unique id's to miners. - private readonly IMinerConfig _minerConfig; - - private readonly IMetaConfig _metaConfig; - - private readonly IDaemonClient _daemonClient; + private readonly IPoolConfig _poolConfig; - private readonly IStratumServerConfig _stratumServerConfig; + private readonly IStorageLayer _storageLayer; private readonly ILogger _logger; - public MinerManager(IPoolConfig poolConfig, IDaemonClient daemonClient) + public MinerManager(IPoolConfig poolConfig, IStorageLayer storageLayer) { - _minerConfig = poolConfig.Miner; - _metaConfig = poolConfig.Meta; - _daemonClient = daemonClient; - _stratumServerConfig = poolConfig.Stratum; + _poolConfig = poolConfig; + _storageLayer = storageLayer; _miners = new Dictionary(); _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); @@ -102,8 +94,9 @@ public T Create(UInt32 extraNonce, IConnection connection, IPool pool) where _counter++, extraNonce, connection, - pool, - this + pool, + this, + _storageLayer }; var instance = Activator.CreateInstance(typeof(T), @params); // create an instance of the miner. @@ -126,17 +119,8 @@ public void Remove(IConnection connection) public void Authenticate(IMiner miner) { - if (_minerConfig.ValidateUsername) // should we validate miner username? - try - { - miner.Authenticated = _daemonClient.ValidateAddress(miner.Username).IsValid; // if so validate it against coin daemon as an address. - } - catch (RpcException) - { - miner.Authenticated = false; - } - else - miner.Authenticated = true; // else just accept him. + // if username validation is not on just authenticate the miner, else ask the current storage layer to do so. + miner.Authenticated = !_poolConfig.Miner.ValidateUsername || _storageLayer.Authenticate(miner); _logger.Information( miner.Authenticated ? "Authenticated miner: {0:l} [{1:l}]" : "Miner authentication failed: {0:l} [{1:l}]", @@ -145,11 +129,11 @@ public void Authenticate(IMiner miner) if (!miner.Authenticated) return; - if (miner is IStratumMiner) + if (miner is IStratumMiner) // if we are handling a stratum-miner, apply stratum specific stuff. { var stratumMiner = (IStratumMiner) miner; - stratumMiner.SetDifficulty(_stratumServerConfig.Diff); // set the initial difficulty for the miner and send it. - stratumMiner.SendMessage(_metaConfig.MOTD); // send the motd. + stratumMiner.SetDifficulty(_poolConfig.Stratum.Diff); // set the initial difficulty for the miner and send it. + stratumMiner.SendMessage(_poolConfig.Meta.MOTD); // send the motd. } OnMinerAuthenticated(new MinerEventArgs(miner)); // notify listeners about the new authenticated miner. diff --git a/src/CoiniumServ/Miners/MinerSoftware.cs b/src/CoiniumServ/Miners/MinerSoftware.cs index 022c26b5e..6961edbf3 100644 --- a/src/CoiniumServ/Miners/MinerSoftware.cs +++ b/src/CoiniumServ/Miners/MinerSoftware.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Miners { public enum MinerSoftware diff --git a/src/CoiniumServ/Payments/IPaymentConfig.cs b/src/CoiniumServ/Payments/IPaymentConfig.cs index 2871ae52c..22d092453 100644 --- a/src/CoiniumServ/Payments/IPaymentConfig.cs +++ b/src/CoiniumServ/Payments/IPaymentConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Configuration; @@ -39,5 +38,7 @@ public interface IPaymentConfig:IConfig /// minimum amount of coins before a miner is eligable for getting a payment. /// double Minimum { get; } + + void Disable(); } } diff --git a/src/CoiniumServ/Payments/IPaymentProcessor.cs b/src/CoiniumServ/Payments/IPaymentProcessor.cs index d880772a7..a56992714 100644 --- a/src/CoiniumServ/Payments/IPaymentProcessor.cs +++ b/src/CoiniumServ/Payments/IPaymentProcessor.cs @@ -24,8 +24,6 @@ namespace CoiniumServ.Payments { public interface IPaymentProcessor { - void Initialize(IPaymentConfig config); - - bool IsEnabled { get; } + void Initialize(); } } diff --git a/src/CoiniumServ/Payments/IPaymentRound.cs b/src/CoiniumServ/Payments/IPaymentRound.cs index f1e760458..86e88f382 100644 --- a/src/CoiniumServ/Payments/IPaymentRound.cs +++ b/src/CoiniumServ/Payments/IPaymentRound.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using CoiniumServ.Persistance.Blocks; diff --git a/src/CoiniumServ/Payments/IRewardsConfig.cs b/src/CoiniumServ/Payments/IRewardsConfig.cs index af17fff63..7bcf8756c 100644 --- a/src/CoiniumServ/Payments/IRewardsConfig.cs +++ b/src/CoiniumServ/Payments/IRewardsConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using CoiniumServ.Configuration; diff --git a/src/CoiniumServ/Payments/IWalletConfig.cs b/src/CoiniumServ/Payments/IWalletConfig.cs index 4bce0abd8..e2344218b 100644 --- a/src/CoiniumServ/Payments/IWalletConfig.cs +++ b/src/CoiniumServ/Payments/IWalletConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Payments diff --git a/src/CoiniumServ/Payments/PaymentConfig.cs b/src/CoiniumServ/Payments/PaymentConfig.cs index 6a1ec4e2d..a5b362c1e 100644 --- a/src/CoiniumServ/Payments/PaymentConfig.cs +++ b/src/CoiniumServ/Payments/PaymentConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; @@ -50,5 +49,10 @@ public PaymentConfig(dynamic config) Log.Logger.ForContext().Error(e, "Error loading payment configuration"); } } + + public void Disable() + { + Enabled = false; + } } } diff --git a/src/CoiniumServ/Payments/PaymentProcessor.cs b/src/CoiniumServ/Payments/PaymentProcessor.cs index a6692ca73..a120a5e52 100644 --- a/src/CoiniumServ/Payments/PaymentProcessor.cs +++ b/src/CoiniumServ/Payments/PaymentProcessor.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Diagnostics; @@ -31,7 +30,8 @@ using CoiniumServ.Daemon.Exceptions; using CoiniumServ.Persistance; using CoiniumServ.Persistance.Blocks; -using CoiniumServ.Pools.Config; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Pools; using Serilog; namespace CoiniumServ.Payments @@ -40,13 +40,11 @@ namespace CoiniumServ.Payments public class PaymentProcessor : IPaymentProcessor { - public bool IsEnabled { get; private set; } + private readonly IPoolConfig _poolConfig; private readonly IDaemonClient _daemonClient; - private readonly IStorage _storage; - - private IPaymentConfig _config; + private readonly IStorageLayer _storageLayer; private readonly IBlockProcessor _blockProcessor; @@ -59,30 +57,23 @@ public class PaymentProcessor : IPaymentProcessor private readonly object _paymentsLock = new object(); private readonly Stopwatch _stopWatch = new Stopwatch(); - private readonly IWalletConfig _walletConfig; - private string _poolAccount = string.Empty; private readonly ILogger _logger; - public PaymentProcessor(IPoolConfig poolConfig, IDaemonClient daemonClient, IStorage storage, IBlockProcessor blockProcessor) + public PaymentProcessor(IPoolConfig poolConfig, IStorageLayer storageLayer, IDaemonClient daemonClient, IBlockProcessor blockProcessor) { + _poolConfig = poolConfig; _daemonClient = daemonClient; - _storage = storage; + _storageLayer = storageLayer; _blockProcessor = blockProcessor; - _walletConfig = poolConfig.Wallet; - _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); } - public void Initialize(IPaymentConfig config) + public void Initialize() { - _config = config; - - IsEnabled = _config.Enabled; - - if (!IsEnabled) + if (!_poolConfig.Payments.Enabled) return; // validate the pool wallet. @@ -97,22 +88,22 @@ public void Initialize(IPaymentConfig config) return; // calculate the minimum amount of payments in satoshis. - _paymentThresholdInSatoshis = (decimal) (_magnitude*config.Minimum); + _paymentThresholdInSatoshis = (decimal) (_magnitude*_poolConfig.Payments.Minimum); // if we reached here, then we can just setup the timer to run payments. - _timer = new Timer(RunPayments, null, _config.Interval * 1000, Timeout.Infinite); + _timer = new Timer(RunPayments, null, _poolConfig.Payments.Interval * 1000, Timeout.Infinite); } private void RunPayments(object state) { - if (!IsEnabled) + if (!_poolConfig.Payments.Enabled) return; lock (_paymentsLock) { _stopWatch.Start(); - var pendingBlocks = _storage.GetBlocks(BlockStatus.Pending); // get all the pending blocks. + var pendingBlocks = _storageLayer.GetBlocks(BlockStatus.Pending); // get all the pending blocks. var nonPendingBlocks = GetNonPendingBlocks(pendingBlocks); // get the confirmed blocks that are either orphan or mature. var rounds = GetPaymentRounds(nonPendingBlocks); // get the list of rounds that should be paid. AssignSharesToRounds(rounds); // process the rounds, calculate shares and payouts per rounds. @@ -126,13 +117,13 @@ private void RunPayments(object state) _stopWatch.Reset(); - _timer.Change(_config.Interval*1000, Timeout.Infinite); // reset the payments timer. + _timer.Change(_poolConfig.Payments.Interval*1000, Timeout.Infinite); // reset the payments timer. } } private Dictionary GetPreviousBalances() { - var previousBalances = _storage.GetPreviousBalances(); + var previousBalances = _storageLayer.GetPreviousBalances(); return previousBalances; } @@ -211,7 +202,7 @@ private void ExecutePayments(IList workerBalances) private void ProcessRemainingBalances(IList workerBalances) { - _storage.SetRemainingBalances(workerBalances); // commit remaining balances to storage. + _storageLayer.SetBalances(workerBalances); // commit remaining balances to storage. } private void ProcessRounds(IEnumerable rounds) @@ -224,12 +215,12 @@ private void ProcessRounds(IEnumerable rounds) switch (round.Block.Status) { case BlockStatus.Confirmed: - _storage.DeleteShares(round); // delete the associated shares. - _storage.MoveBlock(round); // move pending block to appropriate place. + _storageLayer.RemoveShares(round); // delete the associated shares. + _storageLayer.UpdateBlock(round); // update block status. break; case BlockStatus.Orphaned: - _storage.MoveSharesToCurrentRound(round); // move shares to current round so the work of miners aren't gone to void. - _storage.MoveBlock(round); // move pending block to appropriate place. + _storageLayer.MoveSharesToCurrentRound(round); // move shares to current round so the work of miners aren't gone to void. + _storageLayer.UpdateBlock(round); // update block status. break; } } @@ -238,7 +229,7 @@ private void ProcessRounds(IEnumerable rounds) private void AssignSharesToRounds(IList rounds) { // get shares for the rounds. - var shares = _storage.GetSharesForRounds(rounds); + var shares = _storageLayer.GetShares(rounds); // assign shares to the rounds. foreach (var round in rounds) @@ -336,21 +327,27 @@ private IList GetPaymentRounds(IEnumerable block private void GetPoolAccount() { - var result = _daemonClient.GetAccount(_walletConfig.Adress); - _poolAccount = result; + try + { + _poolAccount = _daemonClient.GetAccount(_poolConfig.Wallet.Adress); + } + catch (RpcException e) + { + _logger.Error("Cannot determine pool's central wallet account: {0:l}", e.Message); + } } private bool ValidatePoolAddress() { try { - var result = _daemonClient.ValidateAddress(_walletConfig.Adress); + var result = _daemonClient.ValidateAddress(_poolConfig.Wallet.Adress); // make sure the pool central wallet address is valid and belongs to the daemon we are connected to. if (result.IsValid && result.IsMine) return true; - _logger.Error("Halted as daemon we are connected to does not own the pool address: {0:l}.",_walletConfig.Adress); + _logger.Error("Halted as daemon we are connected to does not own the pool address: {0:l}.",_poolConfig.Wallet.Adress); return false; } catch (RpcException e) diff --git a/src/CoiniumServ/Payments/PaymentRound.cs b/src/CoiniumServ/Payments/PaymentRound.cs index eb08f1d04..a1acab547 100644 --- a/src/CoiniumServ/Payments/PaymentRound.cs +++ b/src/CoiniumServ/Payments/PaymentRound.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; using CoiniumServ.Persistance.Blocks; diff --git a/src/CoiniumServ/Payments/RewardsConfig.cs b/src/CoiniumServ/Payments/RewardsConfig.cs index 111fdf64d..1c839a112 100644 --- a/src/CoiniumServ/Payments/RewardsConfig.cs +++ b/src/CoiniumServ/Payments/RewardsConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections; using System.Collections.Generic; diff --git a/src/CoiniumServ/Payments/WalletConfig.cs b/src/CoiniumServ/Payments/WalletConfig.cs index fc03bae11..46e851916 100644 --- a/src/CoiniumServ/Payments/WalletConfig.cs +++ b/src/CoiniumServ/Payments/WalletConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Payments/WorkerBalance.cs b/src/CoiniumServ/Payments/WorkerBalance.cs index 81375565d..3d39c8241 100644 --- a/src/CoiniumServ/Payments/WorkerBalance.cs +++ b/src/CoiniumServ/Payments/WorkerBalance.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Payments diff --git a/src/CoiniumServ/Persistance/Blocks/IPersistedBlock.cs b/src/CoiniumServ/Persistance/Blocks/IPersistedBlock.cs index 994357d76..a7b38a6e7 100644 --- a/src/CoiniumServ/Persistance/Blocks/IPersistedBlock.cs +++ b/src/CoiniumServ/Persistance/Blocks/IPersistedBlock.cs @@ -20,19 +20,30 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; namespace CoiniumServ.Persistance.Blocks { + [JsonObject(MemberSerialization.OptIn)] public interface IPersistedBlock { + [JsonProperty("height")] UInt32 Height { get; } + [JsonProperty("status")] + [JsonConverter(typeof(StringEnumConverter))] BlockStatus Status { get; set; } + [JsonProperty("blockHash")] string BlockHash { get; } + [JsonProperty("txHash")] string TransactionHash { get; } + [JsonProperty("amount")] decimal Amount { get; } decimal Reward { get; } + [JsonProperty("time")] + DateTime Time { get; } + bool IsPending { get; } void SetReward(decimal reward); diff --git a/src/CoiniumServ/Persistance/Blocks/PersistedBlock.cs b/src/CoiniumServ/Persistance/Blocks/PersistedBlock.cs index 26ff34b1c..e59555451 100644 --- a/src/CoiniumServ/Persistance/Blocks/PersistedBlock.cs +++ b/src/CoiniumServ/Persistance/Blocks/PersistedBlock.cs @@ -21,7 +21,9 @@ // #endregion +using System; using System.Diagnostics; +using CoiniumServ.Utils.Helpers.Time; namespace CoiniumServ.Persistance.Blocks { @@ -40,15 +42,43 @@ public class PersistedBlock:IPersistedBlock public decimal Reward { get; private set; } + public DateTime Time { get; private set; } + public bool IsPending { get { return Status != BlockStatus.Orphaned && Status != BlockStatus.Confirmed; } } - public PersistedBlock(BlockStatus status, uint height, string blockHash, string transactionHash, decimal amount) + public PersistedBlock(Int32 height, Boolean orphaned, Boolean confirmed, String blockHash, String txHash, Decimal amount, DateTime time) { - Status = status; - Height = height; + // used by hybrid storage layer. + + // determine the block status + if(orphaned) + Status = BlockStatus.Orphaned; + else if(confirmed) + Status = BlockStatus.Confirmed; + else + Status = BlockStatus.Pending; + + Height = (uint)height; BlockHash = blockHash; - TransactionHash = transactionHash; + TransactionHash = txHash; Amount = amount; + Time = time; + } + + public PersistedBlock(UInt32 height, String blockhash, Double amount, Int32 confirmations, Int32 time) + { + // used by mpos storage layer. + + // determine the block status + if (confirmations == -1) + Status = BlockStatus.Orphaned; + else + Status = confirmations > 120 ? BlockStatus.Confirmed : BlockStatus.Pending; + + Height = height; + BlockHash = blockhash; + Amount = (decimal)amount; + Time = time.UnixTimeToDateTime(); } public void SetReward(decimal reward) diff --git a/src/CoiniumServ/Persistance/IStorageConfig.cs b/src/CoiniumServ/Persistance/IStorageConfig.cs index 6b0610b92..bacf59666 100644 --- a/src/CoiniumServ/Persistance/IStorageConfig.cs +++ b/src/CoiniumServ/Persistance/IStorageConfig.cs @@ -20,12 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; +using CoiniumServ.Persistance.Layers; namespace CoiniumServ.Persistance { - public interface IStorageConfig:IConfig + public interface IStorageConfig : IConfig { + IStorageLayerConfig Layer { get; } } } diff --git a/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayer.cs b/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayer.cs new file mode 100644 index 000000000..2616dcb90 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayer.cs @@ -0,0 +1,117 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System.Collections.Generic; +using CoiniumServ.Miners; +using CoiniumServ.Payments; +using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Server.Mining.Stratum; +using CoiniumServ.Shares; + +namespace CoiniumServ.Persistance.Layers.Empty +{ + public class EmptyStorageLayer : IStorageLayer + { + public bool IsEnabled { get; private set; } + public bool SupportsShareStorage { get { return false; } } + public bool SupportsBlockStorage { get { return false; } } + public bool SupportsPaymentsStorage { get { return false; } } + + public void AddShare(IShare share) + { + return; // just skip. + } + + public void RemoveShares(IPaymentRound round) + { + return; // just skip. + } + + public void MoveShares(IShare share) + { + return; // just skip. + } + + public void MoveSharesToCurrentRound(IPaymentRound round) + { + return; // just skip. + } + + public Dictionary GetCurrentShares() + { + return new Dictionary(); // return an empty dictionary. + } + + public Dictionary> GetShares(IList rounds) + { + return new Dictionary>(); // return an empty dictionary. + } + + public void AddBlock(IShare share) + { + return; // just skip. + } + + public void UpdateBlock(IPaymentRound round) + { + return; // just skip. + } + + public IDictionary GetTotalBlocks() + { + return new Dictionary(); // return an empty dictionary. + } + + public IEnumerable GetBlocks() + { + return new List(); // return an empty list. + } + + public IEnumerable GetBlocks(BlockStatus status) + { + return new List(); // return an empty list. + } + + public Dictionary GetPreviousBalances() + { + return new Dictionary(); // return an empty dictionary. + } + + public void SetBalances(IList workerBalances) + { + return; + } + + public bool Authenticate(IMiner miner) + { + // empty storage layer is only used when no valid storage-layer configuration is available. + // just authenticate all requests as basically we can't validate nor pay miners actually. + return true; + } + + public void UpdateDifficulty(IStratumMiner miner) + { + // as we don't have an actual persistance layer, we can't write difficulty update information. + return; + } + } +} diff --git a/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayerConfig.cs b/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayerConfig.cs new file mode 100644 index 000000000..e8cfd6319 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Empty/EmptyStorageLayerConfig.cs @@ -0,0 +1,45 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System.Collections.Generic; +using CoiniumServ.Persistance.Providers; + +namespace CoiniumServ.Persistance.Layers.Empty +{ + public class EmptyStorageLayerConfig:IStorageLayerConfig + { + public bool Valid { get; private set; } + public bool Enabled { get; private set; } + public IList Providers { get; private set; } + + public static EmptyStorageLayerConfig Empty = new EmptyStorageLayerConfig(); + + public EmptyStorageLayerConfig() + { + Enabled = true; + + Providers = new List(); + + Valid = true; + } + } +} diff --git a/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayer.cs b/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayer.cs new file mode 100644 index 000000000..e8b3e2ab9 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayer.cs @@ -0,0 +1,459 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using CoiniumServ.Daemon; +using CoiniumServ.Daemon.Exceptions; +using CoiniumServ.Miners; +using CoiniumServ.Payments; +using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; +using CoiniumServ.Persistance.Providers.Redis; +using CoiniumServ.Pools; +using CoiniumServ.Server.Mining.Stratum; +using CoiniumServ.Shares; +using CoiniumServ.Utils.Extensions; +using CoiniumServ.Utils.Helpers.Time; +using Dapper; +using MySql.Data.MySqlClient; +using Serilog; + +namespace CoiniumServ.Persistance.Layers.Hybrid +{ + public class HybridStorageLayer : IStorageLayer + { + public bool IsEnabled { get; private set; } + public bool SupportsShareStorage { get { return true; } } + public bool SupportsBlockStorage { get { return true; } } + public bool SupportsPaymentsStorage { get { return true; } } + + private readonly IDaemonClient _daemonClient; + + private readonly ILogger _logger; + + private readonly IRedisProvider _redisProvider; + + private readonly IMySqlProvider _mySqlProvider; + + private readonly string _coin; + + public HybridStorageLayer(IEnumerable providers, IDaemonClient daemonClient, IPoolConfig poolConfig) + { + _daemonClient = daemonClient; + _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); + _coin = poolConfig.Coin.Name.ToLower(); // pool's associated coin name. + + // try loading providers. + try + { + foreach (var provider in providers) + { + if (provider is IRedisProvider) + _redisProvider = (IRedisProvider) provider; + else if (provider is IMySqlProvider) + _mySqlProvider = (IMySqlProvider) provider; + } + + IsEnabled = (_redisProvider != null && _mySqlProvider != null); + } + catch (Exception e) + { + _logger.Error("Error initializing hybrid storage layer; {0:l}", e.Message); + } + } + + public void AddShare(IShare share) + { + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return; + + //_client.StartPipe(); // batch the commands. + + // add the share to round + var currentKey = string.Format("{0}:shares:round:current", _coin); + _redisProvider.Client.HIncrByFloat(currentKey, share.Miner.Username, share.Difficulty); + + // increment shares stats. + var statsKey = string.Format("{0}:stats", _coin); + _redisProvider.Client.HIncrBy(statsKey, share.IsValid ? "validShares" : "invalidShares", 1); + + // add to hashrate + if (share.IsValid) + { + var hashrateKey = string.Format("{0}:hashrate", _coin); + var entry = string.Format("{0}:{1}", share.Difficulty, share.Miner.Username); + _redisProvider.Client.ZAdd(hashrateKey, Tuple.Create(TimeHelpers.NowInUnixTime(), entry)); + } + + //_client.EndPipe(); // execute the batch commands. + } + catch (Exception e) + { + _logger.Error("An exception occured while comitting share: {0:l}", e.Message); + } + } + + public void RemoveShares(IPaymentRound round) + { + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return; + + var roundKey = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); + + _redisProvider.Client.Del(roundKey); // delete the associated shares. + } + catch (Exception e) + { + _logger.Error("An exception occured while deleting shares: {0:l}", e.Message); + } + } + + public void MoveShares(IShare share) + { + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return; + + if (!share.IsBlockAccepted) + return; + + // rename round. + var currentKey = string.Format("{0}:shares:round:current", _coin); + var roundKey = string.Format("{0}:shares:round:{1}", _coin, share.Height); + _redisProvider.Client.Rename(currentKey, roundKey); + } + catch (Exception e) + { + _logger.Error("An exception occured while moving shares for new block: {0:l}", e.Message); + } + } + + public void MoveSharesToCurrentRound(IPaymentRound round) + { + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return; + + if (round.Block.Status == BlockStatus.Confirmed || round.Block.Status == BlockStatus.Pending) + return; + + var currentRound = string.Format("{0}:shares:round:current", _coin); // current round key. + var roundShares = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); // rounds shares key. + + //_client.StartPipeTransaction(); // batch the commands as atomic. + + // add shares to current round again. + foreach (var pair in round.Shares) + { + _redisProvider.Client.HIncrByFloat(currentRound, pair.Key, pair.Value); + } + + _redisProvider.Client.Del(roundShares); // delete the associated shares. + + //_client.EndPipe(); // execute the batch commands. + } + catch (Exception e) + { + _logger.Error("An exception occured while moving shares: {0:l}", e.Message); + } + } + + public Dictionary GetCurrentShares() + { + var shares = new Dictionary(); + + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return shares; + + var key = string.Format("{0}:shares:round:{1}", _coin, "current"); + var hashes = _redisProvider.Client.HGetAll(key); + + foreach (var hash in hashes) + { + shares.Add(hash.Key, double.Parse(hash.Value, CultureInfo.InvariantCulture)); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting shares for current round: {0:l}", e.Message); + } + + return shares; + } + + public Dictionary> GetShares(IList rounds) + { + var sharesForRounds = new Dictionary>(); // dictionary of block-height <-> shares. + + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return sharesForRounds; + + foreach (var round in rounds) + { + var roundKey = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); + var hashes = _redisProvider.Client.HGetAll(roundKey); + + var shares = hashes.ToDictionary(x => x.Key, x => double.Parse(x.Value, CultureInfo.InvariantCulture)); + sharesForRounds.Add(round.Block.Height, shares); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting shares for round: {0:l}", e.Message); + } + + return sharesForRounds; + } + + public void AddBlock(IShare share) + { + try + { + if (!IsEnabled) + return; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + connection.Execute( + @"insert blocks(height, blockHash, txHash, amount, time) values (@height, @blockHash, @txHash, @amount, @time)", + new + { + height = share.Block.Height, + blockHash = share.BlockHash.ToHexString(), + txHash = share.Block.Tx.First(), + amount = share.GenerationTransaction.TotalAmount, + time = share.Block.Time.UnixTimeToDateTime() + }); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while adding block; {0:l}", e.Message); + } + } + + public void UpdateBlock(IPaymentRound round) + { + try + { + if (!IsEnabled) + return; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + connection.Execute( + @"update blocks set orphaned = @orphaned, confirmed = @confirmed where height = @height", + new + { + orphaned = round.Block.Status == BlockStatus.Orphaned, + confirmed = round.Block.Status == BlockStatus.Confirmed, + height = round.Block.Status + }); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while updating block; {0:l}", e.Message); + } + } + + public IDictionary GetTotalBlocks() + { + var blocks = new Dictionary { { "total", 0 }, { "pending", 0 }, { "orphaned", 0 }, { "confirmed", 0 } }; + + try + { + if (!IsEnabled) + return blocks; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var result = connection.Query(@"select count(*), + (select count(*) from blocks where orphaned = false and confirmed = false) as pending, + (select count(*) from blocks where orphaned = true) as orphaned, + (select count(*) from blocks where confirmed = true) as confirmed + from blocks"); + + var data = result.First(); + blocks["pending"] = (int) data.pending; + blocks["orphaned"] = (int) data.orphaned; + blocks["confirmed"] = (int) data.confirmed; + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting block totals: {0:l}", e.Message); + } + + return blocks; + } + + public IEnumerable GetBlocks() + { + var blocks = new List(); + + try + { + if (!IsEnabled) + return blocks; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var results = connection.Query( + "select height, orphaned, confirmed, blockHash, txHash, amount, time from blocks order by height DESC LIMIT 20"); + + blocks.AddRange(results); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting blocks: {0:l}", e.Message); + } + + return blocks; + } + + public IEnumerable GetBlocks(BlockStatus status) + { + var blocks = new List(); + + try + { + if (!IsEnabled) + return blocks; + + string filter = string.Empty; + + switch (status) + { + case BlockStatus.Pending: + filter = "orphaned = false and confirmed = false"; + break; + case BlockStatus.Orphaned: + filter = "orphaned = true"; + break; + case BlockStatus.Confirmed: + filter = "confirmed = true"; + break; + } + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var results = connection.Query(string.Format( + "select height, orphaned, confirmed, blockHash, txHash, amount, time from blocks where {0} order by height DESC LIMIT 20", + filter)); + + blocks.AddRange(results); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting blocks: {0:l} blocks: {1:l}", status.ToString().ToLower(), e.Message); + } + + return blocks; + } + + public Dictionary GetPreviousBalances() + { + var previousBalances = new Dictionary(); + + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return previousBalances; + + var key = string.Format("{0}:balances", _coin); + var hashes = _redisProvider.Client.HGetAll(key); + previousBalances = hashes.ToDictionary(x => x.Key, x => double.Parse(x.Value, CultureInfo.InvariantCulture)); + } + catch (Exception e) + { + _logger.Error("An exception occured while getting previous balances: {0:l}", e.Message); + } + + return previousBalances; + } + + public void SetBalances(IList workerBalances) + { + try + { + if (!IsEnabled || !_redisProvider.IsConnected) + return; + + var balancesKey = string.Format("{0}:balances", _coin); + + foreach (var workerBalance in workerBalances) + { + //_client.StartPipeTransaction(); // batch the commands as atomic. + + _redisProvider.Client.HDel(balancesKey, workerBalance.Worker); // first delete the existing key. + + if (!workerBalance.Paid) // if outstanding balance exists, commit it. + _redisProvider.Client.HIncrByFloat(balancesKey, workerBalance.Worker, (double)workerBalance.Balance); // increment the value. + + //_client.EndPipe(); // execute the batch commands. + } + } + catch (Exception e) + { + _logger.Error("An exception occured while setting remaining balance: {0:l}", e.Message); + } + } + + public bool Authenticate(IMiner miner) + { + // within current implementation of hybrid storage layer, we don't have users registered to a pool but they + // just mine with supplying a valid coin wallet address as username. So we just need to make sure the username + // is valid address against the coin network. + try + { + return _daemonClient.ValidateAddress(miner.Username).IsValid; // if so validate it against coin daemon as an address. + } + catch (RpcException) + { + return false; + } + } + + public void UpdateDifficulty(IStratumMiner miner) + { + // with-in our current hybrid-storage-layer, we don't need to write difficulty to persistance layer. + return; + } + } +} diff --git a/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayerConfig.cs b/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayerConfig.cs new file mode 100644 index 000000000..57082b97b --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Hybrid/HybridStorageLayerConfig.cs @@ -0,0 +1,61 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; +using CoiniumServ.Persistance.Providers.Redis; +using Serilog; + +namespace CoiniumServ.Persistance.Layers.Hybrid +{ + public class HybridStorageLayerConfig : IStorageLayerConfig + { + public bool Valid { get; private set; } + public bool Enabled { get; private set; } + public IList Providers { get; private set; } + + public HybridStorageLayerConfig(dynamic config) + { + try + { + Enabled = config.enabled; + + Providers = new List + { + new MySqlProviderConfig(config.mysql), + new RedisProviderConfig(config.redis) + }; + + // make sure all supplied provider configs are valid + Valid = Providers.All(provider => provider.Valid); + } + catch (Exception e) + { + Valid = false; + Log.Logger.ForContext().Error(e, "Error loading hybrid storage layer configuration"); + } + } + } +} diff --git a/src/CoiniumServ/Persistance/Redis/IRedis.cs b/src/CoiniumServ/Persistance/Layers/Hybrid/IMigrationManager.cs similarity index 91% rename from src/CoiniumServ/Persistance/Redis/IRedis.cs rename to src/CoiniumServ/Persistance/Layers/Hybrid/IMigrationManager.cs index f0e51f794..fa670815f 100644 --- a/src/CoiniumServ/Persistance/Redis/IRedis.cs +++ b/src/CoiniumServ/Persistance/Layers/Hybrid/IMigrationManager.cs @@ -21,10 +21,9 @@ // #endregion -namespace CoiniumServ.Persistance.Redis +namespace CoiniumServ.Persistance.Layers.Hybrid { - public interface IRedis + public interface IMigrationManager { - bool IsConnected { get; } } } diff --git a/src/CoiniumServ/Persistance/Layers/Hybrid/MigrationManager.cs b/src/CoiniumServ/Persistance/Layers/Hybrid/MigrationManager.cs new file mode 100644 index 000000000..c3d1984e5 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Hybrid/MigrationManager.cs @@ -0,0 +1,76 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion + +using System.Reflection; +using CoiniumServ.Persistance.Providers.MySql; +using CoiniumServ.Pools; +using FluentMigrator; +using FluentMigrator.Runner; +using FluentMigrator.Runner.Announcers; +using FluentMigrator.Runner.Initialization; +using Serilog; + +namespace CoiniumServ.Persistance.Layers.Hybrid +{ + public class MigrationManager:IMigrationManager + { + private readonly IMySqlProvider _provider; + + private readonly ILogger _logger; + + public MigrationManager(IMySqlProvider provider, IPoolConfig poolConfig) + { + _provider = provider; + _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); + + Check(); + } + + private void Check() + { + var announcer = new TextWriterAnnouncer(WriteLog); + var assembly = Assembly.GetExecutingAssembly(); + var migrationContext = new RunnerContext(announcer); + + var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 }; + var factory = new FluentMigrator.Runner.Processors.MySql.MySqlProcessorFactory(); + var processor = factory.Create(_provider.ConnectionString, announcer, options); + var runner = new MigrationRunner(assembly, migrationContext, processor); + + runner.MigrateUp(true); + } + + private void WriteLog(string s) + { + if (!string.IsNullOrWhiteSpace(s)) // filter out empty lines + _logger.Debug(s); + } + } + + public class MigrationOptions : IMigrationProcessorOptions + { + public bool PreviewOnly { get; set; } + public string ProviderSwitches { get; set; } + public int Timeout { get; set; } + } +} diff --git a/src/CoiniumServ/Statistics/LatestBlocks.cs b/src/CoiniumServ/Persistance/Layers/Hybrid/Migrations/M001CreateBlocksTable.cs similarity index 54% rename from src/CoiniumServ/Statistics/LatestBlocks.cs rename to src/CoiniumServ/Persistance/Layers/Hybrid/Migrations/M001CreateBlocksTable.cs index 1741b12cf..f2df9d47c 100644 --- a/src/CoiniumServ/Statistics/LatestBlocks.cs +++ b/src/CoiniumServ/Persistance/Layers/Hybrid/Migrations/M001CreateBlocksTable.cs @@ -21,39 +21,29 @@ // #endregion -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using CoiniumServ.Persistance; -using CoiniumServ.Persistance.Blocks; +using FluentMigrator; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Layers.Hybrid.Migrations { - public class LatestBlocks:ILatestBlocks + [Migration(20140901)] + public class M001CreateBlocksTable : Migration { - private IEnumerable _blocks; - - private readonly IStorage _storage; - - public LatestBlocks(IStorage storage) - { - _storage = storage; - } - - public IEnumerator GetEnumerator() - { - return _blocks.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() + public override void Up() { - return GetEnumerator(); + Create.Table("blocks") + .WithColumn("id").AsInt32().NotNullable().PrimaryKey().Identity() + .WithColumn("height").AsInt32().NotNullable() + .WithColumn("orphaned").AsBoolean().NotNullable().WithDefaultValue(false) + .WithColumn("confirmed").AsBoolean().NotNullable().WithDefaultValue(false) + .WithColumn("blockHash").AsString(65).NotNullable() + .WithColumn("txHash").AsString(65).NotNullable() + .WithColumn("amount").AsDecimal().NotNullable() + .WithColumn("time").AsDateTime().NotNullable(); } - public void Recache(object state) + public override void Down() { - // read latest blocks - _blocks = _storage.GetAllBlocks().OrderByDescending(x => x.Key).Take(20).Select(item => item.Value).ToList(); + Delete.Table("blocks"); } } } diff --git a/src/CoiniumServ/Persistance/IStorage.cs b/src/CoiniumServ/Persistance/Layers/IStorageLayer.cs similarity index 61% rename from src/CoiniumServ/Persistance/IStorage.cs rename to src/CoiniumServ/Persistance/Layers/IStorageLayer.cs index 23e749e8a..cc71736e5 100644 --- a/src/CoiniumServ/Persistance/IStorage.cs +++ b/src/CoiniumServ/Persistance/Layers/IStorageLayer.cs @@ -20,45 +20,70 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; +using CoiniumServ.Miners; using CoiniumServ.Payments; using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Shares; -namespace CoiniumServ.Persistance +namespace CoiniumServ.Persistance.Layers { - public interface IStorage + public interface IStorageLayer { + bool IsEnabled { get; } - void AddShare(IShare share); + #region share storage - void AddBlock(IShare share); + bool SupportsShareStorage { get; } - void SetRemainingBalances(IList workerBalances); + void AddShare(IShare share); - void DeleteShares(IPaymentRound round); + void RemoveShares(IPaymentRound round); + + void MoveShares(IShare share); void MoveSharesToCurrentRound(IPaymentRound round); - void MoveBlock(IPaymentRound round); + Dictionary GetCurrentShares(); + + Dictionary> GetShares(IList rounds); - IDictionary GetBlockCounts(); + #endregion - void DeleteExpiredHashrateData(int until); + #region block storage - IDictionary GetHashrateData(int since); + bool SupportsBlockStorage { get; } + + void AddBlock(IShare share); + void UpdateBlock(IPaymentRound round); + + IDictionary GetTotalBlocks(); + + IEnumerable GetBlocks(); IEnumerable GetBlocks(BlockStatus status); - IDictionary GetAllBlocks(); + #endregion + + #region user storage + + bool Authenticate(IMiner miner); - Dictionary GetSharesForCurrentRound(); + void UpdateDifficulty(IStratumMiner miner); - Dictionary> GetSharesForRounds(IList rounds); + #endregion + + #region payments storage + + bool SupportsPaymentsStorage { get; } Dictionary GetPreviousBalances(); + + void SetBalances(IList workerBalances); + + #endregion } } diff --git a/src/CoiniumServ/Statistics/ILatestBlocks.cs b/src/CoiniumServ/Persistance/Layers/IStorageLayerConfig.cs similarity index 80% rename from src/CoiniumServ/Statistics/ILatestBlocks.cs rename to src/CoiniumServ/Persistance/Layers/IStorageLayerConfig.cs index 7aef93770..f68cfa913 100644 --- a/src/CoiniumServ/Statistics/ILatestBlocks.cs +++ b/src/CoiniumServ/Persistance/Layers/IStorageLayerConfig.cs @@ -20,13 +20,16 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; -using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Configuration; +using CoiniumServ.Persistance.Providers; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Layers { - public interface ILatestBlocks: IEnumerable, IStatisticsProvider + public interface IStorageLayerConfig : IConfig { + bool Enabled { get; } + + IList Providers { get; } } } diff --git a/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayer.cs b/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayer.cs new file mode 100644 index 000000000..1055c5170 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayer.cs @@ -0,0 +1,318 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using CoiniumServ.Miners; +using CoiniumServ.Payments; +using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; +using CoiniumServ.Pools; +using CoiniumServ.Server.Mining.Stratum; +using CoiniumServ.Server.Mining.Stratum.Sockets; +using CoiniumServ.Shares; +using CoiniumServ.Utils.Extensions; +using Dapper; +using MySql.Data.MySqlClient; +using Serilog; + +namespace CoiniumServ.Persistance.Layers.Mpos +{ + public class MposStorageLayer : IStorageLayer + { + public bool IsEnabled { get; private set; } + public bool SupportsShareStorage { get { return true; } } + public bool SupportsBlockStorage { get { return true; } } + public bool SupportsPaymentsStorage { get { return true; } } + + private readonly IMySqlProvider _mySqlProvider; + + private readonly ILogger _logger; + + public MposStorageLayer(IEnumerable providers, PoolConfig poolConfig) + { + _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); + + foreach (var provider in providers) + { + if (provider is IMySqlProvider) + _mySqlProvider = (IMySqlProvider) provider; + } + } + + public void AddShare(IShare share) + { + try + { + if (!IsEnabled) + return; + + var ourResult = share.IsValid ? 'Y' : 'N'; + var upstreamResult = share.IsBlockCandidate ? 'Y' : 'N'; + + object errorReason; + if (share.Error != ShareError.None) + errorReason = share.Error; + else + errorReason = null; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + connection.Execute( + @"insert shares(rem_host, username, our_result, upstream_result, reason, solution, difficulty,time) + values (@rem_host, @username, @our_result, @upstream_result, @reason, @solution, @difficulty, @time)", + new + { + rem_host = ((IClient) share.Miner).Connection.RemoteEndPoint.Address.ToString(), + username = share.Miner.Username, + our_result = ourResult, + upstream_result = upstreamResult, + reason = errorReason, + solution = share.BlockHash.ToHexString(), + difficulty = share.Difficulty, // should we consider mpos difficulty multiplier here? + time = DateTime.Now + }); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while comitting share; {0:l}", e.Message); + } + } + + public void RemoveShares(IPaymentRound round) + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public void MoveShares(IShare share) + { + // The function is not supported as MPOS mode doesn't require the functionality. + } + + public void MoveSharesToCurrentRound(IPaymentRound round) + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public Dictionary GetCurrentShares() + { + var shares = new Dictionary(); + + try + { + if (!IsEnabled) + return shares; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var results = connection.Query( + @"select username, sum(difficulty) as diff from shares group by username"); + + foreach (var row in results) + { + shares.Add(row.username, row.diff); + } + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting shares for current round: {0:l}", e.Message); + } + + return shares; + } + + public Dictionary> GetShares(IList rounds) + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public void AddBlock(IShare share) + { + // Blocks are handled by MPOS by itself, we don't need to persist found block data. + } + + public void UpdateBlock(IPaymentRound round) + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public IDictionary GetTotalBlocks() + { + var blocks = new Dictionary {{"total", 0}, {"pending", 0}, {"orphaned", 0}, {"confirmed", 0}}; + + try + { + if (!IsEnabled) + return blocks; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var result = connection.Query(@"select count(*), + (select count(*) from blocks where confirmations >= 0 and confirmations < 120) as pending, + (select count(*) from blocks where confirmations < 0) as orphaned, + (select count(*) from blocks where confirmations >= 120) as confirmed + from blocks"); + + var data = result.First(); + blocks["pending"] = (int) data.pending; + blocks["orphaned"] = (int) data.orphaned; + blocks["confirmed"] = (int) data.confirmed; + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting block totals: {0:l}", e.Message); + } + + return blocks; + } + + public IEnumerable GetBlocks() + { + var blocks = new List(); + + try + { + if (!IsEnabled) + return blocks; + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var results = connection.Query( + "select height, blockhash, amount, confirmations, time from blocks order by height DESC LIMIT 20"); + + blocks.AddRange(results); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting blocks: {0:l}", e.Message); + } + + return blocks; + } + + public IEnumerable GetBlocks(BlockStatus status) + { + var blocks = new List(); + + try + { + if (!IsEnabled) + return blocks; + + string filter = string.Empty; + + switch (status) + { + case BlockStatus.Pending: + filter = "confirmations >= 0 and confirmations < 120"; + break; + case BlockStatus.Orphaned: + filter = "confirmations = -1"; + break; + case BlockStatus.Confirmed: + filter = "confirmations >= 120"; + break; + } + + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + var results = connection.Query(string.Format( + "select height, blockhash, amount, confirmations, time from blocks where {0} order by height DESC LIMIT 20", + filter)); + + blocks.AddRange(results); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting blocks: {0:l} blocks: {1:l}", status.ToString().ToLower(), e.Message); + } + + return blocks; + } + + public Dictionary GetPreviousBalances() + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public void SetBalances(IList workerBalances) + { + // The function is not supported as it's only required by payments processor. In MPOS mode payments processor should be disabled. + throw new NotImplementedException(); + } + + public bool Authenticate(IMiner miner) + { + try + { + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + // query the username against mpos pool_worker table. + var result = connection.Query( + "SELECT password FROM pool_worker where username = @username", + new {username = miner.Username}).FirstOrDefault(); + + // if matching record exists for given miner username, then authenticate the miner. + // note: we don't check for password on purpose. + return result != null; + } + } + catch (Exception e) + { + _logger.Error("An exception occured while reading pool_worker table; {0:l}", e.Message); + return false; + } + } + + public void UpdateDifficulty(IStratumMiner miner) + { + try + { + using (var connection = new MySqlConnection(_mySqlProvider.ConnectionString)) + { + connection.Execute( + "update pool_worker set difficulty = @difficulty where username = @username", new + { + difficulty = miner.Difficulty, + username = miner.Username + }); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while updating difficulty for miner; {0:l}", e.Message); + } + } + } +} diff --git a/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayerConfig.cs b/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayerConfig.cs new file mode 100644 index 000000000..3b30f984f --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/Mpos/MposStorageLayerConfig.cs @@ -0,0 +1,59 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; +using Serilog; + +namespace CoiniumServ.Persistance.Layers.Mpos +{ + public class MposStorageLayerConfig:IStorageLayerConfig + { + public bool Valid { get; private set; } + public bool Enabled { get; private set; } + public IList Providers { get; private set; } + + public MposStorageLayerConfig(dynamic config) + { + try + { + Enabled = config.enabled; + + Providers = new List + { + new MySqlProviderConfig(config.mysql) + }; + + // make sure all supplied provider configs are valid + Valid = Providers.All(provider => provider.Valid); + } + catch (Exception e) + { + Valid = false; + Log.Logger.ForContext().Error(e, "Error loading mpos storage layer configuration"); + } + } + } +} diff --git a/src/CoiniumServ/Persistance/Layers/StorageLayers.cs b/src/CoiniumServ/Persistance/Layers/StorageLayers.cs new file mode 100644 index 000000000..059329dd8 --- /dev/null +++ b/src/CoiniumServ/Persistance/Layers/StorageLayers.cs @@ -0,0 +1,31 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +namespace CoiniumServ.Persistance.Layers +{ + public static class StorageLayers + { + public const string Mpos = "mpos"; + public const string Hybrid = "hybrid"; + public const string Empty = "empty"; + } +} diff --git a/src/CoiniumServ/Statistics/IStatisticsProvider.cs b/src/CoiniumServ/Persistance/Providers/IStorageProvider.cs similarity index 89% rename from src/CoiniumServ/Statistics/IStatisticsProvider.cs rename to src/CoiniumServ/Persistance/Providers/IStorageProvider.cs index 3574c405d..e56c41a32 100644 --- a/src/CoiniumServ/Statistics/IStatisticsProvider.cs +++ b/src/CoiniumServ/Persistance/Providers/IStorageProvider.cs @@ -20,10 +20,8 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Providers { - public interface IStatisticsProvider - { - void Recache(object state); - } + public interface IStorageProvider + { } } diff --git a/src/CoiniumServ/Statistics/IJsonResponse.cs b/src/CoiniumServ/Persistance/Providers/IStorageProviderConfig.cs similarity index 88% rename from src/CoiniumServ/Statistics/IJsonResponse.cs rename to src/CoiniumServ/Persistance/Providers/IStorageProviderConfig.cs index eafe9296a..99300223a 100644 --- a/src/CoiniumServ/Statistics/IJsonResponse.cs +++ b/src/CoiniumServ/Persistance/Providers/IStorageProviderConfig.cs @@ -20,13 +20,11 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using CoiniumServ.Configuration; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Providers { - public interface IJsonResponse + public interface IStorageProviderConfig:IConfig { - string Json { get; } - - object GetResponseObject(); } } diff --git a/src/CoiniumServ/Persistance/Providers/MySql/IMySqlProvider.cs b/src/CoiniumServ/Persistance/Providers/MySql/IMySqlProvider.cs new file mode 100644 index 000000000..ba8a4bb33 --- /dev/null +++ b/src/CoiniumServ/Persistance/Providers/MySql/IMySqlProvider.cs @@ -0,0 +1,31 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using MySql.Data.MySqlClient; + +namespace CoiniumServ.Persistance.Providers.MySql +{ + public interface IMySqlProvider : IStorageProvider + { + string ConnectionString { get; } + } +} diff --git a/src/CoiniumServ/Statistics/IPerAlgorithm.cs b/src/CoiniumServ/Persistance/Providers/MySql/IMySqlProviderConfig.cs similarity index 79% rename from src/CoiniumServ/Statistics/IPerAlgorithm.cs rename to src/CoiniumServ/Persistance/Providers/MySql/IMySqlProviderConfig.cs index 8c9a371d4..6bf572217 100644 --- a/src/CoiniumServ/Statistics/IPerAlgorithm.cs +++ b/src/CoiniumServ/Persistance/Providers/MySql/IMySqlProviderConfig.cs @@ -20,21 +20,16 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Providers.MySql { - public interface IPerAlgorithm:IJsonResponse + public interface IMySqlProviderConfig : IStorageProviderConfig { - string Name { get; } - - Int32 WorkerCount { get; } - - UInt64 Hashrate { get; } - - void Reset(); - - void Recache(UInt64 hashrate, int workerCount); + string Host { get; } + Int32 Port { get;} + string Username { get; } + string Password { get; } + string Database { get; } } } diff --git a/src/CoiniumServ/Persistance/Providers/MySql/MySqlProvider.cs b/src/CoiniumServ/Persistance/Providers/MySql/MySqlProvider.cs new file mode 100644 index 000000000..3c2a42e69 --- /dev/null +++ b/src/CoiniumServ/Persistance/Providers/MySql/MySqlProvider.cs @@ -0,0 +1,68 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Data; +using CoiniumServ.Pools; +using MySql.Data.MySqlClient; +using Serilog; + +namespace CoiniumServ.Persistance.Providers.MySql +{ + // TODO: dapper doesn't manage connections life-cyle - check this pattern: http://stackoverflow.com/questions/23023534/managing-connection-with-non-buffered-queries-in-dapper + + public class MySqlProvider : IMySqlProvider + { + public string ConnectionString { get; private set; } + + private readonly IMySqlProviderConfig _config; + + private readonly ILogger _logger; + + public MySqlProvider(IPoolConfig poolConfig, IMySqlProviderConfig config) + { + _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); + + _config = config; + + Initialize(); + } + private void Initialize() + { + try + { + ConnectionString = string.Format("Server={0};Port={1};Uid={2};Password={3};Database={4};", + _config.Host, _config.Port, _config.Username, _config.Password, _config.Database); + + using (var connection = new MySqlConnection(ConnectionString)) + { + connection.Open(); + _logger.Information("Mysql storage initialized: {0:l}:{1}, database: {2:l}.", _config.Host, _config.Port, _config.Database); + } + } + catch (Exception e) + { + _logger.Error("Mysql storage initialization failed: {0:l}:{1}, database: {2:l} - {3:l}", _config.Host, _config.Port, _config.Database, e.Message); + } + } + } +} diff --git a/src/CoiniumServ/Persistance/Providers/MySql/MySqlProviderConfig.cs b/src/CoiniumServ/Persistance/Providers/MySql/MySqlProviderConfig.cs new file mode 100644 index 000000000..3957502cc --- /dev/null +++ b/src/CoiniumServ/Persistance/Providers/MySql/MySqlProviderConfig.cs @@ -0,0 +1,56 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using Serilog; + +namespace CoiniumServ.Persistance.Providers.MySql +{ + public class MySqlProviderConfig : IMySqlProviderConfig + { + public bool Valid { get; private set; } + public string Host { get; private set; } + public int Port { get; private set; } + public string Username { get; private set; } + public string Password { get; private set; } + public string Database { get; private set; } + + public MySqlProviderConfig(dynamic config) + { + try + { + // load the config data. + Host = string.IsNullOrEmpty(config.host) ? "127.0.0.1" : config.host; + Port = config.port == 0 ? 3306 : config.port; + Username = config.user; + Password = config.password; + Database = config.database; + Valid = true; + } + catch (Exception e) + { + Valid = false; + Log.Logger.ForContext().Error(e, "Error loading mysql configuration"); + } + } + } +} diff --git a/src/CoiniumServ/Statistics/IGlobal.cs b/src/CoiniumServ/Persistance/Providers/Redis/IRedisProvider.cs similarity index 84% rename from src/CoiniumServ/Statistics/IGlobal.cs rename to src/CoiniumServ/Persistance/Providers/Redis/IRedisProvider.cs index 4f13f5369..7e7aeccb9 100644 --- a/src/CoiniumServ/Statistics/IGlobal.cs +++ b/src/CoiniumServ/Persistance/Providers/Redis/IRedisProvider.cs @@ -20,15 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using CSRedis; -using System; - -namespace CoiniumServ.Statistics +namespace CoiniumServ.Persistance.Providers.Redis { - public interface IGlobal: IJsonResponse, IStatisticsProvider + public interface IRedisProvider:IStorageProvider { - UInt64 Hashrate { get; } + bool IsConnected { get; } - Int32 WorkerCount { get; } + RedisClient Client { get; } } } diff --git a/src/CoiniumServ/Persistance/Redis/IRedisConfig.cs b/src/CoiniumServ/Persistance/Providers/Redis/IRedisProviderConfig.cs similarity index 86% rename from src/CoiniumServ/Persistance/Redis/IRedisConfig.cs rename to src/CoiniumServ/Persistance/Providers/Redis/IRedisProviderConfig.cs index 7ce27f23e..f8be56a55 100644 --- a/src/CoiniumServ/Persistance/Redis/IRedisConfig.cs +++ b/src/CoiniumServ/Persistance/Providers/Redis/IRedisProviderConfig.cs @@ -20,15 +20,12 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; -namespace CoiniumServ.Persistance.Redis +namespace CoiniumServ.Persistance.Providers.Redis { - public interface IRedisConfig : IStorageConfig + public interface IRedisProviderConfig:IStorageProviderConfig { - bool Enabled { get; } - /// /// redis host. /// @@ -37,16 +34,16 @@ public interface IRedisConfig : IStorageConfig /// /// redis port. /// - Int32 Port { get; } + Int32 Port { get; } /// /// the password if redis installation requires one. /// - string Password { get; } + string Password { get; } /// /// redis database instance id /// - int DatabaseId { get; } + int DatabaseId { get; } } } diff --git a/src/CoiniumServ/Persistance/Providers/Redis/RedisProvider.cs b/src/CoiniumServ/Persistance/Providers/Redis/RedisProvider.cs new file mode 100644 index 000000000..b24a14d45 --- /dev/null +++ b/src/CoiniumServ/Persistance/Providers/Redis/RedisProvider.cs @@ -0,0 +1,113 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Net; +using CoiniumServ.Pools; +using CSRedis; +using Serilog; + +namespace CoiniumServ.Persistance.Providers.Redis +{ + public class RedisProvider : IRedisProvider + { + public bool IsConnected { get { return Client.IsConnected; } } + + public RedisClient Client { get; private set; } + private readonly Version _requiredMinimumVersion = new Version(2, 6); + + private readonly IRedisProviderConfig _config; + + private readonly ILogger _logger; + + public RedisProvider(IPoolConfig poolConfig, IRedisProviderConfig config) + { + _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); + + _config = config; + + Initialize(); + } + + private void Initialize() + { + try + { + // for mono compatibility, we need to define an endpoint. + var endpoint = new IPEndPoint(IPAddress.Parse(_config.Host), _config.Port); + + // create the connection + Client = new RedisClient(endpoint) + { + ReconnectAttempts = 3, + ReconnectWait = 200 + }; + + // select the database + Client.Select(_config.DatabaseId); + + // authenticate if needed. + if (!string.IsNullOrEmpty(_config.Password)) + Client.Auth(_config.Password); + + // check the version + var version = GetVersion(); + if (version < _requiredMinimumVersion) + throw new Exception(string.Format("You are using redis version {0}, minimum required version is 2.6", version)); + + _logger.Information("Redis storage initialized: {0:l}:{1}, v{2:l}.", _config.Host, _config.Port, version); + } + catch (Exception e) + { + _logger.Error("Redis storage initialization failed: {0:l}:{1} - {2:l}", _config.Host, _config.Port, e.Message); + } + } + + private Version GetVersion() + { + Version version = null; + + try + { + var info = Client.Info("server"); + + var parts = info.Split(new[] { Environment.NewLine }, StringSplitOptions.None); + + foreach (var part in parts) + { + var data = part.Split(':'); + + if (data[0] != "redis_version") + continue; + + version = new Version(data[1]); + } + } + catch (Exception e) + { + _logger.Error("An exception occured while getting version info: {0:l}", e.Message); + } + + return version; + } + } +} diff --git a/src/CoiniumServ/Persistance/Redis/RedisConfig.cs b/src/CoiniumServ/Persistance/Providers/Redis/RedisProviderConfig.cs similarity index 82% rename from src/CoiniumServ/Persistance/Redis/RedisConfig.cs rename to src/CoiniumServ/Persistance/Providers/Redis/RedisProviderConfig.cs index e0a9e714d..cbce41dbb 100644 --- a/src/CoiniumServ/Persistance/Redis/RedisConfig.cs +++ b/src/CoiniumServ/Persistance/Providers/Redis/RedisProviderConfig.cs @@ -20,36 +20,34 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; -namespace CoiniumServ.Persistance.Redis +namespace CoiniumServ.Persistance.Providers.Redis { - public class RedisConfig:IRedisConfig + public class RedisProviderConfig:IRedisProviderConfig { - public bool Enabled { get; private set; } + public bool Valid { get; private set; } public string Host { get; private set; } - public Int32 Port { get; private set; } + public int Port { get; private set; } public string Password { get; private set; } public int DatabaseId { get; private set; } - public bool Valid { get; private set; } - public RedisConfig(dynamic config) + public RedisProviderConfig(dynamic config) { try { // load the config data. - Enabled = config.enabled; Host = string.IsNullOrEmpty(config.host) ? "127.0.0.1" : config.host; Port = config.port == 0 ? 6379 : config.port; Password = config.password; DatabaseId = config.databaseId; + Valid = true; } catch (Exception e) { Valid = false; - Log.Logger.ForContext().Error(e, "Error loading redis configuration"); + Log.Logger.ForContext().Error(e, "Error loading redis configuration"); } } } diff --git a/src/CoiniumServ/Persistance/Storages.cs b/src/CoiniumServ/Persistance/Providers/StorageProviders.cs similarity index 89% rename from src/CoiniumServ/Persistance/Storages.cs rename to src/CoiniumServ/Persistance/Providers/StorageProviders.cs index 6c6bc5023..992df4812 100644 --- a/src/CoiniumServ/Persistance/Storages.cs +++ b/src/CoiniumServ/Persistance/Providers/StorageProviders.cs @@ -20,10 +20,11 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion -namespace CoiniumServ.Persistance +namespace CoiniumServ.Persistance.Providers { - public static class Storages + public static class StorageProviders { public const string Redis = "redis"; + public const string MySql = "mysql"; } } diff --git a/src/CoiniumServ/Persistance/Redis/Redis.cs b/src/CoiniumServ/Persistance/Redis/Redis.cs deleted file mode 100644 index 4884754ed..000000000 --- a/src/CoiniumServ/Persistance/Redis/Redis.cs +++ /dev/null @@ -1,536 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using CoiniumServ.Payments; -using CoiniumServ.Persistance.Blocks; -using CoiniumServ.Pools.Config; -using CoiniumServ.Shares; -using CoiniumServ.Utils.Helpers.Time; -using CoiniumServ.Utils.Extensions; -using CSRedis; -using Serilog; - -namespace CoiniumServ.Persistance.Redis -{ - /// - /// CSRedis based redis client. - /// - public class Redis:IStorage, IRedis - { - public bool IsEnabled { get; private set; } - public bool IsConnected { get { return _client != null && _client.Connected; } } - - private readonly Version _requiredMinimumVersion = new Version(2, 6); - private readonly IRedisConfig _redisConfig; - private readonly IPoolConfig _poolConfig; - - private readonly string _coin; - - private RedisClient _client; - - private readonly ILogger _logger; - - public Redis(PoolConfig poolConfig) - { - _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); - - _poolConfig = poolConfig; // the pool config. - _redisConfig = (IRedisConfig)poolConfig.Storage; // redis config. - _coin = _poolConfig.Coin.Name.ToLower(); // pool's associated coin name. - - IsEnabled = _redisConfig.Enabled; - - if (IsEnabled) - Initialize(); - } - - public void AddShare(IShare share) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - //_client.StartPipe(); // batch the commands. - - // add the share to round - var currentKey = string.Format("{0}:shares:round:current", _coin); - _client.HIncrByFloat(currentKey, share.Miner.Username, share.Difficulty); - - // increment shares stats. - var statsKey = string.Format("{0}:stats", _coin); - _client.HIncrBy(statsKey, share.IsValid ? "validShares" : "invalidShares", 1); - - // add to hashrate - if (share.IsValid) - { - var hashrateKey = string.Format("{0}:hashrate", _coin); - var entry = string.Format("{0}:{1}", share.Difficulty, share.Miner.Username); - _client.ZAdd(hashrateKey, Tuple.Create(TimeHelpers.NowInUnixTime(), entry)); - } - - //_client.EndPipe(); // execute the batch commands. - } - catch (Exception e) - { - _logger.Error("An exception occured while comitting share: {0:l}", e.Message); - } - } - - public void AddBlock(IShare share) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - //_client.StartPipe(); // batch the commands. - - if (share.IsBlockAccepted) - { - // rename round. - var currentKey = string.Format("{0}:shares:round:current", _coin); - var roundKey = string.Format("{0}:shares:round:{1}", _coin, share.Height); - _client.Rename(currentKey, roundKey); - - // add block to pending. - var pendingKey = string.Format("{0}:blocks:pending", _coin); - var entry = string.Format("{0}:{1}:{2}", share.BlockHash.ToHexString(), share.Block.Tx.First(), share.GenerationTransaction.TotalAmount); // entry format: blockHash:txHash:Amount - _client.ZAdd(pendingKey, Tuple.Create(share.Block.Height, entry)); - } - - // increment block stats. - var statsKey = string.Format("{0}:stats", _coin); - _client.HIncrBy(statsKey, share.IsBlockAccepted ? "validBlocks" : "invalidBlocks", 1); - - //_client.EndPipe(); // execute the batch commands. - } - catch (Exception e) - { - _logger.Error("An exception occured while adding block: {0:l}", e.Message); - } - } - - public void SetRemainingBalances(IList workerBalances) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - var balancesKey = string.Format("{0}:balances", _coin); - - foreach (var workerBalance in workerBalances) - { - //_client.StartPipeTransaction(); // batch the commands as atomic. - - _client.HDel(balancesKey, workerBalance.Worker); // first delete the existing key. - - if (!workerBalance.Paid) // if outstanding balance exists, commit it. - _client.HIncrByFloat(balancesKey, workerBalance.Worker, (double) workerBalance.Balance); // increment the value. - - //_client.EndPipe(); // execute the batch commands. - } - } - catch (Exception e) - { - _logger.Error("An exception occured while setting remaining balance: {0:l}", e.Message); - } - } - - public void DeleteShares(IPaymentRound round) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - var roundKey = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); - - _client.Del(roundKey); // delete the associated shares. - } - catch (Exception e) - { - _logger.Error("An exception occured while deleting shares: {0:l}", e.Message); - } - } - - public void MoveSharesToCurrentRound(IPaymentRound round) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - if (round.Block.Status == BlockStatus.Confirmed || round.Block.Status == BlockStatus.Pending) - return; - - var currentRound = string.Format("{0}:shares:round:current", _coin); // current round key. - var roundShares = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); // rounds shares key. - - //_client.StartPipeTransaction(); // batch the commands as atomic. - - // add shares to current round again. - foreach (var pair in round.Shares) - { - _client.HIncrByFloat(currentRound, pair.Key, pair.Value); - } - - _client.Del(roundShares); // delete the associated shares. - - //_client.EndPipe(); // execute the batch commands. - } - catch (Exception e) - { - _logger.Error("An exception occured while moving shares: {0:l}", e.Message); - } - } - - public void MoveBlock(IPaymentRound round) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - if (round.Block.Status == BlockStatus.Pending) - return; - - // re-flag the rounds. - var pendingKey = string.Format("{0}:blocks:pending", _coin); // old key for the round. - var newKey = string.Empty; // new key for the round. - - switch (round.Block.Status) - { - case BlockStatus.Orphaned: - newKey = string.Format("{0}:blocks:orphaned", _coin); - break; - case BlockStatus.Confirmed: - newKey = string.Format("{0}:blocks:confirmed", _coin); - break; - } - - var entry = string.Format("{0}:{1}:{2}", round.Block.BlockHash, round.Block.TransactionHash, round.Block.Amount); // entry format: blockHash:txHash:Amount - - //_client.StartPipeTransaction(); // batch the commands as atomic. - _client.ZRemRangeByScore(pendingKey, round.Block.Height, round.Block.Height); - _client.ZAdd(newKey, Tuple.Create(round.Block.Height, entry)); - //_client.EndPipe(); // execute the batch commands. - } - catch (Exception e) - { - _logger.Error("An exception occured while moving block: {0:l}", e.Message); - } - } - - public IDictionary GetBlockCounts() - { - var blocks = new Dictionary(); - - try - { - if (!IsEnabled || !IsConnected) - return blocks; - - var pendingKey = string.Format("{0}:blocks:pending", _coin); - var confirmedKey = string.Format("{0}:blocks:confirmed", _coin); - var oprhanedKey = string.Format("{0}:blocks:orphaned", _coin); - - //_client.StartPipe(); // batch the commands as atomic. - - blocks["pending"] = (int) _client.ZCard(pendingKey); - blocks["confirmed"] = (int)_client.ZCard(confirmedKey); - blocks["orphaned"] = (int)_client.ZCard(oprhanedKey); - - /*var results = _client.EndPipe(); // execute the batch commands. - - blocks["pending"] = Convert.ToInt32(results[0]); - blocks["confirmed"] = Convert.ToInt32(results[1]); - blocks["orphaned"] = Convert.ToInt32(results[2]);*/ - } - catch (Exception e) - { - _logger.Error("An exception occured while getting block counts: {0:l}", e.Message); - } - - return blocks; - } - - public void DeleteExpiredHashrateData(int until) - { - try - { - if (!IsEnabled || !IsConnected) - return; - - var key = string.Format("{0}:hashrate", _coin); - - _client.ZRemRangeByScore(key, double.NegativeInfinity, until); - } - catch (Exception e) - { - _logger.Error("An exception occured while deleting expired hashrate data: {0:l}", e.Message); - } - } - - public IDictionary GetHashrateData(int since) - { - var hashrates = new Dictionary(); - - try - { - if (!IsEnabled || !IsConnected) - return hashrates; - - var key = string.Format("{0}:hashrate", _coin); - - var results = _client.ZRangeByScore(key, since, double.PositiveInfinity); - - foreach (var result in results) - { - var data = result.Split(':'); - var share = double.Parse(data[0].Replace(',', '.'), CultureInfo.InvariantCulture); - var worker = data[1]; - - if (!hashrates.ContainsKey(worker)) - hashrates.Add(worker, 0); - - hashrates[worker] += share; - } - } - catch (Exception e) - { - _logger.Error("An exception occured while getting hashrate data: {0:l}", e.Message); - } - - return hashrates; - } - - public IEnumerable GetBlocks(BlockStatus status) - { - var blocks = new Dictionary(); - - try - { - if (!IsEnabled || !IsConnected) - return blocks.Values.ToList(); - - var key = string.Empty; - - switch (status) - { - case BlockStatus.Pending: - key = string.Format("{0}:blocks:pending", _coin); - break; - case BlockStatus.Orphaned: - key = string.Format("{0}:blocks:orphaned", _coin); - break; - case BlockStatus.Confirmed: - key = string.Format("{0}:blocks:confirmed", _coin); - break; - } - - var results = _client.ZRevRangeByScoreWithScores(key, double.PositiveInfinity, 0, true); - - foreach (var result in results) - { - var item = result.Item1; - var score = result.Item2; - - var data = item.Split(':'); - var blockHash = data[0]; - var transactionHash = data[1]; - var amount = decimal.Parse(data[2]); - - blocks.Add((UInt32)score, new PersistedBlock(status, (UInt32)score, blockHash, transactionHash, amount)); - } - } - catch (Exception e) - { - _logger.Error("An exception occured while getting {0:l} blocks: {1:l}", status.ToString().ToLower(), e.Message); - } - - return blocks.Values.ToList(); - } - - public IDictionary GetAllBlocks() - { - var blocks = new Dictionary(); - - if (!IsEnabled || !IsConnected) - return blocks; - - foreach (var block in GetBlocks(BlockStatus.Confirmed)) - { - blocks.Add(block.Height, block); - } - - foreach (var block in GetBlocks(BlockStatus.Orphaned)) - { - blocks.Add(block.Height, block); - } - - foreach (var block in GetBlocks(BlockStatus.Pending)) - { - blocks.Add(block.Height, block); - } - - return blocks; - } - - public Dictionary GetSharesForCurrentRound() - { - var shares = new Dictionary(); - - try - { - if (!IsEnabled || !IsConnected) - return shares; - - var key = string.Format("{0}:shares:round:{1}", _coin, "current"); - var hashes = _client.HGetAll(key); - - foreach (var hash in hashes) - { - shares.Add(hash.Key, double.Parse(hash.Value, CultureInfo.InvariantCulture)); - } - } - catch (Exception e) - { - _logger.Error("An exception occured while getting shares for current round", e.Message); - } - - return shares; - } - - public Dictionary> GetSharesForRounds(IList rounds) - { - var sharesForRounds = new Dictionary>(); // dictionary of block-height <-> shares. - - try - { - if (!IsEnabled || !IsConnected) - return sharesForRounds; - - foreach (var round in rounds) - { - var roundKey = string.Format("{0}:shares:round:{1}", _coin, round.Block.Height); - var hashes = _client.HGetAll(roundKey); - - var shares = hashes.ToDictionary(x => x.Key, x => double.Parse(x.Value, CultureInfo.InvariantCulture)); - sharesForRounds.Add(round.Block.Height, shares); - } - } - catch (Exception e) - { - _logger.Error("An exception occured while getting shares for round: {0:l}", e.Message); - } - - return sharesForRounds; - } - - public Dictionary GetPreviousBalances() - { - var previousBalances = new Dictionary(); - - try - { - if (!IsEnabled || !IsConnected) - return previousBalances; - - var key = string.Format("{0}:balances", _coin); - var hashes = _client.HGetAll(key); - previousBalances = hashes.ToDictionary(x => x.Key, x => double.Parse(x.Value, CultureInfo.InvariantCulture)); - } - catch (Exception e) - { - _logger.Error("An exception occured while getting previous balances: {0:l}", e.Message); - } - - return previousBalances; - } - - private void Initialize() - { - try - { - // create the connection - _client = new RedisClient(_redisConfig.Host, _redisConfig.Port) - { - ReconnectAttempts = 3, - ReconnectTimeout = 200 - }; - - // select the database - _client.Select(_redisConfig.DatabaseId); - - // authenticate if needed. - if (!string.IsNullOrEmpty(_redisConfig.Password)) - _client.Auth(_redisConfig.Password); - - // check the version - var version = GetVersion(); - if (version < _requiredMinimumVersion) - throw new Exception(string.Format("You are using redis version {0}, minimum required version is 2.6", version)); - - _logger.Information("Storage initialized: {0:l}:{1}, v{2:l}.", _redisConfig.Host, _redisConfig.Port, version); - } - catch (Exception e) - { - _logger.Error("Storage initialization failed: {0:l}:{1} - {2:l}", _redisConfig.Host, _redisConfig.Port, e.Message); - } - } - - private Version GetVersion() - { - Version version = null; - - try - { - var info = _client.Info("server"); - - var parts = info.Split(new[] {Environment.NewLine}, StringSplitOptions.None); - - foreach (var part in parts) - { - var data = part.Split(':'); - - if (data[0] != "redis_version") - continue; - - version = new Version(data[1]); - } - } - catch (Exception e) - { - _logger.Error("An exception occured while getting version info: {0:l}", e.Message); - } - - return version; - } - } -} diff --git a/src/CoiniumServ/Persistance/StorageConfig.cs b/src/CoiniumServ/Persistance/StorageConfig.cs new file mode 100644 index 000000000..20d0b37f5 --- /dev/null +++ b/src/CoiniumServ/Persistance/StorageConfig.cs @@ -0,0 +1,83 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Empty; +using CoiniumServ.Persistance.Layers.Hybrid; +using CoiniumServ.Persistance.Layers.Mpos; +using Serilog; + +namespace CoiniumServ.Persistance +{ + public class StorageConfig:IStorageConfig + { + public bool Valid { get; private set; } + + public IStorageLayerConfig Layer { get; private set; } + + private readonly ILogger _logger; + + public StorageConfig(dynamic config) + { + try + { + _logger = Log.ForContext(); + + // try loading layer configs. + + var layers = new List + { + new HybridStorageLayerConfig(config.hybrid), + new MposStorageLayerConfig(config.mpos) + }; + + var enabledLayers = layers.Count(layer => layer.Enabled && layer.Valid); // find the count of enabled storage layers. + + if (enabledLayers == 0) // make sure we have at least a single enabled layer. + { + _logger.Error("Storage will be not working as no valid storage configuration was found!"); + Layer = EmptyStorageLayerConfig.Empty; + Valid = false; + } + else if (enabledLayers > 1) // we can have either hybrid or mpos layer enabled only at a time. + { + _logger.Error("Storage will be not working as only a single storage configuration can be enabled!"); + Layer = EmptyStorageLayerConfig.Empty; + Valid = false; + } + else // the configuration meets our expectations + { + Layer = layers.First(layer => layer.Enabled && layer.Valid); // set the enabled layer. + Valid = true; + } + } + catch (Exception e) + { + Valid = false; + _logger.Error(e, "Error loading storage configuration"); + } + } + } +} diff --git a/src/CoiniumServ/Pools/BlocksCache.cs b/src/CoiniumServ/Pools/BlocksCache.cs new file mode 100644 index 000000000..16a7ed9ff --- /dev/null +++ b/src/CoiniumServ/Pools/BlocksCache.cs @@ -0,0 +1,112 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Persistance.Layers; +using Newtonsoft.Json; + +namespace CoiniumServ.Pools +{ + public class BlocksCache : IBlocksCache + { + public int Pending { get; private set; } + public int Confirmed { get; private set; } + public int Orphaned { get; private set; } + public int Total { get; private set; } + + public Dictionary Latest { + get { return _storage.ToDictionary(b => b.Height); } + } + + private readonly IList _storage; + + private readonly IStorageLayer _storageLayer; + + public BlocksCache(IStorageLayer storageLayer) + { + _storageLayer = storageLayer; + _storage = new List(); + } + + public IEnumerator GetEnumerator() + { + return _storage.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public IQueryable SearchFor(Expression> predicate) + { + return _storage.AsQueryable().Where(predicate); + } + + public IEnumerable GetAll() + { + return _storage; + } + + public IQueryable GetAllAsQueryable() + { + return _storage.AsQueryable(); + } + + public IReadOnlyCollection GetAllAsReadOnly() + { + return new ReadOnlyCollection(_storage); + } + + public int Count { get { return _storage.Count; } } + + public string ServiceResponse { get; private set; } + + public void Recache() + { + _storage.Clear(); + + // recache blocks. + var blocks = _storageLayer.GetBlocks(); + foreach (var block in blocks) + { + _storage.Add(block); + } + + // recache block counts. + var blockCounts = _storageLayer.GetTotalBlocks(); + Pending = blockCounts.ContainsKey("pending") ? blockCounts["pending"] : 0; + Confirmed = blockCounts.ContainsKey("confirmed") ? blockCounts["confirmed"] : 0; + Orphaned = blockCounts.ContainsKey("orphaned") ? blockCounts["orphaned"] : 0; + Total = Pending + Confirmed + Orphaned; + + // cache the json-service response + ServiceResponse = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + } + } +} diff --git a/src/CoiniumServ/Statistics/IBlockStats.cs b/src/CoiniumServ/Pools/IBlocksCache.cs similarity index 66% rename from src/CoiniumServ/Statistics/IBlockStats.cs rename to src/CoiniumServ/Pools/IBlocksCache.cs index 649d3c1b4..69610217b 100644 --- a/src/CoiniumServ/Statistics/IBlockStats.cs +++ b/src/CoiniumServ/Pools/IBlocksCache.cs @@ -20,16 +20,30 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using System.Collections.Generic; +using CoiniumServ.Persistance.Blocks; +using CoiniumServ.Server.Web.Service; +using CoiniumServ.Utils.Repository; +using Newtonsoft.Json; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Pools { - public interface IBlocksCount : IStatisticsProvider + [JsonObject(MemberSerialization.OptIn)] + public interface IBlocksCache : IRepository, IJsonService { + [JsonProperty("pending")] int Pending { get; } + + [JsonProperty("confirmed")] int Confirmed { get; } + + [JsonProperty("orphaned")] int Orphaned { get; } + + [JsonProperty("total")] int Total { get; } - ILatestBlocks Latest { get; } + [JsonProperty("latest")] + Dictionary Latest { get; } } } diff --git a/src/CoiniumServ/Pools/IPool.cs b/src/CoiniumServ/Pools/IPool.cs index 47263621a..febeb7b93 100644 --- a/src/CoiniumServ/Pools/IPool.cs +++ b/src/CoiniumServ/Pools/IPool.cs @@ -20,17 +20,38 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - -using CoiniumServ.Pools.Config; +using System; +using System.Collections.Generic; +using CoiniumServ.Cryptology.Algorithms; +using CoiniumServ.Miners; +using CoiniumServ.Server.Web.Service; using CoiniumServ.Statistics; +using Newtonsoft.Json; namespace CoiniumServ.Pools { - public interface IPool + [JsonObject(MemberSerialization.OptIn)] + public interface IPool: IJsonService { + [JsonProperty("config")] IPoolConfig Config { get; } - IPerPool Statistics { get; } + [JsonProperty("hashrate")] + UInt64 Hashrate { get; } + + [JsonProperty("round")] + Dictionary RoundShares { get; } + + IHashAlgorithm HashAlgorithm { get; } + + [JsonProperty("miners")] + IMinerManager MinerManager { get; } + + [JsonProperty("network")] + INetworkStats NetworkStats { get; } + + [JsonProperty("blocks")] + IBlocksCache BlocksCache { get; } void Start(); diff --git a/src/CoiniumServ/Pools/Config/IPoolConfig.cs b/src/CoiniumServ/Pools/IPoolConfig.cs similarity index 90% rename from src/CoiniumServ/Pools/Config/IPoolConfig.cs rename to src/CoiniumServ/Pools/IPoolConfig.cs index df42ebf31..c392d15ca 100644 --- a/src/CoiniumServ/Pools/Config/IPoolConfig.cs +++ b/src/CoiniumServ/Pools/IPoolConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Banning; using CoiniumServ.Coin.Config; using CoiniumServ.Configuration; @@ -31,16 +30,19 @@ using CoiniumServ.Persistance; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Vanilla; +using Newtonsoft.Json; -namespace CoiniumServ.Pools.Config +namespace CoiniumServ.Pools { - public interface IPoolConfig:IConfig + [JsonObject(MemberSerialization.OptIn)] + public interface IPoolConfig : IConfig { /// /// Is the configuration enabled? /// bool Enabled { get; } + [JsonProperty("coin")] ICoinConfig Coin { get; } IDaemonConfig Daemon { get; } @@ -57,6 +59,7 @@ public interface IPoolConfig:IConfig IJobConfig Job { get; } + [JsonProperty("stratum")] IStratumServerConfig Stratum { get; } IBanConfig Banning { get; } diff --git a/src/CoiniumServ/Pools/IPoolManager.cs b/src/CoiniumServ/Pools/IPoolManager.cs index 8e73811e9..2f1c3a1f6 100644 --- a/src/CoiniumServ/Pools/IPoolManager.cs +++ b/src/CoiniumServ/Pools/IPoolManager.cs @@ -20,16 +20,14 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - -using System.Collections.Generic; +using CoiniumServ.Server.Web.Service; +using CoiniumServ.Utils.Repository; namespace CoiniumServ.Pools { - public interface IPoolManager + public interface IPoolManager : IRepository, IJsonService { - IReadOnlyCollection Pools { get; } - - IPool GetBySymbol(string symbol); + IPool Get(string symbol); void Run(); } diff --git a/src/CoiniumServ/Statistics/PerAlgorithm.cs b/src/CoiniumServ/Pools/NetworkStats.cs similarity index 53% rename from src/CoiniumServ/Statistics/PerAlgorithm.cs rename to src/CoiniumServ/Pools/NetworkStats.cs index 0c0616a10..e90cf93db 100644 --- a/src/CoiniumServ/Statistics/PerAlgorithm.cs +++ b/src/CoiniumServ/Pools/NetworkStats.cs @@ -20,51 +20,42 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using CoiniumServ.Daemon; +using CoiniumServ.Daemon.Exceptions; +using CoiniumServ.Statistics; -using System; -using System.Dynamic; -using Newtonsoft.Json; - -namespace CoiniumServ.Statistics +namespace CoiniumServ.Pools { - public class PerAlgorithm:IPerAlgorithm + public class NetworkStats:INetworkStats { - public string Json { get; private set; } - public string Name { get; private set; } - public int WorkerCount { get; private set; } + public double Difficulty { get; private set; } + public int Round { get; private set; } public ulong Hashrate { get; private set; } - private readonly dynamic _response; - - public PerAlgorithm(string algorithm) - { - Name = algorithm; - - _response = new ExpandoObject(); - } + private readonly IDaemonClient _daemonClient; - public void Reset() + public NetworkStats(IDaemonClient daemonClient) { - Hashrate = 0; - WorkerCount = 0; + _daemonClient = daemonClient; } - public void Recache(UInt64 hashrate, int workerCount) - { - // recache data. - Hashrate = hashrate; - WorkerCount = workerCount; - - // recache json response. - _response.hashrate = Hashrate; - _response.workers = WorkerCount; - - Json = JsonConvert.SerializeObject(_response); - } + public string ServiceResponse { get; private set; } - public object GetResponseObject() + public void Recache() { - return _response; + try + { + var miningInfo = _daemonClient.GetMiningInfo(); + Hashrate = miningInfo.NetworkHashps; + Difficulty = miningInfo.Difficulty; + Round = miningInfo.Blocks + 1; + } + catch (RpcException) + { + Hashrate = 0; + Difficulty = 0; + Round = -1; + } } } } diff --git a/src/CoiniumServ/Pools/Pool.cs b/src/CoiniumServ/Pools/Pool.cs index 2f5d8cac7..1a808deb4 100644 --- a/src/CoiniumServ/Pools/Pool.cs +++ b/src/CoiniumServ/Pools/Pool.cs @@ -20,9 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; +using System.Linq; using System.Security.Cryptography; using CoiniumServ.Banning; using CoiniumServ.Coin.Helpers; @@ -32,13 +32,18 @@ using CoiniumServ.Factories; using CoiniumServ.Jobs.Manager; using CoiniumServ.Miners; -using CoiniumServ.Persistance; -using CoiniumServ.Pools.Config; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Empty; +using CoiniumServ.Persistance.Layers.Hybrid; +using CoiniumServ.Persistance.Layers.Mpos; +using CoiniumServ.Persistance.Providers; +using CoiniumServ.Persistance.Providers.MySql; using CoiniumServ.Server.Mining; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Shares; using CoiniumServ.Statistics; using CoiniumServ.Utils.Helpers.Validation; +using Newtonsoft.Json; using Serilog; namespace CoiniumServ.Pools @@ -49,19 +54,26 @@ namespace CoiniumServ.Pools public class Pool : IPool { public IPoolConfig Config { get; private set; } - - public IPerPool Statistics { get; private set; } + public ulong Hashrate { get; private set; } + public Dictionary RoundShares { get; private set; } + public IHashAlgorithm HashAlgorithm { get; private set; } + public IMinerManager MinerManager { get; private set; } + public INetworkStats NetworkStats { get; private set; } + public IBlocksCache BlocksCache { get; private set; } // object factory. private readonly IObjectFactory _objectFactory; // dependent objects. - private IDaemonClient _daemonClient; - private IMinerManager _minerManager; + private IDaemonClient _daemonClient; + private IJobManager _jobManager; - private IShareManager _shareManager; - private IHashAlgorithm _hashAlgorithm; + + private IShareManager _shareManager; + private IBanManager _banningManager; + + private IStorageLayer _storageLayer; private Dictionary _servers; @@ -77,9 +89,7 @@ public class Pool : IPool /// /// /// - public Pool( - IPoolConfig poolConfig, - IObjectFactory objectFactory) + public Pool(IPoolConfig poolConfig, IObjectFactory objectFactory) { Enforce.ArgumentNotNull(() => poolConfig); // make sure we have a config instance supplied. Enforce.ArgumentNotNull(() => objectFactory); // make sure we have a objectFactory instance supplied. @@ -95,6 +105,7 @@ public Pool( GenerateInstanceId(); InitDaemon(); + InitStorage(); InitManagers(); InitServers(); } @@ -108,14 +119,15 @@ private void InitDaemon() } _daemonClient = _objectFactory.GetDaemonClient(Config); - _hashAlgorithm = _objectFactory.GetHashAlgorithm(Config.Coin.Algorithm); + HashAlgorithm = _objectFactory.GetHashAlgorithm(Config.Coin.Algorithm); + // read getinfo(). try { var info = _daemonClient.GetInfo(); _logger.Information("Coin symbol: {0:l} algorithm: {1:l} " + - "Coin version: {2} protocol: {3} wallet: {4} " + + "Coin version: {2:l} protocol: {3} wallet: {4} " + "Daemon network: {5:l} peers: {6} blocks: {7} errors: {8:l} ", Config.Coin.Symbol, Config.Coin.Algorithm, @@ -132,6 +144,7 @@ private void InitDaemon() return; } + // read getmininginfo(). try { // try reading mininginfo(), some coins may not support it. @@ -139,42 +152,74 @@ private void InitDaemon() _logger.Information("Network difficulty: {0:0.00000000} block difficulty: {1:0.00} Network hashrate: {2:l} ", miningInfo.Difficulty, - miningInfo.Difficulty * _hashAlgorithm.Multiplier, + miningInfo.Difficulty * HashAlgorithm.Multiplier, miningInfo.NetworkHashps.GetReadableHashrate()); } catch (RpcException e) { _logger.Error("Can not read mininginfo() - the coin may not support the request: {0:l}", e.Message); } + + // read getdifficulty() to determine if it's POS coin. + try + { + /* By default proof-of-work coins return a floating point as difficulty (https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_lis). + * Though proof-of-stake coins returns a json-object; + * { "proof-of-work" : 41867.16992903, "proof-of-stake" : 0.00390625, "search-interval" : 0 } + * So basically we can use this info to determine if assigned coin is a proof-of-stake one. + */ + + var response = _daemonClient.MakeRawRequest("getdifficulty"); + if (response.Contains("proof-of-stake")) // if response contains proof-of-stake field + Config.Coin.IsPOS = true; // then automatically set coin-config.IsPOS to true. + } + catch (RpcException e) + { + _logger.Error("Can not read getdifficulty() - the coin may not support the request: {0:l}", e.Message); + } + } + + private void InitStorage() + { + // load the providers for the current storage layer. + var providers = + Config.Storage.Layer.Providers.Select( + providerConfig => + _objectFactory.GetStorageProvider( + providerConfig is IMySqlProviderConfig ? StorageProviders.MySql : StorageProviders.Redis, + Config, providerConfig)).ToList(); + + // start the migration manager if needed + if (Config.Storage.Layer is HybridStorageLayerConfig) + _objectFactory.GetMigrationManager((IMySqlProvider)providers.First(p => p is MySqlProvider), Config); // run migration manager. + + // load the storage layer. + if (Config.Storage.Layer is HybridStorageLayerConfig) + _storageLayer = _objectFactory.GetStorageLayer(StorageLayers.Hybrid, providers, _daemonClient, Config); + else if (Config.Storage.Layer is MposStorageLayerConfig) + _storageLayer = _objectFactory.GetStorageLayer(StorageLayers.Mpos, providers, _daemonClient, Config); + else if (Config.Storage.Layer is EmptyStorageLayerConfig) + _storageLayer = _objectFactory.GetStorageLayer(StorageLayers.Empty, providers, _daemonClient, Config); } private void InitManagers() { try { - var storage = _objectFactory.GetStorage(Storages.Redis, Config); - - _minerManager = _objectFactory.GetMinerManager(Config, _daemonClient); + BlocksCache = _objectFactory.GetBlocksCache(_storageLayer); + MinerManager = _objectFactory.GetMinerManager(Config, _storageLayer); + NetworkStats = _objectFactory.GetNetworkStats(_daemonClient); var jobTracker = _objectFactory.GetJobTracker(); - var blockProcessor = _objectFactory.GetBlockProcessor(Config, _daemonClient); - - _shareManager = _objectFactory.GetShareManager(Config, _daemonClient, jobTracker, storage, blockProcessor); - - var vardiffManager = _objectFactory.GetVardiffManager(Config, _shareManager); - + _shareManager = _objectFactory.GetShareManager(Config, _daemonClient, jobTracker, _storageLayer, blockProcessor); + _objectFactory.GetVardiffManager(Config, _shareManager); _banningManager = _objectFactory.GetBanManager(Config, _shareManager); - - _jobManager = _objectFactory.GetJobManager(Config, _daemonClient, jobTracker, _shareManager, _minerManager, _hashAlgorithm); + _jobManager = _objectFactory.GetJobManager(Config, _daemonClient, jobTracker, _shareManager, MinerManager, HashAlgorithm); _jobManager.Initialize(InstanceId); - var paymentProcessor = _objectFactory.GetPaymentProcessor(Config, _daemonClient, storage, blockProcessor); - paymentProcessor.Initialize(Config.Payments); - - var latestBlocks = _objectFactory.GetLatestBlocks(storage); - var blockStats = _objectFactory.GetBlockStats(latestBlocks, storage); - Statistics = _objectFactory.GetPerPoolStats(Config, _daemonClient, _minerManager, _hashAlgorithm, blockStats, storage); + var paymentProcessor = _objectFactory.GetPaymentProcessor(Config, _daemonClient, _storageLayer, blockProcessor); + paymentProcessor.Initialize(); } catch (Exception e) { @@ -190,7 +235,7 @@ private void InitServers() if (Config.Stratum != null && Config.Stratum.Enabled) { - var stratumServer = _objectFactory.GetMiningServer("Stratum", Config, this, _minerManager, _jobManager, _banningManager); + var stratumServer = _objectFactory.GetMiningServer("Stratum", Config, this, MinerManager, _jobManager, _banningManager); var stratumService = _objectFactory.GetMiningService("Stratum", Config, _shareManager, _daemonClient); stratumServer.Initialize(Config.Stratum); @@ -199,7 +244,7 @@ private void InitServers() if (Config.Vanilla != null && Config.Vanilla.Enabled) { - var vanillaServer = _objectFactory.GetMiningServer("Vanilla", Config, this, _minerManager, _jobManager, _banningManager); + var vanillaServer = _objectFactory.GetMiningServer("Vanilla", Config, this, MinerManager, _jobManager, _banningManager); var vanillaService = _objectFactory.GetMiningService("Vanilla", Config, _shareManager, _daemonClient); vanillaServer.Initialize(Config.Vanilla); @@ -238,5 +283,34 @@ private void GenerateInstanceId() InstanceId = BitConverter.ToUInt32(randomBytes, 0); // convert them to instance Id. _logger.Debug("Generated cryptographically random instance Id: {0}", InstanceId); } + + public string ServiceResponse { get; private set; } + + public void Recache() + { + BlocksCache.Recache(); // recache the blocks. + NetworkStats.Recache(); // let network statistics recache. + CalculateHashrate(); // calculate the pool hashrate. + RecacheRound(); // recache current round. + + // cache the json-service response + ServiceResponse = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + } + + private void RecacheRound() + { + RoundShares = _storageLayer.GetCurrentShares(); + } + + private void CalculateHashrate() + { + //// read hashrate stats. + //var windowTime = TimeHelpers.NowInUnixTime() - _statisticsConfig.HashrateWindow; + //_storage.DeleteExpiredHashrateData(windowTime); + //var hashrates = _storage.GetHashrateData(windowTime); + + //double total = hashrates.Sum(pair => pair.Value); + //Hashrate = Convert.ToUInt64(_shareMultiplier * total / _statisticsConfig.HashrateWindow); + } } } diff --git a/src/CoiniumServ/Pools/Config/PoolConfig.cs b/src/CoiniumServ/Pools/PoolConfig.cs similarity index 81% rename from src/CoiniumServ/Pools/Config/PoolConfig.cs rename to src/CoiniumServ/Pools/PoolConfig.cs index 81fb443ac..cc7a53e6c 100644 --- a/src/CoiniumServ/Pools/Config/PoolConfig.cs +++ b/src/CoiniumServ/Pools/PoolConfig.cs @@ -20,8 +20,8 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; +using System.Diagnostics; using CoiniumServ.Banning; using CoiniumServ.Coin.Config; using CoiniumServ.Daemon.Config; @@ -29,12 +29,14 @@ using CoiniumServ.Miners; using CoiniumServ.Payments; using CoiniumServ.Persistance; -using CoiniumServ.Persistance.Redis; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Persistance.Layers.Mpos; +using CoiniumServ.Persistance.Providers.Redis; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Vanilla; using Serilog; -namespace CoiniumServ.Pools.Config +namespace CoiniumServ.Pools { /// /// Reads and serves the configuration for a pool. @@ -56,6 +58,8 @@ public class PoolConfig : IPoolConfig public IStorageConfig Storage { get; private set; } public IVanillaServerConfig Vanilla { get; private set; } + private readonly ILogger _logger; + /// /// Initializes a new instance of the class. /// @@ -65,6 +69,8 @@ public PoolConfig(dynamic config, ICoinConfig coinConfig) { try { + _logger = Log.ForContext().ForContext("Component", coinConfig.Name); + Enabled = config.enabled ? config.enabled : false; if (Enabled == false) // if the configuration is not enabled @@ -82,15 +88,25 @@ public PoolConfig(dynamic config, ICoinConfig coinConfig) Job = new JobConfig(config.job); Stratum = new StratumServerConfig(config.stratum); Banning = new BanConfig(config.banning); - Storage = new RedisConfig(config.storage.redis); + Storage = new StorageConfig(config.storage); Vanilla = new VanillaServerConfig(config.vanilla); + // process extra checks + if (Storage.Layer is MposStorageLayerConfig) + { + if (Payments.Enabled) + { + Payments.Disable(); + _logger.Information("Disabled payments processor as it can not be enabled when MPOS mode is on"); + } + } + Valid = true; } catch (Exception e) { Valid = false; - Log.Logger.ForContext().Error(e, "Error loading pool configuration"); + _logger.Error(e, "Error loading pool configuration"); } } } diff --git a/src/CoiniumServ/Pools/PoolManager.cs b/src/CoiniumServ/Pools/PoolManager.cs index 4ee833f0f..48e3ceb45 100644 --- a/src/CoiniumServ/Pools/PoolManager.cs +++ b/src/CoiniumServ/Pools/PoolManager.cs @@ -20,46 +20,102 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; +using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; +using System.Linq.Expressions; using CoiniumServ.Configuration; using CoiniumServ.Factories; +using Newtonsoft.Json; using Serilog; namespace CoiniumServ.Pools { public class PoolManager : IPoolManager { - public IReadOnlyCollection Pools { get { return _pools.Values.ToList(); } } - - private readonly Dictionary _pools; + private readonly IList _storage; private readonly ILogger _logger; public PoolManager(IObjectFactory objectFactory , IConfigManager configManager) { _logger = Log.ForContext(); - _pools = new Dictionary(); - foreach (var config in configManager.PoolConfigs) + _storage = new List(); // initialize the pool storage. + + foreach (var config in configManager.PoolConfigs) // loop through all enabled pool configurations. { - _pools.Add(config.Coin.Symbol, objectFactory.GetPool(config)); + var pool = objectFactory.GetPool(config); // create pool for the given configuration. + _storage.Add(pool); // add it to storage. } } - public IPool GetBySymbol(string symbol) + public IQueryable SearchFor(Expression> predicate) + { + return _storage.AsQueryable().Where(predicate); + } + + public IEnumerable GetAll() + { + return _storage; + } + + public IQueryable GetAllAsQueryable() + { + return _storage.AsQueryable(); + } + + public IReadOnlyCollection GetAllAsReadOnly() { - return _pools.Values.FirstOrDefault(pair => pair.Config.Coin.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase)); + return new ReadOnlyCollection(_storage); + } + + public int Count { get { return _storage.Count; } } + + public string ServiceResponse { get; private set; } + + public void Recache() + { + try + { + foreach (var pool in _storage) // recache per-pool stats + { + pool.Recache(); + } + + // cache the json-service response + var cache = _storage.ToDictionary(pool => pool.Config.Coin.Symbol.ToLower()); + ServiceResponse = JsonConvert.SerializeObject(cache, Formatting.Indented, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}); + } + catch (Exception e) + { + _logger.Error("Error recaching statistics; {0:l}", e.Message); + } + } + + public IPool Get(string symbol) + { + return _storage.FirstOrDefault(p => p.Config.Coin.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase)); } public void Run() { - foreach (var kvp in _pools) + foreach (var pool in _storage) { - kvp.Value.Start(); + pool.Start(); } } + + public IEnumerator GetEnumerator() + { + return _storage.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } } diff --git a/src/CoiniumServ/Program.cs b/src/CoiniumServ/Program.cs index 61e365e99..5e34edf16 100644 --- a/src/CoiniumServ/Program.cs +++ b/src/CoiniumServ/Program.cs @@ -20,13 +20,12 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Globalization; using System.Reflection; using System.Threading; +using CoiniumServ.Container; using CoiniumServ.Factories; -using CoiniumServ.Repository; using CoiniumServ.Utils; using CoiniumServ.Utils.Commands; using CoiniumServ.Utils.Platform; @@ -77,13 +76,19 @@ static void Main(string[] args) // initialize config manager. configManager.Initialize(); - // initialize metrics support - objectFactory.GetMetricsManager(); - // start pool manager. var poolManager = objectFactory.GetPoolManager(); poolManager.Run(); + // run algorithm manager. + objectFactory.GetAlgorithmManager(poolManager); + + // run statistics manager. + objectFactory.GetStatisticsManager(); + + // initialize metrics support + objectFactory.GetMetricsManager(); + // start web server. objectFactory.GetWebServer(); diff --git a/src/CoiniumServ/Server/Commands/Server.cs b/src/CoiniumServ/Server/Commands/Server.cs index 6d7c6ad93..1260b6644 100644 --- a/src/CoiniumServ/Server/Commands/Server.cs +++ b/src/CoiniumServ/Server/Commands/Server.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Utils.Commands; diff --git a/src/CoiniumServ/Server/Commands/Stats.cs b/src/CoiniumServ/Server/Commands/Stats.cs index 54c0795b8..2bbab76be 100644 --- a/src/CoiniumServ/Server/Commands/Stats.cs +++ b/src/CoiniumServ/Server/Commands/Stats.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Diagnostics; using System.Text; diff --git a/src/CoiniumServ/Server/Commands/Uptime.cs b/src/CoiniumServ/Server/Commands/Uptime.cs index 495637d68..53cddecf2 100644 --- a/src/CoiniumServ/Server/Commands/Uptime.cs +++ b/src/CoiniumServ/Server/Commands/Uptime.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Utils.Commands; diff --git a/src/CoiniumServ/Server/Commands/Version.cs b/src/CoiniumServ/Server/Commands/Version.cs index ab92b7c3f..db77bf623 100644 --- a/src/CoiniumServ/Server/Commands/Version.cs +++ b/src/CoiniumServ/Server/Commands/Version.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Reflection; using CoiniumServ.Utils.Commands; diff --git a/src/CoiniumServ/Server/IServer.cs b/src/CoiniumServ/Server/IServer.cs index c52c3aff6..8f6b7d79e 100644 --- a/src/CoiniumServ/Server/IServer.cs +++ b/src/CoiniumServ/Server/IServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Server { /// diff --git a/src/CoiniumServ/Server/Mining/IMiningServer.cs b/src/CoiniumServ/Server/Mining/IMiningServer.cs index f69b1cb78..3df050b16 100644 --- a/src/CoiniumServ/Server/Mining/IMiningServer.cs +++ b/src/CoiniumServ/Server/Mining/IMiningServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Server.Mining { /// diff --git a/src/CoiniumServ/Server/Mining/IMiningServerConfig.cs b/src/CoiniumServ/Server/Mining/IMiningServerConfig.cs index ed26f09fb..e3775c147 100644 --- a/src/CoiniumServ/Server/Mining/IMiningServerConfig.cs +++ b/src/CoiniumServ/Server/Mining/IMiningServerConfig.cs @@ -20,12 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Configuration; +using Newtonsoft.Json; namespace CoiniumServ.Server.Mining { + [JsonObject(MemberSerialization.OptIn)] public interface IServerConfig:IConfig { bool Enabled { get; } @@ -38,6 +39,7 @@ public interface IServerConfig:IConfig /// /// port to listen for connections. /// + [JsonProperty("port")] Int32 Port { get; } } } diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/AuthenticationError.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/AuthenticationError.cs index 299e5d26b..4e3f79cbb 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/AuthenticationError.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/AuthenticationError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; namespace CoiniumServ.Server.Mining.Stratum.Errors diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/DuplicateShareError.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/DuplicateShareError.cs index 7f14bb95b..d0a90d0b8 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/DuplicateShareError.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/DuplicateShareError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using AustinHarris.JsonRpc; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/JobNotFoundError.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/JobNotFoundError.cs index c5445506a..75fe9aff7 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/JobNotFoundError.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/JobNotFoundError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using AustinHarris.JsonRpc; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/LowDifficultyShare.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/LowDifficultyShare.cs index 07c70f264..949393942 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/LowDifficultyShare.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/LowDifficultyShare.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; namespace CoiniumServ.Server.Mining.Stratum.Errors diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/NotSubscriberError.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/NotSubscriberError.cs index 55fd45692..76e671b60 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/NotSubscriberError.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/NotSubscriberError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; namespace CoiniumServ.Server.Mining.Stratum.Errors diff --git a/src/CoiniumServ/Server/Mining/Stratum/Errors/OtherError.cs b/src/CoiniumServ/Server/Mining/Stratum/Errors/OtherError.cs index e674da547..8df9fb8c3 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Errors/OtherError.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Errors/OtherError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; namespace CoiniumServ.Server.Mining.Stratum.Errors diff --git a/src/CoiniumServ/Server/Mining/Stratum/IStratumMiner.cs b/src/CoiniumServ/Server/Mining/Stratum/IStratumMiner.cs index 6f4b24245..217a5b92c 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/IStratumMiner.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/IStratumMiner.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Jobs; using CoiniumServ.Miners; diff --git a/src/CoiniumServ/Server/Mining/Stratum/IStratumServerConfig.cs b/src/CoiniumServ/Server/Mining/Stratum/IStratumServerConfig.cs index f9f09e5ea..79a897d95 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/IStratumServerConfig.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/IStratumServerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Vardiff; namespace CoiniumServ.Server.Mining.Stratum diff --git a/src/CoiniumServ/Server/Mining/Stratum/Responses/SubscribeResponse.cs b/src/CoiniumServ/Server/Mining/Stratum/Responses/SubscribeResponse.cs index 6b2d672e5..9e261d000 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Responses/SubscribeResponse.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Responses/SubscribeResponse.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections; using System.Collections.Generic; using System.Globalization; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Service/SocketServiceContext.cs b/src/CoiniumServ/Server/Mining/Stratum/Service/SocketServiceContext.cs index 637234b60..14e795ef1 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Service/SocketServiceContext.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Service/SocketServiceContext.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Miners; namespace CoiniumServ.Server.Mining.Stratum.Service diff --git a/src/CoiniumServ/Server/Mining/Stratum/Service/StratumService.cs b/src/CoiniumServ/Server/Mining/Stratum/Service/StratumService.cs index b5d377495..1529d7816 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Service/StratumService.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Service/StratumService.cs @@ -20,10 +20,9 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; using CoiniumServ.Jobs; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Server.Mining.Stratum.Responses; using CoiniumServ.Shares; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/BannedConnectionEventArgs.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/BannedConnectionEventArgs.cs index 521247ebc..350d4fc5c 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/BannedConnectionEventArgs.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/BannedConnectionEventArgs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Net; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/Connection.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/Connection.cs index 01d8e899f..f4c250f92 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/Connection.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/Connection.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionDataEventArgs.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionDataEventArgs.cs index 8cc664dbe..8ef81ceea 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionDataEventArgs.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionDataEventArgs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionEventArgs.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionEventArgs.cs index 625e259f5..d76b41cc1 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionEventArgs.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ConnectionEventArgs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Server.Mining.Stratum.Sockets diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/IConnection.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/IConnection.cs index 80bf7f904..277961e05 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/IConnection.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/IConnection.cs @@ -20,16 +20,17 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Net; using System.Net.Sockets; +using Newtonsoft.Json; namespace CoiniumServ.Server.Mining.Stratum.Sockets { /// /// Connection interface. /// + [JsonObject(MemberSerialization.OptIn)] public interface IConnection { /// diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ISocketServer.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ISocketServer.cs index 979f611e8..2fbf228fc 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/ISocketServer.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/ISocketServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Server.Mining.Stratum.Sockets diff --git a/src/CoiniumServ/Server/Mining/Stratum/Sockets/SocketServer.cs b/src/CoiniumServ/Server/Mining/Stratum/Sockets/SocketServer.cs index 67fc31777..70c95b69f 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/Sockets/SocketServer.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/Sockets/SocketServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Server/Mining/Stratum/StratumMiner.cs b/src/CoiniumServ/Server/Mining/Stratum/StratumMiner.cs index 52f259300..7fd6b1d87 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/StratumMiner.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/StratumMiner.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Diagnostics; @@ -30,6 +29,7 @@ using CoiniumServ.Jobs; using CoiniumServ.Logging; using CoiniumServ.Miners; +using CoiniumServ.Persistance.Layers; using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Stratum.Errors; using CoiniumServ.Server.Mining.Stratum.Service; @@ -54,11 +54,13 @@ public class StratumMiner : IClient, IStratumMiner /// /// Unique subscription id for identifying the miner. /// + [JsonProperty("id")] public int Id { get; private set; } /// /// Username of the miner. /// + [JsonProperty("username")] public string Username { get; private set; } /// @@ -69,13 +71,16 @@ public class StratumMiner : IClient, IStratumMiner /// /// Is the miner authenticated? /// + [JsonProperty("authenticated")] public bool Authenticated { get; set; } public int ValidShares { get; set; } + public int InvalidShares { get; set; } public IPool Pool { get; private set; } + [JsonProperty("difficulty")] public float Difficulty { get; set; } public float PreviousDifficulty { get; set; } @@ -90,6 +95,8 @@ public class StratumMiner : IClient, IStratumMiner private readonly IMinerManager _minerManager; + private readonly IStorageLayer _storageLayer; + private readonly ILogger _logger; private readonly ILogger _packetLogger; @@ -108,13 +115,15 @@ public class StratumMiner : IClient, IStratumMiner /// /// /// - public StratumMiner(int id, UInt32 extraNonce, IConnection connection, IPool pool, IMinerManager minerManager) + /// + public StratumMiner(int id, UInt32 extraNonce, IConnection connection, IPool pool, IMinerManager minerManager, IStorageLayer storageLayer) { Id = id; // the id of the miner. ExtraNonce = extraNonce; Connection = connection; // the underlying connection. - _minerManager = minerManager; Pool = pool; + _minerManager = minerManager; + _storageLayer = storageLayer; Subscribed = false; // miner has to subscribe. Authenticated = false; // miner has to authenticate. @@ -247,7 +256,7 @@ public void SendMessage(string message) } /// - /// Sends difficulty to the miner. + /// Sets a new difficulty to the miner and sends it. /// public void SetDifficulty(float difficulty) { @@ -264,7 +273,8 @@ public void SetDifficulty(float difficulty) Params = new List{ Difficulty } }; - Send(notification); + Send(notification); //send the difficulty update message. + _storageLayer.UpdateDifficulty(this); // store the new difficulty within persistance layer. } /// diff --git a/src/CoiniumServ/Server/Mining/Stratum/StratumServer.cs b/src/CoiniumServ/Server/Mining/Stratum/StratumServer.cs index 222341149..6bf08b210 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/StratumServer.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/StratumServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Net; using System.Net.Sockets; @@ -28,7 +27,6 @@ using CoiniumServ.Jobs.Manager; using CoiniumServ.Miners; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using CoiniumServ.Server.Mining.Stratum.Sockets; using Serilog; diff --git a/src/CoiniumServ/Server/Mining/Stratum/StratumServerConfig.cs b/src/CoiniumServ/Server/Mining/Stratum/StratumServerConfig.cs index 4d37d7365..5a0e6180f 100644 --- a/src/CoiniumServ/Server/Mining/Stratum/StratumServerConfig.cs +++ b/src/CoiniumServ/Server/Mining/Stratum/StratumServerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Vardiff; using Serilog; diff --git a/src/CoiniumServ/Server/Mining/Vanilla/HttpServer.cs b/src/CoiniumServ/Server/Mining/Vanilla/HttpServer.cs index fc5cb680c..2e7b494a0 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/HttpServer.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/HttpServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Net; diff --git a/src/CoiniumServ/Server/Mining/Vanilla/IVanillaMiner.cs b/src/CoiniumServ/Server/Mining/Vanilla/IVanillaMiner.cs index b496a06bc..f1bcc9b47 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/IVanillaMiner.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/IVanillaMiner.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Miners; namespace CoiniumServ.Server.Mining.Vanilla diff --git a/src/CoiniumServ/Server/Mining/Vanilla/Service/HttpServiceContext.cs b/src/CoiniumServ/Server/Mining/Vanilla/Service/HttpServiceContext.cs index d994fe022..555e8d3f5 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/Service/HttpServiceContext.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/Service/HttpServiceContext.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Net; using CoiniumServ.Miners; diff --git a/src/CoiniumServ/Server/Mining/Vanilla/Service/VanillaService.cs b/src/CoiniumServ/Server/Mining/Vanilla/Service/VanillaService.cs index 9348deba4..cd24d20ab 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/Service/VanillaService.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/Service/VanillaService.cs @@ -20,13 +20,11 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using AustinHarris.JsonRpc; using CoiniumServ.Coin.Config; using CoiniumServ.Daemon; using CoiniumServ.Daemon.Responses; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using CoiniumServ.Server.Mining.Service; using CoiniumServ.Shares; using Serilog; @@ -40,13 +38,10 @@ public class VanillaService : JsonRpcService, IRpcService { private readonly IDaemonClient _daemonClient; // TODO: remove this! - private readonly IShareManager _shareManager; - public VanillaService(IPoolConfig poolConfig, IShareManager shareManager, IDaemonClient daemonClient): base(poolConfig.Coin.Name) { _daemonClient = daemonClient; - _shareManager = shareManager; } /// diff --git a/src/CoiniumServ/Server/Mining/Vanilla/VanillaMiner.cs b/src/CoiniumServ/Server/Mining/Vanilla/VanillaMiner.cs index 29c909e6b..90173bb41 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/VanillaMiner.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/VanillaMiner.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using System.Net; diff --git a/src/CoiniumServ/Server/Mining/Vanilla/VanillaServer.cs b/src/CoiniumServ/Server/Mining/Vanilla/VanillaServer.cs index 9e6fecafe..7a28c4bf6 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/VanillaServer.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/VanillaServer.cs @@ -20,14 +20,12 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Net; // classic server uses json-rpc 1.0 (over http) & json-rpc.net (http://jsonrpc2.codeplex.com/) using CoiniumServ.Jobs.Manager; using CoiniumServ.Miners; using CoiniumServ.Pools; -using CoiniumServ.Pools.Config; using Serilog; namespace CoiniumServ.Server.Mining.Vanilla @@ -38,8 +36,6 @@ public class VanillaServer : HttpServer, IMiningServer private readonly IMinerManager _minerManager; - private readonly IJobManager _jobManager; - private readonly IPool _pool; private readonly ILogger _logger; @@ -48,7 +44,6 @@ public VanillaServer(IPoolConfig poolConfig, IPool pool, IMinerManager minerMana { _pool = pool; _minerManager = minerManager; - _jobManager = jobManager; _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); } diff --git a/src/CoiniumServ/Server/Mining/Vanilla/VanillaServerConfig.cs b/src/CoiniumServ/Server/Mining/Vanilla/VanillaServerConfig.cs index 6d10973cc..5dd201961 100644 --- a/src/CoiniumServ/Server/Mining/Vanilla/VanillaServerConfig.cs +++ b/src/CoiniumServ/Server/Mining/Vanilla/VanillaServerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Server/Web/ErrorConfiguration.cs b/src/CoiniumServ/Server/Web/ErrorConfiguration.cs index b9009ee3e..a8595c75d 100644 --- a/src/CoiniumServ/Server/Web/ErrorConfiguration.cs +++ b/src/CoiniumServ/Server/Web/ErrorConfiguration.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using Nancy; using Nancy.CustomErrors; diff --git a/src/CoiniumServ/Server/Web/HttpServer.cs b/src/CoiniumServ/Server/Web/HttpServer.cs index 0a90d5d38..b8b49c681 100644 --- a/src/CoiniumServ/Server/Web/HttpServer.cs +++ b/src/CoiniumServ/Server/Web/HttpServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Net; using System.Net.Sockets; diff --git a/src/CoiniumServ/Server/Web/IBackendConfig.cs b/src/CoiniumServ/Server/Web/IBackendConfig.cs index 10d9a76f7..6d16eb1f0 100644 --- a/src/CoiniumServ/Server/Web/IBackendConfig.cs +++ b/src/CoiniumServ/Server/Web/IBackendConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Server.Web diff --git a/src/CoiniumServ/Server/Web/IWebServer.cs b/src/CoiniumServ/Server/Web/IWebServer.cs index 031ae7e85..a950cc9a0 100644 --- a/src/CoiniumServ/Server/Web/IWebServer.cs +++ b/src/CoiniumServ/Server/Web/IWebServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Server.Web { public interface IWebServer: IServer diff --git a/src/CoiniumServ/Server/Web/IWebServerConfig.cs b/src/CoiniumServ/Server/Web/IWebServerConfig.cs index 12cfdcca2..1fb011dff 100644 --- a/src/CoiniumServ/Server/Web/IWebServerConfig.cs +++ b/src/CoiniumServ/Server/Web/IWebServerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Configuration; using CoiniumServ.Statistics; diff --git a/src/CoiniumServ/Server/Web/Models/ErrorModel.cs b/src/CoiniumServ/Server/Web/Models/ApiModel.cs similarity index 87% rename from src/CoiniumServ/Server/Web/Models/ErrorModel.cs rename to src/CoiniumServ/Server/Web/Models/ApiModel.cs index 03088b8a3..336e373f0 100644 --- a/src/CoiniumServ/Server/Web/Models/ErrorModel.cs +++ b/src/CoiniumServ/Server/Web/Models/ApiModel.cs @@ -20,12 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion +using CoiniumServ.Coin.Config; namespace CoiniumServ.Server.Web.Models { - public class ErrorModel + public class ApiModel { - public string Summary { get; set; } - public string Details { get; set; } + public string BaseUrl { get; set; } + public ICoinConfig Coin { get; set; } } } diff --git a/src/CoiniumServ/Server/Web/Models/CurrentRoundModel.cs b/src/CoiniumServ/Server/Web/Models/CurrentRoundModel.cs index 217ab5065..fe2bf1b91 100644 --- a/src/CoiniumServ/Server/Web/Models/CurrentRoundModel.cs +++ b/src/CoiniumServ/Server/Web/Models/CurrentRoundModel.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Server.Web.Models diff --git a/src/CoiniumServ/Server/Web/Models/IndexModel.cs b/src/CoiniumServ/Server/Web/Models/IndexModel.cs index f0a7c8592..aa1e68e1a 100644 --- a/src/CoiniumServ/Server/Web/Models/IndexModel.cs +++ b/src/CoiniumServ/Server/Web/Models/IndexModel.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using CoiniumServ.Pools; using CoiniumServ.Statistics; @@ -31,6 +30,6 @@ public class IndexModel { public IReadOnlyCollection Pools { get; set; } - public IStatistics Statistics { get; set; } + public IStatisticsManager Statistics { get; set; } } } diff --git a/src/CoiniumServ/Server/Web/Models/JsonError.cs b/src/CoiniumServ/Server/Web/Models/JsonError.cs index c62c45964..6259e4166 100644 --- a/src/CoiniumServ/Server/Web/Models/JsonError.cs +++ b/src/CoiniumServ/Server/Web/Models/JsonError.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Server.Web.Models { public class JsonError diff --git a/src/CoiniumServ/Server/Web/Models/PoolModel.cs b/src/CoiniumServ/Server/Web/Models/PoolModel.cs index f6c167180..4d865bf34 100644 --- a/src/CoiniumServ/Server/Web/Models/PoolModel.cs +++ b/src/CoiniumServ/Server/Web/Models/PoolModel.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Pools; namespace CoiniumServ.Server.Web.Models diff --git a/src/CoiniumServ/Server/Web/Models/WorkersModel.cs b/src/CoiniumServ/Server/Web/Models/WorkersModel.cs index eb16fa924..33ca78c30 100644 --- a/src/CoiniumServ/Server/Web/Models/WorkersModel.cs +++ b/src/CoiniumServ/Server/Web/Models/WorkersModel.cs @@ -20,13 +20,13 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; +using CoiniumServ.Miners; namespace CoiniumServ.Server.Web.Models { public class WorkersModel { - public IDictionary Workers { get; set; } + public IList Workers { get; set; } } } diff --git a/src/CoiniumServ/Server/Web/Modules/Api.cs b/src/CoiniumServ/Server/Web/Modules/Api.cs index 87972fb38..dc9f094d7 100644 --- a/src/CoiniumServ/Server/Web/Modules/Api.cs +++ b/src/CoiniumServ/Server/Web/Modules/Api.cs @@ -20,9 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Linq; using CoiniumServ.Coin.Config; +using CoiniumServ.Cryptology.Algorithms; +using CoiniumServ.Pools; using CoiniumServ.Server.Web.Models; using CoiniumServ.Statistics; using Nancy; @@ -32,95 +33,68 @@ namespace CoiniumServ.Server.Web.Modules { public class ApiModule: NancyModule { - public ApiModule(IStatistics statistics) + private static readonly Response PoolNotFound = JsonConvert.SerializeObject(new JsonError("Pool not found!")); + private static readonly Response AlgorithmNotFound = JsonConvert.SerializeObject(new JsonError("Algorithm not found!")); + + // TODO: use base("/api"); + public ApiModule(IStatisticsManager statisticsManager, IPoolManager poolManager, IAlgorithmManager algorithmManager) + :base("/api") { - Get["/api/"] = _ => + Get["/"] = _ => { // include common data required by layout. ViewBag.Title = "API"; ViewBag.Heading = "Public API"; - ViewBag.Pools = statistics.Pools; - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. // return our view return View["api", new ApiModel { BaseUrl = Request.Url.SiteBase, - Coin = statistics.Pools.First().Value.Config.Coin + Coin = poolManager.First().Config.Coin }]; }; - Get["/api/global"] = _ => Response.AsJson(statistics.Global.GetResponseObject()); - - Get["/api/pools"] = _ => Response.AsJson(statistics.Pools.GetResponseObject()); - Get["/api/pool/{slug}"] = _ => + Get["/pools"] = _ => { - var pool = statistics.Pools.GetBySymbol(_.slug); - - Response response; - - if (pool == null) - response = JsonConvert.SerializeObject(new JsonError("Pool not found!")); - else - response = (Response)pool.Json; - + var response = (Response) poolManager.ServiceResponse; response.ContentType = "application/json"; - return response; + return response; }; - Get["/api/pool/{slug}/workers"] = _ => + Get["/pool/{slug}"] = _ => { - var pool = statistics.Pools.GetBySymbol(_.slug); - - Response response; - - if (pool == null) - response = JsonConvert.SerializeObject(new JsonError("Pool not found!")); - else - response = (Response)pool.WorkersJson; + var pool = poolManager.Get(_.slug); // query the requested pool. + var response = pool != null ? (Response)pool.ServiceResponse : PoolNotFound; response.ContentType = "application/json"; return response; }; - Get["/api/pool/{slug}/round"] = _ => + Get["/algorithms"] = _ => { - var pool = statistics.Pools.GetBySymbol(_.slug); - - Response response; - - if (pool == null) - response = JsonConvert.SerializeObject(new JsonError("Pool not found!")); - else - response = (Response)pool.CurrentRoundJson; - + var response = (Response)algorithmManager.ServiceResponse; response.ContentType = "application/json"; return response; }; - Get["/api/algorithms"] = _ => Response.AsJson(statistics.Algorithms.GetResponseObject()); - - Get["/api/algorithm/{slug}"] = _ => + Get["/algorithm/{slug}"] = _ => { - var algorithm = statistics.Algorithms.GetByName(_.slug); - - Response response; + var algorithm = algorithmManager.Get(_.slug); // query the requested pool. - if (algorithm == null) - response = JsonConvert.SerializeObject(new JsonError("Algorithm not found!")); - else - response = (Response)algorithm.Json; - + var response = algorithm != null ? (Response)algorithm.ServiceResponse : AlgorithmNotFound; response.ContentType = "application/json"; - return response; + return response; }; - } - } - public class ApiModel - { - public string BaseUrl { get; set; } - public ICoinConfig Coin { get; set; } + Get["/global"] = _ => + { + var response = (Response) statisticsManager.ServiceResponse; + response.ContentType = "application/json"; + return response; + }; + } } } diff --git a/src/CoiniumServ/Server/Web/Modules/BackendConfig.cs b/src/CoiniumServ/Server/Web/Modules/BackendConfig.cs index 60b736224..f17e1d21b 100644 --- a/src/CoiniumServ/Server/Web/Modules/BackendConfig.cs +++ b/src/CoiniumServ/Server/Web/Modules/BackendConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Server/Web/Modules/Donate.cs b/src/CoiniumServ/Server/Web/Modules/Donate.cs index 4161da7c5..e8e8cf040 100644 --- a/src/CoiniumServ/Server/Web/Modules/Donate.cs +++ b/src/CoiniumServ/Server/Web/Modules/Donate.cs @@ -20,7 +20,7 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using CoiniumServ.Pools; using CoiniumServ.Statistics; using Nancy; @@ -28,15 +28,15 @@ namespace CoiniumServ.Server.Web.Modules { public class DonateModule : NancyModule { - public DonateModule(IStatistics statistics) + public DonateModule(IStatisticsManager statisticsManager, IPoolManager poolManager) { Get["/donate/"] = _ => { // include common data required by layout. ViewBag.Title = "Donation"; ViewBag.Heading = "Donation"; - ViewBag.Pools = statistics.Pools; - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. // return our view return View["donate"]; diff --git a/src/CoiniumServ/Server/Web/Modules/Index.cs b/src/CoiniumServ/Server/Web/Modules/Index.cs index 50a0863d7..63fc532e0 100644 --- a/src/CoiniumServ/Server/Web/Modules/Index.cs +++ b/src/CoiniumServ/Server/Web/Modules/Index.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Pools; using CoiniumServ.Server.Web.Models; using CoiniumServ.Statistics; @@ -30,20 +29,20 @@ namespace CoiniumServ.Server.Web.Modules { public class IndexModule : NancyModule { - public IndexModule(IPoolManager poolManager, IStatistics statistics) + public IndexModule(IStatisticsManager statisticsManager, IPoolManager poolManager) { Get["/"] = _ => { // include common data required by layout. ViewBag.Heading = "Welcome"; - ViewBag.Pools = statistics.Pools; - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. // return our view return View["index", new IndexModel { - Pools = poolManager.Pools, - Statistics = statistics + Pools = poolManager.GetAllAsReadOnly(), + Statistics = statisticsManager }]; }; } diff --git a/src/CoiniumServ/Server/Web/Modules/Pool.cs b/src/CoiniumServ/Server/Web/Modules/Pool.cs index a7e174f5a..c0eb41142 100644 --- a/src/CoiniumServ/Server/Web/Modules/Pool.cs +++ b/src/CoiniumServ/Server/Web/Modules/Pool.cs @@ -20,31 +20,32 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Pools; using CoiniumServ.Server.Web.Models; using CoiniumServ.Statistics; using Nancy; +using Nancy.CustomErrors; namespace CoiniumServ.Server.Web.Modules { public class PoolModule : NancyModule { - public PoolModule(IPoolManager poolManager, IStatistics statistics) + public PoolModule(IStatisticsManager statisticsManager, IPoolManager poolManager) + :base("/pool") { - Get["/pool/{slug}/"] = _ => + Get["/{slug}"] = _ => { - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. - ViewBag.Pools = statistics.Pools; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; - var pool = poolManager.GetBySymbol(_.slug); // find the requested pool. TODO: use IStatistics instead + var pool = poolManager.Get(_.slug); // find the requested pool. TODO: use IStatistics instead if (pool == null) // make sure queried pool exists. { ViewBag.Title = "Error"; ViewBag.Heading = "An error occured!"; - return View["error", new ErrorModel + return View["error", new ErrorViewModel { Summary = "Pool not found", Details = string.Format("The requested pool does not exist: {0}", _.slug) @@ -61,19 +62,19 @@ public PoolModule(IPoolManager poolManager, IStatistics statistics) }]; }; - Get["/pool/{slug}/workers"] = _ => + Get["/{slug}/workers"] = _ => { - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. - ViewBag.Pools = statistics.Pools; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; - var pool = statistics.Pools.GetBySymbol(_.slug); // find the requested pool. + var pool = poolManager.Get(_.slug); // find the requested pool. if (pool == null) // make sure queried pool exists. { ViewBag.Title = "Error"; ViewBag.Heading = "An error occured!"; - return View["error", new ErrorModel + return View["error", new ErrorViewModel { Summary = "Pool not found", Details = string.Format("The requested pool does not exist: {0}", _.slug) @@ -86,23 +87,23 @@ public PoolModule(IPoolManager poolManager, IStatistics statistics) // return our view return View["workers", new WorkersModel { - Workers = pool.Workers + Workers = pool.MinerManager.Miners }]; }; - Get["/pool/{slug}/round"] = _ => + Get["/{slug}/round"] = _ => { - ViewBag.LastUpdate = statistics.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. - ViewBag.Pools = statistics.Pools; + ViewBag.LastUpdate = statisticsManager.LastUpdate.ToString("HH:mm:ss tt zz"); // last statistics update. + ViewBag.Pools = poolManager; - var pool = statistics.Pools.GetBySymbol(_.slug); // find the requested pool. + var pool = poolManager.Get(_.slug); // find the requested pool. if (pool == null) // make sure queried pool exists. { ViewBag.Title = "Error"; ViewBag.Heading = "An error occured!"; - return View["error", new ErrorModel + return View["error", new ErrorViewModel { Summary = "Pool not found", Details = string.Format("The requested pool does not exist: {0}", _.slug) @@ -115,8 +116,8 @@ public PoolModule(IPoolManager poolManager, IStatistics statistics) // return our view return View["round", new CurrentRoundModel { - Round = pool.Round, - Shares = pool.CurrentRoundShares + Round = pool.NetworkStats.Round, + Shares = pool.RoundShares }]; }; } diff --git a/src/CoiniumServ/Server/Web/RootPathProvider.cs b/src/CoiniumServ/Server/Web/RootPathProvider.cs index 6a687eeb1..ed68f3881 100644 --- a/src/CoiniumServ/Server/Web/RootPathProvider.cs +++ b/src/CoiniumServ/Server/Web/RootPathProvider.cs @@ -20,17 +20,21 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Utils.Helpers.IO; using Nancy; namespace CoiniumServ.Server.Web { - public class CustomRootPathProvider : IRootPathProvider + public class RootPathProvider : IRootPathProvider { + private string _rootPath; // root path of the web files. + public string GetRootPath() { - return FileHelpers.GetAbsolutePath("web/default"); + if (string.IsNullOrEmpty(_rootPath)) // make sure we already determined the absolute root path + _rootPath = FileHelpers.GetAbsolutePath("web/default"); // if not yet do so. + + return _rootPath; } } } diff --git a/src/CoiniumServ/Server/Web/Service/IJsonService.cs b/src/CoiniumServ/Server/Web/Service/IJsonService.cs new file mode 100644 index 000000000..d5fb63836 --- /dev/null +++ b/src/CoiniumServ/Server/Web/Service/IJsonService.cs @@ -0,0 +1,31 @@ +#region License +// +// CoiniumServ - Crypto Currency Mining Pool Server Software +// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org +// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// For the terms of this license, see licenses/gpl_v3.txt. +// +// Alternatively, you can license this software under a commercial +// license or white-label it as set out in licenses/commercial.txt. +// +#endregion +namespace CoiniumServ.Server.Web.Service +{ + public interface IJsonService + { + string ServiceResponse { get; } + + void Recache(); + } +} diff --git a/src/CoiniumServ/Server/Web/WebBootstrapper.cs b/src/CoiniumServ/Server/Web/WebBootstrapper.cs index 3393fed8c..2b0b1e3b2 100644 --- a/src/CoiniumServ/Server/Web/WebBootstrapper.cs +++ b/src/CoiniumServ/Server/Web/WebBootstrapper.cs @@ -20,9 +20,8 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; -using CoiniumServ.Repository.Context; +using CoiniumServ.Container.Context; using Metrics; using Nancy; using Nancy.Bootstrapper; @@ -49,7 +48,7 @@ protected override void ApplicationStartup(TinyIoCContainer container, IPipeline var configManager = container.Resolve(); // todo: enable authentication support - if(configManager.WebServerConfig.Backend.MetricsEnabled) + if (configManager.WebServerConfig.Backend.MetricsEnabled) Metric.Config.WithNancy(config => config.WithMetricsModule("/admin/metrics")); CustomErrors.Enable(pipelines, new ErrorConfiguration()); @@ -57,7 +56,7 @@ protected override void ApplicationStartup(TinyIoCContainer container, IPipeline protected override IRootPathProvider RootPathProvider { - get { return new CustomRootPathProvider(); } + get { return new RootPathProvider(); } } protected override void ConfigureConventions(NancyConventions nancyConventions) diff --git a/src/CoiniumServ/Server/Web/WebServer.cs b/src/CoiniumServ/Server/Web/WebServer.cs index 11852ba4d..877718f9e 100644 --- a/src/CoiniumServ/Server/Web/WebServer.cs +++ b/src/CoiniumServ/Server/Web/WebServer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; using Nancy.Bootstrapper; using Serilog; diff --git a/src/CoiniumServ/Server/Web/WebServerConfig.cs b/src/CoiniumServ/Server/Web/WebServerConfig.cs index 6d180cdfc..5807dff14 100644 --- a/src/CoiniumServ/Server/Web/WebServerConfig.cs +++ b/src/CoiniumServ/Server/Web/WebServerConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Server.Web.Modules; using CoiniumServ.Statistics; diff --git a/src/CoiniumServ/Shares/IShare.cs b/src/CoiniumServ/Shares/IShare.cs index e61dca2b8..4c6ea09a2 100644 --- a/src/CoiniumServ/Shares/IShare.cs +++ b/src/CoiniumServ/Shares/IShare.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Cryptology; using CoiniumServ.Daemon.Responses; diff --git a/src/CoiniumServ/Shares/IShareManager.cs b/src/CoiniumServ/Shares/IShareManager.cs index 6f5d29bde..c5d6590cd 100644 --- a/src/CoiniumServ/Shares/IShareManager.cs +++ b/src/CoiniumServ/Shares/IShareManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Vanilla; diff --git a/src/CoiniumServ/Shares/Share.cs b/src/CoiniumServ/Shares/Share.cs index a2472a1a4..455cbe5e0 100644 --- a/src/CoiniumServ/Shares/Share.cs +++ b/src/CoiniumServ/Shares/Share.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Coin.Coinbase; using CoiniumServ.Cryptology; @@ -133,7 +132,7 @@ public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, st HeaderValue = new BigInteger(HeaderHash); // calculate the share difficulty - Difficulty = ((double)new BigRational(Algorithms.Diff1, HeaderValue)) * Job.HashAlgorithm.Multiplier; + Difficulty = ((double)new BigRational(AlgorithmManager.Diff1, HeaderValue)) * Job.HashAlgorithm.Multiplier; // calculate the block difficulty BlockDiffAdjusted = Job.Difficulty * Job.HashAlgorithm.Multiplier; @@ -142,8 +141,8 @@ public Share(IStratumMiner miner, UInt64 jobId, IJob job, string extraNonce2, st if (Job.Target >= HeaderValue) { IsBlockCandidate = true; - BlockHex = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer); - BlockHash = HeaderBuffer.DoubleDigest().ReverseBuffer(); // TODO: make sure this is okay! + BlockHex = Serializers.SerializeBlock(Job, HeaderBuffer, CoinbaseBuffer, miner.Pool.Config.Coin.IsPOS); + BlockHash = HeaderBuffer.DoubleDigest().ReverseBuffer(); } else { diff --git a/src/CoiniumServ/Shares/ShareEventArgs.cs b/src/CoiniumServ/Shares/ShareEventArgs.cs index 4c70dd77a..6d67fa14d 100644 --- a/src/CoiniumServ/Shares/ShareEventArgs.cs +++ b/src/CoiniumServ/Shares/ShareEventArgs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Server.Mining.Stratum; diff --git a/src/CoiniumServ/Shares/ShareManager.cs b/src/CoiniumServ/Shares/ShareManager.cs index 89194f952..e9a6cd066 100644 --- a/src/CoiniumServ/Shares/ShareManager.cs +++ b/src/CoiniumServ/Shares/ShareManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Diagnostics; using System.Linq; @@ -29,7 +28,8 @@ using CoiniumServ.Daemon; using CoiniumServ.Jobs.Tracker; using CoiniumServ.Persistance; -using CoiniumServ.Pools.Config; +using CoiniumServ.Persistance.Layers; +using CoiniumServ.Pools; using CoiniumServ.Server.Mining.Stratum; using CoiniumServ.Server.Mining.Stratum.Errors; using CoiniumServ.Server.Mining.Vanilla; @@ -48,7 +48,7 @@ public class ShareManager : IShareManager private readonly IDaemonClient _daemonClient; - private readonly IStorage _storage; + private readonly IStorageLayer _storageLayer; private readonly IBlockProcessor _blockProcessor; @@ -62,14 +62,14 @@ public class ShareManager : IShareManager /// /// /// - /// + /// /// - public ShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorage storage, IBlockProcessor blockProcessor) + public ShareManager(IPoolConfig poolConfig, IDaemonClient daemonClient, IJobTracker jobTracker, IStorageLayer storageLayer, IBlockProcessor blockProcessor) { _poolConfig = poolConfig; _daemonClient = daemonClient; _jobTracker = jobTracker; - _storage = storage; + _storageLayer = storageLayer; _blockProcessor = blockProcessor; _logger = Log.ForContext().ForContext("Component", poolConfig.Coin.Name); } @@ -112,7 +112,7 @@ private void HandleValidShare(IShare share) var miner = (IStratumMiner) share.Miner; miner.ValidShares++; - _storage.AddShare(share); // commit the share. + _storageLayer.AddShare(share); // commit the share. _logger.Debug("Share accepted at {0:0.00}/{1} by miner {2:l}", share.Difficulty, miner.Difficulty, miner.Username); // check if share is a block candidate @@ -134,7 +134,8 @@ private void HandleValidShare(IShare share) OnBlockFound(EventArgs.Empty); // notify the listeners about the new block. - _storage.AddBlock(share); // commit the block details to storage. + _storageLayer.AddBlock(share); // commit the block details to storage. + _storageLayer.MoveShares(share); // move associated shares. } private void HandleInvalidShare(IShare share) diff --git a/src/CoiniumServ/Statistics/Algorithms.cs b/src/CoiniumServ/Statistics/Algorithms.cs deleted file mode 100644 index 2201a2388..000000000 --- a/src/CoiniumServ/Statistics/Algorithms.cs +++ /dev/null @@ -1,96 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using CoiniumServ.Pools; -using Newtonsoft.Json; - -namespace CoiniumServ.Statistics -{ - public class Algorithms : IAlgorithms - { - public string Json { get; private set; } - - private readonly Dictionary _algorithms; - private readonly Dictionary _response; - private readonly IPoolManager _poolManager; - - public Algorithms(IPoolManager poolManager) - { - _poolManager = poolManager; - _algorithms = new Dictionary(); - _response = new Dictionary(); - } - - public void Recache(object state) - { - // recache data. - foreach (var pair in _algorithms) - { - pair.Value.Reset(); - } - - foreach (var pool in _poolManager.Pools) - { - if (!_algorithms.ContainsKey(pool.Config.Coin.Algorithm)) - _algorithms.Add(pool.Config.Coin.Algorithm, new PerAlgorithm(pool.Config.Coin.Algorithm)); - - _algorithms[pool.Config.Coin.Algorithm].Recache(pool.Statistics.Hashrate, pool.Statistics.WorkerCount); - } - - // recache response. - _response.Clear(); - - foreach (var pair in _algorithms) - { - var algorithm = pair.Value; - _response.Add(algorithm.Name, algorithm.GetResponseObject()); - } - - Json = JsonConvert.SerializeObject(_response); - } - - public IPerAlgorithm GetByName(string name) - { - return _algorithms.Values.FirstOrDefault(pair => pair.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - } - - public IEnumerator> GetEnumerator() - { - return _algorithms.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public object GetResponseObject() - { - return _response; - } - } -} diff --git a/src/CoiniumServ/Statistics/BlockStats.cs b/src/CoiniumServ/Statistics/BlockStats.cs deleted file mode 100644 index 41e90d1de..000000000 --- a/src/CoiniumServ/Statistics/BlockStats.cs +++ /dev/null @@ -1,57 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using CoiniumServ.Persistance; - -namespace CoiniumServ.Statistics -{ - public class BlocksCount:IBlocksCount - { - public int Pending { get; private set; } - public int Confirmed { get; private set; } - public int Orphaned { get; private set; } - public int Total { get; private set; } - public ILatestBlocks Latest { get; private set; } - - private readonly IStorage _storage; - - public BlocksCount(ILatestBlocks latestBlocks, IStorage storage) - { - _storage = storage; - Latest = latestBlocks; - } - - public void Recache(object state) - { - // get block statistics. - var blockCounts = _storage.GetBlockCounts(); - - // read block stats. - Pending = blockCounts.ContainsKey("pending") ? blockCounts["pending"] : 0; - Confirmed = blockCounts.ContainsKey("confirmed") ? blockCounts["confirmed"] : 0; - Orphaned = blockCounts.ContainsKey("orphaned") ? blockCounts["orphaned"] : 0; - - Latest.Recache(state); - } - } -} diff --git a/src/CoiniumServ/Statistics/Global.cs b/src/CoiniumServ/Statistics/Global.cs deleted file mode 100644 index 874093f72..000000000 --- a/src/CoiniumServ/Statistics/Global.cs +++ /dev/null @@ -1,80 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System; -using System.Dynamic; -using CoiniumServ.Configuration; -using Metrics; -using Newtonsoft.Json; - -namespace CoiniumServ.Statistics -{ - public class Global : IGlobal - { - public UInt64 Hashrate { get; private set; } - public Int32 WorkerCount { get; private set; } - public string Json { get; private set; } - - private readonly dynamic _response; - private readonly IPools _pools; - private readonly IAlgorithms _algorithms; - - public Global(IPools pools, IAlgorithms algorithms, IConfigManager configManager) - { - _pools = pools; - _algorithms = algorithms; - _response = new ExpandoObject(); - - - // add metrics - if(configManager.WebServerConfig.Backend.MetricsEnabled) - Metric.Gauge("global-workers", () => WorkerCount, Unit.Items); - Metric.Gauge("global-hashrate", () => Hashrate, Unit.Custom("hashes")); - } - - public void Recache(object state) - { - // recache data. - Hashrate = 0; - WorkerCount = 0; - - foreach (var pair in _pools) - { - Hashrate += pair.Value.Hashrate; - WorkerCount += pair.Value.WorkerCount; - } - - // recache response. - _response.hashrate = Hashrate; - _response.workers = WorkerCount; - _response.algorithms = _algorithms.GetResponseObject(); - - Json = JsonConvert.SerializeObject(_response); - } - - public object GetResponseObject() - { - return _response; - } - } -} diff --git a/src/CoiniumServ/Statistics/IStatistics.cs b/src/CoiniumServ/Statistics/INetworkStats.cs similarity index 75% rename from src/CoiniumServ/Statistics/IStatistics.cs rename to src/CoiniumServ/Statistics/INetworkStats.cs index 49c6b9af5..2fc856c3b 100644 --- a/src/CoiniumServ/Statistics/IStatistics.cs +++ b/src/CoiniumServ/Statistics/INetworkStats.cs @@ -20,19 +20,22 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; +using CoiniumServ.Server.Web.Service; +using Newtonsoft.Json; namespace CoiniumServ.Statistics { - public interface IStatistics + [JsonObject(MemberSerialization.OptIn)] + public interface INetworkStats: IJsonService { - IGlobal Global { get; } - - IAlgorithms Algorithms { get; } + [JsonProperty("difficulty")] + double Difficulty { get; } - IPools Pools { get; } + [JsonProperty("round")] + int Round { get; } - DateTime LastUpdate { get; } + [JsonProperty("hashrate")] + UInt64 Hashrate { get; } } } diff --git a/src/CoiniumServ/Statistics/IStatisticsConfig.cs b/src/CoiniumServ/Statistics/IStatisticsConfig.cs index 9837338a1..dfb8e9606 100644 --- a/src/CoiniumServ/Statistics/IStatisticsConfig.cs +++ b/src/CoiniumServ/Statistics/IStatisticsConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Statistics diff --git a/src/CoiniumServ/Statistics/IPerPool.cs b/src/CoiniumServ/Statistics/IStatisticsManager.cs similarity index 67% rename from src/CoiniumServ/Statistics/IPerPool.cs rename to src/CoiniumServ/Statistics/IStatisticsManager.cs index 62dc62776..6843db8b9 100644 --- a/src/CoiniumServ/Statistics/IPerPool.cs +++ b/src/CoiniumServ/Statistics/IStatisticsManager.cs @@ -20,34 +20,28 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; -using System.Collections.Generic; -using CoiniumServ.Pools.Config; +using CoiniumServ.Cryptology.Algorithms; +using CoiniumServ.Pools; +using CoiniumServ.Server.Web.Service; +using Newtonsoft.Json; namespace CoiniumServ.Statistics { - public interface IPerPool:IJsonResponse, IStatisticsProvider + [JsonObject(MemberSerialization.OptIn)] + public interface IStatisticsManager:IJsonService { + [JsonProperty("hashrate")] UInt64 Hashrate { get; } - UInt64 NetworkHashrate { get; } - - Int32 WorkerCount { get; } - - Dictionary Workers { get; } - Dictionary CurrentRoundShares { get; } - - double Difficulty { get; } - - int Round { get; } - - IBlocksCount Blocks { get; } + [JsonProperty("miners")] + Int32 MinerCount { get; } - IPoolConfig Config { get; } + [JsonProperty("lastUpdate")] + DateTime LastUpdate { get; } - string WorkersJson { get; } + IAlgorithmManager Algorithms { get; } - string CurrentRoundJson { get; } + IPoolManager Pools { get; } } } diff --git a/src/CoiniumServ/Statistics/PerPool.cs b/src/CoiniumServ/Statistics/PerPool.cs deleted file mode 100644 index b696a816f..000000000 --- a/src/CoiniumServ/Statistics/PerPool.cs +++ /dev/null @@ -1,172 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System; -using System.Collections.Generic; -using System.Dynamic; -using System.Linq; -using CoiniumServ.Configuration; -using CoiniumServ.Cryptology.Algorithms; -using CoiniumServ.Daemon; -using CoiniumServ.Daemon.Exceptions; -using CoiniumServ.Miners; -using CoiniumServ.Persistance; -using CoiniumServ.Pools.Config; -using CoiniumServ.Utils.Helpers.Time; -using Newtonsoft.Json; - -namespace CoiniumServ.Statistics -{ - public class PerPool:IPerPool - { - public ulong Hashrate { get; private set; } - public ulong NetworkHashrate { get; private set; } - public int WorkerCount { get; private set; } - public Dictionary Workers { get; private set; } // todo: convert to enumurable object. - public Dictionary CurrentRoundShares { get; private set; } // todo: convert to enumurable object. - public double Difficulty { get; private set; } - public int Round { get; private set; } - public IBlocksCount Blocks { get; private set; } - public IPoolConfig Config { get; private set; } - - public string Json { get; private set; } - - public string WorkersJson { get; private set; } - - public string CurrentRoundJson { get; private set; } - - private readonly IDaemonClient _daemonClient; - private readonly IStorage _storage; - private readonly IMinerManager _minerManager; - private readonly IStatisticsConfig _statisticsConfig; - - private readonly dynamic _response; - - private readonly double _shareMultiplier; - - public PerPool(IPoolConfig poolConfig, IConfigManager configManager, IDaemonClient daemonClient,IMinerManager minerManager, IHashAlgorithm hashAlgorithm, IBlocksCount blockStatistics, IStorage storage) - { - Config = poolConfig; - _statisticsConfig = configManager.WebServerConfig.Statistics; - _daemonClient = daemonClient; - _minerManager = minerManager; - _storage = storage; - - Blocks = blockStatistics; - Workers = new Dictionary(); - - _response = new ExpandoObject(); - _shareMultiplier = Math.Pow(2, 32) / hashAlgorithm.Multiplier; - } - - public void Recache(object state) - { - // recache data. - WorkerCount = _minerManager.Miners.Count; - - ReadCoinData(); // read coin data. - ReadHashrate(); // read hashrate data. - RecacheWorkers(); // recache the worker data. - RecacheRound(); // recache the current round shares data. - - Blocks.Recache(state); // recache the blocks. - - RecacheJson(); - } - - private void ReadCoinData() - { - try - { - var miningInfo = _daemonClient.GetMiningInfo(); - NetworkHashrate = miningInfo.NetworkHashps; - Difficulty = miningInfo.Difficulty; - Round = miningInfo.Blocks + 1; - } - catch (RpcException) - { - NetworkHashrate = 0; - Difficulty = 0; - Round = -1; - } - } - - private void ReadHashrate() - { - // read hashrate stats. - var windowTime = TimeHelpers.NowInUnixTime() - _statisticsConfig.HashrateWindow; - _storage.DeleteExpiredHashrateData(windowTime); - var hashrates = _storage.GetHashrateData(windowTime); - - double total = hashrates.Sum(pair => pair.Value); - Hashrate = Convert.ToUInt64(_shareMultiplier * total / _statisticsConfig.HashrateWindow); - } - - private void RecacheWorkers() - { - Workers.Clear(); - var shares = _storage.GetSharesForCurrentRound(); - - foreach (var miner in _minerManager.Miners) - { - if (!miner.Authenticated) - continue; - - Workers.Add(miner.Username, shares.ContainsKey(miner.Username) ? shares[miner.Username] : 0); - } - - WorkersJson = JsonConvert.SerializeObject(Workers); - } - - private void RecacheRound() - { - CurrentRoundShares = _storage.GetSharesForCurrentRound(); - - CurrentRoundJson = JsonConvert.SerializeObject(CurrentRoundShares); - } - - private void RecacheJson() - { - // recache json response. - _response.workers = WorkerCount; - _response.hashrate = Hashrate; - - _response.coin = new ExpandoObject(); - _response.coin.symbol = Config.Coin.Symbol; - _response.coin.name = Config.Coin.Name; - _response.coin.algorithm = Config.Coin.Algorithm; - - _response.network = new ExpandoObject(); - _response.network.currentBlock = Round; - _response.network.difficulty = Difficulty; - _response.network.hashrate = NetworkHashrate; - - Json = JsonConvert.SerializeObject(_response); - } - - public object GetResponseObject() - { - return _response; - } - } -} diff --git a/src/CoiniumServ/Statistics/Pools.cs b/src/CoiniumServ/Statistics/Pools.cs deleted file mode 100644 index 615958717..000000000 --- a/src/CoiniumServ/Statistics/Pools.cs +++ /dev/null @@ -1,93 +0,0 @@ -#region License -// -// CoiniumServ - Crypto Currency Mining Pool Server Software -// Copyright (C) 2013 - 2014, CoiniumServ Project - http://www.coinium.org -// http://www.coiniumserv.com - https://github.com/CoiniumServ/CoiniumServ -// -// This software is dual-licensed: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// For the terms of this license, see licenses/gpl_v3.txt. -// -// Alternatively, you can license this software under a commercial -// license or white-label it as set out in licenses/commercial.txt. -// -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Dynamic; -using System.Linq; -using CoiniumServ.Pools; -using Newtonsoft.Json; - -namespace CoiniumServ.Statistics -{ - public class Pools:IPools - { - public string Json { get; private set; } - - private readonly Dictionary _pools; - private readonly IPoolManager _poolManager; - private readonly Dictionary _response; - - public Pools(IPoolManager poolManager) - { - _poolManager = poolManager; - _pools = new Dictionary(); - _response = new Dictionary(); - - foreach (var pool in poolManager.Pools) - { - _pools.Add(pool.Config.Coin.Name, pool.Statistics); - } - } - - public IPerPool GetBySymbol(string symbol) - { - return _pools.Values.FirstOrDefault(pair => pair.Config.Coin.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase)); - } - - public IEnumerator> GetEnumerator() - { - return _pools.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public void Recache(object state) - { - // recache data. - foreach (var pool in _poolManager.Pools) - { - pool.Statistics.Recache(state); - } - - // recache response. - _response.Clear(); - - foreach (var pool in _poolManager.Pools) - { - _response.Add(pool.Config.Coin.Symbol.ToLower(), (ExpandoObject)pool.Statistics.GetResponseObject()); - } - - Json = JsonConvert.SerializeObject(_response); - } - - public object GetResponseObject() - { - return _response; - } - } -} diff --git a/src/CoiniumServ/Statistics/StatisticsConfig.cs b/src/CoiniumServ/Statistics/StatisticsConfig.cs index 3a1b51974..bc22d07a5 100644 --- a/src/CoiniumServ/Statistics/StatisticsConfig.cs +++ b/src/CoiniumServ/Statistics/StatisticsConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Statistics/Statistics.cs b/src/CoiniumServ/Statistics/StatisticsManager.cs similarity index 60% rename from src/CoiniumServ/Statistics/Statistics.cs rename to src/CoiniumServ/Statistics/StatisticsManager.cs index c04d3927e..919959f14 100644 --- a/src/CoiniumServ/Statistics/Statistics.cs +++ b/src/CoiniumServ/Statistics/StatisticsManager.cs @@ -20,22 +20,24 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Diagnostics; using System.Threading; using CoiniumServ.Configuration; -using CoiniumServ.Factories; +using CoiniumServ.Cryptology.Algorithms; +using CoiniumServ.Pools; +using Newtonsoft.Json; using Serilog; namespace CoiniumServ.Statistics { - public class Statistics:IStatistics, IStatisticsProvider + public class StatisticsManager:IStatisticsManager { - public IGlobal Global { get; private set; } - public IAlgorithms Algorithms { get; private set; } - public IPools Pools { get; private set; } + public ulong Hashrate { get; private set; } + public int MinerCount { get; private set; } public DateTime LastUpdate { get; private set; } + public IAlgorithmManager Algorithms { get; private set; } + public IPoolManager Pools { get; private set; } private readonly Timer _recacheTimer; // timer for recaching stastics. @@ -45,35 +47,55 @@ public class Statistics:IStatistics, IStatisticsProvider private readonly ILogger _logger; - public Statistics(IConfigManager configManager, IObjectFactory statisticsObjectFactory) + public StatisticsManager(IConfigManager configManager, IPoolManager poolManager, IAlgorithmManager algorithmManager) { _config = configManager.WebServerConfig.Statistics; + Pools = poolManager; + Algorithms = algorithmManager; - Pools = statisticsObjectFactory.GetPoolStats(); - Global = statisticsObjectFactory.GetGlobalStatistics(); - Algorithms = statisticsObjectFactory.GetAlgorithmStatistics(); - - _logger = Log.ForContext(); + _logger = Log.ForContext(); _recacheTimer = new Timer(Recache, null, Timeout.Infinite, Timeout.Infinite); // create the timer as disabled. Recache(null); // recache data initially. } - public void Recache(object state) + public string ServiceResponse { get; private set; } + + public void Recache() { _stopWatch.Start(); // recache data. - Pools.Recache(state); - Algorithms.Recache(state); - Global.Recache(state); + Pools.Recache(); + Algorithms.Recache(); + RecacheGlobal(); LastUpdate = DateTime.Now; + // cache the json-service response + ServiceResponse = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + _logger.Debug("Recached statistics - took {0:0.000} seconds", (float)_stopWatch.ElapsedMilliseconds / 1000); _stopWatch.Reset(); _recacheTimer.Change(_config.UpdateInterval * 1000, Timeout.Infinite); // reset the recache timer. } + + private void Recache(object state) + { + Recache(); + } + + private void RecacheGlobal() + { + Hashrate = 0; + MinerCount = 0; + + foreach (var pool in Pools) + { + Hashrate += pool.Hashrate; + MinerCount += pool.MinerManager.Count; + } + } } } diff --git a/src/CoiniumServ/Transactions/GenerationTransaction.cs b/src/CoiniumServ/Transactions/GenerationTransaction.cs index 631a1da40..145f15c13 100644 --- a/src/CoiniumServ/Transactions/GenerationTransaction.cs +++ b/src/CoiniumServ/Transactions/GenerationTransaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.IO; @@ -30,8 +29,7 @@ using CoiniumServ.Daemon; using CoiniumServ.Daemon.Responses; using CoiniumServ.Jobs; -using CoiniumServ.Miners; -using CoiniumServ.Payments; +using CoiniumServ.Pools; using CoiniumServ.Transactions.Script; using CoiniumServ.Utils.Helpers.Time; using Gibbed.IO; @@ -109,7 +107,7 @@ public UInt32 InputsCount public IExtraNonce ExtraNonce { get; private set; } - public bool TxMessageEnabled { get; private set; } + public IPoolConfig PoolConfig { get; private set; } /// /// Creates a new instance of generation transaction. @@ -117,26 +115,23 @@ public UInt32 InputsCount /// The extra nonce. /// The daemon client. /// The block template. - /// - /// - /// - /// tx messages supported by the coin? + /// The associated pool's configuration /// /// Reference implementations: /// https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js /// https://github.com/Crypto-Expert/stratum-mining/blob/master/lib/coinbasetx.py /// - public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, IBlockTemplate blockTemplate, IWalletConfig walletConfig, IRewardsConfig rewardsConfig, IMetaConfig metaConfig, bool txMessageEnabled) + public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, IBlockTemplate blockTemplate, IPoolConfig poolConfig) { // TODO: we need a whole refactoring here. // we should use DI and it shouldn't really require daemonClient connection to function. BlockTemplate = blockTemplate; ExtraNonce = extraNonce; - TxMessageEnabled = txMessageEnabled; + PoolConfig = poolConfig; - Version = (UInt32)(txMessageEnabled ? 2 : 1); - TxMessage = Serializers.SerializeString(metaConfig.TxMessage); + Version = (UInt32)(poolConfig.Coin.SupportsTxMessages ? 2 : 1); + TxMessage = Serializers.SerializeString(poolConfig.Meta.TxMessage); LockTime = 0; // transaction inputs @@ -166,7 +161,7 @@ public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, double blockReward = BlockTemplate.Coinbasevalue; // the amount rewarded by the block. // generate output transactions for recipients (set in config). - foreach (var pair in rewardsConfig) + foreach (var pair in poolConfig.Rewards) { var amount = blockReward * pair.Value / 100; // calculate the amount he recieves based on the percent of his shares. blockReward -= amount; @@ -175,7 +170,7 @@ public GenerationTransaction(IExtraNonce extraNonce, IDaemonClient daemonClient, } // send the remaining coins to pool's central wallet. - Outputs.AddPoolWallet(walletConfig.Adress, blockReward); + Outputs.AddPoolWallet(poolConfig.Wallet.Adress, blockReward); } public void Create() @@ -185,7 +180,8 @@ public void Create() { stream.WriteValueU32(Version.LittleEndian()); // write version - // for proof-of-stake coins we need here timestamp - https://github.com/zone117x/node-stratum-pool/blob/b24151729d77e0439e092fe3a1cdbba71ca5d12e/lib/transactions.js#L210 + if(PoolConfig.Coin.IsPOS) // if coin is a proof-of-stake coin + stream.WriteValueU32(BlockTemplate.CurTime); // include time-stamp in the transaction. // write transaction input. stream.WriteBytes(Serializers.VarInt(InputsCount)); @@ -220,7 +216,7 @@ a valid share and/or block. */ stream.WriteValueU32(LockTime.LittleEndian()); - if (TxMessageEnabled) + if (PoolConfig.Coin.SupportsTxMessages) stream.WriteBytes(TxMessage); Final = stream.ToArray(); diff --git a/src/CoiniumServ/Transactions/IGenerationTransaction.cs b/src/CoiniumServ/Transactions/IGenerationTransaction.cs index 85ab702d8..737d54885 100644 --- a/src/CoiniumServ/Transactions/IGenerationTransaction.cs +++ b/src/CoiniumServ/Transactions/IGenerationTransaction.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; diff --git a/src/CoiniumServ/Transactions/IOutputs.cs b/src/CoiniumServ/Transactions/IOutputs.cs index 225c6e822..ba454b481 100644 --- a/src/CoiniumServ/Transactions/IOutputs.cs +++ b/src/CoiniumServ/Transactions/IOutputs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; namespace CoiniumServ.Transactions diff --git a/src/CoiniumServ/Transactions/OutPoint.cs b/src/CoiniumServ/Transactions/OutPoint.cs index 0e20009a3..6562d39e2 100644 --- a/src/CoiniumServ/Transactions/OutPoint.cs +++ b/src/CoiniumServ/Transactions/OutPoint.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Cryptology; diff --git a/src/CoiniumServ/Transactions/Outputs.cs b/src/CoiniumServ/Transactions/Outputs.cs index e230296cd..3625ed441 100644 --- a/src/CoiniumServ/Transactions/Outputs.cs +++ b/src/CoiniumServ/Transactions/Outputs.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.IO; diff --git a/src/CoiniumServ/Transactions/Script/SignatureScript.cs b/src/CoiniumServ/Transactions/Script/SignatureScript.cs index 844e187a8..f3a3df57c 100644 --- a/src/CoiniumServ/Transactions/Script/SignatureScript.cs +++ b/src/CoiniumServ/Transactions/Script/SignatureScript.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.IO; using CoiniumServ.Coin.Coinbase; diff --git a/src/CoiniumServ/Transactions/TxIn.cs b/src/CoiniumServ/Transactions/TxIn.cs index 6f547c45e..69e032bb1 100644 --- a/src/CoiniumServ/Transactions/TxIn.cs +++ b/src/CoiniumServ/Transactions/TxIn.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using CoiniumServ.Transactions.Script; diff --git a/src/CoiniumServ/Transactions/TxOut.cs b/src/CoiniumServ/Transactions/TxOut.cs index f974f3666..745e0a0d5 100644 --- a/src/CoiniumServ/Transactions/TxOut.cs +++ b/src/CoiniumServ/Transactions/TxOut.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Transactions diff --git a/src/CoiniumServ/Transactions/Utils/TransactionUtils.cs b/src/CoiniumServ/Transactions/Utils/TransactionUtils.cs index f47ff3eb2..5e7c8731d 100644 --- a/src/CoiniumServ/Transactions/Utils/TransactionUtils.cs +++ b/src/CoiniumServ/Transactions/Utils/TransactionUtils.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Utils/Buffers/IRingBuffer.cs b/src/CoiniumServ/Utils/Buffers/IRingBuffer.cs index f41440147..65d4cd67b 100644 --- a/src/CoiniumServ/Utils/Buffers/IRingBuffer.cs +++ b/src/CoiniumServ/Utils/Buffers/IRingBuffer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Utils.Buffers { public interface IRingBuffer diff --git a/src/CoiniumServ/Utils/Buffers/RingBuffer.cs b/src/CoiniumServ/Utils/Buffers/RingBuffer.cs index 3831498c1..8168aead1 100644 --- a/src/CoiniumServ/Utils/Buffers/RingBuffer.cs +++ b/src/CoiniumServ/Utils/Buffers/RingBuffer.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Linq; namespace CoiniumServ.Utils.Buffers diff --git a/src/CoiniumServ/Utils/Commands/CommandAttributes.cs b/src/CoiniumServ/Utils/Commands/CommandAttributes.cs index 3c8ddbbaa..26b6d43a0 100644 --- a/src/CoiniumServ/Utils/Commands/CommandAttributes.cs +++ b/src/CoiniumServ/Utils/Commands/CommandAttributes.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Utils.Commands diff --git a/src/CoiniumServ/Utils/Commands/CommandGroup.cs b/src/CoiniumServ/Utils/Commands/CommandGroup.cs index 15a4b0098..9779a60ef 100644 --- a/src/CoiniumServ/Utils/Commands/CommandGroup.cs +++ b/src/CoiniumServ/Utils/Commands/CommandGroup.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections.Generic; using System.Linq; using System.Reflection; diff --git a/src/CoiniumServ/Utils/Commands/CommandManager.cs b/src/CoiniumServ/Utils/Commands/CommandManager.cs index a43d93ffd..3a782ce84 100644 --- a/src/CoiniumServ/Utils/Commands/CommandManager.cs +++ b/src/CoiniumServ/Utils/Commands/CommandManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Utils/ConsoleWindow.cs b/src/CoiniumServ/Utils/ConsoleWindow.cs index d8b6cccde..ab8854cb1 100644 --- a/src/CoiniumServ/Utils/ConsoleWindow.cs +++ b/src/CoiniumServ/Utils/ConsoleWindow.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Utils diff --git a/src/CoiniumServ/Utils/Extensions/ArrayExtensions.cs b/src/CoiniumServ/Utils/Extensions/ArrayExtensions.cs index be5a90a36..945e5c0d5 100644 --- a/src/CoiniumServ/Utils/Extensions/ArrayExtensions.cs +++ b/src/CoiniumServ/Utils/Extensions/ArrayExtensions.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.IO; diff --git a/src/CoiniumServ/Utils/Extensions/EnumerableExtensions.cs b/src/CoiniumServ/Utils/Extensions/EnumerableExtensions.cs index 79d44d867..717f79c9b 100644 --- a/src/CoiniumServ/Utils/Extensions/EnumerableExtensions.cs +++ b/src/CoiniumServ/Utils/Extensions/EnumerableExtensions.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq; diff --git a/src/CoiniumServ/Utils/Extensions/JsonExtensions.cs b/src/CoiniumServ/Utils/Extensions/JsonExtensions.cs index bb1d1e9ab..40fadfc3e 100644 --- a/src/CoiniumServ/Utils/Extensions/JsonExtensions.cs +++ b/src/CoiniumServ/Utils/Extensions/JsonExtensions.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Text; diff --git a/src/CoiniumServ/Utils/Extensions/StringExtensions.cs b/src/CoiniumServ/Utils/Extensions/StringExtensions.cs index 276568a28..66375dc56 100644 --- a/src/CoiniumServ/Utils/Extensions/StringExtensions.cs +++ b/src/CoiniumServ/Utils/Extensions/StringExtensions.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Utils.Extensions diff --git a/src/CoiniumServ/Utils/Helpers/Arrays/ArrayHelpers.cs b/src/CoiniumServ/Utils/Helpers/Arrays/ArrayHelpers.cs index e4002b26b..9ea388a75 100644 --- a/src/CoiniumServ/Utils/Helpers/Arrays/ArrayHelpers.cs +++ b/src/CoiniumServ/Utils/Helpers/Arrays/ArrayHelpers.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Utils.Helpers.Arrays diff --git a/src/CoiniumServ/Utils/Helpers/IO/FileHelpers.cs b/src/CoiniumServ/Utils/Helpers/IO/FileHelpers.cs index 90d027982..98cbc5667 100644 --- a/src/CoiniumServ/Utils/Helpers/IO/FileHelpers.cs +++ b/src/CoiniumServ/Utils/Helpers/IO/FileHelpers.cs @@ -20,12 +20,10 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using CoiniumServ.Utils.Platform; using Serilog; @@ -35,12 +33,12 @@ public static class FileHelpers { public static string AssemblyRoot { - get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } + get { return AppDomain.CurrentDomain.BaseDirectory; } } public static string GetAbsolutePath(string file) { - var path = string.Format("{0}/{1}", AssemblyRoot, file); // first get the path as *unix paths. + var path = Path.Combine(AssemblyRoot, file); // first get the path as *unix paths. if (PlatformManager.Framework == Frameworks.DotNet) // if we are running on windows, path = path.Replace('/', '\\'); // replace to windows-native paths. diff --git a/src/CoiniumServ/Utils/Helpers/Misc/Range.cs b/src/CoiniumServ/Utils/Helpers/Misc/Range.cs index 21b596879..c4d35fcb6 100644 --- a/src/CoiniumServ/Utils/Helpers/Misc/Range.cs +++ b/src/CoiniumServ/Utils/Helpers/Misc/Range.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System.Collections; using System.Collections.Generic; diff --git a/src/CoiniumServ/Utils/Helpers/Time/TimeHelpers.cs b/src/CoiniumServ/Utils/Helpers/Time/TimeHelpers.cs index 9235e7141..a44907348 100644 --- a/src/CoiniumServ/Utils/Helpers/Time/TimeHelpers.cs +++ b/src/CoiniumServ/Utils/Helpers/Time/TimeHelpers.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; namespace CoiniumServ.Utils.Helpers.Time @@ -31,5 +30,13 @@ public static Int32 NowInUnixTime() { return (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; } + + public static DateTime UnixTimeToDateTime(this int unixTimeStamp) + { + // Unix timestamp is seconds past epoch + var dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime(); + return dtDateTime; + } } } diff --git a/src/CoiniumServ/Utils/Helpers/Validation/Enforce.cs b/src/CoiniumServ/Utils/Helpers/Validation/Enforce.cs index aa25f0376..79399cff3 100644 --- a/src/CoiniumServ/Utils/Helpers/Validation/Enforce.cs +++ b/src/CoiniumServ/Utils/Helpers/Validation/Enforce.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Linq.Expressions; diff --git a/src/CoiniumServ/Utils/Numerics/BigInteger.cs b/src/CoiniumServ/Utils/Numerics/BigInteger.cs index 4052a5f37..c6ae7e2df 100644 --- a/src/CoiniumServ/Utils/Numerics/BigInteger.cs +++ b/src/CoiniumServ/Utils/Numerics/BigInteger.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Collections.Generic; using System.Globalization; diff --git a/src/CoiniumServ/Utils/Numerics/BigRational.cs b/src/CoiniumServ/Utils/Numerics/BigRational.cs index 92af3855d..1c2466800 100644 --- a/src/CoiniumServ/Utils/Numerics/BigRational.cs +++ b/src/CoiniumServ/Utils/Numerics/BigRational.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Globalization; using System.Runtime.InteropServices; diff --git a/src/CoiniumServ/Utils/Platform/PlatformManager.cs b/src/CoiniumServ/Utils/Platform/PlatformManager.cs index ebbf0c52c..9f041351b 100644 --- a/src/CoiniumServ/Utils/Platform/PlatformManager.cs +++ b/src/CoiniumServ/Utils/Platform/PlatformManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using System.Reflection; using Serilog; @@ -53,18 +52,14 @@ public class PlatformManager /// The mono version. public static string MonoVersion { get; private set; } - private static readonly ILogger Logger; - static PlatformManager() { - Logger = Log.ForContext(); - IdentifyPlatform(); } public static void PrintPlatformBanner() { - Logger.Information("Running over {0:l}, framework: {1:l} (v{2:l}).", + Log.ForContext().Information("Running over {0:l}, framework: {1:l} (v{2:l}).", Framework == Frameworks.DotNet ? ".Net" : string.Format("Mono {0}", MonoVersion), IsDotNet45 ? "4.5" : "4", FrameworkVersion); } diff --git a/src/CoiniumServ/Statistics/IPools.cs b/src/CoiniumServ/Utils/Repository/IRepository.cs similarity index 73% rename from src/CoiniumServ/Statistics/IPools.cs rename to src/CoiniumServ/Utils/Repository/IRepository.cs index 6c4d2c507..535150d5e 100644 --- a/src/CoiniumServ/Statistics/IPools.cs +++ b/src/CoiniumServ/Utils/Repository/IRepository.cs @@ -20,13 +20,23 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - +using System; using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; -namespace CoiniumServ.Statistics +namespace CoiniumServ.Utils.Repository { - public interface IPools : IEnumerable>, IJsonResponse, IStatisticsProvider + public interface IRepository:IEnumerable { - IPerPool GetBySymbol(string symbol); + IQueryable SearchFor(Expression> predicate); + + IEnumerable GetAll(); + + IQueryable GetAllAsQueryable(); + + IReadOnlyCollection GetAllAsReadOnly(); + + int Count { get; } } } diff --git a/src/CoiniumServ/Utils/Versions/VersionInfo.cs b/src/CoiniumServ/Utils/Versions/VersionInfo.cs index ca927ae4f..2dc72896c 100644 --- a/src/CoiniumServ/Utils/Versions/VersionInfo.cs +++ b/src/CoiniumServ/Utils/Versions/VersionInfo.cs @@ -41,7 +41,7 @@ public static class Assembly /// /// Main assemby version. /// - public const string Version = "0.1.2.*"; + public const string Version = "0.1.3.*"; } } } diff --git a/src/CoiniumServ/Vardiff/IVardiffConfig.cs b/src/CoiniumServ/Vardiff/IVardiffConfig.cs index 1d791fb28..69a4eb503 100644 --- a/src/CoiniumServ/Vardiff/IVardiffConfig.cs +++ b/src/CoiniumServ/Vardiff/IVardiffConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Configuration; namespace CoiniumServ.Vardiff diff --git a/src/CoiniumServ/Vardiff/IVardiffManager.cs b/src/CoiniumServ/Vardiff/IVardiffManager.cs index 38f59065b..15629d2fe 100644 --- a/src/CoiniumServ/Vardiff/IVardiffManager.cs +++ b/src/CoiniumServ/Vardiff/IVardiffManager.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - namespace CoiniumServ.Vardiff { public interface IVardiffManager diff --git a/src/CoiniumServ/Vardiff/IVardiffMiner.cs b/src/CoiniumServ/Vardiff/IVardiffMiner.cs index efaf55598..d4520a9ae 100644 --- a/src/CoiniumServ/Vardiff/IVardiffMiner.cs +++ b/src/CoiniumServ/Vardiff/IVardiffMiner.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using CoiniumServ.Utils.Buffers; namespace CoiniumServ.Vardiff diff --git a/src/CoiniumServ/Vardiff/VardiffConfig.cs b/src/CoiniumServ/Vardiff/VardiffConfig.cs index c4da3d265..ee64dc94c 100644 --- a/src/CoiniumServ/Vardiff/VardiffConfig.cs +++ b/src/CoiniumServ/Vardiff/VardiffConfig.cs @@ -20,7 +20,6 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; using Serilog; diff --git a/src/CoiniumServ/Vardiff/VardiffManager.cs b/src/CoiniumServ/Vardiff/VardiffManager.cs index 4a668ece4..4d356c3f0 100644 --- a/src/CoiniumServ/Vardiff/VardiffManager.cs +++ b/src/CoiniumServ/Vardiff/VardiffManager.cs @@ -20,9 +20,8 @@ // license or white-label it as set out in licenses/commercial.txt. // #endregion - using System; -using CoiniumServ.Pools.Config; +using CoiniumServ.Pools; using CoiniumServ.Shares; using CoiniumServ.Utils.Buffers; using CoiniumServ.Utils.Helpers.Time; diff --git a/src/CoiniumServ/config/coins/tekcoin.json b/src/CoiniumServ/config/coins/tekcoin.json index 4b3a27652..a806f9616 100644 --- a/src/CoiniumServ/config/coins/tekcoin.json +++ b/src/CoiniumServ/config/coins/tekcoin.json @@ -2,5 +2,6 @@ "name": "Tekcoin", "symbol": "TEK", "algorithm": "sha256", - "txMessages": "true" + "txMessages": true, + "reward": "pos" } diff --git a/src/CoiniumServ/config/pools/advanced-example.json b/src/CoiniumServ/config/pools/advanced-example.json index 2771ed33d..7abbedc70 100644 --- a/src/CoiniumServ/config/pools/advanced-example.json +++ b/src/CoiniumServ/config/pools/advanced-example.json @@ -150,45 +150,53 @@ # Per-pool Storage Configuration # ------------------------------- - # redis: - # enabled: is redis enabled? + # hybrid storage layer + # enabled: set this true to enable hybrid storage mode where redis and mysql is used together. + + # mpos layer + # enabled: set this true to enable mpos compatibility mode - make sure to internal disable payment-processor! + + # redis # host: redis host. # port: redis port. # password: set the password if your redis installation requires one. # databaseId: redis database instance id (optional) - "storage": { - "redis": { - "enabled": true, - "host": "127.0.0.1", - "port": 6379, - "password": "", - "databaseId": 0 - } - }, - - # ------------------------------- - # MPOS Compatibility Mode - # ------------------------------- - - # NOT-IMPLEMENTED-YET! - # enabled: set this true to enable mpos compatibility mode - make sure to internal disable payment-processor! + # mysql # host: database host. # port: database port. - # name: database-name. # username: username for connecting the database. # password: password for connecting the database. + # database: database name. - "mpos": { - "enabled": false, - "database": { - "host": "127.0.0.1", - "port": 3306, - "name": "db-name", - "user": "username", - "password": "password" - } - }, + "storage": { + "hybrid": { + "enabled": false, + "redis": { + "host": "127.0.0.1", + "port": 6379, + "password": "", + "databaseId": 0 + }, + "mysql": { + "host": "127.0.0.1", + "port": 3306, + "user": "username", + "password": "password", + "database": "db-name" + } + }, + "mpos": { + "enabled": false, + "mysql": { + "host": "127.0.0.1", + "port": 3306, + "user": "username", + "password": "password", + "database": "db-name" + } + } + }, # ------------------------------- # Getwork Server Configuration diff --git a/src/CoiniumServ/config/pools/default-example.json b/src/CoiniumServ/config/pools/default-example.json index 8d0b8b40d..41ce3c471 100644 --- a/src/CoiniumServ/config/pools/default-example.json +++ b/src/CoiniumServ/config/pools/default-example.json @@ -108,38 +108,47 @@ # Per-pool Storage Configuration # ------------------------------- - # redis: + # hybrid storage layer + # enabled: set this true to enable hybrid storage mode where redis and mysql is used together. + + # mpos layer + # enabled: set this true to enable mpos compatibility mode - make sure to internal disable payment-processor! + + # redis # host: redis host. # port: redis port. # password: set the password if your redis installation requires one. # databaseId: redis database instance id (optional) - "storage": { - "redis": { - "host": "127.0.0.1", - "port": 6379, - "password": "", - "databaseId": 0 - } - }, - - # ------------------------------- - # MPOS Compatibility Mode - # ------------------------------- - - # NOT-IMPLEMENTED-YET! + # mysql # host: database host. # port: database port. # username: username for connecting the database. # password: password for connecting the database. - "mpos": { - "database": { - "host": "127.0.0.1", - "port": 3306, - "user": "username", - "password": "password" - } + "storage": { + "hybrid": { + "redis": { + "host": "127.0.0.1", + "port": 6379, + "password": "", + "databaseId": 0 + }, + "mysql": { + "host": "127.0.0.1", + "port": 3306, + "user": "username", + "password": "password" + } + }, + "mpos": { + "mysql": { + "host": "127.0.0.1", + "port": 3306, + "user": "username", + "password": "password" + } + } }, # ------------------------------- diff --git a/src/CoiniumServ/config/pools/example.json b/src/CoiniumServ/config/pools/example.json index 782598349..678a6fac0 100644 --- a/src/CoiniumServ/config/pools/example.json +++ b/src/CoiniumServ/config/pools/example.json @@ -85,28 +85,25 @@ # Per-pool Storage Configuration # ------------------------------- - # redis: - # enabled: is redis enabled? + # hybrid storage layer + # enabled: set this true to enable hybrid storage mode where redis and mysql is used together. - "storage": { - "redis": { - "enabled": true - } - }, - - # ------------------------------- - # MPOS Compatibility Mode - # ------------------------------- - - # NOT-IMPLEMENTED-YET! + # mpos layer # enabled: set this true to enable mpos compatibility mode - make sure to internal disable payment-processor! - # name: database-name. - "mpos": { - "enabled": false, - "database": { - "name": "db-name" - } + "storage": { + "hybrid": { + "enabled": false, + "mysql": { + "database": "db-name" + } + }, + "mpos": { + "enabled": false, + "mysql": { + "database": "db-name" + } + } }, # ------------------------------- diff --git a/src/CoiniumServ/packages.config b/src/CoiniumServ/packages.config index 1fbb814ab..24db37016 100644 --- a/src/CoiniumServ/packages.config +++ b/src/CoiniumServ/packages.config @@ -3,14 +3,21 @@ + + + + - - + + + + + - + - + - + \ No newline at end of file diff --git a/src/CoiniumServ/web.config b/src/CoiniumServ/web.config deleted file mode 100644 index 0f0a3f190..000000000 --- a/src/CoiniumServ/web.config +++ /dev/null @@ -1,25 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/CoiniumServ/web/default/api.cshtml b/src/CoiniumServ/web/default/api.cshtml index d7e80cfb4..c96b52034 100644 --- a/src/CoiniumServ/web/default/api.cshtml +++ b/src/CoiniumServ/web/default/api.cshtml @@ -1,5 +1,5 @@ @using System.Linq -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ Layout = "layout.cshtml"; } @@ -55,34 +55,6 @@ } - - - pool workers - coin symbol - Pool Workers
Returns list of connected workers to pool. - - @if (@Model.Coin != null) - { -
- - -
- } - - - - pool round - coin symbol - Pool Round
Returns list of shares for current round. - - @if (@Model.Coin != null) - { -
- - -
- } - algorithms diff --git a/src/CoiniumServ/web/default/donate.cshtml b/src/CoiniumServ/web/default/donate.cshtml index 6d179eb31..7dabd4d34 100644 --- a/src/CoiniumServ/web/default/donate.cshtml +++ b/src/CoiniumServ/web/default/donate.cshtml @@ -13,20 +13,14 @@ 18qqrtR4xHujLKf9oqiCsjmwmH5vGpch4D Bitcoin (BTC) - - - -
Rb9kcLs96VDHTmiXVjcWC2RBsfCJ73UQyr Reddcoin (RDD) diff --git a/src/CoiniumServ/web/default/error.cshtml b/src/CoiniumServ/web/default/error.cshtml index 758dc8cb8..720c8340f 100644 --- a/src/CoiniumServ/web/default/error.cshtml +++ b/src/CoiniumServ/web/default/error.cshtml @@ -1,4 +1,4 @@ -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ Layout = "layout.cshtml"; } diff --git a/src/CoiniumServ/web/default/index.cshtml b/src/CoiniumServ/web/default/index.cshtml index 03644b331..bf98d3d4b 100644 --- a/src/CoiniumServ/web/default/index.cshtml +++ b/src/CoiniumServ/web/default/index.cshtml @@ -3,37 +3,101 @@ @{ Layout = "layout.cshtml"; } +
- - -
-
+ +
-
+

Per Algorithm Statistics

@@ -46,15 +110,17 @@ Algorithm Workers Hashrate + Pools @foreach (var algorithm in Model.Statistics.Algorithms) { - @algorithm.Value.Name - @algorithm.Value.WorkerCount - @algorithm.Value.Hashrate.GetReadableHashrate() + @algorithm.Name + @algorithm.MinerCount + @algorithm.Hashrate.GetReadableHashrate() + @algorithm.Count } @@ -93,12 +159,12 @@ { @pool.Config.Coin.Name - @pool.Statistics.Hashrate.GetReadableHashrate() - @pool.Statistics.NetworkHashrate.GetReadableHashrate() - @pool.Statistics.Difficulty - @pool.Statistics.WorkerCount + @pool.Hashrate.GetReadableHashrate() + @pool.NetworkStats.Hashrate.GetReadableHashrate() + @pool.NetworkStats.Difficulty + @pool.MinerManager.Count @pool.Config.Coin.Algorithm - @pool.Statistics.Round + @pool.NetworkStats.Round } diff --git a/src/CoiniumServ/web/default/layout.cshtml b/src/CoiniumServ/web/default/layout.cshtml index e3dd5ccb8..169594ec7 100644 --- a/src/CoiniumServ/web/default/layout.cshtml +++ b/src/CoiniumServ/web/default/layout.cshtml @@ -36,13 +36,16 @@