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

Commit

Permalink
Dev (#161)
Browse files Browse the repository at this point in the history
- Package update
- Switch back to dedicated loop thread per stratum port instead of per stratum
- Maintain maximum hashrate precision as long as possible.
- Min window adjustment
- Miner payments API - Improves #27
- Pool Top Miners API - Improves #27
- API no longer requires on a pool to be running to respond. It just needs to configured - improves -  - Prevent startup exception for externals
- Fix last block time
- Miner performance API for per-worker hashrate graphs (daily, monthly) - Improves #27
- Hashrate calculation safeguards
- Various StatsRepository fixes
  • Loading branch information
Oliver Weichhold authored Jan 9, 2018
1 parent 2b4cd86 commit 23d4e75
Show file tree
Hide file tree
Showing 26 changed files with 596 additions and 320 deletions.
258 changes: 203 additions & 55 deletions src/MiningCore/Api/ApiServer.cs

Large diffs are not rendered by default.

13 changes: 5 additions & 8 deletions src/MiningCore/Api/Extensions/MiningPoolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@
using AutoMapper;
using MiningCore.Api.Responses;
using MiningCore.Blockchain;
using MiningCore.Configuration;
using MiningCore.Mining;

namespace MiningCore.Api.Extensions
{
public static class MiningPoolExtensions
{
public static PoolInfo ToPoolInfo(this IMiningPool pool, IMapper mapper)
public static PoolInfo ToPoolInfo(this PoolConfig pool, IMapper mapper)
{
var poolInfo = mapper.Map<PoolInfo>(pool.Config);

poolInfo.PoolStats = pool.PoolStats;
poolInfo.NetworkStats = pool.NetworkStats;
var poolInfo = mapper.Map<PoolInfo>(pool);

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

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

return poolInfo;
}
Expand Down
8 changes: 8 additions & 0 deletions src/MiningCore/Api/Responses/GetMinerStatsResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

namespace MiningCore.Api.Responses
{
public class MinerPerformanceStats
{
public string Miner { get; set; }
public double Hashrate { get; set; }
public double SharesPerSecond { get; set; }
}

public class WorkerPerformanceStats
{
public double Hashrate { get; set; }
Expand All @@ -43,5 +50,6 @@ public class MinerStats
public DateTime? LastPayment { get; set; }
public string LastPaymentLink { get; set; }
public WorkerPerformanceStatsContainer Performance { get; set; }
public WorkerPerformanceStatsContainer[] Performance24H { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/MiningCore/Api/Responses/GetPoolsResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public partial class PoolInfo

// Stats
public PoolStats PoolStats { get; set; }

public BlockchainStats NetworkStats { get; set; }
public MinerPerformanceStats[] TopMiners { get; set; }
}

public class GetPoolsResponse
Expand Down
11 changes: 11 additions & 0 deletions src/MiningCore/AutoMapperProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ public AutoMapperProfile()
.ForMember(dest => dest.PoolId, opt => opt.Ignore())
.ForMember(dest => dest.Created, opt => opt.Ignore());

CreateMap<BlockchainStats, PoolStats>()
.ForMember(dest => dest.PoolId, opt => opt.Ignore())
.ForMember(dest => dest.Created, opt => opt.Ignore());

// API
CreateMap<PoolConfig, Api.Responses.PoolInfo>();
CreateMap<PoolStats, Api.Responses.PoolInfo>();
CreateMap<PoolStats, Api.Responses.AggregatedPoolStats>();
CreateMap<Block, Api.Responses.Block>();
CreateMap<Payment, Api.Responses.Payment>();
Expand Down Expand Up @@ -81,8 +86,14 @@ public AutoMapperProfile()
CreateMap<Persistence.Postgres.Entities.Payment, Payment>();
CreateMap<Persistence.Postgres.Entities.PoolStats, PoolStats>();
CreateMap<Persistence.Postgres.Entities.MinerWorkerPerformanceStats, MinerWorkerPerformanceStats>();
CreateMap<Persistence.Postgres.Entities.MinerWorkerPerformanceStats, Api.Responses.MinerPerformanceStats>();

CreateMap<PoolStats, Mining.PoolStats>();
CreateMap<BlockchainStats, Mining.PoolStats>();

CreateMap<PoolStats, BlockchainStats>()
.ForMember(dest => dest.RewardType, opt => opt.Ignore())
.ForMember(dest => dest.NetworkType, opt => opt.Ignore());
}
}
}
60 changes: 32 additions & 28 deletions src/MiningCore/Blockchain/Bitcoin/BitcoinJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,34 @@ protected virtual async Task ShowDaemonSyncProgressAsync()
}
}

