Replace `new Random()` with `Random.Shared`
MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/Create/ConfirmRecoveryWordsViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/Create/ConfirmRecoveryWordsViewModel.cs
@@ -52,7 +52,7 @@ public partial class ConfirmRecoveryWordsViewModel : RoutableViewModel
.Subscribe();
// Select random words to confirm.
- _confirmationWordsSourceList.AddRange(mnemonicWords.OrderBy(_ => new Random().NextDouble()).Take(3));
+ _confirmationWordsSourceList.AddRange(mnemonicWords.OrderBy(_ => Random.Shared.NextDouble()).Take(3));
}
public ReadOnlyObservableCollection<RecoveryWordViewModel> ConfirmationWords => _confirmationWords;

MODIFY
WalletWasabi.Tests/Helpers/CryptoHelpers.cs
WalletWasabi.Tests/Helpers/CryptoHelpers.cs
@@ -37,5 +37,5 @@ public static class CryptoHelpers
}
public static int RandomInt(int minInclusive, int maxInclusive)
- => new Random().Next(minInclusive, maxInclusive + 1);
+ => Random.Shared.Next(minInclusive, maxInclusive + 1);
}

MODIFY
WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs
WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs
@@ -6,8 +6,6 @@ namespace WalletWasabi.Tests.Helpers;
public class MempoolInfoGenerator
{
- private static readonly Random Random = new();
-
private static readonly int[] FeeLimits = new[]
{
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 17, 20, 25, 30, 40, 50, 60, 70, 80,
@@ -18,7 +16,7 @@ public class MempoolInfoGenerator
public static (int from, int to)[] FeeRanges { get; } = FeeLimits.Zip(FeeLimits.Skip(1), (from, to) => (from, to)).ToArray();
public static FeeRate GenerateFeeRateForTarget(int target)
- => new((decimal)(4_000 / (target * target) * Random.Gaussian(1.0, 0.2)));
+ => new((decimal)(4_000 / (target * target) * Random.Shared.Gaussian(1.0, 0.2)));
public static MemPoolInfo GenerateMempoolInfo()
{
@@ -43,8 +41,8 @@ public class MempoolInfoGenerator
private static FeeRateGroup GenerateFeeRateGroup(int from, int to)
{
- var count = Math.Max(1, Random.Gaussian(10_000 - 5 * to, 1_000));
- var sizes = count * Math.Max(250, Random.Gaussian(500, 100));
+ var count = Math.Max(1, Random.Shared.Gaussian(10_000 - 5 * to, 1_000));
+ var sizes = count * Math.Max(250, Random.Shared.Gaussian(500, 100));
return new FeeRateGroup
{
Count = (uint)count,

MODIFY
WalletWasabi.Tests/UnitTests/IoTests.cs
WalletWasabi.Tests/UnitTests/IoTests.cs
@@ -153,11 +153,10 @@ public class IoTests
static string RandomString()
{
StringBuilder builder = new();
- var rnd = new Random();
char ch;
- for (int i = 0; i < rnd.Next(10, 100); i++)
+ for (int i = 0; i < Random.Shared.Next(10, 100); i++)
{
- ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * rnd.NextDouble() + 65)));
+ ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * Random.Shared.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();

MODIFY
WalletWasabi.Tests/UnitTests/KeyManagementTests.cs
WalletWasabi.Tests/UnitTests/KeyManagementTests.cs
@@ -117,13 +117,11 @@ public class KeyManagementTests
manager.ToFile(); // assert it does not throw
- var random = new Random();
-
for (int i = 0; i < 1000; i++)
{
- var isInternal = random.Next(2) == 0;
+ var isInternal = Random.Shared.Next(2) == 0;
var label = RandomString.AlphaNumeric(21);
- var keyState = (KeyState)random.Next(3);
+ var keyState = (KeyState)Random.Shared.Next(3);
manager.GenerateNewKey(label, keyState, isInternal, toFile: false);
}
manager.ToFile();
@@ -146,8 +144,6 @@ public class KeyManagementTests
var network = Network.Main;
var manager = KeyManager.CreateNew(out _, password, network);
- var random = new Random();
-
var k1 = manager.GenerateNewKey(SmartLabel.Empty, KeyState.Clean, true);
var k2 = manager.GenerateNewKey(label: null!, KeyState.Clean, true);
Assert.Equal(SmartLabel.Empty, k1.Label);
@@ -155,9 +151,9 @@ public class KeyManagementTests
for (int i = 0; i < 1000; i++)
{
- var isInternal = random.Next(2) == 0;
+ var isInternal = Random.Shared.Next(2) == 0;
var label = RandomString.AlphaNumeric(21);
- var keyState = (KeyState)random.Next(3);
+ var keyState = (KeyState)Random.Shared.Next(3);
var generatedKey = manager.GenerateNewKey(label, keyState, isInternal);
Assert.Equal(isInternal, generatedKey.IsInternal);

MODIFY
WalletWasabi.Tests/UnitTests/Tor/Socks5/Pool/TorHttpPoolTests.cs
WalletWasabi.Tests/UnitTests/Tor/Socks5/Pool/TorHttpPoolTests.cs
@@ -216,7 +216,7 @@ public class TorHttpPoolTests
public TransportStream(string testName)
{
// Construct unique pipe name.
- int n = new Random().Next(0, 1_000_000);
+ int n = Random.Shared.Next(0, 1_000_000);
string pipeName = $"{testName}.Pipe.{n}";
Server = new(pipeName, PipeDirection.InOut, maxNumberOfServerInstances: 4, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs
@@ -41,8 +41,6 @@ public class CredentialDependencyTests
// And all sent requests, for testing purposes.
var sent = new HashSet<RequestNode>();
- var rng = new Random();
-
// Simulate sending a request. Instead of actual Credential objects,
// credentials are just represented as longs.
async Task<ImmutableSortedDictionary<CredentialType, IEnumerable<long>>> SimulateRequest(
@@ -59,7 +57,7 @@ public class CredentialDependencyTests
Assert.DoesNotContain(node, sent);
sent.Add(node);
- await Task.Delay(1 + rng.Next(10));
+ await Task.Delay(1 + Random.Shared.Next(10));
return requested;
}

MODIFY
WalletWasabi.Tests/UnitTests/Wallet/LockTimeSelectorTests.cs
WalletWasabi.Tests/UnitTests/Wallet/LockTimeSelectorTests.cs
@@ -9,7 +9,7 @@ public class LockTimeSelectorTests
[Fact]
public void GetLockTimeBasedOnDistributionTest()
{
- var lockTimeSelector = new LockTimeSelector(new Random());
+ var lockTimeSelector = new LockTimeSelector(Random.Shared);
uint tipHeight = 600_000;
LockTime lockTime = lockTimeSelector.GetLockTimeBasedOnDistribution(tipHeight);

MODIFY
WalletWasabi/Blockchain/TransactionBuilding/BranchAndBound.cs
WalletWasabi/Blockchain/TransactionBuilding/BranchAndBound.cs
@@ -8,8 +8,6 @@ namespace WalletWasabi.Blockchain.TransactionBuilding;
/// <seealso href="https://murch.one/wp-content/uploads/2016/11/erhardt2016coinselection.pdf">Section "5.3 Branch and Bound".</seealso>
public class BranchAndBound
{
- private readonly Random _random = new();
-
/// <summary>
/// Attempts to find a set of values that sum up to the target value.
/// </summary>
@@ -114,7 +112,7 @@ public class BranchAndBound
private NextAction GetRandomNextAction()
{
- return _random.Next() > (int.MaxValue / 2) ? NextAction.IncludeFirstThenOmit : NextAction.OmitFirstThenInclude;
+ return Random.Shared.Next() > (int.MaxValue / 2) ? NextAction.IncludeFirstThenOmit : NextAction.OmitFirstThenInclude;
}
private static NextAction GetNextStep(NextAction action)

MODIFY
WalletWasabi/CoinJoin/Client/Clients/CoinJoinClient.cs
WalletWasabi/CoinJoin/Client/Clients/CoinJoinClient.cs
@@ -156,12 +156,12 @@ public class CoinJoinClient
// if mixing >= connConf
if (State.GetActivelyMixingRounds().Any())
{
- int delaySeconds = new Random().Next(2, 7);
+ int delaySeconds = Random.Shared.Next(2, 7);
Synchronizer.MaxRequestIntervalForMixing = TimeSpan.FromSeconds(delaySeconds);
}
else if (Interlocked.Read(ref _frequentStatusProcessingIfNotMixing) == 1 || State.GetPassivelyMixingRounds().Any() || State.GetWaitingListCount() > 0)
{
- double rand = double.Parse($"0.{new Random().Next(2, 6)}"); // randomly between every 0.2 * connConfTimeout - 7 and 0.6 * connConfTimeout
+ double rand = double.Parse($"0.{Random.Shared.Next(2, 6)}"); // randomly between every 0.2 * connConfTimeout - 7 and 0.6 * connConfTimeout
int delaySeconds = Math.Max(0, (int)((rand * State.GetSmallestRegistrationTimeout()) - 7));
Synchronizer.MaxRequestIntervalForMixing = TimeSpan.FromSeconds(delaySeconds);
@@ -250,7 +250,7 @@ public class CoinJoinClient
}
StateUpdated?.Invoke(this, null);
- int delaySeconds = new Random().Next(0, 7); // delay the response to defend timing attack privacy.
+ int delaySeconds = Random.Shared.Next(0, 7); // delay the response to defend timing attack privacy.
if (Network == Network.RegTest)
{

MODIFY
WalletWasabi/Extensions/LinqExtensions.cs
WalletWasabi/Extensions/LinqExtensions.cs
@@ -45,7 +45,7 @@ public static class LinqExtensions
foreach (T element in source)
{
count++;
- if (new Random().Next(count) == 0)
+ if (Random.Shared.Next(count) == 0)
{
current = element;
}
@@ -55,12 +55,11 @@ public static class LinqExtensions
public static IList<T> Shuffle<T>(this IList<T> list)
{
- var rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
- int k = rng.Next(n + 1);
+ int k = Random.Shared.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;

MODIFY
WalletWasabi/WabiSabi/Client/AmountDecomposer.cs
WalletWasabi/WabiSabi/Client/AmountDecomposer.cs
@@ -187,10 +187,9 @@ public class AmountDecomposer
var remainingVsize = AvailableVsize;
var setCandidates = new Dictionary<int, (IEnumerable<Money> Decomp, Money Cost)>();
- var random = new Random();
// How many times can we participate with the same denomination.
- var maxDenomUsage = random.Next(2, 8);
+ var maxDenomUsage = Random.Shared.Next(2, 8);
// Create the most naive decomposition for starter.
List<Money> naiveSet = new();
@@ -290,7 +289,7 @@ public class AmountDecomposer
var finalCandidate = orderedCandidates.First().Decomp;
foreach (var candidate in orderedCandidates)
{
- if (random.NextDouble() < 0.5)
+ if (Random.Shared.NextDouble() < 0.5)
{
finalCandidate = candidate.Decomp;
break;

MODIFY
WalletWasabi/Wallets/LockTimeSelector.cs
WalletWasabi/Wallets/LockTimeSelector.cs
@@ -10,7 +10,7 @@ public class LockTimeSelector
{
static LockTimeSelector()
{
- Instance = new LockTimeSelector(new Random());
+ Instance = new LockTimeSelector(Random.Shared);
}
public LockTimeSelector(Random random)

Replace `new Random()` with `Random.Shared`