Skip to content

Commit

Permalink
Merge pull request #16 from nopara73/services
Browse files Browse the repository at this point in the history
Services
  • Loading branch information
nopara73 committed Feb 22, 2018
2 parents e9caba2 + af4e470 commit 4dee7ce
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,4 @@ paket-files/
__pycache__/
*.pyc
/MagicalCryptoWallet.Backend/Logs.txt
/MagicalCryptoWallet.Backend/Log.txt
6 changes: 3 additions & 3 deletions MagicalCryptoWallet.Backend/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static string DataDir
{
if (!string.IsNullOrWhiteSpace(_dataDir)) return _dataDir;

_dataDir = EnvironmentHelpers.GetDataDir("MagicalCryptoWalletBackend");
_dataDir = EnvironmentHelpers.GetDataDir(Path.Combine("MagicalCryptoWallet","Backend"));

return _dataDir;
}
Expand Down Expand Up @@ -79,10 +79,10 @@ private static async Task AssertRpcNodeFullyInitializedAsync()

if (blocks != headers)
{
throw new NotSupportedException("Bitcoin Core is not fully syncronized.");
throw new NotSupportedException("Bitcoin Core is not fully synchronized.");
}

Logger.LogInfo<RPCClient>("Bitcoin Core is fully syncronized.");
Logger.LogInfo<RPCClient>("Bitcoin Core is fully synchronized.");

var estimateSmartFeeResponse = await RpcClient.TryEstimateSmartFeeAsync(2, EstimateSmartFeeMode.Conservative);
if (estimateSmartFeeResponse == null) throw new NotSupportedException($"Bitcoin Core cannot estimate network fees yet.");
Expand Down
4 changes: 2 additions & 2 deletions MagicalCryptoWallet.Backend/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public static async Task Main(string[] args)
{
try
{
Logger.SetMinimumLevel(LogLevel.Debug);
Logger.SetMinimumLevel(LogLevel.Info);
Logger.SetModes(LogMode.Debug, LogMode.Console, LogMode.File);
Logger.SetFilePath("Logs.txt");
Logger.SetFilePath(Path.Combine(Global.DataDir,"Logs.txt"));

await Global.InitializeAsync();

Expand Down
4 changes: 2 additions & 2 deletions MagicalCryptoWallet.Tests/KeyManagementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ public void CanSerialize()
{
string password = "password";
var manager = KeyManager.CreateNew(out Mnemonic mnemonic, password);

var filePath = "WalletDir/Wallet.json";
var filePath = Path.Combine(SharedFixture.DataDir, nameof(CanSerialize), "Wallet.json");
DeleteFileAndDirectoryIfExists(filePath);

Assert.Throws<FileNotFoundException>(() => KeyManager.FromFile(filePath));
Expand Down
17 changes: 16 additions & 1 deletion MagicalCryptoWallet.Tests/SharedFixture.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
using MagicalCryptoWallet.Logging;
using MagicalCryptoWallet.Helpers;
using MagicalCryptoWallet.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace MagicalCryptoWallet.Tests
{
public class SharedFixture : IDisposable
{
private static string _dataDir = null;
public static string DataDir
{
get
{
if (!string.IsNullOrWhiteSpace(_dataDir)) return _dataDir;

_dataDir = EnvironmentHelpers.GetDataDir(Path.Combine("MagicalCryptoWallet", "Tests"));

return _dataDir;
}
}

public SharedFixture()
{
// Initialize tests...
Expand Down
34 changes: 34 additions & 0 deletions MagicalCryptoWallet.Tests/WalletTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using MagicalCryptoWallet.KeyManagement;
using MagicalCryptoWallet.Services;
using NBitcoin;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace MagicalCryptoWallet.Tests
{
public class WalletTests : IClassFixture<SharedFixture>
{
private SharedFixture SharedFixture { get; }

public WalletTests(SharedFixture fixture)
{
SharedFixture = fixture;
}

[Fact]
public async Task BasicWalletTestAsync()
{
var manager = KeyManager.CreateNew(out Mnemonic mnemonic, "password");
var dataFolder = Path.Combine(SharedFixture.DataDir, nameof(BasicWalletTestAsync));
using (var wallet = new WalletService(dataFolder, Network.TestNet, manager))
{
wallet.Start();
await Task.Delay(1000);
}
}
}
}
127 changes: 127 additions & 0 deletions MagicalCryptoWallet/Services/WalletService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using MagicalCryptoWallet.Helpers;
using MagicalCryptoWallet.KeyManagement;
using MagicalCryptoWallet.Logging;
using NBitcoin;
using NBitcoin.Protocol;
using NBitcoin.Protocol.Behaviors;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace MagicalCryptoWallet.Services
{
public class WalletService : IDisposable
{
#region MembersAndProperties

public Network Network { get; }

public KeyManager KeyManager { get; }

public string WorkFolderPath { get; }

public NodeConnectionParameters ConnectionParameters { get; }

public string AddressManagerFilePath { get; }

// ToDo: I am accessing it a different way than HiddenWallet/Nicolas's SPV sample
// He has a GetAddressManager(), which always looks for AddressManager inside ConnectionParameters.TemplateBehaviors
// Not sure if I had a reason to do this, or I just used Nicolas's legacy
// ToDo: Does it work with RegTest? Or at least acts like it does.
public AddressManager AddressManager { get; private set; }

public NodesGroup Nodes { get; private set; }

#endregion

#region ConstructorsAndInitializers

public WalletService(string workFolderPath, Network network, KeyManager keyManager)
{
WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath);
Network = Guard.NotNull(nameof(network), network);
KeyManager = Guard.NotNull(nameof(keyManager), keyManager);

AddressManagerFilePath = Path.Combine(WorkFolderPath, $"AddressManager{Network}.dat");
ConnectionParameters = new NodeConnectionParameters();
Directory.CreateDirectory(WorkFolderPath);

try
{
AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);
}
catch (Exception ex) // ToDo: find out what the specific exception that is thrown and catch that
{
Logger.LogTrace<WalletService>(ex);
AddressManager = new AddressManager();
}

//So we find nodes faster
ConnectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));

Nodes = new NodesGroup(Network, ConnectionParameters,
new NodeRequirement
{
RequiredServices = NodeServices.Network,
MinVersion = ProtocolVersion.SENDHEADERS_VERSION
})
{
NodeConnectionParameters = ConnectionParameters
};
}

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
{
Nodes?.Dispose();
}
catch (Exception ex)
{
Logger.LogWarning<WalletService>(ex);
}
}

// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.

_disposedValue = true;
}
}

// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~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);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}

#endregion
}
}

0 comments on commit 4dee7ce

Please sign in to comment.