예제 #1
0
 public void AddOrReplaceRound(CcjClientRound round)
 {
     lock (StateLock)
     {
         foreach (var r in Rounds.Where(x => x.State.RoundId == round.State.RoundId))
         {
             r?.Registration?.AliceClient?.Dispose();
             Logger.LogInfo <CcjClientState>($"Round ({round.State.RoundId}) removed. Reason: It's being replaced.");
         }
         Rounds.RemoveAll(x => x.State.RoundId == round.State.RoundId);
         Rounds.Add(round);
         Logger.LogInfo <CcjClientState>($"Round ({round.State.RoundId}) added.");
     }
 }
예제 #2
0
        public void UpdateRoundsByStates(ConcurrentDictionary <TxoRef, IEnumerable <HdPubKeyBlindedPair> > exposedLinks, params CcjRunningRoundState[] allRunningRoundsStates)
        {
            Guard.NotNullOrEmpty(nameof(allRunningRoundsStates), allRunningRoundsStates);
            IsInErrorState = false;
            lock (StateLock)
            {
                // Find the rounds those aren't running anymore
                //	Put their coins back to the waiting list
                //	Remove them
                // Find the rounds those needs to be updated
                //	Update them

                IEnumerable <long> roundsToRemove = Rounds.Select(x => x.State.RoundId).Where(y => !allRunningRoundsStates.Select(z => z.RoundId).Contains(y));

                foreach (CcjClientRound round in Rounds.Where(x => roundsToRemove.Contains(x.State.RoundId)))
                {
                    var  newSuccessfulRoundCount = allRunningRoundsStates.FirstOrDefault()?.SuccessfulRoundCount;
                    bool roundFailed             = newSuccessfulRoundCount != null && round.State.SuccessfulRoundCount == newSuccessfulRoundCount;
                    if (roundFailed)
                    {
                        IsInErrorState = true;
                    }

                    foreach (SmartCoin coin in round.CoinsRegistered)
                    {
                        if (round.Registration.IsPhaseActionsComleted(CcjRoundPhase.Signing))
                        {
                            var delayRegistration = TimeSpan.FromSeconds(60);
                            WaitingList.Add(coin, DateTimeOffset.UtcNow + delayRegistration);
                            Logger.LogInfo <CcjClientState>($"Coin added to the waiting list: {coin.Index}:{coin.TransactionId}, but its registration is not allowed till {delayRegistration.TotalSeconds} seconds, because this coin might already be spent.");

                            if (roundFailed)
                            {
                                // Cleanup non-exposed links.
                                foreach (TxoRef input in round.Registration.CoinsRegistered.Select(x => x.GetTxoRef()))
                                {
                                    if (exposedLinks.ContainsKey(input))                                     // This should always be the case.
                                    {
                                        exposedLinks[input] = exposedLinks[input].Where(x => !x.IsBlinded);
                                    }
                                }
                            }
                        }
                        else
                        {
                            WaitingList.Add(coin, DateTimeOffset.UtcNow);
                            Logger.LogInfo <CcjClientState>($"Coin added to the waiting list: {coin.Index}:{coin.TransactionId}.");
                        }
                    }

                    round?.Registration?.AliceClient?.Dispose();

                    Logger.LogInfo <CcjClientState>($"Round ({round.State.RoundId}) removed. Reason: It's not running anymore.");
                }
                Rounds.RemoveAll(x => roundsToRemove.Contains(x.State.RoundId));

                foreach (CcjClientRound round in Rounds)
                {
                    if (allRunningRoundsStates.Select(x => x.RoundId).Contains(round.State.RoundId))
                    {
                        round.State = allRunningRoundsStates.Single(x => x.RoundId == round.State.RoundId);
                    }
                }

                foreach (CcjRunningRoundState state in allRunningRoundsStates)
                {
                    if (!Rounds.Select(x => x.State.RoundId).Contains(state.RoundId))
                    {
                        var r = new CcjClientRound(state);
                        Rounds.Add(r);
                        Logger.LogInfo <CcjClientState>($"Round ({r.State.RoundId}) added.");
                    }
                }
            }
        }