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

Commit

Permalink
Merge pull request #931 from coinfoundry/oliverw
Browse files Browse the repository at this point in the history
Merge dev branch
  • Loading branch information
Oliver Weichhold authored Sep 13, 2021
2 parents 1291255 + 52d0ba4 commit 82a6c6a
Show file tree
Hide file tree
Showing 95 changed files with 15,904 additions and 795 deletions.
18 changes: 10 additions & 8 deletions examples/ethereum_pool.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,16 @@
}
],
"paymentProcessing": {
"enabled": true,
"minimumPayment": 1,
"payoutScheme": "PPLNS",
"payoutSchemeConfig": {
"factor": 0.5
},
"keepUncles": false,
"keepTransactionFees": false
"enabled": true,
"minimumPayment": 1,
"payoutScheme": "PPLNS",
"payoutSchemeConfig": {
"factor": 0.5
},
"gas": 21000,
"maxFeePerGas": 50000000000,
"keepUncles": false,
"keepTransactionFees": false
}
}
]
Expand Down
Binary file added libs/runtimes/win-x64/libkawpow.dll
Binary file not shown.
17 changes: 16 additions & 1 deletion src/Miningcore/Api/Controllers/AdminApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.Concurrent;
using System.Net;
using System.Threading.Tasks;
using NLog;

namespace Miningcore.Api.Controllers
{
Expand All @@ -31,6 +32,8 @@ public AdminApiController(IComponentContext ctx) : base(ctx)

private readonly Responses.AdminGcStats gcStats;

private static readonly ILogger logger = LogManager.GetCurrentClassLogger();

#region Actions

[HttpGet("stats/gc")]
Expand Down Expand Up @@ -87,10 +90,22 @@ public async Task<decimal> GetMinerBalanceAsync(string poolId, string address)

// map settings
var mapped = mapper.Map<Persistence.Model.MinerSettings>(settings);

// clamp limit
if(pool.PaymentProcessing != null)
mapped.PaymentThreshold = Math.Max(mapped.PaymentThreshold, pool.PaymentProcessing.MinimumPayment);

mapped.PoolId = pool.Id;
mapped.Address = address;

var result = await cf.RunTx((con, tx) => minerRepo.UpdateSettings(con, tx, mapped));
var result = await cf.RunTx(async (con, tx) =>
{
await minerRepo.UpdateSettings(con, tx, mapped);

return await minerRepo.GetSettings(con, tx, mapped.PoolId, mapped.Address);
});

logger.Info(()=> $"Updated settings for pool {pool.Id}, miner {address}");

return mapper.Map<Responses.MinerSettings>(result);
}
Expand Down
74 changes: 71 additions & 3 deletions src/Miningcore/Api/Controllers/PoolApiController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Autofac;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Miningcore.Api.Extensions;
Expand All @@ -8,20 +7,19 @@
using Miningcore.Configuration;
using Miningcore.Extensions;
using Miningcore.Mining;
using Miningcore.Persistence;
using Miningcore.Persistence.Model;
using Miningcore.Persistence.Model.Projections;
using Miningcore.Persistence.Repositories;
using Miningcore.Time;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using NLog;

