Skip to content

Commit

Permalink
Algorithm implementations are now per-pool instantiated so that the o…
Browse files Browse the repository at this point in the history
…nes like scrypt-n can cache extra config data.

Handled the exception thrown when an invalid algorithm is tried to load.
Fixed scrypt-n, should work all good now.
  • Loading branch information
bonesoul committed Oct 28, 2014
1 parent 6995c05 commit 40f4aeb
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 42 deletions.
40 changes: 20 additions & 20 deletions src/CoiniumServ/Algorithms/AlgorithmRegistry.cs
Expand Up @@ -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<IAlgorithmManager, AlgorithmManager>().AsSingleton();
_applicationContext.Container.Register<IAlgorithmManager, AlgorithmManager>().AsMultiInstance();

// sha variants
_applicationContext.Container.Register<IHashAlgorithm, Sha256>(Sha256).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Sha1>(Sha1).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Sha256>(Sha256).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Sha1>(Sha1).AsMultiInstance();

// scrypt variants
_applicationContext.Container.Register<IHashAlgorithm, Scrypt>(Scrypt).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, ScryptOg>(ScryptOg).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, ScryptN>(ScryptN).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Scrypt>(Scrypt).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, ScryptOg>(ScryptOg).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, ScryptN>(ScryptN).AsMultiInstance();

// multi-hashers
_applicationContext.Container.Register<IHashAlgorithm, X11>(X11).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, X13>(X13).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, X14>(X14).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, X15>(X15).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, X17>(X17).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, X11>(X11).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, X13>(X13).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, X14>(X14).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, X15>(X15).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, X17>(X17).AsMultiInstance();

// misc ones
_applicationContext.Container.Register<IHashAlgorithm, Blake>(Blake).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Fresh>(Fresh).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Fugue>(Fugue).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Groestl>(Groestl).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Keccak>(Keccak).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Nist5>(Nist5).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Qubit>(Qubit).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Shavite3>(Shavite3).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Skein>(Skein).AsSingleton();
_applicationContext.Container.Register<IHashAlgorithm, Blake>(Blake).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Fresh>(Fresh).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Fugue>(Fugue).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Groestl>(Groestl).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Keccak>(Keccak).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Nist5>(Nist5).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Qubit>(Qubit).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Shavite3>(Shavite3).AsMultiInstance();
_applicationContext.Container.Register<IHashAlgorithm, Skein>(Skein).AsMultiInstance();
}
}
}
35 changes: 22 additions & 13 deletions src/CoiniumServ/Algorithms/Implementations/ScryptN.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -57,34 +58,42 @@ public sealed class ScryptN : HashAlgorithmBase
{524288, 1769642992},
};

public ScryptN()
private Dictionary<Int32, UInt64> _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<Int32, UInt64>();
var now = (UInt64)TimeHelpers.NowInUnixTimestamp();
_timeTable = new Dictionary<int, ulong>();

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<string, object> pair in config.timeTable)
// else use the table provided by the coin configuration within extra.timeTable section.
foreach (KeyValuePair<string, object> 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);
}
}
}
2 changes: 1 addition & 1 deletion src/CoiniumServ/Container/IObjectFactory.cs
Expand Up @@ -128,7 +128,7 @@ public interface IObjectFactory
/// Returns the given hash algorithm helper.
/// </summary>
/// <returns></returns>
IHashAlgorithm GetHashAlgorithm(string name);
IHashAlgorithm GetHashAlgorithm(ICoinConfig coinConfig);

IAlgorithmManager GetAlgorithmManager();

Expand Down
9 changes: 7 additions & 2 deletions src/CoiniumServ/Container/ObjectFactory.cs
Expand Up @@ -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<IHashAlgorithm>(name);
var @params = new NamedParameterOverloads
{
{"coinConfig", coinConfig},
};

return _applicationContext.Container.Resolve<IHashAlgorithm>(coinConfig.Algorithm, @params);
}

public IAlgorithmManager GetAlgorithmManager()
Expand Down
2 changes: 1 addition & 1 deletion src/CoiniumServ/Daemon/DaemonBase.cs
Expand Up @@ -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.

Expand Down
24 changes: 19 additions & 5 deletions src/CoiniumServ/Pools/Pool.cs
Expand Up @@ -44,6 +44,7 @@
using CoiniumServ.Server.Mining.Service;
using CoiniumServ.Shares;
using CoiniumServ.Utils.Helpers;
using Nancy.TinyIoc;
using Newtonsoft.Json;
using Serilog;

Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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)
Expand All @@ -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()
Expand Down

0 comments on commit 40f4aeb

Please sign in to comment.