From aeda9d7234b2601d480a222ebe1bffe5fdac56c7 Mon Sep 17 00:00:00 2001 From: luzius1089 Date: Fri, 20 Feb 2026 20:04:37 +0100 Subject: [PATCH] Unit Tests improvement --- .gitattributes | 1 + Contrib/update-nuget-deps.sh | 60 +++++++++++++++++++ Directory.Packages.props | 9 ++- .../Guides/HowToUpdateDepsNix.md | 30 +++++----- .../Models/Wallets/HardwareWalletInterface.cs | 9 ++- .../Helpers/MempoolInfoGenerator.cs | 9 +-- WalletWasabi.Tests/Helpers/ServiceFactory.cs | 2 + WalletWasabi.Tests/Helpers/TestNodeBuilder.cs | 2 + .../Helpers/WabiSabiTestFactory.cs | 17 ++++-- .../IntegrationTests/P2pTests.cs | 2 +- .../RegressionTests/BackendTests.cs | 2 +- .../BuildTransactionReorgsTest.cs | 6 +- .../BuildTransactionValidationsTest.cs | 2 +- .../RegressionTests/CancelTests.cs | 2 +- .../RegressionTests/MaxFeeTests.cs | 2 +- .../RegressionTests/ReplaceByFeeTxTest.cs | 2 +- .../RegressionTests/SelfSpendSpeedupTests.cs | 2 +- .../RegressionTests/SendSpeedupTests.cs | 2 +- .../RegressionTests/SendTests.cs | 2 +- .../SpendUnconfirmedTxTests.cs | 2 +- .../RegressionTests/WalletTests.cs | 14 ++--- .../UnitTests/AllFeeEstimateTests.cs | 6 +- .../UnitTests/BlockNotifierTests.cs | 5 +- .../ChangelessTransactionCoinSelectorTests.cs | 3 +- .../TransactionOutputs/CoinsRegistryTests.cs | 6 +- .../UnitTests/Clients/WasabiClientTests.cs | 9 +-- WalletWasabi.Tests/UnitTests/RpcTests.cs | 2 +- .../ExchangeRateProviderTests.cs | 8 +++ WalletWasabi.Tests/UnitTests/TestWallet.cs | 2 +- .../UnitTests/Tor/TorProcessManagerTests.cs | 2 +- .../Transactions/SmartTransactionTests.cs | 5 +- .../UnitTests/Userfacing/ParserTests.cs | 15 ++--- .../StepTransactionSigningTests.cs | 4 +- .../Client/CoinJoinCoinSelectionTests.cs | 27 +++++---- .../Client/CredentialDependencyTests.cs | 11 ++-- .../Client/PaymentAwareOutputProviderTests.cs | 5 +- .../Models/MultipartyTransactionTests.cs | 3 +- .../UnitTests/Wallet/WalletBuilder.cs | 2 + .../Wallets/SpecificNodeBlockProviderTests.cs | 2 +- WalletWasabi.Tests/WalletWasabi.Tests.csproj | 4 -- WalletWasabi/Services/ExchangeRateService.cs | 2 +- 41 files changed, 197 insertions(+), 105 deletions(-) create mode 100644 Contrib/update-nuget-deps.sh diff --git a/.gitattributes b/.gitattributes index 3c2d7d29c4..80a3e73696 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,6 +13,7 @@ *.md text eol=lf *.json text eol=lf *.nix text eol=lf +*.sh text eol=lf ############################################################################### diff --git a/Contrib/update-nuget-deps.sh b/Contrib/update-nuget-deps.sh new file mode 100644 index 0000000000..0ae3cb543b --- /dev/null +++ b/Contrib/update-nuget-deps.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +find_repo_root() { + local d="$PWD" + while [[ "$d" != "/" ]]; do + [[ -f "$d/flake.nix" ]] && { echo "$d"; return 0; } + d="$(dirname "$d")" + done + echo "ERROR: Could not find flake.nix in any parent directory." >&2 + exit 1 +} + +nix_build_flags=( + --extra-experimental-features nix-command + --extra-experimental-features flakes +) + +update_deps() { + local attr="$1" # .#packages.x86_64-linux.default + local target="$2" # deps.nix + + echo "==> Updating ${target} from ${attr}.passthru.fetch-deps" + + local helper + helper="$(nix build "${attr}.passthru.fetch-deps" \ + --no-link --print-out-paths \ + "${nix_build_flags[@]}")" + + if [[ -z "$helper" || ! -e "$helper" ]]; then + echo "ERROR: nix did not return a valid output path for fetch-deps." >&2 + exit 2 + fi + + local out gen_path + out="$("$helper" 2>&1 || true)" + gen_path="$(printf '%s\n' "$out" | sed -nE 's/^Succesfully wrote lockfile to (.*)$/\1/p' | tail -n 1)" + + if [[ -z "$gen_path" ]]; then + echo "ERROR: Could not find generated lockfile path in fetch-deps output." >&2 + echo "---- fetch-deps output (last 120 lines) ----" >&2 + printf '%s\n' "$out" | tail -n 120 >&2 + exit 3 + fi + + cp -f "$gen_path" "$target" + echo " Wrote $target (from $gen_path)" +} + +main() { + local root + root="$(find_repo_root)" + cd "$root" + + update_deps ".#packages.x86_64-linux.default" "deps.nix" + + echo "==> Done. Commit deps.nix" +} + +main "$@" diff --git a/Directory.Packages.props b/Directory.Packages.props index b2b3e09a97..d0e7d38ddf 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -57,11 +57,10 @@ - - - - + + + - \ No newline at end of file + diff --git a/WalletWasabi.Documentation/Guides/HowToUpdateDepsNix.md b/WalletWasabi.Documentation/Guides/HowToUpdateDepsNix.md index 53a87e028d..7aece19b1e 100644 --- a/WalletWasabi.Documentation/Guides/HowToUpdateDepsNix.md +++ b/WalletWasabi.Documentation/Guides/HowToUpdateDepsNix.md @@ -1,20 +1,22 @@ -## How to update Deps.nix file +## How to update `deps.nix` -### Windows (wsl) +### Windows (WSL) -1. Run Ubuntu. -2. Install nix (If you have it installed, skip this step) - ```powershell +1. Open **Ubuntu (WSL)**. +2. Install **Nix** (skip if already installed): + ```bash sh <(curl -L https://nixos.org/nix/install) --no-daemon ``` -2. Go to your `GingerWallet` folder. (The folder where you can find `flake.nix` file) -4. Run the following command to create a bash script: - ```powershell - nix build .#packages.x86_64-linux.default.passthru.fetch-deps --extra-experimental-features nix-command --extra-experimental-features flakes +3. Go to the repository folder (anywhere inside the repo is fine, the script finds `flake.nix` automatically): + ```bash + cd /mnt/c/Users//Documents/work/GingerPrivacy/GingerBackend ``` -5. Run the bash script - ```powershell - ./result +4. Run the update script: + ```bash + ./Contrib/update-nuget-deps.sh + ``` +5. Commit the updated lockfile: + ```bash + git add deps.nix + git commit -m "Update deps.nix" ``` -6. The last terminal message tells you where is the new nix file. (e.g. `Succesfully wrote lockfile to /tmp/WalletWasabi.Backend-deps-7dpBuk.nix`) -7. Find the file under `\\wsl$\\tmp\`, rename it to `deps.nix` and copy it to GingerWallet folder to override the previous one. \ No newline at end of file diff --git a/WalletWasabi.Fluent/Models/Wallets/HardwareWalletInterface.cs b/WalletWasabi.Fluent/Models/Wallets/HardwareWalletInterface.cs index a0e40ba6b0..053eead337 100644 --- a/WalletWasabi.Fluent/Models/Wallets/HardwareWalletInterface.cs +++ b/WalletWasabi.Fluent/Models/Wallets/HardwareWalletInterface.cs @@ -24,11 +24,16 @@ public async Task DetectAsync(CancellationToken cancelToken using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3)); using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancelToken); - var detectedHardwareWallets = (await client.EnumerateAsync(timeoutCts.Token).ConfigureAwait(false)).ToArray(); + var all = (await client.EnumerateAsync(timeoutCts.Token).ConfigureAwait(false)).ToArray(); cancelToken.ThrowIfCancellationRequested(); - return detectedHardwareWallets; + // Return only devices that are actually usable. + var usable = all + .Where(d => d.Code is null && d.Fingerprint is not null) + .ToArray(); + + return usable; } public async Task InitHardwareWalletAsync(HwiEnumerateEntry device, CancellationToken cancelToken) diff --git a/WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs b/WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs index e37c63dcf2..699aa6bc68 100644 --- a/WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs +++ b/WalletWasabi.Tests/Helpers/MempoolInfoGenerator.cs @@ -1,10 +1,11 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; using NBitcoin; using NBitcoin.RPC; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; namespace WalletWasabi.Tests.Helpers; @@ -89,7 +90,7 @@ static IEnumerable ExtractFeeRateGroups(JToken? jt) => return new FeeRateGroup { - Group = int.Parse(p.Name), + Group = int.Parse(p.Name, CultureInfo.InvariantCulture), Sizes = p.Value.Value("sizes"), Count = p.Value.Value("count"), Fees = Money.Satoshis(p.Value.Value("fees")), diff --git a/WalletWasabi.Tests/Helpers/ServiceFactory.cs b/WalletWasabi.Tests/Helpers/ServiceFactory.cs index 737e2b124a..8b67797a14 100644 --- a/WalletWasabi.Tests/Helpers/ServiceFactory.cs +++ b/WalletWasabi.Tests/Helpers/ServiceFactory.cs @@ -16,7 +16,9 @@ public static TransactionFactory CreateTransactionFactory(GingerRandom rnd, IEnu KeyManager keyManager = watchOnly ? CreateWatchOnlyKeyManager() : CreateKeyManager(password); SmartCoin[] sCoins = CreateCoins(rnd, keyManager, coins); var coinsView = new CoinsView(sCoins); +#pragma warning disable CA2000 // Dispose objects before losing scope var mockTransactionStore = new AllTransactionStore(".", Network.Main); +#pragma warning restore CA2000 // Dispose objects before losing scope return new TransactionFactory(Network.Main, keyManager, coinsView, mockTransactionStore, password); } diff --git a/WalletWasabi.Tests/Helpers/TestNodeBuilder.cs b/WalletWasabi.Tests/Helpers/TestNodeBuilder.cs index 19de22d153..db73b09923 100644 --- a/WalletWasabi.Tests/Helpers/TestNodeBuilder.cs +++ b/WalletWasabi.Tests/Helpers/TestNodeBuilder.cs @@ -37,6 +37,7 @@ public static async Task CreateForHeavyConcurrencyAsync([CallerFilePat private static CoreNodeParams CreateDefaultCoreNodeParams(MempoolService mempoolService, string dataDir) { +#pragma warning disable CA2000 // Dispose objects before losing scope var nodeParameters = new CoreNodeParams( Network.RegTest, mempoolService ?? new MempoolService(), @@ -52,6 +53,7 @@ private static CoreNodeParams CreateDefaultCoreNodeParams(MempoolService mempool userAgent: $"/WasabiClient:{Constants.ClientVersion}/", fallbackFee: Money.Coins(0.0002m), // https://github.com/bitcoin/bitcoin/pull/16524 new MemoryCache(new MemoryCacheOptions())); +#pragma warning restore CA2000 // Dispose objects before losing scope nodeParameters.ListenOnion = 0; nodeParameters.Discover = 0; nodeParameters.DnsSeed = 0; diff --git a/WalletWasabi.Tests/Helpers/WabiSabiTestFactory.cs b/WalletWasabi.Tests/Helpers/WabiSabiTestFactory.cs index 8c5b27f1c0..259af93366 100644 --- a/WalletWasabi.Tests/Helpers/WabiSabiTestFactory.cs +++ b/WalletWasabi.Tests/Helpers/WabiSabiTestFactory.cs @@ -1,19 +1,24 @@ +using GingerCommon.Crypto.Random; using Moq; using NBitcoin; using NBitcoin.Crypto; using NBitcoin.RPC; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; using WabiSabi.CredentialRequesting; using WabiSabi.Crypto; +using WabiSabi.Crypto.Randomness; using WabiSabi.Crypto.ZeroKnowledge; using WalletWasabi.Blockchain.Keys; using WalletWasabi.Blockchain.TransactionOutputs; using WalletWasabi.Crypto; using WalletWasabi.Helpers; +using WalletWasabi.Models; +using WalletWasabi.Tests.TestCommon; using WalletWasabi.Tests.UnitTests; using WalletWasabi.WabiSabi; using WalletWasabi.WabiSabi.Backend; @@ -22,15 +27,11 @@ using WalletWasabi.WabiSabi.Backend.Rounds; using WalletWasabi.WabiSabi.Backend.Rounds.CoinJoinStorage; using WalletWasabi.WabiSabi.Client; +using WalletWasabi.WabiSabi.Client.CoinJoin.Client; using WalletWasabi.WabiSabi.Client.RoundStateAwaiters; using WalletWasabi.WabiSabi.Models; using WalletWasabi.Wallets; using WalletWasabi.WebClients.Wasabi; -using WalletWasabi.WabiSabi.Client.CoinJoin.Client; -using WabiSabi.Crypto.Randomness; -using System.Runtime.CompilerServices; -using WalletWasabi.Tests.TestCommon; -using GingerCommon.Crypto.Random; namespace WalletWasabi.Tests.Helpers; @@ -45,7 +46,9 @@ public static WabiSabiConfig CreateDefaultWabiSabiConfig() public static Coin CreateCoin(Key? key = null, Money? amount = null, ScriptPubKeyType scriptPubKeyType = ScriptPubKeyType.Segwit) { +#pragma warning disable CA2000 // Dispose objects before losing scope key ??= new(); +#pragma warning restore CA2000 // Dispose objects before losing scope amount ??= Money.Coins(1); return new( new OutPoint(Hashes.DoubleSHA256(key.PubKey.ToBytes().Concat(BitConverter.GetBytes(amount)).ToArray()), 0), @@ -54,7 +57,9 @@ public static Coin CreateCoin(Key? key = null, Money? amount = null, ScriptPubKe public static Tuple CreateCoinWithOwnershipProof(GingerRandom rnd, Key? key = null, Money? amount = null, uint256? roundId = null, ScriptPubKeyType scriptPubKeyType = ScriptPubKeyType.Segwit) { +#pragma warning disable CA2000 // Dispose objects before losing scope key ??= new(); +#pragma warning restore CA2000 // Dispose objects before losing scope var coin = CreateCoin(key, amount, scriptPubKeyType); roundId ??= uint256.One; var ownershipProof = CreateOwnershipProof(rnd, key, roundId); @@ -354,7 +359,7 @@ public static CoinJoinClient CreateTestCoinJoinClient( 0, TimeSpan.Zero, TimeSpan.Zero, - null); + null!); // Overwrite Maximum Request Delay parameter but still use the original method. mock.Setup(m => m.GetScheduledDates(It.IsAny(), It.IsAny(), It.IsAny(), It.IsNotIn(TimeSpan.FromSeconds(1)))) diff --git a/WalletWasabi.Tests/IntegrationTests/P2pTests.cs b/WalletWasabi.Tests/IntegrationTests/P2pTests.cs index 820d48ebd5..58b932f1be 100644 --- a/WalletWasabi.Tests/IntegrationTests/P2pTests.cs +++ b/WalletWasabi.Tests/IntegrationTests/P2pTests.cs @@ -103,7 +103,7 @@ public async Task TestServicesAsync(string networkString) KeyManager keyManager = KeyManager.CreateNew(out _, "password", network); await using WasabiHttpClientFactory httpClientFactory = new(Common.TorSocks5Endpoint, backendUriGetter: () => new Uri("http://localhost:12345")); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); ServiceConfiguration serviceConfig = new(new IPEndPoint(IPAddress.Loopback, network.DefaultPort), Money.Coins(Constants.DefaultDustThreshold)); using MemoryCache cache = new(new MemoryCacheOptions diff --git a/WalletWasabi.Tests/RegressionTests/BackendTests.cs b/WalletWasabi.Tests/RegressionTests/BackendTests.cs index a7df78877a..c6a5ccaaf2 100644 --- a/WalletWasabi.Tests/RegressionTests/BackendTests.cs +++ b/WalletWasabi.Tests/RegressionTests/BackendTests.cs @@ -146,7 +146,7 @@ public async Task GetUnconfirmedTxChainAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); // 4. Create key manager service. var keyManager = KeyManager.CreateNew(out _, password, network); diff --git a/WalletWasabi.Tests/RegressionTests/BuildTransactionReorgsTest.cs b/WalletWasabi.Tests/RegressionTests/BuildTransactionReorgsTest.cs index 5c593fe05f..f484b510fc 100644 --- a/WalletWasabi.Tests/RegressionTests/BuildTransactionReorgsTest.cs +++ b/WalletWasabi.Tests/RegressionTests/BuildTransactionReorgsTest.cs @@ -63,7 +63,7 @@ public async Task BuildTransactionReorgsTestAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. @@ -261,14 +261,14 @@ public async Task BuildTransactionReorgsTestAsync() await Task.Delay(2000); // Waits for the funding transaction get to the mempool. Assert.Contains(fundingBumpTxId.TransactionId, wallet.Coins.Select(x => x.TransactionId)); Assert.DoesNotContain(fundingTxId, wallet.Coins.Select(x => x.TransactionId)); - Assert.Single(wallet.Coins.Where(x => x.TransactionId == fundingBumpTxId.TransactionId)); + Assert.Single(wallet.Coins, x => x.TransactionId == fundingBumpTxId.TransactionId); // Confirm the coin Interlocked.Exchange(ref setup.FiltersProcessedByWalletCount, 0); await rpc.GenerateAsync(1); await setup.WaitForFiltersToBeProcessedAsync(TimeSpan.FromSeconds(120), 1); - Assert.Single(wallet.Coins.Where(x => x.Confirmed && x.TransactionId == fundingBumpTxId.TransactionId)); + Assert.Single(wallet.Coins, x => x.Confirmed && x.TransactionId == fundingBumpTxId.TransactionId); } finally { diff --git a/WalletWasabi.Tests/RegressionTests/BuildTransactionValidationsTest.cs b/WalletWasabi.Tests/RegressionTests/BuildTransactionValidationsTest.cs index eecf2a8ddf..9715c35a7a 100644 --- a/WalletWasabi.Tests/RegressionTests/BuildTransactionValidationsTest.cs +++ b/WalletWasabi.Tests/RegressionTests/BuildTransactionValidationsTest.cs @@ -60,7 +60,7 @@ public async Task BuildTransactionValidationsTestAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); // 4. Create key manager service. var keyManager = KeyManager.CreateNew(out _, password, network); diff --git a/WalletWasabi.Tests/RegressionTests/CancelTests.cs b/WalletWasabi.Tests/RegressionTests/CancelTests.cs index 893e3f9d4c..86acaa122a 100644 --- a/WalletWasabi.Tests/RegressionTests/CancelTests.cs +++ b/WalletWasabi.Tests/RegressionTests/CancelTests.cs @@ -60,7 +60,7 @@ public async Task CancelTestsAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/MaxFeeTests.cs b/WalletWasabi.Tests/RegressionTests/MaxFeeTests.cs index a957c8abbe..44c6c4a1b3 100644 --- a/WalletWasabi.Tests/RegressionTests/MaxFeeTests.cs +++ b/WalletWasabi.Tests/RegressionTests/MaxFeeTests.cs @@ -64,7 +64,7 @@ public async Task CalculateMaxFeeTestAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/ReplaceByFeeTxTest.cs b/WalletWasabi.Tests/RegressionTests/ReplaceByFeeTxTest.cs index d4945e6f5f..81e0aff551 100644 --- a/WalletWasabi.Tests/RegressionTests/ReplaceByFeeTxTest.cs +++ b/WalletWasabi.Tests/RegressionTests/ReplaceByFeeTxTest.cs @@ -54,7 +54,7 @@ public async Task ReplaceByFeeTxTestAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); // 4. Create key manager service. var keyManager = KeyManager.CreateNew(out _, password, network); diff --git a/WalletWasabi.Tests/RegressionTests/SelfSpendSpeedupTests.cs b/WalletWasabi.Tests/RegressionTests/SelfSpendSpeedupTests.cs index 64d6cf2eed..d412cbe904 100644 --- a/WalletWasabi.Tests/RegressionTests/SelfSpendSpeedupTests.cs +++ b/WalletWasabi.Tests/RegressionTests/SelfSpendSpeedupTests.cs @@ -63,7 +63,7 @@ public async Task SelfSpendSpeedupTestsAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/SendSpeedupTests.cs b/WalletWasabi.Tests/RegressionTests/SendSpeedupTests.cs index 8fea5a2e2b..37492e784d 100644 --- a/WalletWasabi.Tests/RegressionTests/SendSpeedupTests.cs +++ b/WalletWasabi.Tests/RegressionTests/SendSpeedupTests.cs @@ -62,7 +62,7 @@ public async Task SendSpeedupTestsAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/SendTests.cs b/WalletWasabi.Tests/RegressionTests/SendTests.cs index 69fbe7749f..c6d31d8496 100644 --- a/WalletWasabi.Tests/RegressionTests/SendTests.cs +++ b/WalletWasabi.Tests/RegressionTests/SendTests.cs @@ -63,7 +63,7 @@ public async Task SendTestsAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/SpendUnconfirmedTxTests.cs b/WalletWasabi.Tests/RegressionTests/SpendUnconfirmedTxTests.cs index 243c20c2ed..8ddab72195 100644 --- a/WalletWasabi.Tests/RegressionTests/SpendUnconfirmedTxTests.cs +++ b/WalletWasabi.Tests/RegressionTests/SpendUnconfirmedTxTests.cs @@ -63,7 +63,7 @@ public async Task SpendUnconfirmedTxTestAsync() // 3. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 10000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); using UnconfirmedTransactionChainProvider unconfirmedChainProvider = new(httpClientFactory); // 4. Create key manager service. diff --git a/WalletWasabi.Tests/RegressionTests/WalletTests.cs b/WalletWasabi.Tests/RegressionTests/WalletTests.cs index 0addea7884..cb82fc8c5e 100644 --- a/WalletWasabi.Tests/RegressionTests/WalletTests.cs +++ b/WalletWasabi.Tests/RegressionTests/WalletTests.cs @@ -53,7 +53,7 @@ public async Task WalletTestsAsync() // 2. Create wasabi synchronizer service. await using WasabiHttpClientFactory httpClientFactory = new(torEndPoint: null, backendUriGetter: () => new Uri(RegTestFixture.BackendEndPoint)); using WasabiSynchronizer synchronizer = new(period: TimeSpan.FromSeconds(3), 1000, bitcoinStore, httpClientFactory); - FeeRateProvider feeProvider = new(httpClientFactory, network); + using FeeRateProvider feeProvider = new(httpClientFactory, network); // 3. Create key manager service. var keyManager = KeyManager.CreateNew(out _, setup.Password, network); @@ -170,7 +170,7 @@ public async Task WalletTestsAsync() await rpc.GenerateAsync(2); await setup.WaitForFiltersToBeProcessedAsync(TimeSpan.FromSeconds(120), 2); - Assert.NotEmpty(wallet.Coins.Where(x => x.TransactionId == txId4)); + Assert.Contains(wallet.Coins, x => x.TransactionId == txId4); var tip = await rpc.GetBestBlockHashAsync(); await rpc.InvalidateBlockAsync(tip); // Reorg 1 tip = await rpc.GetBestBlockHashAsync(); @@ -182,8 +182,8 @@ public async Task WalletTestsAsync() Assert.Equal(4, await blockRepository.CountAsync(testDeadlineCts.Token)); Assert.Equal(4, wallet.Coins.Count()); - Assert.Empty(wallet.Coins.Where(x => x.TransactionId == txId4)); - Assert.NotEmpty(wallet.Coins.Where(x => x.TransactionId == tx4bumpRes.TransactionId)); + Assert.DoesNotContain(wallet.Coins, x => x.TransactionId == txId4); + Assert.Contains(wallet.Coins, x => x.TransactionId == tx4bumpRes.TransactionId); var rbfCoin = wallet.Coins.Single(x => x.TransactionId == tx4bumpRes.TransactionId); Assert.Equal(Money.Coins(0.03m), rbfCoin.Amount); @@ -205,13 +205,13 @@ public async Task WalletTestsAsync() Assert.Equal(85, keyManager.GetKeys(KeyState.Clean).Count()); Assert.Equal(87, keyManager.GetKeys().Count()); - Assert.Single(keyManager.GetKeys(KeyState.Used, false).Where(x => x.Labels == "foo label")); - Assert.Single(keyManager.GetKeys(KeyState.Used, false).Where(x => x.Labels == "bar label")); + Assert.Single(keyManager.GetKeys(KeyState.Used, false), x => x.Labels == "foo label"); + Assert.Single(keyManager.GetKeys(KeyState.Used, false), x => x.Labels == "bar label"); // TEST MEMPOOL var txId5 = await rpc.SendToAddressAsync(key.GetP2wpkhAddress(network), Money.Coins(0.1m)); await Task.Delay(1000); // Wait tx to arrive and get processed. - Assert.NotEmpty(wallet.Coins.Where(x => x.TransactionId == txId5)); + Assert.Contains(wallet.Coins, x => x.TransactionId == txId5); var mempoolCoin = wallet.Coins.Single(x => x.TransactionId == txId5); Assert.Equal(Height.Mempool, mempoolCoin.Height); diff --git a/WalletWasabi.Tests/UnitTests/AllFeeEstimateTests.cs b/WalletWasabi.Tests/UnitTests/AllFeeEstimateTests.cs index 43eb0a3dd5..3bc85d8e3c 100644 --- a/WalletWasabi.Tests/UnitTests/AllFeeEstimateTests.cs +++ b/WalletWasabi.Tests/UnitTests/AllFeeEstimateTests.cs @@ -315,7 +315,7 @@ public async Task RealWorldMempoolSpaceMinFeeAsync() mockRpc.OnEstimateSmartFeeAsync = (_, _) => Task.FromResult(FeeRateResponse(2, 0m)); var feeRates = await mockRpc.EstimateAllFeeAsync(); var estimations = feeRates.Estimations; - var minFee = estimations.Min(x => x.Value); + var minFee = estimations.Min(x => x.Value)!; Assert.Equal(15, minFee.SatoshiPerByte); // this is the calculated MempoolMinFee needed to be in the top 200MB } @@ -332,7 +332,7 @@ public async Task RealWorldMempoolRpcMinFeeAsync(string filePath, int expectedMi mockRpc.OnEstimateSmartFeeAsync = (_, _) => Task.FromResult(FeeRateResponse(2, 0m)); var feeRates = await mockRpc.EstimateAllFeeAsync(); var estimations = feeRates.Estimations; - var minFee = estimations.Min(x => x.Value); + var minFee = estimations.Min(x => x.Value)!; Assert.Equal(expectedMinFee, minFee.SatoshiPerByte); } @@ -359,7 +359,7 @@ public async Task RealWorldMempoolRpcMaxFeeAsync(string filePath, int expectedMa var feeRates = await mockRpc.EstimateAllFeeAsync(); var estimations = feeRates.Estimations; - var maxFee = estimations.Max(x => x.Value); + var maxFee = estimations.Max(x => x.Value)!; Assert.Equal(expectedMaxFee, maxFee.SatoshiPerByte); } diff --git a/WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs b/WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs index 171b9f171f..054e9c7ac3 100644 --- a/WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs +++ b/WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs @@ -1,7 +1,8 @@ +using NBitcoin; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using NBitcoin; using WalletWasabi.Blockchain.Blocks; using WalletWasabi.Helpers; using Xunit; @@ -88,7 +89,7 @@ void OnBlockInv(object? blockNotifier, Block b) if (h1 != h2) { - message = string.Format("height={0}, [h1] {1} != [h2] {2}", height, h1, h2); + message = string.Format(CultureInfo.InvariantCulture, "height={0}, [h1] {1} != [h2] {2}", height, h1, h2); cts.Cancel(); return; } diff --git a/WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs b/WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs index e668da4c7b..62d1bb1b10 100644 --- a/WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs +++ b/WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Threading.Tasks; using WalletWasabi.Blockchain.Keys; using WalletWasabi.Blockchain.TransactionBuilding; using WalletWasabi.Blockchain.TransactionBuilding.BnB; @@ -114,7 +115,7 @@ public void TooExpensiveSolution() /// BnB algorithm chooses coins in the way that either all coins with the same scriptPubKey are selected or no coin with that scriptPubKey is selected. /// [Fact] - public async void BnBRespectScriptPubKeyPrivacyRuleAsync() + public async Task BnBRespectScriptPubKeyPrivacyRuleAsync() { var rnd = TestRandom.Get(); using CancellationTokenSource testDeadlineCts = new(TimeSpan.FromMinutes(5)); diff --git a/WalletWasabi.Tests/UnitTests/Blockchain/TransactionOutputs/CoinsRegistryTests.cs b/WalletWasabi.Tests/UnitTests/Blockchain/TransactionOutputs/CoinsRegistryTests.cs index 08e783d019..3e41084184 100644 --- a/WalletWasabi.Tests/UnitTests/Blockchain/TransactionOutputs/CoinsRegistryTests.cs +++ b/WalletWasabi.Tests/UnitTests/Blockchain/TransactionOutputs/CoinsRegistryTests.cs @@ -246,9 +246,9 @@ public void UndoTransaction_PrevOutCache() SmartCoin finalCoin = Assert.Single(Coins); Assert.Equal("E", finalCoin.HdPubKey.Labels); - Assert.Empty(Coins.AsAllCoinsView().Where(coin => coin.HdPubKey.Labels == "B")); - Assert.Empty(Coins.AsAllCoinsView().Where(coin => coin.HdPubKey.Labels == "C")); - Assert.Empty(Coins.AsAllCoinsView().Where(coin => coin.HdPubKey.Labels == "D")); + Assert.DoesNotContain(Coins.AsAllCoinsView(), coin => coin.HdPubKey.Labels == "B"); + Assert.DoesNotContain(Coins.AsAllCoinsView(), coin => coin.HdPubKey.Labels == "C"); + Assert.DoesNotContain(Coins.AsAllCoinsView(), coin => coin.HdPubKey.Labels == "D"); // Replaced transactions tx1 and tx2 have to be removed because tx3 replaced tx1. Assert.False(Coins.IsKnown(tx1.GetHash())); diff --git a/WalletWasabi.Tests/UnitTests/Clients/WasabiClientTests.cs b/WalletWasabi.Tests/UnitTests/Clients/WasabiClientTests.cs index f427cce6d8..deedcec35c 100644 --- a/WalletWasabi.Tests/UnitTests/Clients/WasabiClientTests.cs +++ b/WalletWasabi.Tests/UnitTests/Clients/WasabiClientTests.cs @@ -1,6 +1,7 @@ using NBitcoin; using Newtonsoft.Json; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; @@ -41,7 +42,7 @@ async Task FakeServerCodeAsync(HttpMethod method, string re var mockTorHttpClient = new MockIHttpClient(); mockTorHttpClient.OnSendAsync = req => - FakeServerCodeAsync(req.Method, req.RequestUri.PathAndQuery, req.Content, CancellationToken.None); + FakeServerCodeAsync(req.Method, req.RequestUri!.PathAndQuery, req.Content, CancellationToken.None); var client = new WasabiClient(mockTorHttpClient); Assert.Empty(WasabiClient.TransactionCache); @@ -104,10 +105,10 @@ private static Transaction CreateTransaction() [Fact] public void ConstantsTests() { - var min = int.Parse(WalletWasabi.Helpers.Constants.ClientSupportBackendVersionMin); - var max = int.Parse(WalletWasabi.Helpers.Constants.ClientSupportBackendVersionMax); + var min = int.Parse(WalletWasabi.Helpers.Constants.ClientSupportBackendVersionMin, CultureInfo.InvariantCulture); + var max = int.Parse(WalletWasabi.Helpers.Constants.ClientSupportBackendVersionMax, CultureInfo.InvariantCulture); Assert.True(min <= max); - int.Parse(WalletWasabi.Helpers.Constants.BackendMajorVersion); + int.Parse(WalletWasabi.Helpers.Constants.BackendMajorVersion, CultureInfo.InvariantCulture); } } diff --git a/WalletWasabi.Tests/UnitTests/RpcTests.cs b/WalletWasabi.Tests/UnitTests/RpcTests.cs index 32d84f6664..1a1d064877 100644 --- a/WalletWasabi.Tests/UnitTests/RpcTests.cs +++ b/WalletWasabi.Tests/UnitTests/RpcTests.cs @@ -103,7 +103,7 @@ public async Task ParsingRequestTestsAsync(string request, string expectedRespon [Fact] public void BuildTransactionWithFees() { - var service = new WasabiJsonRpcService(null); + var service = new WasabiJsonRpcService(null!); var paymentInfo = new PaymentInfo { Amount = Money.Coins(1), diff --git a/WalletWasabi.Tests/UnitTests/StandaloneTests/ExchangeRateProviderTests.cs b/WalletWasabi.Tests/UnitTests/StandaloneTests/ExchangeRateProviderTests.cs index 559cb39003..76ae609b14 100644 --- a/WalletWasabi.Tests/UnitTests/StandaloneTests/ExchangeRateProviderTests.cs +++ b/WalletWasabi.Tests/UnitTests/StandaloneTests/ExchangeRateProviderTests.cs @@ -116,6 +116,14 @@ public async Task CoinGateExchangeRateProviderTestAsync() await TestProviderAsync(new CoingateExchangeRateProvider()); } + [Fact] + public async Task BlockchainInfoExchangeRateProviderTestAsync() + { + var provider = new BlockchainInfoExchangeRateProvider(); + await TestProviderAsync(provider); + Assert.Equal(ExchangeRateService.DefaultCurrencies, provider.Currencies); + } + [Fact] public async Task MempoolSpaceExchangeRateProviderTestAsync() { diff --git a/WalletWasabi.Tests/UnitTests/TestWallet.cs b/WalletWasabi.Tests/UnitTests/TestWallet.cs index 4a95a1b589..6c7297c940 100644 --- a/WalletWasabi.Tests/UnitTests/TestWallet.cs +++ b/WalletWasabi.Tests/UnitTests/TestWallet.cs @@ -45,7 +45,7 @@ public BitcoinAddress CreateNewAddress(bool isInternal = false) var key = CreateNewKey(isInternal); var scriptPubKey = key.PrivateKey.GetScriptPubKey(ScriptPubKeyType.Segwit); ScriptPubKeys.Add(scriptPubKey, key); - return scriptPubKey.GetDestinationAddress(Rpc.Network); + return Guard.NotNull(nameof(BitcoinAddress), scriptPubKey.GetDestinationAddress(Rpc.Network)); } public (Transaction, Coin) CreateTemplateTransaction() diff --git a/WalletWasabi.Tests/UnitTests/Tor/TorProcessManagerTests.cs b/WalletWasabi.Tests/UnitTests/Tor/TorProcessManagerTests.cs index a90b5fa3d0..2a3628046d 100644 --- a/WalletWasabi.Tests/UnitTests/Tor/TorProcessManagerTests.cs +++ b/WalletWasabi.Tests/UnitTests/Tor/TorProcessManagerTests.cs @@ -60,7 +60,7 @@ public async Task StartProcessAsync() await using (TorProcessManager manager = mockTorProcessManager.Object) { // No exception is expected here. - (CancellationToken ct1, TorControlClient client1) = await manager.StartAsync(timeoutCts.Token); + (CancellationToken ct1, TorControlClient? client1) = await manager.StartAsync(timeoutCts.Token); // Wait for the Tor process crash (see (1)). await ct1.WhenCanceled().WaitAsync(timeoutCts.Token); diff --git a/WalletWasabi.Tests/UnitTests/Transactions/SmartTransactionTests.cs b/WalletWasabi.Tests/UnitTests/Transactions/SmartTransactionTests.cs index ae852cc31e..44771e3dbb 100644 --- a/WalletWasabi.Tests/UnitTests/Transactions/SmartTransactionTests.cs +++ b/WalletWasabi.Tests/UnitTests/Transactions/SmartTransactionTests.cs @@ -1,5 +1,6 @@ using NBitcoin; using System.Collections.Generic; +using System.Globalization; using System.Linq; using WalletWasabi.Blockchain.Keys; using WalletWasabi.Blockchain.Transactions; @@ -133,9 +134,9 @@ public void SmartTransactionLineDeserialization() Assert.Equal(txHex, stx.Transaction.ToHex()); Assert.Equal(height, stx.Height.ToString()); Assert.Equal(blockHash, Guard.Correct(stx.BlockHash?.ToString())); - Assert.Equal(blockIndex, stx.BlockIndex.ToString()); + Assert.Equal(blockIndex, stx.BlockIndex.ToString(CultureInfo.InvariantCulture)); Assert.Equal(label, stx.Labels); - Assert.Equal(unixSeconds, stx.FirstSeen.ToUnixTimeSeconds().ToString()); + Assert.Equal(unixSeconds, stx.FirstSeen.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture)); Assert.Equal(isReplacement, stx.IsReplacement.ToString()); Assert.Equal(isSpeedup, stx.IsSpeedup.ToString()); Assert.Equal(isCancellation, stx.IsCancellation.ToString()); diff --git a/WalletWasabi.Tests/UnitTests/Userfacing/ParserTests.cs b/WalletWasabi.Tests/UnitTests/Userfacing/ParserTests.cs index bc71e0c73e..1b4a80ade9 100644 --- a/WalletWasabi.Tests/UnitTests/Userfacing/ParserTests.cs +++ b/WalletWasabi.Tests/UnitTests/Userfacing/ParserTests.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Linq; using System.Net; using WalletWasabi.Extensions; @@ -65,14 +66,14 @@ public void EndPointParserTests(string host) "999999999999999999999", "foo", "-999999999999999999999", - int.MaxValue.ToString(), - uint.MaxValue.ToString(), - long.MaxValue.ToString(), + int.MaxValue.ToString(CultureInfo.InvariantCulture), + uint.MaxValue.ToString(CultureInfo.InvariantCulture), + long.MaxValue.ToString(CultureInfo.InvariantCulture), "0.1", - int.MinValue.ToString(), - long.MinValue.ToString(), - (ushort.MinValue - 1).ToString(), - (ushort.MaxValue + 1).ToString() + int.MinValue.ToString(CultureInfo.InvariantCulture), + long.MinValue.ToString(CultureInfo.InvariantCulture), + (ushort.MinValue - 1).ToString(CultureInfo.InvariantCulture), + (ushort.MaxValue + 1).ToString(CultureInfo.InvariantCulture) }; var validPorts = new[] diff --git a/WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs b/WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs index 393bef8753..f874265c7b 100644 --- a/WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs +++ b/WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PhaseStepping/StepTransactionSigningTests.cs @@ -167,7 +167,7 @@ public async Task TimeoutInsufficientPeersAsync() 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.DoesNotContain(arena.Rounds, x => x is BlameRound); Assert.True(prison.IsBanned(aliceClient1.SmartCoin.Outpoint, cfg.GetDoSConfiguration(), DateTimeOffset.UtcNow)); @@ -210,7 +210,7 @@ public async Task TimeoutSufficientPeersAsync() 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)); + Assert.Single(arena.Rounds, x => x is BlameRound); var badOutpoint = alice3.Coin.Outpoint; Assert.True(prison.IsBanned(badOutpoint, cfg.GetDoSConfiguration(), DateTimeOffset.UtcNow)); diff --git a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CoinJoinCoinSelectionTests.cs b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CoinJoinCoinSelectionTests.cs index 7f7f6cf232..f0015f4053 100644 --- a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CoinJoinCoinSelectionTests.cs +++ b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CoinJoinCoinSelectionTests.cs @@ -1,6 +1,7 @@ using Moq; using NBitcoin; using System.Linq; +using System.Threading.Tasks; using WabiSabi.Crypto.Randomness; using WalletWasabi.Blockchain.Analysis; using WalletWasabi.Blockchain.Keys; @@ -32,7 +33,7 @@ public static RoundParameters CreateRoundParameters() /// This test is to make sure no coins are selected when there are no coins. /// [Fact] - public async void SelectNothingFromEmptySetOfCoinsAsync() + public async Task SelectNothingFromEmptySetOfCoinsAsync() { CoinJoinCoinSelectorRandomnessGenerator generator = CreateSelectorGenerator(inputTarget: 5); @@ -49,7 +50,7 @@ public async void SelectNothingFromEmptySetOfCoinsAsync() /// This test is to make sure no coins are selected when all coins are private. /// [Fact] - public async void SelectNothingFromFullyPrivateSetOfCoinsAsync() + public async Task SelectNothingFromFullyPrivateSetOfCoinsAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; @@ -87,7 +88,7 @@ public async void SelectNothingFromFullyPrivateSetOfCoinsAsync() /// Although the coin amount is larger than the smallest reasonable effective denomination, if the algorithm is right, then the effective input amount is considered. /// [Fact] - public async void SelectSomethingFromPrivateButExternalSetOfCoins1Async() + public async Task SelectSomethingFromPrivateButExternalSetOfCoins1Async() { var rnd = TestRandom.Get(); // Although all coins have reached the desired anonymity set, they are not sufficiently distanced from external keys, because they are external keys. @@ -109,7 +110,7 @@ public async void SelectSomethingFromPrivateButExternalSetOfCoins1Async() } [Fact] - public async void SelectSomethingFromPrivateButNotDistancedSetOfCoins2Async() + public async Task SelectSomethingFromPrivateButNotDistancedSetOfCoins2Async() { var rnd = TestRandom.Get(); // Although all coins have reached the desired anonymity set, they are not sufficiently distanced from external keys. @@ -131,7 +132,7 @@ public async void SelectSomethingFromPrivateButNotDistancedSetOfCoins2Async() } [Fact] - public async void SelectSomethingFromPrivateButExternalSetOfCoins3Async() + public async Task SelectSomethingFromPrivateButExternalSetOfCoins3Async() { var rnd = TestRandom.Get(); // Although all coins have reached the desired anonymity set, they are not sufficiently distanced from external keys. @@ -163,7 +164,7 @@ public async void SelectSomethingFromPrivateButExternalSetOfCoins3Async() } [Fact] - public async void SelectNothingFromTooSmallCoinAsync() + public async Task SelectNothingFromTooSmallCoinAsync() { var km = KeyManager.CreateNew(out _, "", Network.Main); var coinsToSelectFrom = new[] { BitcoinFactory.CreateSmartCoin(TestRandom.Get(), BitcoinFactory.CreateHdPubKey(km), Money.Coins(0.00017423m), anonymitySet: 1) }; @@ -184,7 +185,7 @@ public async void SelectNothingFromTooSmallCoinAsync() /// This test is to make sure no coins are selected when there too small coins. /// [Fact] - public async void SelectNothingFromTooSmallSetOfCoinsAsync() + public async Task SelectNothingFromTooSmallSetOfCoinsAsync() { var rnd = TestRandom.Get(); var km = KeyManager.CreateNew(out _, "", Network.Main); @@ -210,7 +211,7 @@ public async void SelectNothingFromTooSmallSetOfCoinsAsync() /// This test is to make sure the coins are selected when the selection's effective sum is exactly the smallest reasonable effective denom. /// [Fact] - public async void SelectSomethingFromJustEnoughSetOfCoinsAsync() + public async Task SelectSomethingFromJustEnoughSetOfCoinsAsync() { var rnd = TestRandom.Get(); var km = KeyManager.CreateNew(out _, "", Network.Main); @@ -236,7 +237,7 @@ public async void SelectSomethingFromJustEnoughSetOfCoinsAsync() /// This test is to make sure that we select the non-private coin in the set. /// [Fact] - public async void SelectNonPrivateCoinFromOneNonPrivateCoinInBigSetOfCoinsConsolidationModeAsync() + public async Task SelectNonPrivateCoinFromOneNonPrivateCoinInBigSetOfCoinsConsolidationModeAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; @@ -264,7 +265,7 @@ public async void SelectNonPrivateCoinFromOneNonPrivateCoinInBigSetOfCoinsConsol /// This test is to make sure that we select the only non-private coin when it is the only coin in the wallet. /// [Fact] - public async void SelectNonPrivateCoinFromOneCoinSetOfCoinsAsync() + public async Task SelectNonPrivateCoinFromOneCoinSetOfCoinsAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; @@ -290,7 +291,7 @@ public async void SelectNonPrivateCoinFromOneCoinSetOfCoinsAsync() /// /// Note randomization can make this test fail even though that's unlikely. [Fact] - public async void SelectMoreNonPrivateCoinFromTwoCoinsSetOfCoinsAsync() + public async Task SelectMoreNonPrivateCoinFromTwoCoinsSetOfCoinsAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; @@ -316,7 +317,7 @@ public async void SelectMoreNonPrivateCoinFromTwoCoinsSetOfCoinsAsync() /// This test is to make sure that we select more than one non-private coin. /// [Fact] - public async void SelectTwoNonPrivateCoinsFromTwoCoinsSetOfCoinsConsolidationModeAsync() + public async Task SelectTwoNonPrivateCoinsFromTwoCoinsSetOfCoinsConsolidationModeAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; @@ -342,7 +343,7 @@ public async void SelectTwoNonPrivateCoinsFromTwoCoinsSetOfCoinsConsolidationMod /// This test is to make sure no coins are selected when all coins are private. /// [Fact] - public async void SelectNothingFromFullyPrivateAndBelowMinAllowedSetOfCoinsAsync() + public async Task SelectNothingFromFullyPrivateAndBelowMinAllowedSetOfCoinsAsync() { var rnd = TestRandom.Get(); const int AnonymitySet = 10; diff --git a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs index 1335efa1ab..fb3326c572 100644 --- a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs +++ b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -12,7 +13,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client; public class CredentialDependencyTests { [Fact] - public async void AsyncDependencyGraphTraversalAsync() + public async Task AsyncDependencyGraphTraversalAsync() { var g = DependencyGraph.ResolveCredentialDependencies( inputValues: new[] { new[] { 10000L, 1930L }, new[] { 1000L, 1930L } }, @@ -168,7 +169,7 @@ public void ResolveCredentialDependenciesNoVsize() var edges = g.OutEdges(g.Vertices[0], CredentialType.Amount); Assert.Equal(2, edges.Count()); - Assert.Single(edges.Where(x => x.Value > 0)); + Assert.Single(edges, x => x.Value > 0); var nonZeroEdge = edges.OrderByDescending(e => e.Value).First(); Assert.Equal(1L, nonZeroEdge.Value); @@ -255,15 +256,15 @@ public void ResolveCredentialDependenciesNoVsize() [InlineData("13,255 1,255 1,255 1,255 1,255 1,255", "3,255 3,255 3,255 3,255 3,255 3,255", 17)] [InlineData("99991099,186 39991099,186 29991099,186 19991099,186 9991099,186", "33558431,31 33558431,31 33558431,31 33558431,31 33558431,31 28701813,31", 14)] [InlineData("99991099,186 39991099,186 29991099,186 19991099,186 9991099,186", "33558431,31 33558431,31 33558431,31 33558431,31 33558431,31 28701813,31 3192645,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 17121,31 12067,31", 50)] - public async void ResolveCredentialDependenciesAsync(string inputs, string outputs, int finalVertexCount) + public async Task ResolveCredentialDependenciesAsync(string inputs, string outputs, int finalVertexCount) { // blackbox tests (apart from finalVertexCount, which leaks // information about implementation) covering valid range // of inputs with various corner cases that must be handled. // Parse values out of strings because InputData can't contain arrays - var inputValues = inputs.Split(" ").Select(x => x.Split(",").Select(y => long.Parse(y))); - var outputValues = outputs.Split(" ").Select(x => x.Split(",").Select(y => long.Parse(y))); + var inputValues = inputs.Split(" ").Select(x => x.Split(",").Select(y => long.Parse(y, CultureInfo.InvariantCulture))); + var outputValues = outputs.Split(" ").Select(x => x.Split(",").Select(y => long.Parse(y, CultureInfo.InvariantCulture))); var g = DependencyGraph.ResolveCredentialDependencies(inputValues, outputValues); diff --git a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/PaymentAwareOutputProviderTests.cs b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/PaymentAwareOutputProviderTests.cs index 9d0c7e1cb6..2c4af56b6c 100644 --- a/WalletWasabi.Tests/UnitTests/WabiSabi/Client/PaymentAwareOutputProviderTests.cs +++ b/WalletWasabi.Tests/UnitTests/WabiSabi/Client/PaymentAwareOutputProviderTests.cs @@ -1,5 +1,6 @@ using NBitcoin; using System.Collections.Generic; +using System.Globalization; using System.Linq; using WalletWasabi.Extensions; using WalletWasabi.Tests.Helpers; @@ -58,10 +59,10 @@ public void BestPaymentSetTest(string[] amountsToPay, string availableAmountStr, var roundParameters = WabiSabiTestFactory.CreateRoundParameters(WabiSabiTestFactory.CreateDefaultWabiSabiConfig()); var paymentBatch = new PaymentBatch(); - var payments = amountsToPay.Select(a => (Destination: GetNewSegwitAddress(), Amount: Money.Coins(decimal.Parse(a)))); + var payments = amountsToPay.Select(a => (Destination: GetNewSegwitAddress(), Amount: Money.Coins(decimal.Parse(a, CultureInfo.InvariantCulture)))); payments.ToList().ForEach(p => paymentBatch.AddPayment(p.Destination, p.Amount)); - var availableMoney = Money.Coins(decimal.Parse(availableAmountStr)); + var availableMoney = Money.Coins(decimal.Parse(availableAmountStr, CultureInfo.InvariantCulture)); var paymentSet = paymentBatch.GetBestPaymentSet(availableMoney, availableVsize, roundParameters); Assert.True(paymentSet.TotalAmount < availableMoney); diff --git a/WalletWasabi.Tests/UnitTests/WabiSabi/Models/MultipartyTransactionTests.cs b/WalletWasabi.Tests/UnitTests/WabiSabi/Models/MultipartyTransactionTests.cs index 4b074d1495..e616d1eb1d 100644 --- a/WalletWasabi.Tests/UnitTests/WabiSabi/Models/MultipartyTransactionTests.cs +++ b/WalletWasabi.Tests/UnitTests/WabiSabi/Models/MultipartyTransactionTests.cs @@ -1,5 +1,6 @@ using NBitcoin; using System.Collections.Immutable; +using System.Globalization; using System.Linq; using WalletWasabi.Crypto; using WalletWasabi.Extensions; @@ -424,7 +425,7 @@ public void FeeTests(int inputCount, int outputCount, string feeRateString) { var rnd = TestRandom.Get(); - FeeRate feeRate = new(satoshiPerByte: decimal.Parse(feeRateString)); + FeeRate feeRate = new(satoshiPerByte: decimal.Parse(feeRateString, CultureInfo.InvariantCulture)); CoordinationFeeRate coordinatorFeeRate = new(0m, Money.Zero); var cfg1 = WabiSabiTestFactory.CreateDefaultWabiSabiConfig(); diff --git a/WalletWasabi.Tests/UnitTests/Wallet/WalletBuilder.cs b/WalletWasabi.Tests/UnitTests/Wallet/WalletBuilder.cs index bb4088a082..de90b3c84b 100644 --- a/WalletWasabi.Tests/UnitTests/Wallet/WalletBuilder.cs +++ b/WalletWasabi.Tests/UnitTests/Wallet/WalletBuilder.cs @@ -66,7 +66,9 @@ public WalletBuilder(MockNode node, [CallerMemberName] string callerName = "NN") var serviceConfiguration = new ServiceConfiguration(new UriEndPoint(new Uri("http://www.nomatter.dontcare")), Money.Coins(WalletWasabi.Helpers.Constants.DefaultDustThreshold)); +#pragma warning disable CA2000 // Dispose objects before losing scope var feeProvider = new FeeRateProvider(HttpClientFactory, keyManager.GetNetwork()); +#pragma warning restore CA2000 // Dispose objects before losing scope WalletFactory walletFactory = new(DataDir, Network.RegTest, BitcoinStore, Synchronizer, serviceConfiguration, feeProvider, BlockDownloadService, UnconfirmedTransactionChainProvider); return walletFactory.CreateAndInitialize(keyManager); diff --git a/WalletWasabi.Tests/UnitTests/Wallets/SpecificNodeBlockProviderTests.cs b/WalletWasabi.Tests/UnitTests/Wallets/SpecificNodeBlockProviderTests.cs index 6ee25a35af..38cf958918 100644 --- a/WalletWasabi.Tests/UnitTests/Wallets/SpecificNodeBlockProviderTests.cs +++ b/WalletWasabi.Tests/UnitTests/Wallets/SpecificNodeBlockProviderTests.cs @@ -63,7 +63,7 @@ public async Task GetValidBlockAsync() .Throws(new OperationCanceledException("Got disconnected")); // Mock the provider. - Mock mockProvider = new(MockBehavior.Strict, network, serviceConfiguration, /* torEndPoint */ null) { CallBase = true }; + Mock mockProvider = new(MockBehavior.Strict, network, serviceConfiguration, /* torEndPoint */ null!) { CallBase = true }; mockProvider.Setup(c => c.ConnectAsync(It.IsAny())) .ReturnsAsync(mockNode.Object); diff --git a/WalletWasabi.Tests/WalletWasabi.Tests.csproj b/WalletWasabi.Tests/WalletWasabi.Tests.csproj index 1e590c295e..2e34eea6e3 100644 --- a/WalletWasabi.Tests/WalletWasabi.Tests.csproj +++ b/WalletWasabi.Tests/WalletWasabi.Tests.csproj @@ -13,10 +13,6 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/WalletWasabi/Services/ExchangeRateService.cs b/WalletWasabi/Services/ExchangeRateService.cs index 1bfbe9d39f..d45f6e2416 100644 --- a/WalletWasabi/Services/ExchangeRateService.cs +++ b/WalletWasabi/Services/ExchangeRateService.cs @@ -32,7 +32,7 @@ public ExchangeRateService(TimeSpan period, WasabiHttpClientFactory httpClientFa public event EventHandler>? SupportedCurrenciesChanged; public static readonly ImmutableSortedSet DefaultCurrencies = [ - "ARS","AUD","BRL","CAD","CHF","CLP","CNY","CZK","DKK","EUR","GBP","HKD","HUF","INR","ISK","JPY","KRW","NGN","NZD","PLN","RON","RUB","SEK","SGD","THB","TRY","TWD","USD" + "ARS","AUD","BRL","CAD","CHF","CLP","CNY","CZK","DKK","EUR","GBP","GHS","HKD","HUF","INR","ISK","JPY","KRW","NGN","NZD","PLN","RON","RUB","SEK","SGD","THB","TRY","TWD","USD" ]; public bool Active { get; set; } = true;