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

Commit

Permalink
Dev (#328)
Browse files Browse the repository at this point in the history
* Handle SIGTERM for graceful shutdown
* Shutdown Logging
* RVN, PGN address meta data
* Eth nonce parsing
* Implemented support for Tcp-Proxy-Protocol. Fixes #306
* Callisto Mainnet support
* Disable Ethereum wallet ownership check at startup as it seems to do more harm than good.
* Changed Ethash Future DAG generation
* Equihashverify update
* Short-time ban for unauthorized miners to prevent potential validateaddress RPC DDos
* Max inbound request length increase
* Support static diff for bitcoin family of pools using d=diff as part of the password
* Partition API into regular and admin-api on different ports
* MessageBus for loosely coupled inter-component communication
* Publish shares over MessageBus
* Refactor external share receiver logic from ShareRecorder into own component
  • Loading branch information
Oliver Weichhold authored Apr 27, 2018
1 parent 9f373a1 commit df1348e
Show file tree
Hide file tree
Showing 95 changed files with 8,234 additions and 884 deletions.
22 changes: 22 additions & 0 deletions src/MiningCore.Tests/Crypto/HashingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,28 @@ public void EquihashVerifier_Should_Verify_Success()
Assert.True(result);
}

[Fact]
public void EquihashVerifier_Should_Not_Verify_Invalid_Solution()
{
var hasher = EquihashSolver.Instance.Value;
var header = "0400000008e9694cc2120ec1b5733cc12687b609058eec4f7046a521ad1d1e3049b400003e7420ed6f40659de0305ef9b7ec037f4380ed9848bc1c015691c90aa16ff3930000000000000000000000000000000000000000000000000000000000000000c9310d5874e0001f000000000000000000000000000000010b000000000000000000000000000040".HexToByteArray();
var solution = "90b43863a213bfe79f00337f5a729f09710abcc07035ef8ac34372abddecf2f82715f7223f075af96f0604fc124d6151fc8fb516d24a137faec123a89aa9a433f8a25a6bcfc554c28be556f6c878f96539186fab191505f278df48bf1ad2240e5bb39f372a143de1dd1b672312e00d52a3dd83f471b0239a7e8b30d4b9153027df87c8cd0b64de76749539fea376b4f39d08cf3d5e821495e52fdfa6f8085e59fc670656121c9d7c01388c8b4b4585aa7b9ac3f7ae796f9eb1fadba1730a1860eed797feabb18832b5e8f003c0adaf0788d1016e7a8969144018ecc86140aa4553962aa739a4850b509b505e158c5f9e2d5376374652e9e6d81b19fa0351be229af136efbce681463cc53d7880c1eeca3411154474ff8a7b2bac034a2026646776a517bf63921c31fbbd6be7c3ff42aab28230bfe81d33800b892b262f3579b7a41925a59f5cc1d4f523577c19ff9f92023146fa26486595bd89a1ba459eb0b5cec0578c3a071dbec73eca054c723ab30ce8e69de32e779cd2f1030e39878ac6ea3cdca743b43aedefe1a9b4f2da861038e2759defef0b8cad11d4179f2f08881b53ccc203e558c0571e049d998a257b3279016aad0d7999b609f6331a0d0f88e286a70432ca7f50a5bb8fafbbe9230b4ccb1fa57361c163d6b9f84579d61f41585a022d07dc8e55a8de4d8f87641dae777819458a2bf1bb02c438480ff11621ca8442ec2946875cce247c8877051359e9c822670d37bb00fa806e60e8e890ce62540fda2d5b1c790ca1e005030ac6d8e63db577bb98be111ee146828f9c48ee6257d7627b93ea3dd11aac3412e63dfc7ca132a73c4f51e7650f3f8ecf57bfc18716990b492d50e0a3e5fbf6136e771b91f7283ec3326209265b9531d157f8a07a4117fc8fb29ba1363afc6f9f0608251ea595256727a5bbe28f42a42edfbfa9017680e32980d4ad381612612b2bc7ad91e82eca693ea4fc27049a99636b50a576f1e55c72202d582b150ef194c1419f53177ecf315ea6b0e2f1aa8cd8f59b165aa0d89561c537fb6141f5813b7a4968fe16afc703326113f68508d88ff8d0aee1e88a84c0ae56c72f27511290ced48e93e8c95419d14aed1a5b2e9b2c9c1070c593e5eb50bb9a80e14e9f9fe501f56b1b3140159e8213b75d48d14af472a604484cd8e7e7abb6820245ed3ab29f9947463a033c586194be45eadec8392c8614d83a1e9ca0fe5655fa14f7a9c1d1f8f2185a06193ff4a3c3e9a96b02310033ceaa25894e7c56a6147e691597098054e285d39656d3d459ec5d13243c062b6eb44e19a13bdfc0b3c96bd3d1aeb75bb6b080322aea23555993cb529243958bb1a0e5d5027e6c78155437242d1d13c1d6e442a0e3783147a08bbfc0c2529fb705ad27713df40486fd58f001977f25dfd3c202451c07010a3880bca63959ca61f10ed3871f1152166fce2b52135718a8ceb239a0664a31c62defaad70be4b920dce70549c10d9138fbbad7f291c5b73fa21c3889929b143bc1576b72f70667ac11052b686891085290d871db528b5cfdc10a6d563925227609f10d1768a0e02dc7471ad424f94f737d4e7eb0fb167f1434fc4ae2d49e152f06f0845b6db0a44f0d6f5e7410420e6bd1f430b1af956005bf72b51405a04d9a5d9906ceca52c22c855785c3c3ac4c3e9bf532d31bab321e1db66f6a9f7dc9c017f2b7d8dfeb933cf5bbae71311ae318f6d187ebc5c843be342b08a9a0ff7c4b9c4b0f4fa74b13296afe84b6481440d58332e07b3d051ed55219d28e77af6612134da4431b797c63ef55bc53831e2f421db620fee51ba0967e4ed7009ef90af2204259bbfbb54537fd35c2132fa8e7f9c84bf9938d248862c6ca1cca9f48b0b33aa1589185c4eabc1c32".HexToByteArray();
var result = hasher.Verify(header, solution);

Assert.False(result);
}

