Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Commit

Permalink
Dev (#405)
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Weichhold authored Sep 28, 2018
1 parent b4aff45 commit 893c653
Show file tree
Hide file tree
Showing 28 changed files with 322 additions and 211 deletions.
18 changes: 16 additions & 2 deletions src/MiningCore/Api/ApiServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
Expand Down Expand Up @@ -123,6 +124,8 @@ public ApiServer(
NullValueHandling = NullValueHandling.Ignore
};

private readonly ConcurrentDictionary<string, IMiningPool> pools = new ConcurrentDictionary<string, IMiningPool>();

private readonly Dictionary<Regex, Func<HttpContext, Match, Task>> requestMap;
private readonly Dictionary<Regex, Func<HttpContext, Match, Task>> requestMapAdmin;

Expand Down Expand Up @@ -247,8 +250,11 @@ private async Task GetPoolInfosAsync(HttpContext context, Match m)
// load stats
var stats = cf.Run(con => statsRepo.GetLastPoolStats(con, config.Id));

// get pool
pools.TryGetValue(config.Id, out var pool);

// map
var result = config.ToPoolInfo(mapper, stats);
var result = config.ToPoolInfo(mapper, stats, pool);

// enrich
result.TotalPaid = cf.Run(con => statsRepo.GetTotalPoolPayments(con, config.Id));
Expand Down Expand Up @@ -278,9 +284,12 @@ private async Task GetPoolInfoAsync(HttpContext context, Match m)
// load stats
var stats = cf.Run(con => statsRepo.GetLastPoolStats(con, pool.Id));

// get pool
pools.TryGetValue(pool.Id, out var poolInstance);

var response = new GetPoolResponse
{
Pool = pool.ToPoolInfo(mapper, stats)
Pool = pool.ToPoolInfo(mapper, stats, poolInstance)
};

// enrich
Expand Down Expand Up @@ -665,6 +674,11 @@ public void Start(ClusterConfig clusterConfig)
StartAdminApi(clusterConfig);
}

public void AttachPool(IMiningPool pool)
{
pools[pool.Config.Id] = pool;
}

#endregion // API-Surface
}
}
12 changes: 6 additions & 6 deletions src/MiningCore/Api/Extensions/MiningPoolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ namespace MiningCore.Api.Extensions
{
public static class MiningPoolExtensions
{
public static PoolInfo ToPoolInfo(this PoolConfig pool, IMapper mapper, Persistence.Model.PoolStats stats)
public static PoolInfo ToPoolInfo(this PoolConfig poolConfig, IMapper mapper, Persistence.Model.PoolStats stats, IMiningPool pool)
{
var poolInfo = mapper.Map<PoolInfo>(pool);
var poolInfo = mapper.Map<PoolInfo>(poolConfig);

// enrich with basic information
poolInfo.Coin.Algorithm = GetPoolAlgorithm(pool);
poolInfo.Coin.Algorithm = GetPoolAlgorithm(poolConfig);

poolInfo.PoolStats = mapper.Map<PoolStats>(stats);
poolInfo.NetworkStats = mapper.Map<BlockchainStats>(stats);
poolInfo.NetworkStats = pool?.NetworkStats ?? mapper.Map<BlockchainStats>(stats);

// pool wallet link
CoinMetaData.AddressInfoLinks.TryGetValue(pool.Coin.Type, out var addressInfobaseUrl);
CoinMetaData.AddressInfoLinks.TryGetValue(poolConfig.Coin.Type, out var addressInfobaseUrl);
if (!string.IsNullOrEmpty(addressInfobaseUrl))
poolInfo.AddressInfoLink = string.Format(addressInfobaseUrl, poolInfo.Address);

// pool fees
poolInfo.PoolFeePercent = (float) pool.RewardRecipients.Sum(x => x.Percentage);
poolInfo.PoolFeePercent = (float) poolConfig.RewardRecipients.Sum(x => x.Percentage);

// strip security critical stuff
if (poolInfo.PaymentProcessing.Extra != null)
Expand Down
2 changes: 1 addition & 1 deletion src/MiningCore/Blockchain/Abstractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class BlockchainStats
public double NetworkHashrate { get; set; }
public double NetworkDifficulty { get; set; }
public DateTime? LastNetworkBlockTime { get; set; }
public long BlockHeight { get; set; }
public ulong BlockHeight { get; set; }
public int ConnectedPeers { get; set; }
public string RewardType { get; set; }
}
Expand Down
7 changes: 2 additions & 5 deletions src/MiningCore/Blockchain/Bitcoin/BitcoinJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ public BitcoinJobManager(

protected virtual void SetupJobUpdates()
{
if (poolConfig.EnableInternalStratum == false)
return;

jobRebroadcastTimeout = TimeSpan.FromSeconds(Math.Max(1, poolConfig.JobRebroadcastTimeout));
var blockSubmission = blockSubmissionSubject.Synchronize();
var pollTimerRestart = blockSubmissionSubject.Synchronize();
Expand Down Expand Up @@ -439,7 +436,7 @@ private async Task UpdateNetworkStatsLegacyAsync()

public IObservable<object> Jobs { get; private set; }

public virtual async Task<bool> ValidateAddressAsync(string address)
public virtual async Task<bool> ValidateAddressAsync(string address, CancellationToken ct)
{
Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(address), $"{nameof(address)} must not be empty");

Expand Down Expand Up @@ -493,7 +490,7 @@ public string[] GetTransactions(StratumClient worker, object requestParams)
}

public virtual async Task<Share> SubmitShareAsync(StratumClient worker, object submission,
double stratumDifficultyBase)
double stratumDifficultyBase, CancellationToken ct)
{
Contract.RequiresNonNull(worker, nameof(worker));
Contract.RequiresNonNull(submission, nameof(submission));
Expand Down
22 changes: 14 additions & 8 deletions src/MiningCore/Blockchain/Bitcoin/BitcoinPoolBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected virtual void OnSubscribe(StratumClient client, Timestamped<JsonRpcRequ
client.Notify(BitcoinStratumMethods.MiningNotify, currentJobParams);
}

protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest)
protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest, CancellationToken ct)
{
var request = tsRequest.Value;

Expand All @@ -117,7 +117,7 @@ protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped<
var workerName = split?.Skip(1).FirstOrDefault()?.Trim() ?? string.Empty;

// assumes that workerName is an address
context.IsAuthorized = !string.IsNullOrEmpty(minerName) && await manager.ValidateAddressAsync(minerName);
context.IsAuthorized = !string.IsNullOrEmpty(minerName) && await manager.ValidateAddressAsync(minerName, ct);
context.MinerName = minerName;
context.WorkerName = workerName;

Expand Down Expand Up @@ -156,7 +156,7 @@ protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped<
}
}

