예제 #1
0
 public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, IBackendHttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration)
 {
     WalletManager        = walletManager;
     HttpClientFactory    = backendHttpClientFactory;
     RoundStatusUpdater   = roundStatusUpdater;
     ServiceConfiguration = serviceConfiguration;
 }
예제 #2
0
 public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, HttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration)
 {
     WalletManager        = walletManager;
     ArenaRequestHandler  = new WabiSabiHttpApiClient(backendHttpClientFactory.NewBackendHttpClient(Mode.SingleCircuitPerLifetime));
     RoundStatusUpdater   = roundStatusUpdater;
     ServiceConfiguration = serviceConfiguration;
 }
예제 #3
0
        public async Task ConfirmConnectionTaskAsync(
            TimeSpan connectionConfirmationTimeout,
            AliceClient aliceClient,
            IEnumerable <long> amounts,
            IEnumerable <long> vsizes,
            Money effectiveValue,
            int vsizeValue,
            RoundStateUpdater roundStateUpdater,
            CancellationToken cancellationToken)
        {
            var amountsToRequest = AddExtraCredentialRequests(amounts, effectiveValue.Satoshi);
            var vsizesToRequest  = AddExtraCredentialRequests(vsizes, vsizeValue);

            await aliceClient.ConfirmConnectionAsync(connectionConfirmationTimeout, amountsToRequest, vsizesToRequest, roundStateUpdater, cancellationToken).ConfigureAwait(false);

            // TODO keep extra credentials
            var(amountCredentials, _) = SeparateExtraCredentials(aliceClient.IssuedAmountCredentials, amounts);
            var(vsizeCredentials, _)  = SeparateExtraCredentials(aliceClient.IssuedVsizeCredentials, vsizes);

            foreach (var(tcs, credential) in AmountCredentialTasks.Zip(amountCredentials))
            {
                tcs.SetResult(credential);
            }
            foreach (var(tcs, credential) in VsizeCredentialTasks.Zip(vsizeCredentials))
            {
                tcs.SetResult(credential);
            }
        }
예제 #4
0
 public CoinJoinClient(
     IWabiSabiApiRequestHandler arenaRequestHandler,
     Kitchen kitchen,
     KeyManager keymanager,
     RoundStateUpdater roundStatusUpdater)
 {
     ArenaRequestHandler = arenaRequestHandler;
     Kitchen             = kitchen;
     Keymanager          = keymanager;
     RoundStatusUpdater  = roundStatusUpdater;
     SecureRandom        = new SecureRandom();
 }
예제 #5
0
 public CoinJoinClient(
     IBackendHttpClientFactory httpClientFactory,
     Kitchen kitchen,
     KeyManager keymanager,
     RoundStateUpdater roundStatusUpdater)
 {
     HttpClientFactory  = httpClientFactory;
     Kitchen            = kitchen;
     Keymanager         = keymanager;
     RoundStatusUpdater = roundStatusUpdater;
     SecureRandom       = new SecureRandom();
 }
