Skip to content

Commit 267cf63

Browse files
authored
Merge pull request #2 from itswisdomagain/decred
test against decred binaries without pre-running harness
2 parents 96186fa + 6aee134 commit 267cf63

26 files changed

Lines changed: 2080 additions & 756 deletions

NBitcoin.Altcoins/Decred.cs

Lines changed: 859 additions & 168 deletions
Large diffs are not rendered by default.

NBitcoin.Altcoins/NBitcoin.Altcoins.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
<None Include="..\icon.png" Pack="true" PackagePath="\" />
3434
<Compile Remove="HashX11\NeoScrypt.cs" />
3535
</ItemGroup>
36+
<ItemGroup>
37+
<PackageReference Include="Blake3" Version="0.6.1" />
38+
</ItemGroup>
3639
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3740
<DebugType>portable</DebugType>
3841
<PublishRepositoryUrl>true</PublishRepositoryUrl>

NBitcoin.TestFramework/NodeBuilder.cs

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,15 @@ public NodeOSDownloadData GetCurrentOSDownloadData()
130130
}
131131
public class NodeBuilder : IDisposable
132132
{
133-
public static NodeBuilder Create(NodeDownloadData downloadData, Network network = null, [CallerMemberNameAttribute]string caller = null, bool showNodeConsole = false)
133+
public static NodeBuilder Create(NodeDownloadData downloadData, Network network = null, Func<Network, bool> useNetwork = null, [CallerMemberNameAttribute] string caller = null, Func<NodeRunner> customNodeRunner = null, bool showNodeConsole = false)
134134
{
135135
network = network ?? Network.RegTest;
136+
if (useNetwork != null && useNetwork(network) == false) return null;
136137
var isFilePath = downloadData.Version.Length >= 2 && downloadData.Version[1] == ':';
137138
var path = isFilePath ? downloadData.Version : EnsureDownloaded(downloadData);
138139
if (!Directory.Exists(caller))
139140
Directory.CreateDirectory(caller);
140-
return new NodeBuilder(caller, path) { Network = network, NodeImplementation = downloadData, ShowNodeConsole = showNodeConsole };
141+
return new NodeBuilder(caller, path) { Network = network, NodeImplementation = downloadData, CustomNodeRunner = customNodeRunner, ShowNodeConsole = showNodeConsole };
141142
}
142143

143144
public static string EnsureDownloaded(NodeDownloadData downloadData)
@@ -218,6 +219,7 @@ public Network Network
218219
set;
219220
} = Network.RegTest;
220221
public NodeDownloadData NodeImplementation { get; private set; }
222+
public Func<NodeRunner> CustomNodeRunner { get; private set; }
221223
public RPCWalletType? RPCWalletType { get; set; }
222224
public bool CreateWallet { get; set; } = true;
223225

@@ -295,6 +297,8 @@ public NodeConfigParameters ConfigParameters
295297
}
296298
}
297299

300+
private readonly NodeRunner _NodeRunner;
301+
298302
public CoreNode(string folder, NodeBuilder builder)
299303
{
300304
this._Builder = builder;
@@ -308,6 +312,19 @@ public CoreNode(string folder, NodeBuilder builder)
308312
ConfigParameters.Import(builder.ConfigParameters, true);
309313
ports = new int[2];
310314

315+
// Some coins (such as decred) have a (slightly) different way of
316+
// running their nodes. They may require more than 2 ports, for
317+
// example. And they'd usually require a (slightly) different
318+
// cleanup proceedure than the one doen below.
319+
if (builder.CustomNodeRunner != null)
320+
{
321+
this._NodeRunner = builder.CustomNodeRunner();
322+
if (_NodeRunner.PortsNeeded > 2)
323+
ports = new int[_NodeRunner.PortsNeeded];
324+
if (builder.CleanBeforeStartingNode)
325+
_NodeRunner.StopPreviouslyRunningProcesses(dataDir);
326+
}
327+
311328
if (builder.CleanBeforeStartingNode && File.Exists(_Config))
312329
{
313330
var oldCreds = ExtractCreds(File.ReadAllText(_Config));
@@ -330,6 +347,15 @@ public CoreNode(string folder, NodeBuilder builder)
330347
throw new InvalidOperationException("A running instance of bitcoind of a previous run prevent this test from starting. Please close bitcoind process manually and restart the test.");
331348
}
332349
}
350+
}
351+
352+
// If cleaning previous process(es) is required, it would have been
353+
// done above by `builder.NodeRunner.StopPreviouslyRunningProcesses`
354+
// if applicable or by the if block just above. Now repeatedly try
355+
// to delete the data directory for about 10 seconds, since it may
356+
// take a while for all process(es) to fully stop.
357+
if (builder.CleanBeforeStartingNode)
358+
{
333359
CancellationTokenSource cts = new CancellationTokenSource();
334360
cts.CancelAfter(10000);
335361
while (!cts.IsCancellationRequested && Directory.Exists(_Folder))
@@ -441,16 +467,23 @@ public NetworkCredential RPCCredentials
441467
creds = value;
442468
}
443469
}
470+
471+
public string TLSCertFilePath => _NodeRunner == null ? null : _NodeRunner.TLSCertFilePath(dataDir);
472+
444473
public RPCClient CreateRPCClient()
445474
{
446-
return new RPCClient(GetRPCAuth(), RPCUri, Network);
475+
// Some coins (like decred) require a tls cert for rpc connections.
476+
return new RPCClient(GetRPCAuth(), RPCUri, TLSCertFilePath, Network);
447477
}
448478