protected virtual async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest)
protected virtual async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest, CancellationToken ct)
{
var request = tsRequest.Value;
var context = client.ContextAs<BitcoinWorkerContext>();
Expand All @@ -171,7 +171,7 @@ protected virtual async Task OnSubmitAsync(StratumClient client, Timestamped<Jso

if (requestAge > maxShareAge)
{
logger.Debug(() => $"[{client.ConnectionId}] Dropping stale share submission request (not client's fault)");
logger.Warn(() => $"[{client.ConnectionId}] Dropping stale share submission request (server overloaded?)");
return;
}

Expand All @@ -188,7 +188,7 @@ protected virtual async Task OnSubmitAsync(StratumClient client, Timestamped<Jso
var requestParams = request.ParamsAs<string[]>();
var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port];

var share = await manager.SubmitShareAsync(client, requestParams, poolEndpoint.Difficulty);
var share = await manager.SubmitShareAsync(client, requestParams, poolEndpoint.Difficulty, ct);

client.Respond(true, request.Id);

Expand Down Expand Up @@ -340,6 +340,12 @@ protected override async Task SetupJobManager(CancellationToken ct)
// we need work before opening the gates
await manager.Jobs.Take(1).ToTask(ct);
}

else
{
// keep updating NetworkStats
disposables.Add(manager.Jobs.Subscribe());
}
}

protected override void InitStats()
Expand All @@ -355,7 +361,7 @@ protected override WorkerContextBase CreateClientContext()
}