[Fact]
public void EquihashVerifier_Should_Not_Verify_Fake_Solution()
{
var hasher = EquihashSolver.Instance.Value;
var header = "0400000008e9694cc2120ec1b5733cc12687b609058eec4f7046a521ad1d1e3049b400003e7420ed6f40659de0305ef9b7ec037f4380ed9848bc1c015691c90aa16ff3930000000000000000000000000000000000000000000000000000000000000000c9310d5874e0001f000000000000000000000000000000010b000000000000000000000000000040".HexToByteArray();
var solution = Enumerable.Repeat((byte) 0, 1344).ToArray();
var result = hasher.Verify(header, solution);

Assert.False(result);
}

[Fact]
public void EquihashVerifier_Should_Throw_On_Null_Input()
{
Expand Down
6 changes: 3 additions & 3 deletions src/MiningCore.Tests/MiningCore.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Microsoft.Reactive.Testing" Version="3.1.1" />
<PackageReference Include="xunit" Version="2.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
Expand Down
101 changes: 88 additions & 13 deletions src/MiningCore/Api/ApiServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using MiningCore.Blockchain;
using MiningCore.Configuration;
using MiningCore.Extensions;
using MiningCore.Messaging;
using MiningCore.Mining;
using MiningCore.Notifications.Messages;
using MiningCore.Persistence;
using MiningCore.Persistence.Model;
using MiningCore.Persistence.Repositories;
Expand All @@ -60,14 +62,16 @@ public ApiServer(
IBlockRepository blocksRepo,
IPaymentRepository paymentsRepo,
IStatsRepository statsRepo,
IMasterClock clock)
IMasterClock clock,
IMessageBus messageBus)
{
Contract.RequiresNonNull(cf, nameof(cf));
Contract.RequiresNonNull(statsRepo, nameof(statsRepo));
Contract.RequiresNonNull(blocksRepo, nameof(blocksRepo));
Contract.RequiresNonNull(paymentsRepo, nameof(paymentsRepo));
Contract.RequiresNonNull(mapper, nameof(mapper));
Contract.RequiresNonNull(clock, nameof(clock));
Contract.RequiresNonNull(messageBus, nameof(messageBus));

this.cf = cf;
this.statsRepo = statsRepo;
Expand All @@ -76,6 +80,8 @@ public ApiServer(
this.mapper = mapper;
this.clock = clock;

messageBus.Listen<BlockNotification>().Subscribe(OnBlockNotification);

requestMap = new Dictionary<Regex, Func<HttpContext, Match, Task>>
{
{ new Regex("^/api/pools$", RegexOptions.Compiled), GetPoolInfosAsync },
Expand All @@ -88,8 +94,10 @@ public ApiServer(
{ new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/balancechanges$", RegexOptions.Compiled), PageMinerBalanceChangesAsync },
{ new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)/performance$", RegexOptions.Compiled), GetMinerPerformanceAsync },
{ new Regex("^/api/pools/(?<poolId>[^/]+)/miners/(?<address>[^/]+)$", RegexOptions.Compiled), GetMinerInfoAsync },
};

// admin api
requestMapAdmin = new Dictionary<Regex, Func<HttpContext, Match, Task>>
{
{ new Regex("^/api/admin/forcegc$", RegexOptions.Compiled), HandleForceGcAsync },
{ new Regex("^/api/admin/stats/gc$", RegexOptions.Compiled), HandleGcStatsAsync },
};
Expand All @@ -104,6 +112,7 @@ public ApiServer(

private ClusterConfig clusterConfig;
private IWebHost webHost;
private IWebHost webHostAdmin;
private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
private static readonly Encoding encoding = new UTF8Encoding(false);

Expand All @@ -115,6 +124,7 @@ public ApiServer(
};

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

private PoolConfig GetPool(HttpContext context, Match m)
{
Expand Down Expand Up @@ -153,6 +163,12 @@ private async Task SendJsonAsync(HttpContext context, object response)
}
}

private void OnBlockNotification(BlockNotification notification)
{
}

#region API

private async Task HandleRequest(HttpContext context)
{
var request = context.Request;
Expand Down Expand Up @@ -560,20 +576,13 @@ private async Task HandleGcStatsAsync(HttpContext context, Match m)
Program.gcStats.GcGen0 = GC.CollectionCount(0);
Program.gcStats.GcGen1 = GC.CollectionCount(1);
Program.gcStats.GcGen2 = GC.CollectionCount(2);
Program.gcStats.MemAllocated = FormatUtil.FormatCapacity(GC.GetTotalMemory(false));
Program.gcStats.MemAllocated = FormatUtil.FormatCapacity(GC.GetTotalMemory(false));

await SendJsonAsync(context, Program.gcStats);
}

#region API-Surface

public void Start(ClusterConfig clusterConfig)
private void StartApi(ClusterConfig clusterConfig)
{
Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
this.clusterConfig = clusterConfig;

logger.Info(() => $"Launching ...");

var address = clusterConfig.Api?.ListenAddress != null
? (clusterConfig.Api.ListenAddress != "*" ? IPAddress.Parse(clusterConfig.Api.ListenAddress) : IPAddress.Any)
: IPAddress.Parse("127.0.0.1");
Expand All @@ -587,10 +596,76 @@ public void Start(ClusterConfig clusterConfig)

webHost.Start();

logger.Info(() => $"Online @ {address}:{port}");
logger.Info(() => $"API Online @ {address}:{port}");
}

#endregion // API

#region Admin API

private async Task HandleRequestAdmin(HttpContext context)
{
var request = context.Request;

try
{
logger.Debug(() => $"Processing request {request.GetEncodedPathAndQuery()}");

foreach (var path in requestMapAdmin.Keys)
{
var m = path.Match(request.Path);

if (m.Success)
{
var handler = requestMapAdmin[path];
await handler(context, m);
return;
}
}

context.Response.StatusCode = 404;
}

catch (Exception ex)
{
logger.Error(ex);
throw;
}
}

private void StartAdminApi(ClusterConfig clusterConfig)
{
var address = clusterConfig.Api?.ListenAddress != null
? (clusterConfig.Api.ListenAddress != "*" ? IPAddress.Parse(clusterConfig.Api.ListenAddress) : IPAddress.Any)
: IPAddress.Parse("127.0.0.1");

var port = clusterConfig.Api?.AdminPort ?? 4001;

webHostAdmin = new WebHostBuilder()
.Configure(app => { app.Run(HandleRequestAdmin); })
.UseKestrel(options => { options.Listen(address, port); })
.Build();

webHostAdmin.Start();

logger.Info(() => $"Admin API Online @ {address}:{port}");
}

#endregion // Admin API

#region API-Surface

public void Start(ClusterConfig clusterConfig)
{
Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
this.clusterConfig = clusterConfig;

logger.Info(() => $"Launching ...");
StartApi(clusterConfig);
StartAdminApi(clusterConfig);
}

#endregion // API-Surface
#endregion // API-Surface

}
}
2 changes: 2 additions & 0 deletions src/MiningCore/Api/Responses/GetBlocksResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class Block
public decimal Reward { get; set; }
public string InfoLink { get; set; }
public string Hash { get; set; }
public string Miner { get; set; }
public string Source { get; set; }
public DateTime Created { get; set; }
}
}
8 changes: 8 additions & 0 deletions src/MiningCore/AutofacModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using MiningCore.Blockchain.ZCash;
using MiningCore.Blockchain.ZCash.DaemonResponses;
using MiningCore.Configuration;
using MiningCore.Messaging;
using MiningCore.Mining;
using MiningCore.Notifications;
using MiningCore.Payments;
Expand Down Expand Up @@ -65,6 +66,10 @@ protected override void Load(ContainerBuilder builder)
ContractResolver = new CamelCasePropertyNamesContractResolver()
});

