Remove code from Wallet.cs file
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -283,6 +283,7 @@ namespace WalletWasabi.Gui
RegTestMempoolServingNode = null;
}
+ Nodes.MaximumNodeConnection = 16;
Nodes.Connect();
Logger.LogInfo("Start connecting to nodes...");
@@ -328,7 +329,15 @@ namespace WalletWasabi.Gui
#endregion JsonRpcServerInitialization
- WalletManager.RegisterServices(BitcoinStore, Synchronizer, Nodes, Config.ServiceConfiguration, FeeProviders, BitcoinCoreNode);
+ #region Blocks provider
+
+ var blockProvider = new CachedBlockProvider(
+ new P2pBlockProvider(Nodes, BitcoinCoreNode, Synchronizer, Config.ServiceConfiguration, Network),
+ new FileSystemBlockRepository(blocksFolderPath, Network));
+
+ #endregion Blocks provider
+
+ WalletManager.RegisterServices(BitcoinStore, Synchronizer, Nodes, Config.ServiceConfiguration, FeeProviders, blockProvider);
}
catch (Exception ex)
{

MODIFY
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
@@ -104,7 +104,7 @@ namespace WalletWasabi.Gui.ViewModels
Peers = Tor == TorStatus.NotRunning ? 0 : Nodes.Count;
- Observable.FromEventPattern<bool>(typeof(Wallet), nameof(Wallet.DownloadingBlockChanged))
+ Observable.FromEventPattern<bool>(typeof(P2pBlockProvider), nameof(P2pBlockProvider.DownloadingBlockChanged))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => DownloadingBlock = x.EventArgs)
.DisposeWith(Disposables);

RENAME
WalletWasabi/Wallets/CachedBlocksProvider.cs
WalletWasabi/Wallets/CachedBlockProvider.cs
@@ -7,16 +7,16 @@ namespace WalletWasabi.Wallets
/// <summary>
/// CachedBlocksProvider is a blocks provider that keep the blocks on a repository to satify future requests.
/// </summary>
- public class CachedBlocksProvider : IBlocksProvider
+ public class CachedBlockProvider : IBlockProvider
{
- public CachedBlocksProvider(IBlocksProvider blocksSourceProvider, IRepository<uint256, Block> blocksRepository)
+ public CachedBlockProvider(IBlockProvider blockSourceProvider, IRepository<uint256, Block> blockRepository)
{
- BlocksRepository = blocksRepository;
- BlocksSourceProvider = blocksSourceProvider;
+ BlockRepository = blockRepository;
+ BlockSourceProvider = blockSourceProvider;
}
- public IRepository<uint256, Block> BlocksRepository { get; }
- public IBlocksProvider BlocksSourceProvider { get; }
+ public IRepository<uint256, Block> BlockRepository { get; }
+ public IBlockProvider BlockSourceProvider { get; }
/// <summary>
/// Gets a bitcoin block. In case the requested block is not available in the repository it is returned
@@ -28,11 +28,11 @@ namespace WalletWasabi.Wallets
/// <returns>The requested bitcoin block.</returns>
public async Task<Block> GetBlockAsync(uint256 hash, CancellationToken cancellationToken)
{
- Block block = await BlocksRepository.GetAsync(hash, cancellationToken);
+ Block block = await BlockRepository.GetAsync(hash, cancellationToken);
if (block is null)
{
- block = await BlocksSourceProvider.GetBlockAsync(hash, cancellationToken);
- await BlocksRepository.SaveAsync(block, cancellationToken);
+ block = await BlockSourceProvider.GetBlockAsync(hash, cancellationToken);
+ await BlockRepository.SaveAsync(block, cancellationToken);
}
return block;
}
@@ -45,7 +45,7 @@ namespace WalletWasabi.Wallets
/// <returns>The requested bitcoin block.</returns>
public Task InvalidateAsync(uint256 hash, CancellationToken cancellationToken)
{
- return BlocksRepository.RemoveAsync(hash, cancellationToken);
+ return BlockRepository.RemoveAsync(hash, cancellationToken);
}
}
}
\ No newline at end of file