protected override async Task OnRequestAsync(StratumClient client,
Timestamped<JsonRpcRequest> tsRequest)
Timestamped<JsonRpcRequest> tsRequest, CancellationToken ct)
{
var request = tsRequest.Value;

Expand All @@ -366,11 +372,11 @@ protected override async Task OnRequestAsync(StratumClient client,
break;

case BitcoinStratumMethods.Authorize:
await OnAuthorizeAsync(client, tsRequest);
await OnAuthorizeAsync(client, tsRequest, ct);
break;

case BitcoinStratumMethods.SubmitShare:
await OnSubmitAsync(client, tsRequest);
await OnSubmitAsync(client, tsRequest, ct);
break;

case BitcoinStratumMethods.SuggestDifficulty:
Expand Down
4 changes: 4 additions & 0 deletions src/MiningCore/Blockchain/CoinMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static class CoinMetaData

{ CoinType.XMR, new Dictionary<string, string> { { string.Empty, $"https://chainradar.com/xmr/block/{BlockHeightPH}" } } },
{ CoinType.ETN, new Dictionary<string, string> { { string.Empty, $"https://blockexplorer.electroneum.com/block/{BlockHeightPH}" } } },
{ CoinType.TUBE, new Dictionary<string, string> { { string.Empty, $"https://explorer.bit.tube/block/{BlockHeightPH}" } } },
{ CoinType.LTC, new Dictionary<string, string> { { string.Empty, $"https://chainz.cryptoid.info/ltc/block.dws?{BlockHeightPH}.htm" } } },
{ CoinType.PPC, new Dictionary<string, string> { { string.Empty, $"https://chainz.cryptoid.info/ppc/block.dws?{BlockHeightPH}.htm" } } },
{ CoinType.BCH, new Dictionary<string, string> { { string.Empty, $"https://www.blocktrail.com/BCC/block/{BlockHeightPH}" } } },
Expand Down Expand Up @@ -74,6 +75,7 @@ public static class CoinMetaData
{
{ CoinType.XMR, "https://chainradar.com/xmr/transaction/{0}" },
{ CoinType.ETN, "https://blockexplorer.electroneum.com/tx/{0}" },
{ CoinType.TUBE, "https://explorer.bit.tube/tx/{0}" },
{ CoinType.ETH, "https://etherscan.io/tx/{0}" },
{ CoinType.ETC, "https://gastracker.io/tx/{0}" },
{ CoinType.CLO, "https://explorer.callisto.network/tx/{0}" },
Expand Down Expand Up @@ -150,6 +152,7 @@ public static class CoinMetaData
private const string Ethash = "Ethash";
private const string Cryptonight = "Cryptonight";
private const string CryptonightLight = "Cryptonight-Light";
private const string CryptonightHeavy = "Cryptonight-Heavy";

public static readonly Dictionary<CoinType, Func<CoinType, string, string>> CoinAlgorithm = new Dictionary<CoinType, Func<CoinType, string, string>>
{
Expand Down Expand Up @@ -180,6 +183,7 @@ public static class CoinMetaData
{ CoinType.MOON, BitcoinProperties.GetAlgorithm },
{ CoinType.XVG, BitcoinProperties.GetAlgorithm },
{ CoinType.XMR, (coin, alg) => Cryptonight },
{ CoinType.TUBE, (coin, alg) => CryptonightHeavy },
{ CoinType.ETN, (coin, alg) => Cryptonight },
{ CoinType.AEON, (coin, alg) => CryptonightLight },
{ CoinType.GBX, BitcoinProperties.GetAlgorithm },
Expand Down
11 changes: 4 additions & 7 deletions src/MiningCore/Blockchain/Ethereum/EthereumJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ protected bool UpdateJob(EthereumBlockTemplate blockTemplate)

// update stats
BlockchainStats.LastNetworkBlockTime = clock.Now;
BlockchainStats.BlockHeight = (long) job.BlockTemplate.Height;
BlockchainStats.BlockHeight = job.BlockTemplate.Height;
BlockchainStats.NetworkDifficulty = job.BlockTemplate.Difficulty;
}

Expand Down Expand Up @@ -385,7 +385,7 @@ public void PrepareWorker(StratumClient client)
}

public async Task<Share> SubmitShareAsync(StratumClient worker,
string[] request, double stratumDifficulty, double stratumDifficultyBase)
string[] request, double stratumDifficulty, double stratumDifficultyBase, CancellationToken ct)
{
Contract.RequiresNonNull(worker, nameof(worker));
Contract.RequiresNonNull(request, nameof(request));
Expand Down Expand Up @@ -577,9 +577,9 @@ protected override async Task PostStartInitAsync(CancellationToken ct)
logger.Info(() => $"Waiting for first valid block template");
await Task.Delay(TimeSpan.FromSeconds(5), ct);
}

SetupJobUpdates();
}

SetupJobUpdates();
}

private void ConfigureRewards()
Expand All @@ -601,9 +601,6 @@ private void ConfigureRewards()