private async Task UpdateNetworkStatsAsync()
{
logger.LogInvoke(LogCat);

var results = await daemon.ExecuteBatchAnyAsync(
new DaemonCmd(BitcoinCommands.GetBlockchainInfo),
new DaemonCmd(BitcoinCommands.GetMiningInfo),
new DaemonCmd(BitcoinCommands.GetNetworkInfo)
);

if (results.Any(x => x.Error != null))
{
var errors = results.Where(x => x.Error != null).ToArray();

if (errors.Any())
logger.Warn(() => $"[{LogCat}] Error(s) refreshing network stats: {string.Join(", ", errors.Select(y => y.Error.Message))}");
}

var infoResponse = results[0].Response.ToObject<BlockchainInfo>();
var miningInfoResponse = results[1].Response.ToObject<MiningInfo>();
var networkInfoResponse = results[2].Response.ToObject<NetworkInfo>();

BlockchainStats.BlockHeight = infoResponse.Blocks;
BlockchainStats.NetworkDifficulty = miningInfoResponse.Difficulty;
BlockchainStats.NetworkHashRate = miningInfoResponse.NetworkHashps;
BlockchainStats.ConnectedPeers = networkInfoResponse.Connections;
}

protected virtual async Task<(bool Accepted, string CoinbaseTransaction)> SubmitBlockAsync(BitcoinShare share)
{
// execute command batch
Expand Down Expand Up @@ -343,34 +371,6 @@ public virtual async Task<BitcoinShare> SubmitShareAsync(StratumClient worker, o
return share;
}

public async Task UpdateNetworkStatsAsync()
{
logger.LogInvoke(LogCat);

var results = await daemon.ExecuteBatchAnyAsync(
new DaemonCmd(BitcoinCommands.GetBlockchainInfo),
new DaemonCmd(BitcoinCommands.GetMiningInfo),
new DaemonCmd(BitcoinCommands.GetNetworkInfo)
);

if (results.Any(x => x.Error != null))
{
var errors = results.Where(x => x.Error != null).ToArray();

if (errors.Any())
logger.Warn(() => $"[{LogCat}] Error(s) refreshing network stats: {string.Join(", ", errors.Select(y => y.Error.Message))}");
}

var infoResponse = results[0].Response.ToObject<BlockchainInfo>();
var miningInfoResponse = results[1].Response.ToObject<MiningInfo>();
var networkInfoResponse = results[2].Response.ToObject<NetworkInfo>();

BlockchainStats.BlockHeight = infoResponse.Blocks;
BlockchainStats.NetworkDifficulty = miningInfoResponse.Difficulty;
BlockchainStats.NetworkHashRate = miningInfoResponse.NetworkHashps;
BlockchainStats.ConnectedPeers = networkInfoResponse.Connections;
}

public BlockchainStats BlockchainStats { get; } = new BlockchainStats();
public double ShareMultiplier { get; private set; }

Expand Down Expand Up @@ -573,7 +573,11 @@ protected virtual async Task<bool> UpdateJob(bool forceUpdate)

// update stats
if (isNew)
{
BlockchainStats.LastNetworkBlockTime = clock.Now;
BlockchainStats.BlockHeight = blockTemplate.Height;
BlockchainStats.NetworkDifficulty = job.Difficulty;
}

lock (jobLock)
{
Expand Down
22 changes: 11 additions & 11 deletions src/MiningCore/Blockchain/Bitcoin/BitcoinPoolBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ protected override async Task SetupJobManager()

await manager.StartAsync();

if (!poolConfig.ExternalStratum)
if (!poolConfig.ExternalStratum)
{
disposables.Add(manager.Jobs.Subscribe(OnNewJob));

Expand All @@ -297,6 +297,13 @@ protected override async Task SetupJobManager()
}
}

protected override void InitStats()
{
base.InitStats();

blockchainStats = manager.BlockchainStats;
}

protected override WorkerContextBase CreateClientContext()
{
return new BitcoinWorkerContext();
Expand Down Expand Up @@ -341,16 +348,16 @@ protected override async Task OnRequestAsync(StratumClient client,
}
}

public override ulong HashrateFromShares(double shares, double interval)
public override double HashrateFromShares(double shares, double interval)
{
var multiplier = BitcoinConstants.Pow2x32 / manager.ShareMultiplier;
var result = Math.Ceiling(shares * multiplier / interval);
var result = shares * multiplier / interval;

// OW: tmp hotfix
if (poolConfig.Coin.Type == CoinType.MONA || poolConfig.Coin.Type == CoinType.VTC || poolConfig.Coin.Type == CoinType.STAK)
result *= 2;

return (ulong)result;
return result;
}

protected override void OnVarDiffUpdate(StratumClient client, double newDiff)
Expand All @@ -368,13 +375,6 @@ protected override void OnVarDiffUpdate(StratumClient client, double newDiff)
}
}