MODIFY
WalletWasabi/Wallets/Wallet.cs
WalletWasabi/Wallets/Wallet.cs
@@ -37,7 +37,6 @@ namespace WalletWasabi.Wallets
{
public class Wallet : BackgroundService
{
- private Node _localBitcoinCoreNode = null;
private WalletState _state;
public Wallet(string dataDir, Network network, string filePath) : this(dataDir, network, KeyManager.FromFile(filePath))
@@ -53,20 +52,6 @@ namespace WalletWasabi.Wallets
RuntimeParams.SetDataDir(dataDir);
HandleFiltersLock = new AsyncLock();
- BlockFolderLock = new AsyncLock();
- BlockFolderPath = Path.Combine(dataDir, "Blocks", Network.ToString());
- if (Directory.Exists(BlockFolderPath))
- {
- if (Network == Network.RegTest)
- {
- Directory.Delete(BlockFolderPath, true);
- Directory.CreateDirectory(BlockFolderPath);
- }
- }
- else
- {
- Directory.CreateDirectory(BlockFolderPath);
- }
KeyManager.AssertCleanKeysIndexed();
KeyManager.AssertLockedInternalKeysIndexed(14);
}
@@ -75,8 +60,6 @@ namespace WalletWasabi.Wallets
public event EventHandler<DequeueResult> OnDequeue;
- public static event EventHandler<bool> DownloadingBlockChanged;
-
public static event EventHandler<bool> InitializingChanged;
public event EventHandler<FilterModel> NewFilterProcessed;
@@ -105,7 +88,6 @@ namespace WalletWasabi.Wallets
public WasabiSynchronizer Synchronizer { get; private set; }
public CoinJoinClient ChaumianClient { get; private set; }
public NodesGroup Nodes { get; private set; }
- public string BlockFolderPath { get; }
public ServiceConfiguration ServiceConfiguration { get; private set; }
public string WalletName => KeyManager.WalletName;
@@ -117,37 +99,19 @@ namespace WalletWasabi.Wallets
public Network Network { get; }
public TransactionProcessor TransactionProcessor { get; private set; }
- public Node LocalBitcoinCoreNode
- {
- get
- {
- if (Network == Network.RegTest)
- {
- return Nodes.ConnectedNodes.First();
- }
-
- return _localBitcoinCoreNode;
- }
- private set => _localBitcoinCoreNode = value;
- }
-
public IFeeProvider FeeProvider { get; private set; }
- public CoreNode CoreNode { get; private set; }
public FilterModel LastProcessedFilter { get; private set; }
+ public IBlockProvider BlockProvider { get; private set; }
private static Random Random { get; } = new Random();
private AsyncLock HandleFiltersLock { get; }
- private AsyncLock BlockFolderLock { get; }
-
- private int NodeTimeouts { get; set; }
-
public void RegisterServices(
BitcoinStore bitcoinStore,
WasabiSynchronizer syncer,
NodesGroup nodes,
ServiceConfiguration serviceConfiguration,
IFeeProvider feeProvider,
- CoreNode coreNode = null)
+ IBlockProvider blockProvider)
{
if (State > WalletState.WaitingForInit)
{
@@ -161,7 +125,6 @@ namespace WalletWasabi.Wallets
Synchronizer = Guard.NotNull(nameof(syncer), syncer);
ServiceConfiguration = Guard.NotNull(nameof(serviceConfiguration), serviceConfiguration);
FeeProvider = Guard.NotNull(nameof(feeProvider), feeProvider);
- CoreNode = coreNode;
ChaumianClient = new CoinJoinClient(Synchronizer, Network, KeyManager);
@@ -175,6 +138,8 @@ namespace WalletWasabi.Wallets
BitcoinStore.IndexStore.Reorged += IndexDownloader_ReorgedAsync;
BitcoinStore.MempoolService.TransactionReceived += Mempool_TransactionReceived;
+ BlockProvider = blockProvider;
+
State = WalletState.Initialized;
}
catch
@@ -242,51 +207,6 @@ namespace WalletWasabi.Wallets
/// <inheritdoc />
protected override Task ExecuteAsync(CancellationToken stoppingToken) => Task.CompletedTask;
- /// <param name="hash">Block hash of the desired block, represented as a 256 bit integer.</param>
- /// <exception cref="OperationCanceledException"></exception>
- public async Task<Block> FetchBlockAsync(uint256 hash, CancellationToken cancel)
- {
- Block block = await TryGetBlockFromFileAsync(hash, cancel);
- if (block is null)
- {
- block = await DownloadBlockAsync(hash, cancel);
- }
- return block;
- }
-
- /// <remarks>
- /// Use it at reorgs.
- /// </remarks>
- public async Task DeleteBlockAsync(uint256 hash)
- {
- try
- {
- using (await BlockFolderLock.LockAsync())
- {
- var filePaths = Directory.EnumerateFiles(BlockFolderPath);
- var fileNames = filePaths.Select(Path.GetFileName);
- var hashes = fileNames.Select(x => new uint256(x));
-
- if (hashes.Contains(hash))
- {
- File.Delete(Path.Combine(BlockFolderPath, hash.ToString()));
- }
- }
- }
- catch (Exception ex)
- {
- Logger.LogWarning(ex);
- }
- }
-
- public async Task<int> CountBlocksAsync()
- {
- using (await BlockFolderLock.LockAsync())
- {
- return Directory.EnumerateFiles(BlockFolderPath).Count();
- }
- }
-
/// <param name="allowUnconfirmed">Allow to spend unconfirmed transactions, if necessary.</param>
/// <param name="allowedInputs">Only these inputs allowed to be used to build the transaction. The wallet must know the corresponding private keys.</param>
/// <exception cref="ArgumentException"></exception>
@@ -352,8 +272,6 @@ namespace WalletWasabi.Wallets
await ChaumianClient.StopAsync(cancel).ConfigureAwait(false);
Logger.LogInfo($"{nameof(ChaumianClient)} is stopped.");
}
-
- DisconnectDisposeNullLocalBitcoinCoreNode();
}
finally
{
@@ -460,7 +378,11 @@ namespace WalletWasabi.Wallets
using (await HandleFiltersLock.LockAsync())
{
uint256 invalidBlockHash = invalidFilter.Header.BlockHash;
- await DeleteBlockAsync(invalidBlockHash);
+ if (BlockProvider is CachedBlockProvider blockCache)
+ {
+ await blockCache.InvalidateAsync(invalidBlockHash, CancellationToken.None).ConfigureAwait(false);
+ }
+
KeyManager.SetMaxBestHeight(new Height(invalidFilter.Header.Height - 1));
TransactionProcessor.UndoBlock((int)invalidFilter.Header.Height);
BitcoinStore.TransactionStore.ReleaseToMempoolFromBlock(invalidBlockHash);
@@ -578,7 +500,7 @@ namespace WalletWasabi.Wallets
var matchFound = filterModel.Filter.MatchAny(KeyManager.GetPubKeyScriptBytes(), filterModel.FilterKey);
if (matchFound)
{
- Block currentBlock = await FetchBlockAsync(filterModel.Header.BlockHash, cancel); // Wait until not downloaded.
+ Block currentBlock = await BlockProvider.GetBlockAsync(filterModel.Header.BlockHash, cancel); // Wait until not downloaded.
var height = new Height(filterModel.Header.Height);
var txsToProcess = new List<SmartTransaction>();
@@ -596,287 +518,6 @@ namespace WalletWasabi.Wallets
LastProcessedFilter = filterModel;
}
- /// <param name="hash">Block hash of the desired block, represented as a 256 bit integer.</param>
- /// <exception cref="OperationCanceledException"></exception>
- private async Task<Block> TryGetBlockFromFileAsync(uint256 hash, CancellationToken cancel)
- {
- // Try get the block
- Block block = null;
- using (await BlockFolderLock.LockAsync())
- {
- var encoder = new HexEncoder();
- var filePath = Path.Combine(BlockFolderPath, hash.ToString());
- if (File.Exists(filePath))
- {
- try
- {
- var blockBytes = await File.ReadAllBytesAsync(filePath, cancel);
- block = Block.Load(blockBytes, Network);
- }
- catch
- {
- // In case the block file is corrupted and we get an EndOfStreamException exception
- // Ignore any error and continue to re-downloading the block.
- Logger.LogDebug($"Block {hash} file corrupted, deleting file and block will be re-downloaded.");
- File.Delete(filePath);
- }
- }
- }
-
- return block;
- }
-
- /// <param name="hash">Block hash of the desired block, represented as a 256 bit integer.</param>
- /// <exception cref="OperationCanceledException"></exception>
- private async Task<Block> DownloadBlockAsync(uint256 hash, CancellationToken cancel)
- {
- Block block = null;
- try
- {
- DownloadingBlockChanged?.Invoke(null, true);
-
- while (true)
- {
- cancel.ThrowIfCancellationRequested();
- try
- {
- // Try to get block information from local running Core node first.
- block = await TryDownloadBlockFromLocalNodeAsync(hash, cancel);
-
- if (block != null)
- {
- break;
- }
-
- // If no connection, wait, then continue.
- while (Nodes.ConnectedNodes.Count == 0)
- {
- await Task.Delay(100, cancel);
- }
-
- // Select a random node we are connected to.
- Node node = Nodes.ConnectedNodes.RandomElement();
- if (node is null || !node.IsConnected)
- {
- await Task.Delay(100, cancel);
- continue;
- }
-
- // Download block from selected node.
- try
- {
- using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(RuntimeParams.Instance.NetworkNodeTimeout))) // 1/2 ADSL 512 kbit/s 00:00:32
- {
- using var lts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancel);
- block = await node.DownloadBlockAsync(hash, lts.Token);
- }
-
- // Validate block
- if (!block.Check())
- {
- Logger.LogInfo($"Disconnected node: {node.RemoteSocketAddress}, because invalid block received.");
- node.DisconnectAsync("Invalid block received.");
- continue;
- }
-
- if (Nodes.ConnectedNodes.Count > 1) // To minimize risking missing unconfirmed transactions.
- {
- Logger.LogInfo($"Disconnected node: {node.RemoteSocketAddress}. Block downloaded: {block.GetHash()}.");
- node.DisconnectAsync("Thank you!");
- }
-
- await NodeTimeoutsAsync(false);
- }
- catch (Exception ex) when (ex is OperationCanceledException || ex is TaskCanceledException || ex is TimeoutException)
- {
- Logger.LogInfo($"Disconnected node: {node.RemoteSocketAddress}, because block download took too long.");
-
- await NodeTimeoutsAsync(true);
-
- node.DisconnectAsync("Block download took too long.");
- continue;
- }
- catch (Exception ex)
- {
- Logger.LogDebug(ex);
- Logger.LogInfo($"Disconnected node: {node.RemoteSocketAddress}, because block download failed: {ex.Message}.");
- node.DisconnectAsync("Block download failed.");
- continue;
- }
-
- break; // If got this far, then we have the block and it's valid. Break.
- }
- catch (Exception ex)
- {
- Logger.LogDebug(ex);
- }
- }
-
- // Save the block
- var path = Path.Combine(BlockFolderPath, hash.ToString());
- await SaveBlockToDiskAsync(path, block);
- }
- finally
- {
- DownloadingBlockChanged?.Invoke(null, false);
- }
-
- return block;
- }
-
- private async Task SaveBlockToDiskAsync(string path, Block block)
- {
- if (!File.Exists(path))
- {
- using (await BlockFolderLock.LockAsync())
- {
- if (!File.Exists(path))
- {
- await File.WriteAllBytesAsync(path, block.ToBytes());
- }
- }
- }
- }
-
- private async Task<Block> TryDownloadBlockFromLocalNodeAsync(uint256 hash, CancellationToken cancel)
- {
- if (CoreNode?.RpcClient is null)
- {
- try
- {
- if (LocalBitcoinCoreNode is null || (!LocalBitcoinCoreNode.IsConnected && Network != Network.RegTest)) // If RegTest then we're already connected do not try again.
- {
- DisconnectDisposeNullLocalBitcoinCoreNode();
- using var handshakeTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancel);
- handshakeTimeout.CancelAfter(TimeSpan.FromSeconds(10));
- var nodeConnectionParameters = new NodeConnectionParameters()
- {
- ConnectCancellation = handshakeTimeout.Token,
- IsRelay = false,
- UserAgent = $"/Wasabi:{Constants.ClientVersion}/"
- };
-
- // If an onion was added must try to use Tor.
- // onlyForOnionHosts should connect to it if it's an onion endpoint automatically and non-Tor endpoints through clearnet/localhost
- if (Synchronizer.WasabiClient.TorClient.IsTorUsed)
- {
- nodeConnectionParameters.TemplateBehaviors.Add(new SocksSettingsBehavior(Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint, onlyForOnionHosts: true, networkCredential: null, streamIsolation: false));
- }
-
- var localEndPoint = ServiceConfiguration.BitcoinCoreEndPoint;
- var localNode = await Node.ConnectAsync(Network, localEndPoint, nodeConnectionParameters);
- try
- {
- Logger.LogInfo("TCP Connection succeeded, handshaking...");
- localNode.VersionHandshake(Constants.LocalNodeRequirements, handshakeTimeout.Token);
- var peerServices = localNode.PeerVersion.Services;
-
- //if (!peerServices.HasFlag(NodeServices.Network) && !peerServices.HasFlag(NodeServices.NODE_NETWORK_LIMITED))
- //{
- // throw new InvalidOperationException("Wasabi cannot use the local node because it does not provide blocks.");
- //}
-
- Logger.LogInfo("Handshake completed successfully.");
-
- if (!localNode.IsConnected)
- {
- throw new InvalidOperationException($"Wasabi could not complete the handshake with the local node and dropped the connection.{Environment.NewLine}" +
- "Probably this is because the node does not support retrieving full blocks or segwit serialization.");
- }
- LocalBitcoinCoreNode = localNode;
- }
- catch (OperationCanceledException) when (handshakeTimeout.IsCancellationRequested)
- {
- Logger.LogWarning($"Wasabi could not complete the handshake with the local node. Probably Wasabi is not whitelisted by the node.{Environment.NewLine}" +
- "Use \"whitebind\" in the node configuration. (Typically whitebind=127.0.0.1:8333 if Wasabi and the node are on the same machine and whitelist=1.2.3.4 if they are not.)");
- throw;
- }
- }
-
- // Get Block from local node
- Block blockFromLocalNode = null;
- // Should timeout faster. Not sure if it should ever fail though. Maybe let's keep like this later for remote node connection.
- using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(64)))
- {
- blockFromLocalNode = await LocalBitcoinCoreNode.DownloadBlockAsync(hash, cts.Token);
- }
-
- // Validate retrieved block
- if (!blockFromLocalNode.Check())
- {
- throw new InvalidOperationException("Disconnected node, because invalid block received!");
- }
-
- // Retrieved block from local node and block is valid
- Logger.LogInfo($"Block acquired from local P2P connection: {hash}.");
- return blockFromLocalNode;
- }
- catch (Exception ex)
- {
- DisconnectDisposeNullLocalBitcoinCoreNode();
-
- if (ex is SocketException)
- {
- Logger.LogTrace("Did not find local listening and running full node instance. Trying to fetch needed block from other source.");
- }
- else if (ex is OperationCanceledException)
- {
- Logger.LogTrace(ex);
- }
- else
- {
- Logger.LogWarning(ex);
- }
- }
- }
- else
- {
- try
- {
- var block = await CoreNode.RpcClient.GetBlockAsync(hash).ConfigureAwait(false);
- Logger.LogInfo($"Block acquired from RPC connection: {hash}.");
- return block;
- }
- catch (Exception ex)
- {
- Logger.LogWarning(ex);
- }
- }
-
- return null;
- }
-
- private void DisconnectDisposeNullLocalBitcoinCoreNode()
- {
- if (LocalBitcoinCoreNode != null)
- {
- try
- {
- LocalBitcoinCoreNode?.Disconnect();
- }
- catch (Exception ex)
- {
- Logger.LogDebug(ex);
- }
- finally
- {
- try
- {
- LocalBitcoinCoreNode?.Dispose();
- }
- catch (Exception ex)
- {
- Logger.LogDebug(ex);
- }
- finally
- {
- LocalBitcoinCoreNode = null;
- Logger.LogInfo("Local Bitcoin Core node disconnected.");
- }
- }
- }
- }
-
private LockTime SelectLockTimeForTransaction()
{
var currentTipHeight = Synchronizer.BitcoinStore.SmartHeaderChain.TipHeight;
@@ -884,55 +525,6 @@ namespace WalletWasabi.Wallets
return InternalSelectLockTimeForTransaction(currentTipHeight, Random);
}
- /// <summary>
- /// Current timeout used when downloading a block from the remote node. It is defined in seconds.
- /// </summary>
- private async Task NodeTimeoutsAsync(bool increaseDecrease)
- {
- if (increaseDecrease)
- {
- NodeTimeouts++;
- }
- else
- {
- NodeTimeouts--;
- }
-
- var timeout = RuntimeParams.Instance.NetworkNodeTimeout;
-
- // If it times out 2 times in a row then increase the timeout.
- if (NodeTimeouts >= 2)
- {
- NodeTimeouts = 0;
- timeout *= 2;
- }
- else if (NodeTimeouts <= -3) // If it does not time out 3 times in a row, lower the timeout.
- {
- NodeTimeouts = 0;
- timeout = (int)Math.Round(timeout * 0.7);
- }
-
- // Sanity check
- if (timeout < 32)
- {
- timeout = 32;
- }
- else if (timeout > 600)
- {
- timeout = 600;
- }
-
- if (timeout == RuntimeParams.Instance.NetworkNodeTimeout)
- {
- return;
- }
-
- RuntimeParams.Instance.NetworkNodeTimeout = timeout;
- await RuntimeParams.Instance.SaveAsync();
-
- Logger.LogInfo($"Current timeout value used on block download is: {timeout} seconds.");
- }
-
public void SetWaitingForInitState()
{
if (State != WalletState.Uninitialized)
@@ -942,10 +534,10 @@ namespace WalletWasabi.Wallets
State = WalletState.WaitingForInit;
}
- public static Wallet CreateAndRegisterServices(Network network, BitcoinStore bitcoinStore, KeyManager keyManager, WasabiSynchronizer synchronizer, NodesGroup nodes, string dataDir, ServiceConfiguration serviceConfiguration, IFeeProvider feeProvider, CoreNode bitcoinCoreNode = null)
+ public static Wallet CreateAndRegisterServices(Network network, BitcoinStore bitcoinStore, KeyManager keyManager, WasabiSynchronizer synchronizer, NodesGroup nodes, string dataDir, ServiceConfiguration serviceConfiguration, IFeeProvider feeProvider, IBlockProvider blockProvider)
{
var wallet = new Wallet(dataDir, network, keyManager);
- wallet.RegisterServices(bitcoinStore, synchronizer, nodes, serviceConfiguration, feeProvider, bitcoinCoreNode);
+ wallet.RegisterServices(bitcoinStore, synchronizer, nodes, serviceConfiguration, feeProvider, blockProvider);
return wallet;
}
}

