Implement CancellationToken in StepTransactionSigningTests,
StepOutputRegistrationTests and
BobClientTests
MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepOutputRegistrationTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepOutputRegistrationTests.cs
@@ -18,9 +18,14 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend.PhaseStepping;
public class StepOutputRegistrationTests
{
+ private TimeSpan Timeout { get; } = TimeSpan.FromMinutes(1);
+
[Fact]
public async Task AllBobsRegisteredAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -41,32 +46,35 @@ public class StepOutputRegistrationTests
destKey1.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials1.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials1.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
using var destKey2 = new Key();
await bobClient.RegisterOutputAsync(
destKey2.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials2.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials2.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
foreach (var alice in alices)
{
- await alice.ReadyToSignAsync(CancellationToken.None);
+ await alice.ReadyToSignAsync(token);
}
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var tx = round.Assert<SigningState>().CreateTransaction();
Assert.Equal(2, tx.Inputs.Count);
Assert.Equal(2 + 1, tx.Outputs.Count); // +1 for the coordinator fee
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task SomeBobsRegisteredTimeoutAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -89,21 +97,24 @@ public class StepOutputRegistrationTests
destKey.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials1.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials1.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var tx = round.Assert<SigningState>().CreateTransaction();
Assert.Equal(2, tx.Inputs.Count);
Assert.Equal(2, tx.Outputs.Count);
Assert.Contains(round.CoordinatorScript, tx.Outputs.Select(x => x.ScriptPubKey));
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task DiffTooSmallToBlameAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -127,13 +138,13 @@ public class StepOutputRegistrationTests
destKey1.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials1.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials1.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
await bobClient.RegisterOutputAsync(
destKey2.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials2.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials2.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
// Add another input. The input must be able to pay for itself, but
// the remaining amount after deducting the fees needs to be less
@@ -143,19 +154,22 @@ public class StepOutputRegistrationTests
round.Alices.Add(extraAlice);
round.CoinjoinState = round.Assert<ConstructionState>().AddInput(extraAlice.Coin, extraAlice.OwnershipProof, WabiSabiFactory.CreateCommitmentData(round.Id));
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var tx = round.Assert<SigningState>().CreateTransaction();
Assert.Equal(3, tx.Inputs.Count);
Assert.Equal(2, tx.Outputs.Count);
Assert.DoesNotContain(round.CoordinatorScript, tx.Outputs.Select(x => x.ScriptPubKey));
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task DoesntSwitchImmaturelyAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -176,42 +190,45 @@ public class StepOutputRegistrationTests
destKey.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
amountCredentials1.Take(ProtocolConstants.CredentialNumber),
vsizeCredentials1.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.OutputRegistration, round.Phase);
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
private async Task<(Round Round, ArenaClient ArenaClient, AliceClient[] alices)>
CreateRoundWithTwoConfirmedConnectionsAsync(Arena arena, IKeyChain keyChain, SmartCoin coin1, SmartCoin coin2)
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
// Get the round.
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
var arenaClient = WabiSabiFactory.CreateArenaClient(arena);
var round = Assert.Single(arena.Rounds);
// Refresh the Arena States because of vsize manipulation.
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
using RoundStateUpdater roundStateUpdater = new(TimeSpan.FromSeconds(2), arena);
- await roundStateUpdater.StartAsync(CancellationToken.None);
- var task1 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin1, keyChain, roundStateUpdater, CancellationToken.None, CancellationToken.None, CancellationToken.None);
- var task2 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin2, keyChain, roundStateUpdater, CancellationToken.None, CancellationToken.None, CancellationToken.None);
+ await roundStateUpdater.StartAsync(token);
+ var task1 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin1, keyChain, roundStateUpdater, token, token, token);
+ var task2 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin2, keyChain, roundStateUpdater, token, token, token);
while (Phase.ConnectionConfirmation != round.Phase)
{
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
}
await Task.WhenAll(task1, task2);
var aliceClient1 = await task1;
var aliceClient2 = await task2;
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.OutputRegistration, round.Phase);
- await roundStateUpdater.StopAsync(CancellationToken.None);
+ await roundStateUpdater.StopAsync(token);
return (round,
arenaClient,

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs
@@ -21,9 +21,14 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend.PhaseStepping;
public class StepTransactionSigningTests
{
+ private TimeSpan Timeout { get; } = TimeSpan.FromMinutes(1);
+
[Fact]
public async Task EveryoneSignedAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -36,26 +41,29 @@ public class StepTransactionSigningTests
using Arena arena = await ArenaBuilder.From(cfg).With(mockRpc).CreateAndStartAsync();
var (round, aliceClient1, aliceClient2) = await CreateRoundWithOutputsReadyToSignAsync(arena, keyChain, coin1, coin2);
- await aliceClient1.ReadyToSignAsync(CancellationToken.None);
- await aliceClient2.ReadyToSignAsync(CancellationToken.None);
+ await aliceClient1.ReadyToSignAsync(token);
+ await aliceClient2.ReadyToSignAsync(token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var signedCoinJoin = round.Assert<SigningState>().CreateTransaction();
- await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.DoesNotContain(round, arena.GetActiveRounds());
Assert.Equal(Phase.Ended, round.Phase);
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task FailsBroadcastAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -72,28 +80,31 @@ public class StepTransactionSigningTests
using Arena arena = await ArenaBuilder.From(cfg, mockRpc, prison).CreateAndStartAsync();
var (round, aliceClient1, aliceClient2) = await CreateRoundWithOutputsReadyToSignAsync(arena, keyChain, coin1, coin2);
- await aliceClient1.ReadyToSignAsync(CancellationToken.None);
- await aliceClient2.ReadyToSignAsync(CancellationToken.None);
+ await aliceClient1.ReadyToSignAsync(token);
+ await aliceClient2.ReadyToSignAsync(token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var signedCoinJoin = round.Assert<SigningState>().CreateTransaction();
- await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.DoesNotContain(round, arena.Rounds.Where(x => x.Phase != Phase.Ended));
Assert.Equal(Phase.Ended, round.Phase);
Assert.Equal(EndRoundState.TransactionBroadcastFailed, round.EndRoundState);
Assert.Empty(prison.GetInmates());
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task AlicesSpentAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -112,17 +123,17 @@ public class StepTransactionSigningTests
var (round, aliceClient1, aliceClient2) = await CreateRoundWithOutputsReadyToSignAsync(arena, keyChain, coin1, coin2);
- await aliceClient1.ReadyToSignAsync(CancellationToken.None);
- await aliceClient2.ReadyToSignAsync(CancellationToken.None);
+ await aliceClient1.ReadyToSignAsync(token);
+ await aliceClient2.ReadyToSignAsync(token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var signedCoinJoin = round.Assert<SigningState>().CreateTransaction();
- await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.DoesNotContain(round, arena.Rounds.Where(x => x.Phase != Phase.Ended));
Assert.Equal(Phase.Ended, round.Phase);
Assert.Equal(EndRoundState.TransactionBroadcastFailed, round.EndRoundState);
@@ -132,12 +143,15 @@ public class StepTransactionSigningTests
// the cost of spending the UTXO is the punishment instead.
Assert.Empty(prison.GetInmates());
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task TimeoutInsufficientPeersAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -155,27 +169,30 @@ public class StepTransactionSigningTests
using Arena arena = await ArenaBuilder.From(cfg, mockRpc, prison).CreateAndStartAsync();
var (round, aliceClient1, aliceClient2) = await CreateRoundWithOutputsReadyToSignAsync(arena, keyChain, coin1, coin2);
- await aliceClient1.ReadyToSignAsync(CancellationToken.None);
- await aliceClient2.ReadyToSignAsync(CancellationToken.None);
+ await aliceClient1.ReadyToSignAsync(token);
+ await aliceClient2.ReadyToSignAsync(token);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var signedCoinJoin = round.Assert<SigningState>().CreateTransaction();
- await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.DoesNotContain(round, arena.Rounds.Where(x => x.Phase != Phase.Ended));
Assert.Equal(Phase.Ended, round.Phase);
Assert.Equal(EndRoundState.AbortedNotEnoughAlicesSigned, round.EndRoundState);
Assert.Empty(arena.Rounds.Where(x => x is BlameRound));
Assert.Contains(aliceClient2.SmartCoin.OutPoint, prison.GetInmates().Select(x => x.Utxo));
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
[Fact]
public async Task TimeoutSufficientPeersAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
WabiSabiConfig cfg = new()
{
MaxInputCountByRound = 2,
@@ -201,13 +218,13 @@ public class StepTransactionSigningTests
alice3.ConfirmedConnection = true;
round.Alices.Add(alice3);
round.CoinjoinState = round.Assert<ConstructionState>().AddInput(alice3.Coin, alice3.OwnershipProof, WabiSabiFactory.CreateCommitmentData(round.Id));
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.TransactionSigning, round.Phase);
var signedCoinJoin = round.Assert<SigningState>().CreateTransaction();
- await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, CancellationToken.None);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await aliceClient1.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await aliceClient2.SignTransactionAsync(signedCoinJoin, keyChain, token);
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.DoesNotContain(round, arena.Rounds.Where(x => x.Phase != Phase.Ended));
Assert.Single(arena.Rounds.Where(x => x is BlameRound));
var badOutpoint = alice3.Coin.Outpoint;
@@ -223,28 +240,31 @@ public class StepTransactionSigningTests
Assert.Contains(aliceClient2.SmartCoin.OutPoint, whitelist);
Assert.DoesNotContain(badOutpoint, whitelist);
- await arena.StopAsync(CancellationToken.None);
+ await arena.StopAsync(token);
}
private async Task<(Round Round, AliceClient AliceClient1, AliceClient AliceClient2)>
CreateRoundWithOutputsReadyToSignAsync(Arena arena, IKeyChain keyChain, SmartCoin coin1, SmartCoin coin2)
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
// Create the round.
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
var round = Assert.Single(arena.Rounds);
var arenaClient = WabiSabiFactory.CreateArenaClient(arena);
// Register Alices.
using RoundStateUpdater roundStateUpdater = new(TimeSpan.FromSeconds(2), arena);
- await roundStateUpdater.StartAsync(CancellationToken.None);
+ await roundStateUpdater.StartAsync(token);
- var task1 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin1, keyChain, roundStateUpdater, CancellationToken.None, CancellationToken.None, CancellationToken.None);
- var task2 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin2, keyChain, roundStateUpdater, CancellationToken.None, CancellationToken.None, CancellationToken.None);
+ var task1 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin1, keyChain, roundStateUpdater, token, token, token);
+ var task2 = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), arenaClient, coin2, keyChain, roundStateUpdater, token, token, token);
while (Phase.OutputRegistration != round.Phase)
{
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(21));
+ await arena.TriggerAndWaitRoundAsync(token);
}
await Task.WhenAll(task1, task2);
@@ -260,15 +280,15 @@ public class StepTransactionSigningTests
destKey1.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
aliceClient1.IssuedAmountCredentials.Take(ProtocolConstants.CredentialNumber),
aliceClient1.IssuedVsizeCredentials.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None).ConfigureAwait(false);
+ token).ConfigureAwait(false);
await bobClient.RegisterOutputAsync(
destKey2.PubKey.GetScriptPubKey(ScriptPubKeyType.Segwit),
aliceClient2.IssuedAmountCredentials.Take(ProtocolConstants.CredentialNumber),
aliceClient2.IssuedVsizeCredentials.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None).ConfigureAwait(false);
+ token).ConfigureAwait(false);
- await roundStateUpdater.StopAsync(CancellationToken.None);
+ await roundStateUpdater.StopAsync(token);
return (round, aliceClient1, aliceClient2);
}
}

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/BobClientTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/BobClientTests.cs
@@ -22,9 +22,14 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client;
public class BobClientTests
{
+ private TimeSpan Timeout { get; } = TimeSpan.FromMinutes(1);
+
[Fact]
public async Task RegisterOutputTestAsync()
{
+ using CancellationTokenSource cancellationTokenSource = new(Timeout);
+ var token = cancellationTokenSource.Token;
+
var config = new WabiSabiConfig { MaxInputCountByRound = 1 };
var round = WabiSabiFactory.CreateRound(config);
var km = ServiceFactory.CreateKeyManager("");
@@ -33,7 +38,7 @@ public class BobClientTests
var mockRpc = WabiSabiFactory.CreatePreconfiguredRpcClient(coin1.Coin);
using Arena arena = await ArenaBuilder.From(config).With(mockRpc).CreateAndStartAsync(round);
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));
+ await arena.TriggerAndWaitRoundAsync(token);
using var memoryCache = new MemoryCache(new MemoryCacheOptions());
var idempotencyRequestCache = new IdempotencyRequestCache(memoryCache);
@@ -56,20 +61,20 @@ public class BobClientTests
Assert.Equal(Phase.InputRegistration, round.Phase);
using RoundStateUpdater roundStateUpdater = new(TimeSpan.FromSeconds(2), wabiSabiApi);
- await roundStateUpdater.StartAsync(CancellationToken.None);
+ await roundStateUpdater.StartAsync(token);
var keyChain = new KeyChain(km, new Kitchen(""));
- var task = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), aliceArenaClient, coin1, keyChain, roundStateUpdater, CancellationToken.None, CancellationToken.None, CancellationToken.None);
+ var task = AliceClient.CreateRegisterAndConfirmInputAsync(RoundState.FromRound(round), aliceArenaClient, coin1, keyChain, roundStateUpdater, token, token, token);
do
{
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));
+ await arena.TriggerAndWaitRoundAsync(token);
}
while (round.Phase != Phase.ConnectionConfirmation);
var aliceClient = await task;
- await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));
+ await arena.TriggerAndWaitRoundAsync(token);
Assert.Equal(Phase.OutputRegistration, round.Phase);
using var destinationKey = new Key();
@@ -81,7 +86,7 @@ public class BobClientTests
destination,
aliceClient.IssuedAmountCredentials.Take(ProtocolConstants.CredentialNumber),
aliceClient.IssuedVsizeCredentials.Take(ProtocolConstants.CredentialNumber),
- CancellationToken.None);
+ token);
var bob = Assert.Single(round.Bobs);
Assert.Equal(destination, bob.Script);