protected override async Task UpdateBlockChainStatsAsync()
{
await manager.UpdateNetworkStatsAsync();

blockchainStats = manager.BlockchainStats;
}

#endregion // Overrides
}
}
64 changes: 33 additions & 31 deletions src/MiningCore/Blockchain/Ethereum/EthereumJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ protected bool UpdateJob(EthereumBlockTemplate blockTemplate)

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

return isNew;
Expand Down Expand Up @@ -262,6 +264,37 @@ private async Task ShowDaemonSyncProgressAsync()
}
}

private async Task UpdateNetworkStatsAsync()
{
logger.LogInvoke(LogCat);

var commands = new[]
{
new DaemonCmd(EC.GetBlockByNumber, new[] { (object) "latest", true }),
new DaemonCmd(EC.GetPeerCount),
};

var results = await daemon.ExecuteBatchAnyAsync(commands);

if (results.Any(x => x.Error != null))
{
var errors = results.Where(x => x.Error != null)
.ToArray();

if (errors.Any())
logger.Warn(() => $"[{LogCat}] Error(s) refreshing network stats: {string.Join(", ", errors.Select(y => y.Error.Message))})");
}

// extract results
var block = results[0].Response.ToObject<Block>();
var peerCount = results[1].Response.ToObject<string>().IntegralFromHex<int>();

BlockchainStats.BlockHeight = block.Height.HasValue ? (long)block.Height.Value : -1;
BlockchainStats.NetworkDifficulty = block.Difficulty.IntegralFromHex<ulong>();
BlockchainStats.NetworkHashRate = 0; // TODO
BlockchainStats.ConnectedPeers = peerCount;
}

private async Task<bool> SubmitBlockAsync(EthereumShare share)
{
// submit work
Expand Down Expand Up @@ -408,37 +441,6 @@ public async Task<EthereumShare> SubmitShareAsync(StratumClient worker,
return share;
}

public async Task UpdateNetworkStatsAsync()
{
logger.LogInvoke(LogCat);

var commands = new[]
{
new DaemonCmd(EC.GetBlockByNumber, new[] { (object) "latest", true }),
new DaemonCmd(EC.GetPeerCount),
};

var results = await daemon.ExecuteBatchAnyAsync(commands);

if (results.Any(x => x.Error != null))
{
var errors = results.Where(x => x.Error != null)
.ToArray();

if (errors.Any())
logger.Warn(() => $"[{LogCat}] Error(s) refreshing network stats: {string.Join(", ", errors.Select(y => y.Error.Message))})");
}

// extract results
var block = results[0].Response.ToObject<Block>();
var peerCount = results[1].Response.ToObject<string>().IntegralFromHex<int>();

BlockchainStats.BlockHeight = block.Height.HasValue ? (long) block.Height.Value : -1;
BlockchainStats.NetworkDifficulty = block.Difficulty.IntegralFromHex<ulong>();
BlockchainStats.NetworkHashRate = 0; // TODO
BlockchainStats.ConnectedPeers = peerCount;
}

public BlockchainStats BlockchainStats { get; } = new BlockchainStats();

#endregion // API-Surface
Expand Down
22 changes: 11 additions & 11 deletions src/MiningCore/Blockchain/Ethereum/EthereumPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ protected override async Task SetupJobManager()

await manager.StartAsync();

if (!poolConfig.ExternalStratum)
if (!poolConfig.ExternalStratum)
{
disposables.Add(manager.Jobs.Subscribe(OnNewJob));

Expand All @@ -271,6 +271,13 @@ protected override async Task SetupJobManager()
}
}

protected override void InitStats()
{
base.InitStats();

blockchainStats = manager.BlockchainStats;
}

protected override WorkerContextBase CreateClientContext()
{
return new EthereumWorkerContext();
Expand Down Expand Up @@ -307,10 +314,10 @@ protected override async Task OnRequestAsync(StratumClient client,
}
}

public override ulong HashrateFromShares(double shares, double interval)
public override double HashrateFromShares(double shares, double interval)
{
var result = Math.Ceiling(shares / interval);
return (ulong)result;
var result = shares / interval;
return result;
}

protected override void OnVarDiffUpdate(StratumClient client, double newDiff)
Expand All @@ -330,13 +337,6 @@ protected override void OnVarDiffUpdate(StratumClient client, double newDiff)
}
}

protected override async Task UpdateBlockChainStatsAsync()
{
await manager.UpdateNetworkStatsAsync();

blockchainStats = manager.BlockchainStats;
}

public override void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
{
base.Configure(poolConfig, clusterConfig);
Expand Down
Loading

0 comments on commit 23d4e75

Please sign in to comment.