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

Commit

Permalink
Dev (#431)
Browse files Browse the repository at this point in the history
* Expose coin family through API
* Return 24h payments in API
* Console only logging in recovery mode
* Added miner earnings by day to API
* AEON
* Completely Async Database Access
* Simplified SoloPaymentScheme reward recipients configuration
* Simplify ShareRecorder queue
* BulkInsert of shares
* Monero v8 fix
* Enable bulk insert
* Update libcryptonight
* Switch to INTEL assembly version for cryptonight v2
* Async-optimized ShareReceiver
  • Loading branch information
Oliver Weichhold authored Oct 19, 2018
1 parent ec14fba commit bf5015a
Show file tree
Hide file tree
Showing 103 changed files with 17,828 additions and 730 deletions.
Binary file modified libs/runtimes/win-x64/libcryptonight.dll
Binary file not shown.
84 changes: 57 additions & 27 deletions src/Miningcore/Api/ApiServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public ApiServer(
{new Regex("^/api/pools/(?<poolId>[^/]+)$", RegexOptions.Compiled), GetPoolInfoAsync},
{new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/payments$", RegexOptions.Compiled), PageMinerPaymentsAsync},
{new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/balancechanges$", RegexOptions.Compiled), PageMinerBalanceChangesAsync},
{new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/earnings/daily", RegexOptions.Compiled), PageMinerEarningsByDayAsync},
{new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/performance$", RegexOptions.Compiled), GetMinerPerformanceAsync},
{new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)$", RegexOptions.Compiled), GetMinerInfoAsync},
};
Expand Down Expand Up @@ -207,7 +208,7 @@ private async Task HandleRequest(HttpContext context)
}
}

private WorkerPerformanceStatsContainer[] GetMinerPerformanceInternal(string mode, PoolConfig pool, string address)
private async Task<WorkerPerformanceStatsContainer[]> GetMinerPerformanceInternal(string mode, PoolConfig pool, string address)
{
Persistence.Model.Projections.WorkerPerformanceStatsContainer[] stats;
var end = clock.Now;
Expand All @@ -223,7 +224,7 @@ private WorkerPerformanceStatsContainer[] GetMinerPerformanceInternal(string mod

var start = end.AddDays(-1);

stats = cf.Run(con => statsRepo.GetMinerPerformanceBetweenHourly(
stats = await cf.Run(con => statsRepo.GetMinerPerformanceBetweenHourlyAsync(
con, pool.Id, address, start, end));
}

Expand All @@ -237,7 +238,7 @@ private WorkerPerformanceStatsContainer[] GetMinerPerformanceInternal(string mod
// set range
var start = end.AddMonths(-1);

stats = cf.Run(con => statsRepo.GetMinerPerformanceBetweenDaily(
stats = await cf.Run(con => statsRepo.GetMinerPerformanceBetweenDailyAsync(
con, pool.Id, address, start, end));
}

Expand All @@ -250,10 +251,10 @@ private async Task GetPoolInfosAsync(HttpContext context, Match m)
{
var response = new GetPoolsResponse
{
Pools = clusterConfig.Pools.Where(x => x.Enabled).Select(config =>
Pools = await Task.WhenAll(clusterConfig.Pools.Where(x => x.Enabled).Select(async config =>
{
// load stats
var stats = cf.Run(con => statsRepo.GetLastPoolStats(con, config.Id));
var stats = await cf.Run(con => statsRepo.GetLastPoolStatsAsync(con, config.Id));

// get pool
pools.TryGetValue(config.Id, out var pool);
Expand All @@ -262,19 +263,19 @@ private async Task GetPoolInfosAsync(HttpContext context, Match m)
var result = config.ToPoolInfo(mapper, stats, pool);

// enrich
result.TotalPaid = cf.Run(con => statsRepo.GetTotalPoolPayments(con, config.Id));
result.TotalPaid = await cf.Run(con => statsRepo.GetTotalPoolPaymentsAsync(con, config.Id));
#if DEBUG
var from = new DateTime(2018, 1, 6, 16, 0, 0);
#else
var from = clock.Now.AddDays(-1);
#endif
result.TopMiners = cf.Run(con => statsRepo.PagePoolMinersByHashrate(
con, config.Id, from, 0, 15))
result.TopMiners = (await cf.Run(con => statsRepo.PagePoolMinersByHashrateAsync(
con, config.Id, from, 0, 15)))
.Select(mapper.Map<MinerPerformanceStats>)
.ToArray();

return result;
}).ToArray()
}).ToArray())
};

await SendJsonAsync(context, response);
Expand All @@ -287,7 +288,7 @@ private async Task GetPoolInfoAsync(HttpContext context, Match m)
return;

// load stats
var stats = cf.Run(con => statsRepo.GetLastPoolStats(con, pool.Id));
var stats = await cf.Run(con => statsRepo.GetLastPoolStatsAsync(con, pool.Id));

// get pool
pools.TryGetValue(pool.Id, out var poolInstance);
Expand All @@ -298,15 +299,15 @@ private async Task GetPoolInfoAsync(HttpContext context, Match m)
};

// enrich
response.Pool.TotalPaid = cf.Run(con => statsRepo.GetTotalPoolPayments(con, pool.Id));
response.Pool.TotalPaid = await cf.Run(con => statsRepo.GetTotalPoolPaymentsAsync(con, pool.Id));
#if DEBUG
var from = new DateTime(2018, 1, 7, 16, 0, 0);
#else
var from = clock.Now.AddDays(-1);
#endif

response.Pool.TopMiners = cf.Run(con => statsRepo.PagePoolMinersByHashrate(
con, pool.Id, from, 0, 15))
response.Pool.TopMiners = (await cf.Run(con => statsRepo.PagePoolMinersByHashrateAsync(
con, pool.Id, from, 0, 15)))
.Select(mapper.Map<MinerPerformanceStats>)
.ToArray();

Expand All @@ -323,7 +324,7 @@ private async Task GetPoolPerformanceAsync(HttpContext context, Match m)
var end = clock.Now;
var start = end.AddDays(-1);

var stats = cf.Run(con => statsRepo.GetPoolPerformanceBetweenHourly(
var stats = await cf.Run(con => statsRepo.GetPoolPerformanceBetweenHourlyAsync(
con, pool.Id, start, end));

var response = new GetPoolStatsResponse
Expand Down Expand Up @@ -353,8 +354,8 @@ private async Task PagePoolMinersAsync(HttpContext context, Match m)
return;
}

var miners = cf.Run(con => statsRepo.PagePoolMinersByHashrate(
con, pool.Id, start, page, pageSize))
var miners = (await cf.Run(con => statsRepo.PagePoolMinersByHashrateAsync(
con, pool.Id, start, page, pageSize)))
.Select(mapper.Map<MinerPerformanceStats>)
.ToArray();

Expand All @@ -376,8 +377,8 @@ private async Task PagePoolBlocksPagedAsync(HttpContext context, Match m)
return;
}

var blocks = cf.Run(con => blocksRepo.PageBlocks(con, pool.Id,
new[] {BlockStatus.Confirmed, BlockStatus.Pending, BlockStatus.Orphaned}, page, pageSize))
var blocks = (await cf.Run(con => blocksRepo.PageBlocksAsync(con, pool.Id,
new[] {BlockStatus.Confirmed, BlockStatus.Pending, BlockStatus.Orphaned}, page, pageSize)))
.Select(mapper.Map<Responses.Block>)
.ToArray();

Expand Down Expand Up @@ -419,8 +420,8 @@ private async Task PagePoolPaymentsAsync(HttpContext context, Match m)
return;
}

var payments = cf.Run(con => paymentsRepo.PagePayments(
con, pool.Id, null, page, pageSize))
var payments = (await cf.Run(con => paymentsRepo.PagePaymentsAsync(
con, pool.Id, null, page, pageSize)))
.Select(mapper.Map<Responses.Payment>)
.ToArray();

Expand Down Expand Up @@ -457,8 +458,8 @@ private async Task GetMinerInfoAsync(HttpContext context, Match m)

var perfMode = context.GetQueryParameter<string>("perfMode", "day");

var statsResult = cf.RunTx((con, tx) =>
statsRepo.GetMinerStats(con, tx, pool.Id, address), true, IsolationLevel.Serializable);
var statsResult = await cf.RunTx((con, tx) =>
statsRepo.GetMinerStatsAsync(con, tx, pool.Id, address), true, IsolationLevel.Serializable);

MinerStats stats = null;

Expand All @@ -478,7 +479,7 @@ private async Task GetMinerInfoAsync(HttpContext context, Match m)
stats.LastPaymentLink = string.Format(baseUrl, statsResult.LastPayment.TransactionConfirmationData);
}

stats.PerformanceSamples = GetMinerPerformanceInternal(perfMode, pool, address);
stats.PerformanceSamples = await GetMinerPerformanceInternal(perfMode, pool, address);
}

await SendJsonAsync(context, stats);
Expand Down Expand Up @@ -506,8 +507,8 @@ private async Task PageMinerPaymentsAsync(HttpContext context, Match m)
return;
}

var payments = cf.Run(con => paymentsRepo.PagePayments(
con, pool.Id, address, page, pageSize))
var payments = (await cf.Run(con => paymentsRepo.PagePaymentsAsync(
con, pool.Id, address, page, pageSize)))
.Select(mapper.Map<Responses.Payment>)
.ToArray();

Expand Down Expand Up @@ -551,14 +552,43 @@ private async Task PageMinerBalanceChangesAsync(HttpContext context, Match m)
return;
}

var balanceChanges = cf.Run(con => paymentsRepo.PageBalanceChanges(
con, pool.Id, address, page, pageSize))
var balanceChanges = (await cf.Run(con => paymentsRepo.PageBalanceChangesAsync(
con, pool.Id, address, page, pageSize)))
.Select(mapper.Map<Responses.BalanceChange>)
.ToArray();

await SendJsonAsync(context, balanceChanges);
}

private async Task PageMinerEarningsByDayAsync(HttpContext context, Match m)
{
var pool = GetPool(context, m);
if (pool == null)
return;

var address = m.Groups["address"]?.Value;
if (string.IsNullOrEmpty(address))
{
context.Response.StatusCode = 404;
return;
}

var page = context.GetQueryParameter<int>("page", 0);
var pageSize = context.GetQueryParameter<int>("pageSize", 20);

if (pageSize == 0)
{
context.Response.StatusCode = 500;
return;
}

var earnings = (await cf.Run(con => paymentsRepo.PageMinerPaymentsByDayAsync(
con, pool.Id, address, page, pageSize)))
.ToArray();

await SendJsonAsync(context, earnings);
}

private async Task GetMinerPerformanceAsync(HttpContext context, Match m)
{
var pool = GetPool(context, m);
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Api/Responses/GetMinerStatsResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class MinerStats
public ulong PendingShares { get; set; }
public decimal PendingBalance { get; set; }
public decimal TotalPaid { get; set; }
public decimal TodayPaid { get; set; }
public DateTime? LastPayment { get; set; }
public string LastPaymentLink { get; set; }
public WorkerPerformanceStatsContainer Performance { get; set; }
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Api/Responses/GetPoolsResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class ApiCoinConfig
{
public string Type { get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Algorithm { get; set; }
}

Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/AutoMapperProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public AutoMapperProfile()
// API
CreateMap<CoinTemplate, Api.Responses.ApiCoinConfig>()
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Symbol))
.ForMember(dest => dest.Family, opt => opt.MapFrom(src => src.Family.ToString().ToLower()))
.ForMember(dest => dest.Algorithm, opt => opt.MapFrom(src => src.GetAlgorithmName()));

CreateMap<PoolConfig, Api.Responses.PoolInfo>()
Expand Down
2 changes: 1 addition & 1 deletion src/Miningcore/Blockchain/Bitcoin/BitcoinJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected virtual void BuildMerkleBranches()
var transactionHashes = BlockTemplate.Transactions
.Select(tx => (tx.TxId ?? tx.Hash)
.HexToByteArray()
.ReverseArray())
.ReverseInPlace())
.ToArray();