protected virtual void SetupJobUpdates()
{
if (poolConfig.EnableInternalStratum == false)
return;

var enableStreaming = extraPoolConfig?.EnableDaemonWebsocketStreaming == true;

if (enableStreaming && !poolConfig.Daemons.Any(x =>
Expand Down
16 changes: 11 additions & 5 deletions src/MiningCore/Blockchain/Ethereum/EthereumPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private void OnAuthorize(StratumClient client, Timestamped<JsonRpcRequest> tsReq
logger.Info(() => $"[{client.ConnectionId}] Authorized worker {workerValue}");
}

private async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest)
private async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcRequest> tsRequest, CancellationToken ct)
{
var request = tsRequest.Value;
var context = client.ContextAs<EthereumWorkerContext>();
Expand All @@ -160,7 +160,7 @@ private async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcReques

if (requestAge > maxShareAge)
{
logger.Debug(() => $"[{client.ConnectionId}] Dropping stale share submission request (not client's fault)");
logger.Warn(() => $"[{client.ConnectionId}] Dropping stale share submission request (server overloaded?)");
return;
}

Expand All @@ -183,7 +183,7 @@ private async Task OnSubmitAsync(StratumClient client, Timestamped<JsonRpcReques
var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port];

var share = await manager.SubmitShareAsync(client, submitRequest, context.Difficulty,
poolEndpoint.Difficulty);
poolEndpoint.Difficulty, ct);

client.Respond(true, request.Id);

Expand Down Expand Up @@ -300,6 +300,12 @@ protected override async Task SetupJobManager(CancellationToken ct)
// we need work before opening the gates
await manager.Jobs.Take(1).ToTask(ct);
}

else
{
// keep updating NetworkStats
disposables.Add(manager.Jobs.Subscribe());
}
}

protected override void InitStats()
Expand All @@ -315,7 +321,7 @@ protected override WorkerContextBase CreateClientContext()
}

protected override async Task OnRequestAsync(StratumClient client,
Timestamped<JsonRpcRequest> tsRequest)
Timestamped<JsonRpcRequest> tsRequest, CancellationToken ct)
{
var request = tsRequest.Value;

Expand All @@ -330,7 +336,7 @@ protected override async Task OnRequestAsync(StratumClient client,
break;

case EthereumStratumMethods.SubmitShare:
await OnSubmitAsync(client, tsRequest);
await OnSubmitAsync(client, tsRequest, ct);
break;

case EthereumStratumMethods.ExtraNonceSubscribe:
Expand Down
13 changes: 6 additions & 7 deletions src/MiningCore/Blockchain/Monero/MoneroConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,44 @@ public class MoneroConstants
{
public const string WalletDaemonCategory = "wallet";

public static readonly Dictionary<CoinType, UInt64> AddressLength = new Dictionary<CoinType, UInt64>
{
{ CoinType.XMR, 95 },
{ CoinType.ETN, 98 },
{ CoinType.AEON, 97 },
};

public static readonly Dictionary<CoinType, UInt64> AddressPrefix = new Dictionary<CoinType, UInt64>
{
{ CoinType.XMR, 18 },
{ CoinType.ETN, 18018 },
{ CoinType.AEON, 178 },
{ CoinType.TUBE, 209 },
};

public static readonly Dictionary<CoinType, UInt64> AddressPrefixTestnet = new Dictionary<CoinType, UInt64>
{
{ CoinType.XMR, 53 },
{ CoinType.ETN, 53 },
{ CoinType.AEON, 178 },
{ CoinType.TUBE, 209 },
};

public static readonly Dictionary<CoinType, UInt64> AddressPrefixIntegrated = new Dictionary<CoinType, UInt64>
{
{ CoinType.XMR, 19 },
{ CoinType.ETN, 18019 },
{ CoinType.AEON, 178 },
{ CoinType.TUBE, 19 },
};

public static readonly Dictionary<CoinType, UInt64> AddressPrefixIntegratedTestnet = new Dictionary<CoinType, UInt64>
{
{ CoinType.XMR, 54 },
{ CoinType.ETN, 54 },
{ CoinType.AEON, 178 },
{ CoinType.TUBE, 54 },
};

public static readonly Dictionary<CoinType, decimal> SmallestUnit = new Dictionary<CoinType, decimal>
{
{ CoinType.XMR, Piconero },
{ CoinType.ETN, 100m }, // BUG: https://github.com/electroneum/electroneum/issues/77
{ CoinType.AEON, Piconero },
{ CoinType.TUBE, (long)1e8 },
};

public const string DaemonRpcLocation = "json_rpc";
Expand Down Expand Up @@ -108,6 +106,7 @@ public class MoneroConstants
public const int BlobNonceOffset = 39;

public const long Piconero = (long) 1e12;
public const long Nanonero = (long)1e9;
public const decimal StaticTransactionFeeReserve = 0.03m; // in monero
}

Expand Down
Loading

0 comments on commit 893c653

Please sign in to comment.