diff --git a/src/CoiniumServ/Algorithms/AlgorithmRegistry.cs b/src/CoiniumServ/Algorithms/AlgorithmRegistry.cs index 32eeb0810..8cf9555e0 100644 --- a/src/CoiniumServ/Algorithms/AlgorithmRegistry.cs +++ b/src/CoiniumServ/Algorithms/AlgorithmRegistry.cs @@ -64,34 +64,34 @@ public void RegisterInstances() // available cryptographic hash functions: http://en.wikipedia.org/wiki/List_of_hash_functions#Cryptographic_hash_functions // algorithm manager - _applicationContext.Container.Register().AsSingleton(); + _applicationContext.Container.Register().AsMultiInstance(); // sha variants - _applicationContext.Container.Register(Sha256).AsSingleton(); - _applicationContext.Container.Register(Sha1).AsSingleton(); + _applicationContext.Container.Register(Sha256).AsMultiInstance(); + _applicationContext.Container.Register(Sha1).AsMultiInstance(); // scrypt variants - _applicationContext.Container.Register(Scrypt).AsSingleton(); - _applicationContext.Container.Register(ScryptOg).AsSingleton(); - _applicationContext.Container.Register(ScryptN).AsSingleton(); + _applicationContext.Container.Register(Scrypt).AsMultiInstance(); + _applicationContext.Container.Register(ScryptOg).AsMultiInstance(); + _applicationContext.Container.Register(ScryptN).AsMultiInstance(); // multi-hashers - _applicationContext.Container.Register(X11).AsSingleton(); - _applicationContext.Container.Register(X13).AsSingleton(); - _applicationContext.Container.Register(X14).AsSingleton(); - _applicationContext.Container.Register(X15).AsSingleton(); - _applicationContext.Container.Register(X17).AsSingleton(); + _applicationContext.Container.Register(X11).AsMultiInstance(); + _applicationContext.Container.Register(X13).AsMultiInstance(); + _applicationContext.Container.Register(X14).AsMultiInstance(); + _applicationContext.Container.Register(X15).AsMultiInstance(); + _applicationContext.Container.Register(X17).AsMultiInstance(); // misc ones - _applicationContext.Container.Register(Blake).AsSingleton(); - _applicationContext.Container.Register(Fresh).AsSingleton(); - _applicationContext.Container.Register(Fugue).AsSingleton(); - _applicationContext.Container.Register(Groestl).AsSingleton(); - _applicationContext.Container.Register(Keccak).AsSingleton(); - _applicationContext.Container.Register(Nist5).AsSingleton(); - _applicationContext.Container.Register(Qubit).AsSingleton(); - _applicationContext.Container.Register(Shavite3).AsSingleton(); - _applicationContext.Container.Register(Skein).AsSingleton(); + _applicationContext.Container.Register(Blake).AsMultiInstance(); + _applicationContext.Container.Register(Fresh).AsMultiInstance(); + _applicationContext.Container.Register(Fugue).AsMultiInstance(); + _applicationContext.Container.Register(Groestl).AsMultiInstance(); + _applicationContext.Container.Register(Keccak).AsMultiInstance(); + _applicationContext.Container.Register(Nist5).AsMultiInstance(); + _applicationContext.Container.Register(Qubit).AsMultiInstance(); + _applicationContext.Container.Register(Shavite3).AsMultiInstance(); + _applicationContext.Container.Register(Skein).AsMultiInstance(); } } } \ No newline at end of file diff --git a/src/CoiniumServ/Algorithms/Implementations/ScryptN.cs b/src/CoiniumServ/Algorithms/Implementations/ScryptN.cs index fe986c142..c7a9f178f 100644 --- a/src/CoiniumServ/Algorithms/Implementations/ScryptN.cs +++ b/src/CoiniumServ/Algorithms/Implementations/ScryptN.cs @@ -24,6 +24,7 @@ using System; using System.Linq; using System.Collections.Generic; +using CoiniumServ.Coin.Config; using CoiniumServ.Utils.Helpers; using CryptSharp.Utility; using JsonConfig; @@ -57,34 +58,42 @@ public sealed class ScryptN : HashAlgorithmBase {524288, 1769642992}, }; - public ScryptN() + private Dictionary _timeTable; // timeTable for the coin. + + public ScryptN(ICoinConfig coinConfig) { - // we don't set N value here on initialization because N is computed dynamically for scrypt-n coins. _r = 1; _p = 1; - Multiplier = (UInt32)Math.Pow(2, 16); + + InitTimeTable(coinConfig.Extra.timeTable); // init the timeTable for the coin. } - public override byte[] Hash(byte[] input, dynamic config) + private void InitTimeTable(dynamic table) { - var timeTable = new Dictionary(); - var now = (UInt64)TimeHelpers.NowInUnixTimestamp(); + _timeTable = new Dictionary(); - if (config.timeTable is NullExceptionPreventer) // if we are not provided a timeTable - timeTable = _defaultTimeTable; // use the default table. + if (table is NullExceptionPreventer) // if we are not provided a timeTable + _timeTable = _defaultTimeTable; // use the default table. else { - foreach (KeyValuePair pair in config.timeTable) + // else use the table provided by the coin configuration within extra.timeTable section. + foreach (KeyValuePair pair in table) { - timeTable.Add(Int32.Parse(pair.Key), UInt64.Parse(pair.Value.ToString())); + _timeTable.Add(Int32.Parse(pair.Key), UInt64.Parse(pair.Value.ToString())); } } + } + + public override byte[] Hash(byte[] input, dynamic config) + { + var now = (UInt64)TimeHelpers.NowInUnixTimestamp(); - var n = timeTable.OrderBy(x => x.Key).First(x => x.Value < now).Key; - var nFactor = (int) (Math.Log(n)/Math.Log(2)); + var index = _timeTable.OrderBy(x => x.Key).First(x => x.Value < now).Key; + var nFactor = (int)(Math.Log(index) / Math.Log(2)); + var n = 1 << nFactor; - return SCrypt.ComputeDerivedKey(input, input, nFactor, _r, _p, null, 32); + return SCrypt.ComputeDerivedKey(input, input, n, _r, _p, null, 32); } } } diff --git a/src/CoiniumServ/Container/IObjectFactory.cs b/src/CoiniumServ/Container/IObjectFactory.cs index 3434c95b5..8ad2cb431 100644 --- a/src/CoiniumServ/Container/IObjectFactory.cs +++ b/src/CoiniumServ/Container/IObjectFactory.cs @@ -128,7 +128,7 @@ public interface IObjectFactory /// Returns the given hash algorithm helper. /// /// - IHashAlgorithm GetHashAlgorithm(string name); + IHashAlgorithm GetHashAlgorithm(ICoinConfig coinConfig); IAlgorithmManager GetAlgorithmManager(); diff --git a/src/CoiniumServ/Container/ObjectFactory.cs b/src/CoiniumServ/Container/ObjectFactory.cs index 6d378307a..03af3dd28 100644 --- a/src/CoiniumServ/Container/ObjectFactory.cs +++ b/src/CoiniumServ/Container/ObjectFactory.cs @@ -353,9 +353,14 @@ public IPaymentRepository GetPaymentRepository(IStorageLayer storageLayer) #region hash algorithms - public IHashAlgorithm GetHashAlgorithm(string name) + public IHashAlgorithm GetHashAlgorithm(ICoinConfig coinConfig) { - return _applicationContext.Container.Resolve(name); + var @params = new NamedParameterOverloads + { + {"coinConfig", coinConfig}, + }; + + return _applicationContext.Container.Resolve(coinConfig.Algorithm, @params); } public IAlgorithmManager GetAlgorithmManager() diff --git a/src/CoiniumServ/Daemon/DaemonBase.cs b/src/CoiniumServ/Daemon/DaemonBase.cs index 69e8ebaf7..4192dab71 100644 --- a/src/CoiniumServ/Daemon/DaemonBase.cs +++ b/src/CoiniumServ/Daemon/DaemonBase.cs @@ -218,7 +218,7 @@ private string GetJsonResponse(HttpWebRequest httpWebRequest) var response = webException.Response as HttpWebResponse; if (response == null) - throw _rpcExceptionFactory.GetRpcException("Error while reading json response", webException); + throw _rpcExceptionFactory.GetRpcException(webException); var error = ReadJsonError(response); // try to read the error response. diff --git a/src/CoiniumServ/Pools/Pool.cs b/src/CoiniumServ/Pools/Pool.cs index 7c068784a..7e870f8fe 100644 --- a/src/CoiniumServ/Pools/Pool.cs +++ b/src/CoiniumServ/Pools/Pool.cs @@ -44,6 +44,7 @@ using CoiniumServ.Server.Mining.Service; using CoiniumServ.Shares; using CoiniumServ.Utils.Helpers; +using Nancy.TinyIoc; using Newtonsoft.Json; using Serilog; @@ -116,8 +117,6 @@ public Pool(IPoolConfig poolConfig, IConfigManager configManager, IObjectFactory Enforce.ArgumentNotNull(() => configManager); // make sure we have a config-manager instance supplied. Enforce.ArgumentNotNull(() => objectFactory); // make sure we have a objectFactory instance supplied. - // TODO: validate pool central wallet & rewards within the startup. - _configManager = configManager; _objectFactory = objectFactory; Config = poolConfig; @@ -127,6 +126,9 @@ public Pool(IPoolConfig poolConfig, IConfigManager configManager, IObjectFactory try { + if (!InitAlgorithm()) // init the hash algorithm required by the coin. + return; + InitDaemon(); // init coin daemon. InitStorage(); // init storage support. InitManagers(); // init managers. @@ -140,6 +142,21 @@ public Pool(IPoolConfig poolConfig, IConfigManager configManager, IObjectFactory } } + private bool InitAlgorithm() + { + try + { + HashAlgorithm = _objectFactory.GetHashAlgorithm(Config.Coin); + _shareMultiplier = Math.Pow(2, 32) / HashAlgorithm.Multiplier; // will be used in hashrate calculation. + return true; + } + catch (TinyIoCResolutionException) + { + _logger.Error("Unknown hash algorithm: {0:l}, pool initializing failed", Config.Coin.Algorithm); + return false; + } + } + private void InitDaemon() { if (Config.Daemon == null || Config.Daemon.Valid == false) @@ -149,10 +166,7 @@ private void InitDaemon() } Daemon = _objectFactory.GetDaemonClient(Config.Daemon, Config.Coin); - HashAlgorithm = _objectFactory.GetHashAlgorithm(Config.Coin.Algorithm); NetworkInfo = _objectFactory.GetNetworkInfo(Daemon, HashAlgorithm, Config); - - _shareMultiplier = Math.Pow(2, 32) / HashAlgorithm.Multiplier; // will be used in hashrate calculation. } private void InitStorage()