namespace Miningcore.Api.Controllers
{
Expand All @@ -33,6 +31,8 @@ public PoolApiController(IComponentContext ctx, IActionDescriptorCollectionProvi
{
statsRepo = ctx.Resolve<IStatsRepository>();
blocksRepo = ctx.Resolve<IBlockRepository>();
minerRepo = ctx.Resolve<IMinerRepository>();
shareRepo = ctx.Resolve<IShareRepository>();
paymentsRepo = ctx.Resolve<IPaymentRepository>();
clock = ctx.Resolve<IMasterClock>();
pools = ctx.Resolve<ConcurrentDictionary<string, IMiningPool>>();
Expand All @@ -42,10 +42,14 @@ public PoolApiController(IComponentContext ctx, IActionDescriptorCollectionProvi
private readonly IStatsRepository statsRepo;
private readonly IBlockRepository blocksRepo;
private readonly IPaymentRepository paymentsRepo;
private readonly IMinerRepository minerRepo;
private readonly IShareRepository shareRepo;
private readonly IMasterClock clock;
private readonly IActionDescriptorCollectionProvider adcp;
private readonly ConcurrentDictionary<string, IMiningPool> pools;

private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();

#region Actions

[HttpGet]
Expand Down Expand Up @@ -537,6 +541,70 @@ public async Task<PagedResultResponse<AmountByDate[]>> PageMinerEarningsByDayV2A
return result;
}

[HttpGet("{poolId}/miners/{address}/settings")]
public async Task<Responses.MinerSettings> GetMinerSettingsAsync(string poolId, string address)
{
var pool = GetPool(poolId);

if(string.IsNullOrEmpty(address))
throw new ApiException("Invalid or missing miner address", HttpStatusCode.NotFound);

var result = await cf.Run(con=> minerRepo.GetSettings(con, null, pool.Id, address));

if(result == null)
throw new ApiException("No settings found", HttpStatusCode.NotFound);

return mapper.Map<Responses.MinerSettings>(result);
}

[HttpPost("{poolId}/miners/{address}/settings")]
public async Task<Responses.MinerSettings> SetMinerSettingsAsync(string poolId, string address,
[FromBody] Requests.UpdateMinerSettingsRequest request)
{
var pool = GetPool(poolId);

if(string.IsNullOrEmpty(address))
throw new ApiException("Invalid or missing miner address", HttpStatusCode.NotFound);

if(request?.Settings == null)
throw new ApiException("Invalid or missing settings", HttpStatusCode.BadRequest);

if(!IPAddress.TryParse(request.IpAddress, out var requestIp))
throw new ApiException("Invalid IP address", HttpStatusCode.BadRequest);

// fetch recent IPs
var ips = await cf.Run(con=> shareRepo.GetRecentyUsedIpAddresses(con, null, poolId, address));

// any known ips?
if(ips == null || ips.Length == 0)
throw new ApiException("Address not recently used for mining", HttpStatusCode.NotFound);

// match?
if(!ips.Any(x=> IPAddress.TryParse(x, out var ipAddress) && ipAddress.IsEqual(requestIp)))
throw new ApiException("None of the recently used IP addresses matches the request", HttpStatusCode.Forbidden);

// map settings
var mapped = mapper.Map<Persistence.Model.MinerSettings>(request.Settings);

// clamp limit
if(pool.PaymentProcessing != null)
mapped.PaymentThreshold = Math.Max(mapped.PaymentThreshold, pool.PaymentProcessing.MinimumPayment);

mapped.PoolId = pool.Id;
mapped.Address = address;

// finally update the settings
return await cf.RunTx(async (con, tx) =>
{
await minerRepo.UpdateSettings(con, tx, mapped);

logger.Info(()=> $"Updated settings for pool {pool.Id}, miner {address}");

var result = await minerRepo.GetSettings(con, tx, mapped.PoolId, mapped.Address);
return mapper.Map<Responses.MinerSettings>(result);
});
}

#endregion // Actions

private async Task<Responses.WorkerPerformanceStatsContainer[]> GetMinerPerformanceInternal(
Expand Down
10 changes: 10 additions & 0 deletions src/Miningcore/Api/Requests/UpdateMinerSettingsRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Miningcore.Api.Responses;

namespace Miningcore.Api.Requests
{
public class UpdateMinerSettingsRequest
{
public string IpAddress { get; set; }
public MinerSettings Settings { get; set; }
}
}
8 changes: 8 additions & 0 deletions src/Miningcore/AutofacModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Newtonsoft.Json.Serialization;
using Module = Autofac.Module;
using Microsoft.AspNetCore.Mvc;
using Miningcore.Blockchain.Ergo;
using Miningcore.Nicehash;
using Miningcore.Pushover;

Expand Down Expand Up @@ -145,13 +146,20 @@ protected override void Load(ContainerBuilder builder)
//////////////////////
// Ethereum

builder.RegisterType<EthereumJobManager>();
builder.RegisterType<EthereumJobManager>();

//////////////////////
// ZCash

builder.RegisterType<EquihashJobManager>();

//////////////////////
// Ergo

builder.RegisterType<EquihashJobManager>();
builder.RegisterType<ErgoJobManager>();

base.Load(builder);
}
}
Expand Down
27 changes: 9 additions & 18 deletions src/Miningcore/Blockchain/Bitcoin/BitcoinJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Miningcore.Configuration;
using Miningcore.Contracts;
using Miningcore.Crypto;
using Miningcore.DaemonInterface;
using Miningcore.Extensions;
using Miningcore.JsonRpc;
using Miningcore.Messaging;
Expand Down Expand Up @@ -48,26 +47,23 @@ protected override object[] GetBlockTemplateParams()
return result;
}

protected async Task<DaemonResponse<BlockTemplate>> GetBlockTemplateAsync(CancellationToken ct)
protected async Task<RpcResponse<BlockTemplate>> GetBlockTemplateAsync(CancellationToken ct)
{
logger.LogInvoke();

var result = await daemon.ExecuteCmdAnyAsync<BlockTemplate>(logger,
var result = await rpcClient.ExecuteAsync<BlockTemplate>(logger,
BitcoinCommands.GetBlockTemplate, ct, extraPoolConfig?.GBTArgs ?? (object) GetBlockTemplateParams());

return result;
}

protected DaemonResponse<BlockTemplate> GetBlockTemplateFromJson(string json)
protected RpcResponse<BlockTemplate> GetBlockTemplateFromJson(string json)
{
logger.LogInvoke();

var result = JsonConvert.DeserializeObject<JsonRpcResponse>(json);

return new DaemonResponse<BlockTemplate>
{
Response = result.ResultAs<BlockTemplate>(),
};
return new RpcResponse<BlockTemplate>(result.ResultAs<BlockTemplate>());
}

private BitcoinJob CreateJob()
Expand Down Expand Up @@ -194,7 +190,7 @@ public override void Configure(PoolConfig poolConfig, ClusterConfig clusterConfi
base.Configure(poolConfig, clusterConfig);
}

public override object[] GetSubscriberData(StratumConnection worker)
public virtual object[] GetSubscriberData(StratumConnection worker)
{
Contract.RequiresNonNull(worker, nameof(worker));

Expand All @@ -213,7 +209,7 @@ public override object[] GetSubscriberData(StratumConnection worker)
return responseData;
}

public override async ValueTask<Share> SubmitShareAsync(StratumConnection worker, object submission,
public virtual async ValueTask<Share> SubmitShareAsync(StratumConnection worker, object submission,
double stratumDifficultyBase, CancellationToken ct)
{
Contract.RequiresNonNull(worker, nameof(worker));
Expand Down Expand Up @@ -247,19 +243,14 @@ public override async ValueTask<Share> SubmitShareAsync(StratumConnection worker
if(job == null)
throw new StratumException(StratumError.JobNotFound, "job not found");

// extract worker/miner/payoutid
var split = workerValue.Split('.');
var minerName = split[0];
var workerName = split.Length > 1 ? split[1] : null;

// validate & process
var (share, blockHex) = job.ProcessShare(worker, extraNonce2, nTime, nonce, versionBits);

// enrich share with common data
share.PoolId = poolConfig.Id;
share.IpAddress = worker.RemoteEndpoint.Address.ToString();
share.Miner = minerName;
share.Worker = workerName;
share.Miner = context.Miner;
share.Worker = context.Worker;
share.UserAgent = context.UserAgent;
share.Source = clusterConfig.ClusterName;
share.Created = clock.Now;
Expand All @@ -276,7 +267,7 @@ public override async ValueTask<Share> SubmitShareAsync(StratumConnection worker

if(share.IsBlockCandidate)
{
logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{share.BlockHash}] submitted by {minerName}");
logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{share.BlockHash}] submitted by {context.Miner}");

OnBlockFound();

Expand Down
Loading

0 comments on commit 82a6c6a

Please sign in to comment.