builder.RegisterType<MessageBus>()
.AsImplementedInterfaces()
.SingleInstance();

builder.RegisterType<PayoutManager>()
.AsSelf()
.SingleInstance();
Expand All @@ -80,6 +85,9 @@ protected override void Load(ContainerBuilder builder)
builder.RegisterType<ShareRecorder>()
.SingleInstance();

builder.RegisterType<ShareReceiver>()
.SingleInstance();

builder.RegisterType<ShareRelay>()
.SingleInstance();

Expand Down
2 changes: 2 additions & 0 deletions src/MiningCore/Blockchain/Bitcoin/BitcoinConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ public class DevDonation
{CoinType.XVG, "D5xPoHLM6HPkwWSqAweECTSQirJBmRjS8i" },
{CoinType.XMR, "475YVJbPHPedudkhrcNp1wDcLMTGYusGPF5fqE7XjnragVLPdqbCHBdZg3dF4dN9hXMjjvGbykS6a77dTAQvGrpiQqHp2eH"},
{CoinType.ETN, "etnkQJwBCjmR1MfkU8D355ZWxxLMhs8miPrtKHWN4U3uUowq9ugeKccVBoEG3n13n74us5AkT8tEoTog46w4HBgn8sMuBRhm9h"},
{CoinType.RVN, "RQPJF65UoodQ2aZUkfnXoeX6gib3GNwm9u"},
{CoinType.PGN, "PRm3ThUGfmU157NwcKzKBqWbgA2DPuFje1"},
};
}

Expand Down
4 changes: 3 additions & 1 deletion src/MiningCore/Blockchain/Bitcoin/BitcoinJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ protected virtual byte[] SerializeHeader(byte[] coinbaseHash, uint nTime, uint n
// build merkle-root
var merkleRoot = mt.WithFirst(coinbaseHash);

#pragma warning disable 618
var blockHeader = new BlockHeader
#pragma warning restore 618
{
Version = (int) BlockTemplate.Version,
Bits = new Target(Encoders.Hex.DecodeData(BlockTemplate.Bits)),
Expand Down Expand Up @@ -381,7 +383,7 @@ protected virtual byte[] SerializeBlock(byte[] header, byte[] coinbase)

// POS coins require a zero byte appended to block which the daemon replaces with the signature
if (isPoS)
bs.ReadWrite((byte) 0);
bs.ReadWrite((byte)0);

return stream.ToArray();
}
Expand Down
Loading

0 comments on commit df1348e

Please sign in to comment.