예제 #6
0
        public static async Task <AliceClient> CreateRegisterAndConfirmInputAsync(
            RoundState roundState,
            ArenaClient arenaClient,
            SmartCoin coin,
            BitcoinSecret bitcoinSecret,
            RoundStateUpdater roundStatusUpdater,
            CancellationToken cancellationToken)
        {
            AliceClient?aliceClient = null;

            try
            {
                aliceClient = await RegisterInputAsync(roundState, arenaClient, coin, bitcoinSecret, cancellationToken).ConfigureAwait(false);

                await aliceClient.ConfirmConnectionAsync(roundStatusUpdater, cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                if (aliceClient is { })
예제 #7
0
        public static async Task <AliceClient> CreateRegisterAndConfirmInputAsync(
            RoundState roundState,
            ArenaClient arenaClient,
            SmartCoin coin,
            BitcoinSecret bitcoinSecret,
            Key identificationKey,
            RoundStateUpdater roundStatusUpdater,
            CancellationToken cancellationToken)
        {
            AliceClient?aliceClient = null;

            try
            {
                aliceClient = await RegisterInputAsync(roundState, arenaClient, coin, bitcoinSecret, identificationKey, cancellationToken).ConfigureAwait(false);

                await aliceClient.ConfirmConnectionAsync(roundStatusUpdater, cancellationToken).ConfigureAwait(false);

                Logger.LogInfo($"Round ({aliceClient.RoundId}), Alice ({aliceClient.AliceId}): Connection successfully confirmed.");
            }
            catch (OperationCanceledException)
            {
                if (aliceClient is { })
예제 #8
0
        public async Task ConfirmConnectionAsync(TimeSpan connectionConfirmationTimeout, IEnumerable <long> amountsToRequest, IEnumerable <long> vsizesToRequest, RoundStateUpdater roundStatusUpdater, CancellationToken cancellationToken)
        {
            do
            {
                using CancellationTokenSource timeout = new(connectionConfirmationTimeout / 2);
                using CancellationTokenSource cts     = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeout.Token);

                try
                {
                    await roundStatusUpdater
                    .CreateRoundAwaiter(
                        RoundId,
                        roundState => roundState.Phase == Phase.ConnectionConfirmation,
                        cts.Token)
                    .ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }while (!await TryConfirmConnectionAsync(amountsToRequest, vsizesToRequest, cancellationToken).ConfigureAwait(false));
        }
        public async Task StartConfirmConnectionsAsync(IEnumerable <AliceClient> aliceClients, DependencyGraph dependencyGraph, TimeSpan connectionConfirmationTimeout, RoundStateUpdater roundStateUpdater, CancellationToken cancellationToken)
        {
            var aliceNodePairs = PairAliceClientAndRequestNodes(aliceClients, Graph);

            List <SmartRequestNode> smartRequestNodes           = new();
            List <Task>             connectionConfirmationTasks = new();

            using CancellationTokenSource ctsOnError = new();
            using CancellationTokenSource linkedCts  = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ctsOnError.Token);

            foreach ((var aliceClient, var node) in aliceNodePairs)
            {
                var amountEdgeTaskCompSources     = Graph.OutEdges(node, CredentialType.Amount).Select(edge => DependencyTasks[edge]);
                var vsizeEdgeTaskCompSources      = Graph.OutEdges(node, CredentialType.Vsize).Select(edge => DependencyTasks[edge]);
                SmartRequestNode smartRequestNode = new(
                    Enumerable.Empty <Task <Credential> >(),
                    Enumerable.Empty <Task <Credential> >(),
                    amountEdgeTaskCompSources,
                    vsizeEdgeTaskCompSources);

                var amountsToRequest = dependencyGraph.OutEdges(node, CredentialType.Amount).Select(e => (long)e.Value);
                var vsizesToRequest  = dependencyGraph.OutEdges(node, CredentialType.Vsize).Select(e => (long)e.Value);

                var task = smartRequestNode
                           .ConfirmConnectionTaskAsync(
                    connectionConfirmationTimeout,
                    aliceClient,
                    amountsToRequest,
                    vsizesToRequest,
                    node.EffectiveValue,
                    node.VsizeRemainingAllocation,
                    roundStateUpdater,
                    linkedCts.Token)
                           .ContinueWith((t) =>
                {
                    if (t.IsFaulted && t.Exception is { } exception)
                    {
                        // If one task is failing, cancel all the tasks and throw.
                        ctsOnError.Cancel();
                        throw exception;
                    }
                }, linkedCts.Token);

                connectionConfirmationTasks.Add(task);
            }

            await Task.WhenAll(connectionConfirmationTasks).ConfigureAwait(false);

            var amountEdges = Graph.Inputs.SelectMany(node => Graph.OutEdges(node, CredentialType.Amount));
            var vsizeEdges  = Graph.Inputs.SelectMany(node => Graph.OutEdges(node, CredentialType.Vsize));

            // Check if all tasks were finished, otherwise Task.Result will block.
            if (!amountEdges.Concat(vsizeEdges).All(edge => DependencyTasks[edge].Task.IsCompletedSuccessfully))
            {
                throw new InvalidOperationException("Some Input nodes out-edges failed to complete.");
            }
        }