Elevate out P2P connection and mempool service from wallet job.
MODIFY
MagicalCryptoWallet.Tests/WalletTests.cs
MagicalCryptoWallet.Tests/WalletTests.cs
@@ -4,6 +4,7 @@ using MagicalCryptoWallet.Models;
using MagicalCryptoWallet.Services;
using NBitcoin;
using NBitcoin.Protocol;
+using NBitcoin.Protocol.Behaviors;
using System;
using System.Collections.Generic;
using System.IO;
@@ -23,21 +24,53 @@ namespace MagicalCryptoWallet.Tests
SharedFixture = fixture;
}
- [Fact]
- public async Task TestServicesAsync()
+ [Theory]
+ [InlineData("test")]
+ [InlineData("main")]
+ public async Task TestServicesAsync(string networkString)
{
+ var network = Network.GetNetwork(networkString);
+
var manager = KeyManager.CreateNew(out Mnemonic mnemonic, "password");
var dataFolder = Path.Combine(SharedFixture.DataDir, nameof(TestServicesAsync));
- using (var wallet = new WalletService(dataFolder, Network.Main, manager))
+ Directory.CreateDirectory(SharedFixture.DataDir);
+
+ var addressManagerFilePath = Path.Combine(SharedFixture.DataDir, $"AddressManager{network}.dat");
+ var connectionParameters = new NodeConnectionParameters();
+ AddressManager addressManager = null;
+ try
+ {
+ try
+ {
+ addressManager = AddressManager.LoadPeerFile(addressManagerFilePath);
+ Logger.LogInfo<WalletService>($"Loaded {nameof(AddressManager)} from `{addressManagerFilePath}`.");
+ }
+ catch (FileNotFoundException ex)
{
+ Logger.LogInfo<WalletService>($"{nameof(AddressManager)} did not exist at `{addressManagerFilePath}`. Initializing new one.");
+ Logger.LogTrace<WalletService>(ex);
+ addressManager = new AddressManager();
+ }
+ connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager));
+ var memPoolService = new MemPoolService();
+ connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(memPoolService));
+
+ using (var nodes = new NodesGroup(network, connectionParameters,
+ new NodeRequirement
+ {
+ RequiredServices = NodeServices.Network,
+ MinVersion = ProtocolVersion.WITNESS_VERSION
+ }))
+ {
+ var wallet = new WalletService(dataFolder, network, manager, nodes, memPoolService);
try
{
- wallet.Nodes.ConnectedNodes.Added += ConnectedNodes_Added;
- wallet.Nodes.ConnectedNodes.Removed += ConnectedNodes_Removed;
- wallet.MemPoolService.TransactionReceived += MemPoolService_TransactionReceived;
+ nodes.ConnectedNodes.Added += ConnectedNodes_Added;
+ nodes.ConnectedNodes.Removed += ConnectedNodes_Removed;
+ memPoolService.TransactionReceived += MemPoolService_TransactionReceived;
- wallet.Start();
+ nodes.Connect();
// Using the interlocked, not because it makes sense in this context, but to
// set an example that these values are often concurrency sensitive
var times = 0;
@@ -64,11 +97,17 @@ namespace MagicalCryptoWallet.Tests
}
finally
{
- wallet.Nodes.ConnectedNodes.Added -= ConnectedNodes_Added;
- wallet.Nodes.ConnectedNodes.Removed -= ConnectedNodes_Removed;
- wallet.MemPoolService.TransactionReceived -= MemPoolService_TransactionReceived;
+ nodes.ConnectedNodes.Added -= ConnectedNodes_Added;
+ nodes.ConnectedNodes.Removed -= ConnectedNodes_Removed;
+ memPoolService.TransactionReceived -= MemPoolService_TransactionReceived;
+ }
}
}
+ finally
+ {
+ addressManager?.SavePeerFile(addressManagerFilePath, network);
+ Logger.LogInfo<WalletTests>($"Saved {nameof(AddressManager)} to `{addressManagerFilePath}`.");
+ }
}
private long _nodeCount = 0;

MODIFY
MagicalCryptoWallet/Services/WalletService.cs
MagicalCryptoWallet/Services/WalletService.cs
@@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace MagicalCryptoWallet.Services
{
- public class WalletService : IDisposable
+ public class WalletService
{
#region MembersAndProperties
@@ -22,14 +22,7 @@ namespace MagicalCryptoWallet.Services
public string WorkFolderPath { get; }
- public NodeConnectionParameters ConnectionParameters { get; }
-
- public string AddressManagerFilePath { get; }
-
- // ToDo: Does it work with RegTest? Or at least acts like it does.
- public AddressManager AddressManager { get; set; }
-
- public NodesGroup Nodes { get; set; }
+ public NodesGroup Nodes { get; }
public MemPoolService MemPoolService { get; }
@@ -37,86 +30,15 @@ namespace MagicalCryptoWallet.Services
#region ConstructorsAndInitializers
- public WalletService(string workFolderPath, Network network, KeyManager keyManager)
+ public WalletService(string workFolderPath, Network network, KeyManager keyManager, NodesGroup nodes, MemPoolService mempoolService)
{
WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath);
Network = Guard.NotNull(nameof(network), network);
KeyManager = Guard.NotNull(nameof(keyManager), keyManager);
+ Nodes = Guard.NotNull(nameof(nodes), nodes);
+ MemPoolService = Guard.NotNull(nameof(mempoolService), mempoolService);
- AddressManagerFilePath = Path.Combine(WorkFolderPath, $"AddressManager{Network}.dat");
- ConnectionParameters = new NodeConnectionParameters();
Directory.CreateDirectory(WorkFolderPath);
-
- try
- {
- AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);
- Logger.LogInfo<WalletService>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
- }
- catch (FileNotFoundException ex)
- {
- Logger.LogInfo<WalletService>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
- Logger.LogTrace<WalletService>(ex);
- AddressManager = new AddressManager();
- }
-
- //So we find nodes faster
- ConnectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));
- MemPoolService = new MemPoolService();
- ConnectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));
-
- Nodes = new NodesGroup(Network, ConnectionParameters,
- new NodeRequirement
- {
- RequiredServices = NodeServices.Network,
- MinVersion = ProtocolVersion.WITNESS_VERSION
- });
- }
-
- public void Start()
- {
- Nodes.Connect();
- }
-
- #endregion
-
-
- #region Disposing
-
- private volatile bool _disposedValue = false; // To detect redundant calls
-
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposedValue)
- {
- if (disposing)
- {
- try
- {
- AddressManager.SavePeerFile(AddressManagerFilePath, Network);
- Logger.LogInfo<WalletService>($"Saved {nameof(AddressManager)} to `{AddressManagerFilePath}`.");
- Nodes?.Dispose();
- }
- catch (Exception ex)
- {
- Logger.LogWarning<WalletService>(ex);
- }
- }
-
- _disposedValue = true;
- }
- }
-
- // ~WalletService() {
- // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- // Dispose(false);
- // }
-
- // This code added to correctly implement the disposable pattern.
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose(true);
- // GC.SuppressFinalize(this);
}
#endregion

Elevate out P2P connection and mempool service from wallet job.