mt = new MerkleTree(transactionHashes);
Expand Down
8 changes: 4 additions & 4 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinPayoutHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public virtual Task CalculateBlockEffortAsync(Block block, double accumulatedBlo
return Task.FromResult(true);
}

public virtual Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, IDbTransaction tx, Block block, PoolConfig pool)
public virtual async Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, IDbTransaction tx, Block block, PoolConfig pool)
{
var blockRewardRemaining = block.Reward;

Expand All @@ -208,11 +208,11 @@ public virtual Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, I
if (address != poolConfig.Address)
{
logger.Info(() => $"Adding {FormatAmount(amount)} to balance of {address}");
balanceRepo.AddAmount(con, tx, poolConfig.Id, poolConfig.Template.Symbol, address, amount, $"Reward for block {block.BlockHeight}");
await balanceRepo.AddAmountAsync(con, tx, poolConfig.Id, poolConfig.Template.Symbol, address, amount, $"Reward for block {block.BlockHeight}");
}
}

return Task.FromResult(blockRewardRemaining);
return blockRewardRemaining;
}

public virtual async Task PayoutAsync(Balance[] balances)
Expand Down Expand Up @@ -296,7 +296,7 @@ public virtual async Task PayoutAsync(Balance[] balances)
else
logger.Info(() => $"[{LogCategory}] Payout transaction id: {txId}");