MODIFY
WalletWasabi/Wallets/WalletManager.cs
WalletWasabi/Wallets/WalletManager.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.BitcoinCore;
@@ -73,9 +72,9 @@ namespace WalletWasabi.Wallets
private bool IsInitialized { get; set; }
private IFeeProvider FeeProvider { get; set; }
- private CoreNode BitcoinCoreNode { get; set; }
public Network Network { get; }
public WalletDirectories WalletDirectories { get; }
+ private IBlockProvider BlockProvider { get; set; }
private void RefreshWalletList()
{
@@ -189,7 +188,7 @@ namespace WalletWasabi.Wallets
if (wallet.State == WalletState.WaitingForInit)
{
- wallet.RegisterServices(BitcoinStore, Synchronizer, Nodes, ServiceConfiguration, FeeProvider, BitcoinCoreNode);
+ wallet.RegisterServices(BitcoinStore, Synchronizer, Nodes, ServiceConfiguration, FeeProvider, BlockProvider);
}
using (await StartStopWalletLock.LockAsync(CancelAllInitialization.Token).ConfigureAwait(false))
@@ -436,18 +435,18 @@ namespace WalletWasabi.Wallets
}
}
- public void RegisterServices(BitcoinStore bitcoinStore, WasabiSynchronizer synchronizer, NodesGroup nodes, ServiceConfiguration serviceConfiguration, IFeeProvider feeProvider, CoreNode bitcoinCoreNode)
+ public void RegisterServices(BitcoinStore bitcoinStore, WasabiSynchronizer synchronizer, NodesGroup nodes, ServiceConfiguration serviceConfiguration, IFeeProvider feeProvider, IBlockProvider blockProvider)
{
BitcoinStore = bitcoinStore;
Synchronizer = synchronizer;
Nodes = nodes;
ServiceConfiguration = serviceConfiguration;
FeeProvider = feeProvider;
- BitcoinCoreNode = bitcoinCoreNode;
+ BlockProvider = blockProvider;
foreach (var wallet in GetWallets().Where(w => w.State == WalletState.WaitingForInit))
{
- wallet.RegisterServices(BitcoinStore, Synchronizer, Nodes, ServiceConfiguration, FeeProvider, BitcoinCoreNode);
+ wallet.RegisterServices(BitcoinStore, Synchronizer, Nodes, ServiceConfiguration, FeeProvider, BlockProvider);
}
IsInitialized = true;

Remove code from Wallet.cs file