Skip to content

Commit 6f510a0

Browse files
authored
Add X1 (#276)
* add X1 to blockcore * add seeds * fix mining configuration
1 parent ad2fca4 commit 6f510a0

39 files changed

Lines changed: 7016 additions & 0 deletions

src/Blockcore.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blockcore.Networks.Impleum"
133133
EndProject
134134
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blockcore.Networks.BCP", "Networks\Blockcore.Networks.BCP\Blockcore.Networks.BCP.csproj", "{120500DF-C04F-43CC-9A1E-523A6429301F}"
135135
EndProject
136+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blockcore.Networks.X1", "Networks\Blockcore.Networks.X1\Blockcore.Networks.X1.csproj", "{9A2BA15A-C316-42B4-8E4D-E01B4873190C}"
137+
EndProject
136138
Global
137139
GlobalSection(SolutionConfigurationPlatforms) = preSolution
138140
Debug|Any CPU = Debug|Any CPU
@@ -351,6 +353,10 @@ Global
351353
{120500DF-C04F-43CC-9A1E-523A6429301F}.Debug|Any CPU.Build.0 = Debug|Any CPU
352354
{120500DF-C04F-43CC-9A1E-523A6429301F}.Release|Any CPU.ActiveCfg = Release|Any CPU
353355
{120500DF-C04F-43CC-9A1E-523A6429301F}.Release|Any CPU.Build.0 = Release|Any CPU
356+
{9A2BA15A-C316-42B4-8E4D-E01B4873190C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
357+
{9A2BA15A-C316-42B4-8E4D-E01B4873190C}.Debug|Any CPU.Build.0 = Debug|Any CPU
358+
{9A2BA15A-C316-42B4-8E4D-E01B4873190C}.Release|Any CPU.ActiveCfg = Release|Any CPU
359+
{9A2BA15A-C316-42B4-8E4D-E01B4873190C}.Release|Any CPU.Build.0 = Release|Any CPU
354360
EndGlobalSection
355361
GlobalSection(SolutionProperties) = preSolution
356362
HideSolutionNode = FALSE
@@ -411,6 +417,7 @@ Global
411417
{4275AF0C-587B-4C9D-A100-0F2DD1702674} = {64694A14-97E0-4CBC-8032-754F9353B2DD}
412418
{64E9C309-867E-45F6-A88E-7BC061305D0B} = {3B56C02B-4468-4268-B797-851562789FCC}
413419
{120500DF-C04F-43CC-9A1E-523A6429301F} = {3B56C02B-4468-4268-B797-851562789FCC}
420+
{9A2BA15A-C316-42B4-8E4D-E01B4873190C} = {3B56C02B-4468-4268-B797-851562789FCC}
414421
EndGlobalSection
415422
GlobalSection(ExtensibilityGlobals) = postSolution
416423
SolutionGuid = {6C780ABA-5872-4B83-AD3F-A5BD423AD907}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<AssemblyTitle>Blockcore.Networks.Xds</AssemblyTitle>
5+
<AssemblyName>Blockcore.Networks.X1</AssemblyName>
6+
<PackageId>Blockcore.Networks.X1</PackageId>
7+
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
8+
<IsPackable>true</IsPackable>
9+
<PackageProjectUrl>https://www.blockcore.net</PackageProjectUrl>
10+
<PackageTags>blockchain;cryptocurrency;crypto;C#;.NET;bitcoin;blockcore;x1crypto;x1</PackageTags>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<EmbeddedResource Include="icon.png" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="Cloo.clSharp" Version="1.0.1" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="..\..\Features\Blockcore.Features.Consensus\Blockcore.Features.Consensus.csproj" />
23+
<ProjectReference Include="..\..\Features\Blockcore.Features.MemoryPool\Blockcore.Features.MemoryPool.csproj" />
24+
<ProjectReference Include="..\..\Features\Blockcore.Features.Miner\Blockcore.Features.Miner.csproj" />
25+
</ItemGroup>
26+
27+
<ItemGroup>
28+
<Compile Update="Properties\Resources.Designer.cs">
29+
<DesignTime>True</DesignTime>
30+
<AutoGen>True</AutoGen>
31+
<DependentUpon>Resources.resx</DependentUpon>
32+
</Compile>
33+
</ItemGroup>
34+
35+
<ItemGroup>
36+
<EmbeddedResource Update="Properties\Resources.resx">
37+
<Generator>ResXFileCodeGenerator</Generator>
38+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
39+
</EmbeddedResource>
40+
</ItemGroup>
41+
</Project>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Blockcore.Base;
2+
using Blockcore.Broadcasters;
3+
using Blockcore.Builder;
4+
using Blockcore.Configuration.Logging;
5+
using Blockcore.Consensus;
6+
using Blockcore.Features.Consensus;
7+
using Blockcore.Features.Consensus.CoinViews;
8+
using Blockcore.Features.Consensus.CoinViews.Coindb;
9+
using Blockcore.Features.Consensus.Interfaces;
10+
using Blockcore.Features.Consensus.ProvenBlockHeaders;
11+
using Blockcore.Features.Consensus.Rules;
12+
using Blockcore.Features.MemoryPool;
13+
using Blockcore.Features.Miner;
14+
using Blockcore.Features.Miner.Broadcasters;
15+
using Blockcore.Features.Miner.Interfaces;
16+
using Blockcore.Features.RPC;
17+
using Blockcore.Features.Wallet.UI;
18+
using Blockcore.Interfaces;
19+
using Blockcore.Interfaces.UI;
20+
using Blockcore.Mining;
21+
using Microsoft.Extensions.DependencyInjection;
22+
23+
namespace Blockcore.Networks.X1.Components
24+
{
25+
public static class ComponentRegistration
26+
{
27+
public static IFullNodeBuilder UseX1Consensus(this IFullNodeBuilder fullNodeBuilder)
28+
{
29+
return AddX1PowPosMining(UseX1PosConsensus(fullNodeBuilder));
30+
}
31+
32+
static IFullNodeBuilder UseX1PosConsensus(this IFullNodeBuilder fullNodeBuilder)
33+
{
34+
LoggingConfiguration.RegisterFeatureNamespace<PosConsensusFeature>("posconsensus");
35+
36+
fullNodeBuilder.ConfigureFeature(features =>
37+
{
38+
features
39+
.AddFeature<PosConsensusFeature>()
40+
.FeatureServices(services =>
41+
{
42+
fullNodeBuilder.PersistenceProviderManager.RequirePersistence<PosConsensusFeature>(services);
43+
44+
services.AddSingleton<IStakdb>(provider => (IStakdb)provider.GetService<ICoindb>());
45+
services.AddSingleton<ICoinView, CachedCoinView>();
46+
services.AddSingleton<StakeChainStore>().AddSingleton<IStakeChain, StakeChainStore>(provider => provider.GetService<StakeChainStore>());
47+
services.AddSingleton<IRewindDataIndexCache, RewindDataIndexCache>();
48+
services.AddSingleton<IConsensusRuleEngine, PosConsensusRuleEngine>();
49+
services.AddSingleton<IChainState, ChainState>();
50+
services.AddSingleton<ConsensusQuery>()
51+
.AddSingleton<INetworkDifficulty, ConsensusQuery>(provider => provider.GetService<ConsensusQuery>())
52+
.AddSingleton<IGetUnspentTransaction, ConsensusQuery>(provider => provider.GetService<ConsensusQuery>());
53+
services.AddSingleton<IProvenBlockHeaderStore, ProvenBlockHeaderStore>();
54+
55+
services.AddSingleton<IStakeValidator, X1StakeValidator>();
56+
});
57+
});
58+
59+
return fullNodeBuilder;
60+
}
61+
62+
/// <summary>
63+
/// Adds POW and POS miner components to the node, so that it can mine or stake.
64+
/// </summary>
65+
/// <param name="fullNodeBuilder">The object used to build the current node.</param>
66+
/// <returns>The full node builder, enriched with the new component.</returns>
67+
static IFullNodeBuilder AddX1PowPosMining(this IFullNodeBuilder fullNodeBuilder)
68+
{
69+
LoggingConfiguration.RegisterFeatureNamespace<X1MiningFeature>("x1mining");
70+
71+
fullNodeBuilder.ConfigureFeature(features =>
72+
{
73+
features
74+
.AddFeature<X1MiningFeature>()
75+
.DependOn<MempoolFeature>()
76+
.DependOn<RPCFeature>()
77+
// TODO: Need a better way to check dependencies. This is really just dependent on IWalletManager...
78+
// Alternatively "DependsOn" should take a list of features that will satisfy the dependency.
79+
//.DependOn<WalletFeature>()
80+
.FeatureServices(services =>
81+
{
82+
services.AddSingleton<MinerSettings, X1MinerSettings>();
83+
services.AddSingleton<IPowMining, X1PowMining>();
84+
services.AddSingleton<IPosMinting, X1PosMinting>();
85+
86+
services.AddSingleton<IBlockProvider, BlockProvider>();
87+
services.AddSingleton<BlockDefinition, PowBlockDefinition>();
88+
services.AddSingleton<BlockDefinition, PosBlockDefinition>();
89+
services.AddSingleton<BlockDefinition, PosPowBlockDefinition>();
90+
services.AddSingleton<INavigationItem, StakeNavigationItem>();
91+
services.AddSingleton<IClientEventBroadcaster, StakingBroadcaster>();
92+
});
93+
});
94+
95+
return fullNodeBuilder;
96+
}
97+
}
98+
}
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Cloo;
5+
using Microsoft.Extensions.Logging;
6+
7+
namespace Blockcore.Networks.X1.Components
8+
{
9+
/// <summary>
10+
/// The famous SpartaCrypt OpenCLMiner, visit the original here:
11+
/// https://github.com/spartacrypt/xds-1/blob/master/src/components/Fullnode/UnnamedCoin.Bitcoin.Features.Miner/OpenCLMiner.cs
12+
/// </summary>
13+
public class OpenCLMiner : IDisposable
14+
{
15+
private const string KernelFunction = "kernel_find_pow";
16+
17+
private readonly ILogger logger;
18+
private readonly ComputeDevice computeDevice;
19+
20+
private List<ComputeKernel> computeKernels = new List<ComputeKernel>();
21+
private ComputeProgram computeProgram;
22+
private ComputeContext computeContext;
23+
private ComputeKernel computeKernel;
24+
private string[] openCLSources;
25+
private bool isDisposed;
26+
27+
/// <summary>
28+
/// Create a new OpenCLMiner instance.
29+
/// </summary>
30+
/// <param name="minerSettings">the minerSettings</param>
31+
/// <param name="loggerFactory">the loggerFactory</param>
32+
public OpenCLMiner(X1MinerSettings minerSettings, ILoggerFactory loggerFactory)
33+
{
34+
this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
35+
var devices = ComputePlatform.Platforms.SelectMany(p => p.Devices).Where(d => d.Available && d.CompilerAvailable).ToList();
36+
37+
if (!devices.Any())
38+
{
39+
this.logger.LogWarning($"No OpenCL Devices Found!");
40+
}
41+
else
42+
{
43+
foreach (ComputeDevice device in devices)
44+
{
45+
this.logger.LogInformation($"Found OpenCL Device: Name={device.Name}, MaxClockFrequency{device.MaxClockFrequency}");
46+
}
47+
48+
this.computeDevice = devices.FirstOrDefault(d => d.Name.Equals(minerSettings.OpenCLDevice, StringComparison.OrdinalIgnoreCase)) ?? devices.FirstOrDefault();
49+
if (this.computeDevice != null)
50+
{
51+
this.logger.LogInformation($"Using OpenCL Device: Name={this.computeDevice.Name}");
52+
}
53+
}
54+
}
55+
56+
/// <summary>
57+
/// Destructor.
58+
/// </summary>
59+
~OpenCLMiner()
60+
{
61+
this.DisposeOpenCLResources();
62+
}
63+
64+
/// <summary>
65+
/// If a compute device for mining is available.
66+
/// </summary>
67+
/// <returns>true if a usable device is found, otherwise false</returns>
68+
public bool CanMine()
69+
{
70+
return this.computeDevice != null;
71+
}
72+
73+
/// <summary>
74+
/// Gets the currently used device name.
75+
/// </summary>
76+
/// <returns></returns>
77+
public string GetDeviceName()
78+
{
79+
if (this.computeDevice == null)
80+
{
81+
throw new InvalidOperationException("GPU not found");
82+
}
83+
84+
return this.computeDevice.Name;
85+
}
86+
87+
/// <summary>
88+
/// Finds the nonce for a block header hash that meets the given target.
89+
/// </summary>
90+
/// <param name="header">serialized block header</param>
91+
/// <param name="bits">the target</param>
92+
/// <param name="nonceStart">the first nonce value to try</param>
93+
/// <param name="iterations">the number of iterations</param>
94+
/// <returns></returns>
95+
public uint FindPow(byte[] header, byte[] bits, uint nonceStart, uint iterations)
96+
{
97+
if (this.computeDevice == null)
98+
{
99+
throw new InvalidOperationException("GPU not found");
100+
}
101+
102+
this.ConstructOpenCLResources();
103+
104+
using var headerBuffer = new ComputeBuffer<byte>(this.computeContext, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, header);
105+
using var bitsBuffer = new ComputeBuffer<byte>(this.computeContext, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, bits);
106+
using var powBuffer = new ComputeBuffer<uint>(this.computeContext, ComputeMemoryFlags.WriteOnly, 1);
107+
108+
this.computeKernel.SetMemoryArgument(0, headerBuffer);
109+
this.computeKernel.SetMemoryArgument(1, bitsBuffer);
110+
this.computeKernel.SetValueArgument(2, nonceStart);
111+
this.computeKernel.SetMemoryArgument(3, powBuffer);
112+
113+
using var commands = new ComputeCommandQueue(this.computeContext, this.computeDevice, ComputeCommandQueueFlags.None);
114+
commands.Execute(this.computeKernel, null, new long[] { iterations }, null, null);
115+
116+
var nonceOut = new uint[1];
117+
commands.ReadFromBuffer(powBuffer, ref nonceOut, true, null);
118+
commands.Finish();
119+
120+
this.DisposeOpenCLResources();
121+
122+
return nonceOut[0];
123+
}
124+
125+
private void ConstructOpenCLResources()
126+
{
127+
if (this.computeDevice != null)
128+
{
129+
if (this.openCLSources == null)
130+
{
131+
GetOpenCLSources();
132+
}
133+
var properties = new ComputeContextPropertyList(this.computeDevice.Platform);
134+
this.computeContext = new ComputeContext(new[] { this.computeDevice }, properties, null, IntPtr.Zero);
135+
this.computeProgram = new ComputeProgram(this.computeContext, this.openCLSources);
136+
this.computeProgram.Build(new[] { this.computeDevice }, null, null, IntPtr.Zero);
137+
this.computeKernels = this.computeProgram.CreateAllKernels().ToList();
138+
this.computeKernel = this.computeKernels.First((k) => k.FunctionName == KernelFunction);
139+
}
140+
}
141+
142+
private void GetOpenCLSources()
143+
{
144+
this.openCLSources = new[]
145+
{
146+
Properties.Resources.SpartacryptOpenCLMiner_opencl_device_info_h,
147+
Properties.Resources.SpartacryptOpenCLMiner_opencl_misc_h,
148+
Properties.Resources.SpartacryptOpenCLMiner_opencl_sha2_common_h,
149+
Properties.Resources.SpartacryptOpenCLMiner_opencl_sha512_h,
150+
Properties.Resources.SpartacryptOpenCLMiner_sha512_miner_cl
151+
};
152+
}
153+
154+
private void DisposeOpenCLResources()
155+
{
156+
this.computeKernels.ForEach(k => k.Dispose());
157+
this.computeKernels.Clear();
158+
this.computeProgram?.Dispose();
159+
this.computeProgram = null;
160+
this.computeContext?.Dispose();
161+
this.computeContext = null;
162+
}
163+
164+
/// <summary>
165+
/// Releases the OpenCL resources.
166+
/// </summary>
167+
public void Dispose()
168+
{
169+
Dispose(true);
170+
GC.SuppressFinalize(this);
171+
}
172+
173+
void Dispose(bool disposing)
174+
{
175+
if (this.isDisposed)
176+
return;
177+
178+
if (disposing)
179+
{
180+
DisposeOpenCLResources();
181+
}
182+
183+
this.isDisposed = true;
184+
}
185+
}
186+
}

0 commit comments

Comments
 (0)