Skip to content

Commit

Permalink
Wabisabi coinjoin tests runnable from IDE (WalletWasabi#13336)
Browse files Browse the repository at this point in the history
* Fix wabisabi tests.

Test were not running on the IDE because of a mess in the lifetime of the registered services.

`MultiClientsCoinJoinTestAsync` was using a real node instead of a fake one. That was changed.

* Make FailToRegisterOutputsCoinJoinTestAsync less fragile

---------

Co-authored-by: Turbolay <[email protected]>
  • Loading branch information
lontivero and turbolay authored Aug 22, 2024
1 parent 8261622 commit daaa65b
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 174 deletions.
44 changes: 43 additions & 1 deletion WalletWasabi.Tests/Helpers/BitcoinFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DynamicData;
using WalletWasabi.Blockchain.Analysis.Clustering;
using WalletWasabi.Blockchain.Keys;
using WalletWasabi.Blockchain.TransactionOutputs;
Expand Down Expand Up @@ -191,9 +192,50 @@ public static MockRpcClient GetMockMinimalRpc()
// We don't use the result, but we need not to throw NotImplementedException.
mockRpc.OnGetBlockCountAsync = () => Task.FromResult(0);
mockRpc.OnUptimeAsync = () => Task.FromResult(TimeSpan.FromDays(365));
mockRpc.OnGetTxOutAsync = (_, _, _) => null;
mockRpc.OnGetTxOutAsync = (txId, i, arg3) =>
{
var tx = GetTransaction(txId);
return tx?.Outputs.Count > i
? new GetTxOutResponse {Confirmations = 100, TxOut = tx.Outputs[i] }
: null;
};
mockRpc.OnGetBlockAsync = blockHash => Task.FromResult(mockRpc.Blockchain.First(x => x.GetHash() == blockHash));
mockRpc.OnSendRawTransactionAsync = transaction =>
{
mockRpc.Mempool.Add(transaction);
return transaction.GetHash();
};
mockRpc.OnGetRawTransactionAsync = (txId, _) => Task.FromResult(GetTransaction(txId));
mockRpc.OnGetRawMempoolAsync = () => Task.FromResult(mockRpc.Mempool.Select(x => x.GetHash()).ToArray());
mockRpc.OnGenerateToAddressAsync = (n, address) =>
{
var prevBlock = mockRpc.Blockchain.LastOrDefault();
var prevBlockHash = prevBlock?.GetHash() ?? uint256.Zero;
var consensusFactory = mockRpc.Network.Consensus.ConsensusFactory;
for (var i = 0; i < n; i++)
{
var block = consensusFactory.CreateBlock();
block.Header.HashPrevBlock = prevBlockHash;
var coinbaseTx = consensusFactory.CreateTransaction();
coinbaseTx.Outputs.Add(Money.Coins(50), address);
block.Transactions.Add(coinbaseTx);
block.Transactions.AddRange(mockRpc.Mempool);
mockRpc.Mempool.Clear();
mockRpc.Blockchain.Add(block);
prevBlockHash = block.GetHash();
}
var txIds = mockRpc.Blockchain.TakeLast(n).Select(x => x.GetHash()).ToArray();
return Task.FromResult(txIds);
};

return mockRpc;

Transaction? GetTransaction(uint256 txId) =>
mockRpc.Blockchain.SelectMany(x => x.Transactions)
.Concat(mockRpc.Mempool)
.FirstOrDefault(tx => tx.GetHash() == txId);

}

public static BitcoinAddress CreateBitcoinAddress(Network network, Key? key = null)
Expand Down
3 changes: 3 additions & 0 deletions WalletWasabi.Tests/UnitTests/MockRpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class MockRpcClient : IRPCClient
public Network Network { get; set; } = Network.RegTest;
public RPCCredentialString CredentialString => new();

public List<Block> Blockchain = new();
public List<Transaction> Mempool = new();

private static Task<T> NotImplementedTask<T>(string nameOfMethod) =>
Task.FromException<T>(new NotImplementedException($"{nameOfMethod} was invoked but never assigned."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static IWebHostBuilder AddMockRpcClient(this IWebHostBuilder builder, Sma
// Instruct the coordinator DI container to use these two scoped
// services to build everything (WabiSabi controller, arena, etc)
services.AddScoped<IRPCClient>(s => rpc));
services.AddSingleton<IRPCClient>(s => rpc));
return builder;
}
}
22 changes: 21 additions & 1 deletion WalletWasabi.Tests/UnitTests/WabiSabi/Integration/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NBitcoin;
using WalletWasabi.Backend.Controllers;
using WalletWasabi.Cache;
using WalletWasabi.WabiSabi.Models.Serialization;

Expand Down Expand Up @@ -35,7 +38,24 @@ public void ConfigureServices(IServiceCollection services)
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Script)));
})
.AddApplicationPart(backendAssembly)
.AddControllersAsServices()
.ConfigureApplicationPartManager(manager =>
{
manager.FeatureProviders.Add(new ControllerProvider(Configuration));
})
.AddNewtonsoftJson(x => x.SerializerSettings.Converters = JsonSerializationOptions.Default.Settings.Converters);
}
}
public class ControllerProvider : ControllerFeatureProvider
{
public readonly IConfiguration _configuration;

public ControllerProvider(IConfiguration configuration)
{
_configuration = configuration;
}

protected override bool IsController(TypeInfo typeInfo)
{
return typeInfo.Name.Contains(nameof(WabiSabiController));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
services.AddHostedService<BackgroundServiceStarter<Arena>>();
services.AddSingleton<Arena>();
services.AddSingleton(_ => Network.RegTest);
services.AddScoped<IRPCClient>(_ => BitcoinFactory.GetMockMinimalRpc());
services.AddScoped<Prison>(_ => WabiSabiFactory.CreatePrison());
services.AddScoped<WabiSabiConfig>();
services.AddScoped<RoundParameterFactory>();
services.AddScoped(typeof(TimeSpan), _ => TimeSpan.FromSeconds(2));
services.AddScoped(s => new CoinJoinScriptStore());
services.AddSingleton<IRPCClient>(_ => BitcoinFactory.GetMockMinimalRpc());
services.AddSingleton<Prison>(_ => WabiSabiFactory.CreatePrison());
services.AddSingleton<WabiSabiConfig>();
services.AddSingleton<RoundParameterFactory>();
services.AddSingleton(typeof(TimeSpan), _ => TimeSpan.FromSeconds(2));
services.AddSingleton(s => new CoinJoinScriptStore());
services.AddSingleton<CoinJoinFeeRateStatStore>();
services.AddHttpClient();
services.AddSingleton(s => new MempoolMirror(null!, null!, TimeSpan.Zero));
Expand Down
Loading

0 comments on commit daaa65b

Please sign in to comment.