Decide whose responsibility is the TransactionCache (spoiler: WalletService for now)
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/HistoryTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/HistoryTabViewModel.cs
@@ -145,7 +145,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
{
var found = txRecordList.FirstOrDefault(x => x.transactionId == coin.TransactionId);
- SmartTransaction foundTransaction = walletService.TransactionProcessor.TransactionCache?.FirstOrDefault(x => x.GetHash() == coin.TransactionId);
+ var foundTransaction = walletService.TryGetTxFromCache(coin.TransactionId);
if (foundTransaction is null)
{
continue;
@@ -182,7 +182,11 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
if (coin.SpenderTransactionId != null)
{
- SmartTransaction foundSpenderTransaction = walletService.TransactionProcessor.TransactionCache.First(x => x.GetHash() == coin.SpenderTransactionId);
+ var foundSpenderTransaction = walletService.TryGetTxFromCache(coin.SpenderTransactionId);
+ if (foundSpenderTransaction is null)
+ {
+ throw new InvalidOperationException($"Transaction {coin.SpenderTransactionId} not found.");
+ }
if (foundSpenderTransaction.Height.Type == HeightType.Chain)
{

MODIFY
WalletWasabi/Services/TransactionProcessor.cs
WalletWasabi/Services/TransactionProcessor.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NBitcoin;
+using WalletWasabi.Helpers;
using WalletWasabi.KeyManagement;
using WalletWasabi.Models;
@@ -9,9 +10,11 @@ namespace WalletWasabi.Services
{
public class TransactionProcessor
{
+ private ConcurrentHashSet<SmartTransaction> TransactionCache { get; }
+
public KeyManager KeyManager { get; }
public ConcurrentHashSet<uint256> TransactionHashes { get; }
- public ConcurrentHashSet<SmartTransaction> TransactionCache { get; }
+
public ObservableConcurrentHashSet<SmartCoin> Coins { get; }
public Money DustThreshold { get; }
@@ -24,14 +27,14 @@ namespace WalletWasabi.Services
public TransactionProcessor(KeyManager keyManager,
ConcurrentHashSet<uint256> transactionHashes,
ObservableConcurrentHashSet<SmartCoin> coins,
- Money dustThreshold
- )
- {
- KeyManager = keyManager;
- TransactionHashes = transactionHashes;
- TransactionCache = new ConcurrentHashSet<SmartTransaction>();
- Coins = coins;
- DustThreshold = dustThreshold;
+ Money dustThreshold,
+ ConcurrentHashSet<SmartTransaction> transactionCache)
+ {
+ KeyManager = Guard.NotNull(nameof(keyManager), keyManager);
+ TransactionHashes = Guard.NotNull(nameof(transactionHashes), transactionHashes);
+ Coins = Guard.NotNull(nameof(coins), coins);
+ DustThreshold = Guard.NotNull(nameof(dustThreshold), dustThreshold);
+ TransactionCache = Guard.NotNull(nameof(transactionCache), transactionCache);
}
public bool Process(SmartTransaction tx)

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -82,6 +82,8 @@ namespace WalletWasabi.Services
public TransactionProcessor TransactionProcessor { get; }
+ private ConcurrentHashSet<SmartTransaction> TransactionCache { get; }
+
public WalletService(
BitcoinStore bitcoinStore,
KeyManager keyManager,
@@ -114,7 +116,9 @@ namespace WalletWasabi.Services
KeyManager.AssertCleanKeysIndexed();
KeyManager.AssertLockedInternalKeysIndexed(14);
- TransactionProcessor = new TransactionProcessor(KeyManager, Mempool.TransactionHashes, Coins, ServiceConfiguration.DustThreshold);
+ TransactionCache = new ConcurrentHashSet<SmartTransaction>();
+
+ TransactionProcessor = new TransactionProcessor(KeyManager, Mempool.TransactionHashes, Coins, ServiceConfiguration.DustThreshold, TransactionCache);
TransactionProcessor.CoinSpent += TransactionProcessor_CoinSpent;
TransactionProcessor.CoinReceived += OnNewCoinFoundAsync;
@@ -193,10 +197,10 @@ namespace WalletWasabi.Services
}
Mempool.TransactionHashes.TryRemove(toRemove.TransactionId);
- var txToRemove = TransactionProcessor.TransactionCache.FirstOrDefault(x => x.GetHash() == toRemove.TransactionId);
+ var txToRemove = TransactionCache.FirstOrDefault(x => x.GetHash() == toRemove.TransactionId);
if (txToRemove != default(SmartTransaction))
{
- TransactionProcessor.TransactionCache.TryRemove(txToRemove);
+ TransactionCache.TryRemove(txToRemove);
}
}
@@ -1468,7 +1472,7 @@ namespace WalletWasabi.Services
}
IoHelpers.EnsureContainingDirectoryExists(TransactionsFilePath);
- string jsonString = JsonConvert.SerializeObject(TransactionProcessor.TransactionCache.OrderByBlockchain(), Formatting.Indented);
+ string jsonString = JsonConvert.SerializeObject(TransactionCache.OrderByBlockchain(), Formatting.Indented);
File.WriteAllText(TransactionsFilePath,
jsonString,
Encoding.UTF8);
@@ -1537,5 +1541,10 @@ namespace WalletWasabi.Services
DisconnectDisposeNullLocalBitcoinCoreNode();
}
+
+ public SmartTransaction TryGetTxFromCache(uint256 txId)
+ {
+ return TransactionCache.FirstOrDefault(x => x.GetHash() == txId);
+ }
}
}

Decide whose responsibility is the TransactionCache (spoiler: WalletService for now)