PersistPayments(balances, txId);
await PersistPaymentsAsync(balances, txId);

NotifyPayoutSuccess(poolConfig.Id, balances, new[] { txId }, null);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ protected override async Task SetupJobManager(CancellationToken ct)
}
}

protected override void InitStats()
protected override async Task InitStatsAsync()
{
base.InitStats();
await base.InitStatsAsync();

blockchainStats = manager.BlockchainStats;
}
Expand Down
1 change: 1 addition & 0 deletions src/Miningcore/Blockchain/Cryptonote/CryptonoteJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out
switch(blobConverted[0])
{
case 9:
case 8:
variant = CryptonightVariant.VARIANT_2;
break;

Expand Down
20 changes: 10 additions & 10 deletions src/Miningcore/Blockchain/Cryptonote/CryptonotePayoutHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public CryptonotePayoutHandler(

protected override string LogCategory => "Monero Payout Handler";

private bool HandleTransferResponse(DaemonResponse<TransferResponse> response, params Balance[] balances)
private async Task<bool> HandleTransferResponseAsync(DaemonResponse<TransferResponse> response, params Balance[] balances)
{
var coin = poolConfig.Template.As<CryptonoteCoinTemplate>();

Expand All @@ -88,7 +88,7 @@ private bool HandleTransferResponse(DaemonResponse<TransferResponse> response, p

logger.Info(() => $"[{LogCategory}] Payout transaction id: {txHash}, TxFee was {FormatAmount(txFee)}");

PersistPayments(balances, txHash);
await PersistPaymentsAsync(balances, txHash);
NotifyPayoutSuccess(poolConfig.Id, balances, new[] { txHash }, txFee);
return true;
}
Expand All @@ -102,7 +102,7 @@ private bool HandleTransferResponse(DaemonResponse<TransferResponse> response, p
}
}

private bool HandleTransferResponse(DaemonResponse<TransferSplitResponse> response, params Balance[] balances)
private async Task<bool> HandleTransferResponseAsync(DaemonResponse<TransferSplitResponse> response, params Balance[] balances)
{
var coin = poolConfig.Template.As<CryptonoteCoinTemplate>();

Expand All @@ -113,7 +113,7 @@ private bool HandleTransferResponse(DaemonResponse<TransferSplitResponse> respon

logger.Info(() => $"[{LogCategory}] Split-Payout transaction ids: {string.Join(", ", txHashes)}, Corresponding TxFees were {string.Join(", ", txFees.Select(FormatAmount))}");

PersistPayments(balances, txHashes.First());
await PersistPaymentsAsync(balances, txHashes.First());
NotifyPayoutSuccess(poolConfig.Id, balances, txHashes, txFees.Sum());
return true;
}
Expand Down Expand Up @@ -181,11 +181,11 @@ private async Task<bool> PayoutBatch(Balance[] balances)

var transferSplitResponse = await walletDaemon.ExecuteCmdSingleAsync<TransferSplitResponse>(logger, CryptonoteWalletCommands.TransferSplit, request);

return HandleTransferResponse(transferSplitResponse, balances);
return await HandleTransferResponseAsync(transferSplitResponse, balances);
}
}

return HandleTransferResponse(transferResponse, balances);
return await HandleTransferResponseAsync(transferResponse, balances);
}