449479
public Uri RPCUri
450480
{
451481
get
452482
{
453-
return new Uri("http://127.0.0.1:" + ports[1].ToString() + "/");
483+
// Some coins (like decred) require a tls cert for rpc
484+
// connections. In such cases, use https.
485+
var uriScheme = TLSCertFilePath == null ? "http" : "https";
486+
return new Uri(uriScheme + "://127.0.0.1:" + ports[1].ToString() + "/");
454487
}
455488
}
456489

@@ -466,6 +499,7 @@ public RestClient CreateRESTClient()
466499
{
467500
return new RestClient(new Uri("http://127.0.0.1:" + ports[1].ToString() + "/"));
468501
}
502+
469503
#if !NOSOCKET
470504
public Node CreateNodeClient()
471505
{
@@ -500,6 +534,16 @@ public NodeDownloadData NodeImplementation
500534

501535
public async Task StartAsync()
502536
{
537+
// Some coins (such as decred) use different configuration options
538+
// and values. For such coins, do not use the generic config builder
539+
// below.
540+
if (_NodeRunner != null)
541+
{
542+
_NodeRunner.WriteConfigFile(dataDir, creds, ports, ConfigParameters);
543+
await Run();
544+
return;
545+
}
546+
503547
NodeConfigParameters config = new NodeConfigParameters();
504548
StringBuilder configStr = new StringBuilder();
505549
if (String.IsNullOrEmpty(NodeImplementation.Chain))
@@ -562,7 +606,14 @@ private async Task Run()
562606
string appPath = new FileInfo(this._Builder.BitcoinD).FullName;
563607
string args = "-conf=bitcoin.conf" + " -datadir=" + dataDir + " -debug=net";
564608

565-
if (_Builder.ShowNodeConsole)
609+
// Some coins (such as decred) have a (slightly) different way
610+
// of running their nodes. Use the custom node runner for such
611+
// coins.
612+
if (_NodeRunner != null)
613+
{
614+
_Process = _NodeRunner.Run(appPath, dataDir, _Builder.ShowNodeConsole).GetAwaiter().GetResult();
615+
}
616+
else if (_Builder.ShowNodeConsole)
566617
{
567618
ProcessStartInfo info = new ProcessStartInfo(appPath, args);
568619
info.UseShellExecute = true;
@@ -602,7 +653,7 @@ private void CreateDefaultWallet()
602653
_ => string.Empty
603654
};
604655

605-
retry:
656+
retry:
606657
string walletToolArgs = $"{string.Format(_Builder.NodeImplementation.GetWalletChainSpecifier, _Builder.NodeImplementation.Chain)} -wallet=\"wallet.dat\"{walletType} -datadir=\"{dataDir}\" create";
607658

608659
var info = new ProcessStartInfo(walletToolPath, walletToolArgs)
@@ -615,7 +666,7 @@ private void CreateDefaultWallet()
615666
info.RedirectStandardOutput = true;
616667
}
617668
using (var walletToolProcess = Process.Start(info))
618-
{
669+
{
619670
walletToolProcess.WaitForExit();
620671
// Some doesn't support this
621672
if (walletToolProcess.ExitCode != 0 && walletType != string.Empty)
@@ -685,6 +736,10 @@ public void Kill(bool cleanFolder = false)
685736
_Process.Kill();
686737
_Process.WaitForExit();
687738
}
739+
if (_NodeRunner != null)
740+
{
741+
_NodeRunner.Kill();
742+
}
688743
_State = CoreNodeState.Killed;
689744
if (cleanFolder)
690745
CleanFolder();

0 commit comments

Comments
 (0)