MODIFY
WalletWasabi/Bases/PeriodicRunner.cs
WalletWasabi/Bases/PeriodicRunner.cs
@@ -47,13 +47,19 @@ public abstract class PeriodicRunner : BackgroundService
/// <summary>
/// Triggers and waits for the action to execute.
/// </summary>
- public async Task TriggerAndWaitRoundAsync(TimeSpan timeout)
+ public async Task TriggerAndWaitRoundAsync(CancellationToken token)
{
EventAwaiter<TimeSpan> eventAwaiter = new(
h => Tick += h,
h => Tick -= h);
TriggerRound();
- await eventAwaiter.WaitAsync(timeout).ConfigureAwait(false);
+ await eventAwaiter.WaitAsync(token).ConfigureAwait(false);
+ }
+
+ public Task TriggerAndWaitRoundAsync(TimeSpan timeout)
+ {
+ using CancellationTokenSource cancellationTokenSource = new(timeout);
+ return TriggerAndWaitRoundAsync(cancellationTokenSource.Token);
}
/// <summary>

MODIFY
WalletWasabi/Helpers/EventAwaiter.cs
WalletWasabi/Helpers/EventAwaiter.cs
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
namespace System;
@@ -16,4 +17,7 @@ public class EventAwaiter<TEventArgs> : EventsAwaiter<TEventArgs>
public new async Task<TEventArgs> WaitAsync(TimeSpan timeout)
=> await Task.WithAwaitCancellationAsync(timeout).ConfigureAwait(false);
+
+ public new async Task<TEventArgs> WaitAsync(CancellationToken token)
+ => await Task.WithAwaitCancellationAsync(token).ConfigureAwait(false);
}

MODIFY
WalletWasabi/Helpers/EventsAwaiter.cs
WalletWasabi/Helpers/EventsAwaiter.cs
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Helpers;
@@ -47,4 +48,7 @@ public class EventsAwaiter<TEventArgs>
public async Task<IEnumerable<TEventArgs>> WaitAsync(TimeSpan timeout)
=> await Task.WhenAll(Tasks).WithAwaitCancellationAsync(timeout).ConfigureAwait(false);
+
+ public async Task<IEnumerable<TEventArgs>> WaitAsync(CancellationToken token)
+ => await Task.WhenAll(Tasks).WithAwaitCancellationAsync(token).ConfigureAwait(false);
}

Implement CancellationToken in StepTransactionSigningTests,
StepOutputRegistrationTests and
BobClientTests