Document more `MempoolNotifiesAsync` test.
MODIFY
WalletWasabi.Tests/UnitTests/BitcoinCore/P2pBasedTests.cs
WalletWasabi.Tests/UnitTests/BitcoinCore/P2pBasedTests.cs
@@ -5,6 +5,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using WalletWasabi.BitcoinCore;
+using WalletWasabi.BitcoinCore.Rpc;
using WalletWasabi.Blockchain.Blocks;
using WalletWasabi.Blockchain.Mempool;
using WalletWasabi.Blockchain.Transactions;
@@ -24,54 +26,68 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
public async Task MempoolNotifiesAsync()
{
using var services = new HostedServices();
- var coreNode = await TestNodeBuilder.CreateAsync(services);
- await services.StartAllAsync(CancellationToken.None);
+ CoreNode coreNode = await TestNodeBuilder.CreateAsync(services);
+ await services.StartAllAsync();
+
using var node = await coreNode.CreateNewP2pNodeAsync();
try
{
+ string dir = Common.GetWorkDir();
var network = coreNode.Network;
var rpc = coreNode.RpcClient;
- var dir = Common.GetWorkDir();
var indexStore = new IndexStore(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain());
var transactionStore = new AllTransactionStore(Path.Combine(dir, "transactionStore"), network);
var mempoolService = new MempoolService();
var blocks = new FileSystemBlockRepository(Path.Combine(dir, "blocks"), network);
+
+ // Construct BitcoinStore.
var bitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);
await bitcoinStore.InitializeAsync();
- await rpc.GenerateAsync(101);
+ await rpc.GenerateAsync(blockCount: 101);
node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior());
node.VersionHandshake();
- var addr = new Key().PubKey.GetSegwitAddress(network);
+ BitcoinWitPubKeyAddress address = new Key().PubKey.GetSegwitAddress(network);
+
+ // Number of transactions to send.
+ const int TransactionsCount = 10;
- var txNum = 10;
var eventAwaiter = new EventsAwaiter<SmartTransaction>(
- h => bitcoinStore.MempoolService.TransactionReceived += h,
- h => bitcoinStore.MempoolService.TransactionReceived -= h,
- txNum);
+ subscribe: h => mempoolService.TransactionReceived += h,
+ unsubscribe: h => mempoolService.TransactionReceived -= h,
+ count: TransactionsCount);
- var txTasks = new List<Task<uint256>>();
- var batch = rpc.PrepareBatch();
- for (int i = 0; i < txNum; i++)
+ var txHashesList = new List<Task<uint256>>();
+ IRPCClient rpcBatch = rpc.PrepareBatch();
+
+ // Add to the batch 10 RPC commands: Send 1 coin to the same address.
+ for (int i = 0; i < TransactionsCount; i++)
{
- txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1)));
+ txHashesList.Add(rpcBatch.SendToAddressAsync(address, Money.Coins(1)));
}
- var batchTask = batch.SendBatchAsync();
- var stxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));
+ // Publish the RPC batch.
+ Task rpcBatchTask = rpcBatch.SendBatchAsync();
- await batchTask;
- var hashes = await Task.WhenAll(txTasks);
- foreach (var stx in stxs)
+ // Wait until the mempool service receives all the sent transactions.
+ IEnumerable<SmartTransaction> mempoolSmartTxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));
+
+ await rpcBatchTask;
+
+ // Collect all the transaction hashes of the sent transactions.
+ uint256[] hashes = await Task.WhenAll(txHashesList);
+
+ // Check that all the received transaction hashes are in the set of sent transaction hashes.
+ foreach (SmartTransaction tx in mempoolSmartTxs)
{
- Assert.Contains(stx.GetHash(), hashes);
+ Assert.Contains(tx.GetHash(), hashes);
}
}
finally
{
- await services.StopAllAsync(CancellationToken.None);
+ await services.StopAllAsync();
node.Disconnect();
await coreNode.TryStopAsync();
}

MODIFY
WalletWasabi/BitcoinCore/Rpc/IRPCClient.cs
WalletWasabi/BitcoinCore/Rpc/IRPCClient.cs
@@ -43,7 +43,7 @@ namespace WalletWasabi.BitcoinCore.Rpc
IRPCClient PrepareBatch();
- Task<uint256> SendToAddressAsync(BitcoinAddress address, Money amount, string commentTx = null, string commentDest = null, bool subtractFeeFromAmount = false, bool replaceable = false);
+ Task<uint256> SendToAddressAsync(BitcoinAddress address, Money amount, string? commentTx = null, string? commentDest = null, bool subtractFeeFromAmount = false, bool replaceable = false);
Task<uint256> GetBlockHashAsync(int height);

MODIFY
WalletWasabi/BitcoinCore/Rpc/RpcClientBase.cs
WalletWasabi/BitcoinCore/Rpc/RpcClientBase.cs
@@ -113,7 +113,7 @@ namespace WalletWasabi.BitcoinCore.Rpc
#region For Testing Only
- public virtual async Task<uint256> SendToAddressAsync(BitcoinAddress address, Money amount, string commentTx = null, string commentDest = null, bool subtractFeeFromAmount = false, bool replaceable = false)
+ public virtual async Task<uint256> SendToAddressAsync(BitcoinAddress address, Money amount, string? commentTx = null, string? commentDest = null, bool subtractFeeFromAmount = false, bool replaceable = false)
{
return await Rpc.SendToAddressAsync(address, amount, commentTx, commentDest, subtractFeeFromAmount, replaceable).ConfigureAwait(false);
}

MODIFY
WalletWasabi/Blockchain/Mempool/MempoolService.cs
WalletWasabi/Blockchain/Mempool/MempoolService.cs
@@ -24,7 +24,7 @@ namespace WalletWasabi.Blockchain.Mempool
TrustedNodeMode = false;
}
- public event EventHandler<SmartTransaction> TransactionReceived;
+ public event EventHandler<SmartTransaction>? TransactionReceived;
private HashSet<uint256> ProcessedTransactionHashes { get; }
private object ProcessedLock { get; }
@@ -166,7 +166,8 @@ namespace WalletWasabi.Blockchain.Mempool
public void Process(Transaction tx)
{
- SmartTransaction txAdded = null;
+ SmartTransaction? txAdded = null;
+
lock (ProcessedLock)
{
if (ProcessedTransactionHashes.Add(tx.GetHash()))
@@ -179,6 +180,7 @@ namespace WalletWasabi.Blockchain.Mempool
}
Interlocked.Increment(ref _totalReceives);
}
+
if (txAdded is { })
{
TransactionReceived?.Invoke(this, txAdded);

MODIFY
WalletWasabi/Services/HostedServices.cs
WalletWasabi/Services/HostedServices.cs
@@ -31,7 +31,7 @@ namespace WalletWasabi.Services
}
}
- public async Task StartAllAsync(CancellationToken token)
+ public async Task StartAllAsync(CancellationToken token = default)
{
if (IsStartAllAsyncStarted)
{
@@ -69,7 +69,7 @@ namespace WalletWasabi.Services
IsStartAllAsyncCompleted = true;
}
- public async Task StopAllAsync(CancellationToken token)
+ public async Task StopAllAsync(CancellationToken token = default)
{
var tasks = CloneServices().Select(x => x.Service.StopAsync(token).ContinueWith(y =>
{

Document more `MempoolNotifiesAsync` test.