private void ExtractAddressAndPaymentId(string input, out string address, out string paymentId)
Expand Down Expand Up @@ -256,7 +256,7 @@ private async Task PayoutToPaymentId(Balance balance)
}
}

HandleTransferResponse(result, balance);
await HandleTransferResponseAsync(result, balance);
}

#region IPayoutHandler
Expand Down Expand Up @@ -389,7 +389,7 @@ public Task CalculateBlockEffortAsync(Block block, double accumulatedBlockShareD
return Task.FromResult(true);
}

public Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, IDbTransaction tx, Block block, PoolConfig pool)
public async Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, IDbTransaction tx, Block block, PoolConfig pool)
{
var blockRewardRemaining = block.Reward;

Expand All @@ -405,14 +405,14 @@ public Task<decimal> UpdateBlockRewardBalancesAsync(IDbConnection con, IDbTransa
if (address != poolConfig.Address)
{
logger.Info(() => $"Adding {FormatAmount(amount)} to balance of {address}");
balanceRepo.AddAmount(con, tx, poolConfig.Id, poolConfig.Template.Symbol, address, amount, $"Reward for block {block.BlockHeight}");
await balanceRepo.AddAmountAsync(con, tx, poolConfig.Id, poolConfig.Template.Symbol, address, amount, $"Reward for block {block.BlockHeight}");
}
}

// Deduct static reserve for tx fees
blockRewardRemaining -= CryptonoteConstants.StaticTransactionFeeReserve;

return Task.FromResult(blockRewardRemaining);
return blockRewardRemaining;
}

public async Task PayoutAsync(Balance[] balances)
Expand Down
Loading

0 comments on commit bf5015a

Please sign in to comment.