public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, IWasabiHttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration) { WalletManager = walletManager; HttpClientFactory = backendHttpClientFactory; RoundStatusUpdater = roundStatusUpdater; ServiceConfiguration = serviceConfiguration; }
public async Task StartParticipatingAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); var apiClient = new WabiSabiHttpApiClient(HttpClientFactory.NewHttpClientWithDefaultCircuit()); using var roundStateUpdater = new RoundStateUpdater(TimeSpan.FromSeconds(3), apiClient); await roundStateUpdater.StartAsync(cancellationToken).ConfigureAwait(false); var coinJoinClient = new CoinJoinClient( HttpClientFactory, Wallet, Wallet, roundStateUpdater, consolidationMode: true); // Run the coinjoin client task. var walletHdPubKey = new HdPubKey(Wallet.PubKey, KeyPath.Parse("m/84'/0/0/0/0"), SmartLabel.Empty, KeyState.Clean); walletHdPubKey.SetAnonymitySet(1); // bug if not settled if (SplitTransaction is null) { throw new InvalidOperationException($"{nameof(GenerateCoinsAsync)} has to be called first."); } var smartCoins = SplitTransaction.Transaction.Outputs.AsIndexedOutputs() .Select(x => new SmartCoin(SplitTransaction, x.N, walletHdPubKey)) .ToList(); // Run the coinjoin client task. await coinJoinClient.StartCoinJoinAsync(smartCoins, cancellationToken).ConfigureAwait(false); await roundStateUpdater.StopAsync(cancellationToken).ConfigureAwait(false); }
public CoinJoinTrackerFactory( IWasabiHttpClientFactory httpClientFactory, RoundStateUpdater roundStatusUpdater, CancellationToken cancellationToken) { HttpClientFactory = httpClientFactory; RoundStatusUpdater = roundStatusUpdater; CancellationToken = cancellationToken; }
public async Task StartParticipatingAsync(CancellationToken cancellationToken) { if (SplitTransaction is null) { throw new InvalidOperationException($"{nameof(GenerateCoinsAsync)} has to be called first."); } var apiClient = new WabiSabiHttpApiClient(HttpClientFactory.NewHttpClientWithDefaultCircuit()); using var roundStateUpdater = new RoundStateUpdater(TimeSpan.FromSeconds(3), apiClient); await roundStateUpdater.StartAsync(cancellationToken).ConfigureAwait(false); var coinJoinClient = WabiSabiFactory.CreateTestCoinJoinClient(HttpClientFactory, Wallet, Wallet, roundStateUpdater);
/// <param name="minAnonScoreTarget">Coins those have reached anonymity target, but still can be mixed if desired.</param> /// <param name="consolidationMode">If true, then aggressively try to consolidate as many coins as it can.</param> public CoinJoinClient( IWasabiHttpClientFactory httpClientFactory, IKeyChain keyChain, IDestinationProvider destinationProvider, RoundStateUpdater roundStatusUpdater, int minAnonScoreTarget = int.MaxValue, bool consolidationMode = false, TimeSpan doNotRegisterInLastMinuteTimeLimit = default) { HttpClientFactory = httpClientFactory; KeyChain = keyChain; DestinationProvider = destinationProvider; RoundStatusUpdater = roundStatusUpdater; MinAnonScoreTarget = minAnonScoreTarget; ConsolidationMode = consolidationMode; SecureRandom = new SecureRandom(); DoNotRegisterInLastMinuteTimeLimit = doNotRegisterInLastMinuteTimeLimit; }
public static async Task <AliceClient> CreateRegisterAndConfirmInputAsync( RoundState roundState, ArenaClient arenaClient, SmartCoin coin, IKeyChain keyChain, RoundStateUpdater roundStatusUpdater, CancellationToken cancellationToken) { AliceClient?aliceClient = null; try { aliceClient = await RegisterInputAsync(roundState, arenaClient, coin, keyChain, cancellationToken).ConfigureAwait(false); await aliceClient.ConfirmConnectionAsync(roundStatusUpdater, cancellationToken).ConfigureAwait(false); Logger.LogInfo($"Round ({aliceClient.RoundId}), Alice ({aliceClient.AliceId}): Connection was confirmed."); } catch (OperationCanceledException) { if (aliceClient is { })
public async Task SoloCoinJoinTest() { const int InputCount = 2; // At the end of the test a coinjoin transaction has to be created and broadcasted. var transactionCompleted = new TaskCompletionSource <Transaction>(); // Total test timeout. using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(120)); cts.Token.Register(() => transactionCompleted.TrySetCanceled(), useSynchronizationContext: false); // Create a key manager and use it to create two fake coins. var keyManager = KeyManager.CreateNew(out var _, password: ""); keyManager.AssertCleanKeysIndexed(); var coins = keyManager.GetKeys() .Take(InputCount) .Select(x => new Coin( BitcoinFactory.CreateOutPoint(), new TxOut(Money.Coins(1), x.P2wpkhScript))) .ToArray(); var httpClient = _apiApplicationFactory.WithWebHostBuilder(builder => { builder.ConfigureServices(services => { var rpc = BitcoinFactory.GetMockMinimalRpc(); // Make the coordinator to believe that those two coins are real and // that they exist in the blockchain with many confirmations. rpc.OnGetTxOutAsync = (txId, idx, _) => new() { Confirmations = 101, IsCoinBase = false, ScriptPubKeyType = "witness_v0_keyhash", TxOut = coins.Single(x => x.Outpoint.Hash == txId && x.Outpoint.N == idx).TxOut }; // Make the coordinator believe that the transaction is being // broadcasted using the RPC interface. Once we receive this tx // (the `SendRawTransationAsync` was invoked) we stop waiting // and finish the waiting tasks to finish the test successfully. rpc.OnSendRawTransactionAsync = (tx) => { transactionCompleted.SetResult(tx); return(tx.GetHash()); }; // Instruct the coodinator DI container to use these two scoped // services to build everything (wabisabi controller, arena, etc) services.AddScoped <IRPCClient>(s => rpc); services.AddScoped <WabiSabiConfig>(s => new WabiSabiConfig { MaxInputCountByRound = InputCount }); }); }).CreateClient(); // Create the coinjoin client var apiClient = _apiApplicationFactory.CreateWabiSabiHttpApiClient(httpClient); using var roundStateUpdater = new RoundStateUpdater(TimeSpan.FromSeconds(1), apiClient); await roundStateUpdater.StartAsync(CancellationToken.None); var kitchen = new Kitchen(); kitchen.Cook(""); var coinJoinClient = new CoinJoinClient(apiClient, coins, kitchen, keyManager, roundStateUpdater); // Run the coinjoin client task. await coinJoinClient.StartCoinJoinAsync(cts.Token); var boadcastedTx = await transactionCompleted.Task.ConfigureAwait(false); // wait for the transaction to be broadcasted. Assert.NotNull(boadcastedTx); await roundStateUpdater.StopAsync(CancellationToken.None); }