Beispiel #1
0
 public bool AllAlices(AliceState state)
 {
     using (RoundSyncronizerLock.Lock())
     {
         return(Alices.All(x => x.State == state));
     }
 }
Beispiel #2
0
        public void Abort(string loggingCategory, string reason, bool syncLock = true)
        {
            if (syncLock)
            {
                using (RoundSyncronizerLock.Lock())
                {
                    Status = CcjRoundStatus.Aborted;
                }
            }
            else
            {
                Status = CcjRoundStatus.Aborted;
            }

            string category = string.IsNullOrWhiteSpace(loggingCategory) ? loggingCategory : nameof(CcjRound);

            if (string.IsNullOrWhiteSpace(reason))
            {
                Logger.LogInfo($"Round ({RoundId}): Aborted.", category);
            }
            else
            {
                Logger.LogInfo($"Round ({RoundId}): Aborted. Reason: {reason}", category);
            }
        }
Beispiel #3
0
 public IEnumerable <Alice> GetAlicesBy(AliceState state)
 {
     using (RoundSyncronizerLock.Lock())
     {
         return(Alices.Where(x => x.State == state).ToList());
     }
 }
Beispiel #4
0
        public async Task <IEnumerable <Alice> > RemoveAlicesIfInputsSpentAsync()
        {
            var alicesRemoved = new List <Alice>();

            using (RoundSyncronizerLock.Lock())
            {
                if ((Phase != CcjRoundPhase.InputRegistration && Phase != CcjRoundPhase.ConnectionConfirmation) || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Removing Alice is only allowed in InputRegistration and ConnectionConfirmation phases.");
                }

                foreach (Alice alice in Alices)
                {
                    foreach (OutPoint input in alice.Inputs.Select(y => y.OutPoint))
                    {
                        GetTxOutResponse getTxOutResponse = await RpcClient.GetTxOutAsync(input.Hash, (int)input.N, includeMempool : true);

                        // Check if inputs are unspent.
                        if (getTxOutResponse == null)
                        {
                            alicesRemoved.Add(alice);
                            Alices.Remove(alice);
                        }
                    }
                }
            }

            foreach (var alice in alicesRemoved)
            {
                Logger.LogInfo <CcjRound>($"Round ({RoundId}): Alice ({alice.UniqueId}) removed.");
            }

            return(alicesRemoved);
        }
Beispiel #5
0
 public Alice TryGetAliceBy(Guid uniqueId)
 {
     using (RoundSyncronizerLock.Lock())
     {
         return(Alices.SingleOrDefault(x => x.UniqueId == uniqueId));
     }
 }
Beispiel #6
0
 public void Fail()
 {
     using (RoundSyncronizerLock.Lock())
     {
         Status = CcjRoundStatus.Failed;
     }
     Logger.LogInfo <CcjRound>($"Round ({RoundId}): Failed.");
 }
Beispiel #7
0
 public IEnumerable <Alice> GetAlicesByNot(AliceState state, bool syncLock = true)
 {
     if (syncLock)
     {
         using (RoundSyncronizerLock.Lock())
         {
             return(Alices.Where(x => x.State != state).ToList());
         }
     }
     return(Alices.Where(x => x.State != state).ToList());
 }
Beispiel #8
0
 public int CountAlices(bool syncLock = true)
 {
     if (syncLock)
     {
         using (RoundSyncronizerLock.Lock())
         {
             return(Alices.Count);
         }
     }
     return(Alices.Count);
 }
Beispiel #9
0
 public int CountBobs(bool syncronized = true)
 {
     if (syncronized)
     {
         using (RoundSyncronizerLock.Lock())
         {
             return(Bobs.Count);
         }
     }
     return(Alices.Count);
 }
Beispiel #10
0
 public void UpdateAnonymitySet(int anonymitySet)
 {
     using (RoundSyncronizerLock.Lock())
     {
         if ((Phase != CcjRoundPhase.InputRegistration && Phase != CcjRoundPhase.ConnectionConfirmation) || Status != CcjRoundStatus.Running)
         {
             throw new InvalidOperationException("Updating anonymity set is only allowed in InputRegistration and ConnectionConfirmation phases.");
         }
         AnonymitySet = anonymitySet;
     }
     Logger.LogInfo <CcjRound>($"Round ({RoundId}): {nameof(AnonymitySet)} updated: {AnonymitySet}.");
 }
Beispiel #11
0
 public void Fail(bool syncLock = true)
 {
     if (syncLock)
     {
         using (RoundSyncronizerLock.Lock())
         {
             Status = CcjRoundStatus.Failed;
         }
     }
     else
     {
         Status = CcjRoundStatus.Failed;
     }
     Logger.LogInfo <CcjRound>($"Round ({RoundId}): Failed.");
 }
Beispiel #12
0
        public void AddAlice(Alice alice)
        {
            using (RoundSyncronizerLock.Lock())
            {
                if (Phase != CcjRoundPhase.InputRegistration || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Adding Alice is only allowed in InputRegistration phase.");
                }
                Alices.Add(alice);
            }

            StartAliceTimeout(alice.UniqueId);

            Logger.LogInfo <CcjRound>($"Round ({RoundId}): Alice ({alice.UniqueId}) added.");
        }
Beispiel #13
0
        public void StartAliceTimeout(Guid uniqueId)
        {
            // 1. Find Alice and set its LastSeen propery.
            var foundAlice = false;
            var started    = DateTimeOffset.UtcNow;

            using (RoundSyncronizerLock.Lock())
            {
                if (Phase != CcjRoundPhase.InputRegistration || Status != CcjRoundStatus.Running)
                {
                    return;                     // Then no need to timeout alice.
                }

                Alice alice = Alices.SingleOrDefault(x => x.UniqueId == uniqueId);
                foundAlice = alice != default(Alice);
                if (foundAlice)
                {
                    alice.LastSeen = started;
                }
            }

            if (foundAlice)
            {
                Task.Run(async() =>
                {
                    // 2. Delay asyncronously to the requested timeout
                    await Task.Delay(AliceRegistrationTimeout);

                    using (await RoundSyncronizerLock.LockAsync())
                    {
                        // 3. If the round is still running and the phase is still InputRegistration
                        if (Status == CcjRoundStatus.Running && Phase == CcjRoundPhase.InputRegistration)
                        {
                            Alice alice = Alices.SingleOrDefault(x => x.UniqueId == uniqueId);
                            if (alice != default(Alice))
                            {
                                // 4. If LastSeen isn't changed by then, remove Alice.
                                if (alice.LastSeen == started)
                                {
                                    Alices.Remove(alice);
                                    Logger.LogInfo <CcjRound>($"Round ({RoundId}): Alice ({alice.UniqueId}) timed out.");
                                }
                            }
                        }
                    }
                });
            }
        }
Beispiel #14
0
        public int RemoveAliceIfContains(OutPoint input)
        {
            var numberOfRemovedAlices = 0;

            using (RoundSyncronizerLock.Lock())
            {
                if ((Phase != CcjRoundPhase.InputRegistration && Phase != CcjRoundPhase.ConnectionConfirmation) || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Removing Alice is only allowed in InputRegistration and ConnectionConfirmation phases.");
                }
                numberOfRemovedAlices = Alices.RemoveAll(x => x.Inputs.Any(y => y.OutPoint == input));
            }

            Logger.LogInfo <CcjRound>($"Round ({RoundId}): {numberOfRemovedAlices} alices are removed.");

            return(numberOfRemovedAlices);
        }
Beispiel #15
0
        public bool ContainsBlindedOutputScriptHex(string blindedOutputScriptHex, out List <Alice> alices)
        {
            alices = new List <Alice>();

            using (RoundSyncronizerLock.Lock())
            {
                foreach (Alice alice in Alices)
                {
                    if (alice.BlindedOutputScriptHex == blindedOutputScriptHex)
                    {
                        alices.Add(alice);
                    }
                }
            }

            return(alices.Count > 0);
        }
Beispiel #16
0
        public bool ContainsInput(OutPoint input, out List <Alice> alices)
        {
            alices = new List <Alice>();

            using (RoundSyncronizerLock.Lock())
            {
                foreach (Alice alice in Alices)
                {
                    if (alice.Inputs.Any(x => x.OutPoint == input))
                    {
                        alices.Add(alice);
                    }
                }
            }

            return(alices.Count > 0);
        }
Beispiel #17
0
        public int RemoveAlicesBy(AliceState state)
        {
            int numberOfRemovedAlices = 0;

            using (RoundSyncronizerLock.Lock())
            {
                if ((Phase != CcjRoundPhase.InputRegistration && Phase != CcjRoundPhase.ConnectionConfirmation) || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Removing Alice is only allowed in InputRegistration and ConnectionConfirmation phases.");
                }
                numberOfRemovedAlices = Alices.RemoveAll(x => x.State == state);
            }
            if (numberOfRemovedAlices != 0)
            {
                Logger.LogInfo <CcjRound>($"Round ({RoundId}): {numberOfRemovedAlices} alices in {state} state are removed.");
            }
            return(numberOfRemovedAlices);
        }
Beispiel #18
0
        public void AddBob(Bob bob)
        {
            using (RoundSyncronizerLock.Lock())
            {
                if (Phase != CcjRoundPhase.OutputRegistration || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Adding Bob is only allowed in OutputRegistration phase.");
                }
                if (Bobs.Any(x => x.ActiveOutputAddress == bob.ActiveOutputAddress))
                {
                    return;                     // Bob is already added.
                }

                Bobs.Add(bob);
            }

            Logger.LogInfo <CcjRound>($"Round ({RoundId}): Bob added.");
        }
Beispiel #19
0
        public int RemoveAlicesBy(params Guid[] ids)
        {
            var numberOfRemovedAlices = 0;

            using (RoundSyncronizerLock.Lock())
            {
                if ((Phase != CcjRoundPhase.InputRegistration && Phase != CcjRoundPhase.ConnectionConfirmation) || Status != CcjRoundStatus.Running)
                {
                    throw new InvalidOperationException("Removing Alice is only allowed in InputRegistration and ConnectionConfirmation phases.");
                }
                foreach (var id in ids)
                {
                    numberOfRemovedAlices = Alices.RemoveAll(x => x.UniqueId == id);
                }
            }

            Logger.LogInfo <CcjRound>($"Round ({RoundId}): {numberOfRemovedAlices} alices are removed.");

            return(numberOfRemovedAlices);
        }