Example #1
0
            private MajorityResults CheckMajority()
            {
                int requiredMajority = MajorityHelper.GetMajorityCount(),
                    maxVotes         = MajorityHelper.GetTotalAuditorsCount();

                //if envelope contains Alpha signature we need to exclude it from count
                var votesCount = resultMessageItem.ResultEnvelope.Signatures.Count;

                if (resultMessageItem.ResultEnvelope.IsSignedBy(Global.Settings.KeyPair))
                {
                    votesCount--;
                }

                //check if we have the majority
                if (votesCount >= requiredMajority)
                {
                    return(MajorityResults.Success);
                }

                var totalOpposition  = processedAuditors.Count - votesCount;
                var maxPossibleVotes = votesCount + (maxVotes - totalOpposition);

                if (maxPossibleVotes < requiredMajority)
                {
                    return(MajorityResults.Unreachable);//no chances to reach the majority
                }
                //not enough votes to decided whether the consensus can be reached or not
                return(MajorityResults.Unknown);
            }
        /// <summary>
        /// Builds and configures Centaurus vault
        /// </summary>
        /// <returns>Transaction cursor</returns>
        private async Task <long> BuildAndConfigureVault(stellar_dotnet_sdk.responses.AccountResponse vaultAccount)
        {
            var majority = MajorityHelper.GetMajorityCount(constellationInitInfo.Auditors.Count());

            var sourceAccount = await StellarAccountHelper.GetStellarAccount(vaultAccount.KeyPair);

            var transactionBuilder = new TransactionBuilder(sourceAccount);

            transactionBuilder.SetFee(10_000);

            var existingTrustlines = vaultAccount.Balances
                                     .Where(b => b.Asset is stellar_dotnet_sdk.AssetTypeCreditAlphaNum)
                                     .Select(b => b.Asset)
                                     .Cast <stellar_dotnet_sdk.AssetTypeCreditAlphaNum>();

            foreach (var a in constellationInitInfo.Assets)
            {
                var asset = a.ToAsset() as stellar_dotnet_sdk.AssetTypeCreditAlphaNum;

                if (asset == null)                                                                  //if null than asset is stellar_dotnet_sdk.AssetTypeNative
                {
                    throw new InvalidOperationException("Native assets are supported by default."); //better to throw exception to avoid confusions with id
                }
                if (existingTrustlines.Any(t => t.Code == asset.Code && t.Issuer == asset.Issuer))
                {
                    continue;
                }

                var trustOperation = new ChangeTrustOperation.Builder(asset, "922337203685.4775807");
                transactionBuilder.AddOperation(trustOperation.Build());
            }

            var optionOperationBuilder = new SetOptionsOperation.Builder()
                                         .SetMasterKeyWeight(0)
                                         .SetLowThreshold(majority)
                                         .SetMediumThreshold(majority)
                                         .SetHighThreshold(majority);

            transactionBuilder.AddOperation(optionOperationBuilder.Build());

            foreach (var signer in constellationInitInfo.Auditors)
            {
                transactionBuilder.AddOperation(new SetOptionsOperation.Builder().SetSigner(Signer.Ed25519PublicKey(signer), 1).Build());
            }

            var transaction = transactionBuilder.Build();

            transaction.Sign(Global.Settings.KeyPair);

            var result = await Global.StellarNetwork.Server.SubmitTransaction(transaction);

            if (!result.IsSuccess())
            {
                throw new Exception($"Transaction failed. Result Xdr: {result.ResultXdr}");
            }

            var tx = await Global.StellarNetwork.Server.Transactions.Transaction(result.Hash);

            return(long.Parse(tx.PagingToken));
        }
Example #3
0
        private void CheckSignatures(MessageEnvelope envelope)
        {
            if (!MajorityHelper.HasMajority(envelope))
            {
                throw new InvalidOperationException("No majority");
            }

            if (!envelope.AreSignaturesValid())
            {
                throw new InvalidOperationException("Signatures is invalid");
            }
        }
Example #4
0
        /// <summary>
        /// Builds and configures Centaurus vault
        /// </summary>
        /// <returns>Transaction cursor</returns>
        private async Task <long> BuildAndConfigureVault(AccountModel vaultAccount)
        {
            var majority = MajorityHelper.GetMajorityCount(constellationInitInfo.Auditors.Count());

            var sourceAccount = await Context.StellarDataProvider.GetAccountData(vaultAccount.KeyPair.AccountId);

            var transactionBuilder = new TransactionBuilder(sourceAccount.ToITransactionBuilderAccount());

            transactionBuilder.SetFee(10_000);

            foreach (var a in constellationInitInfo.Assets)
            {
                if (a.IsXlm)
                {
                    throw new InvalidOperationException("Native assets are supported by default."); //better to throw exception to avoid confusions with id
                }
                if (vaultAccount.ExistingTrustLines.Any(ta => ta == a.ToString()))
                {
                    continue;
                }

                var trustOperation = new ChangeTrustOperation.Builder(a.ToAsset(), "922337203685.4775807");
                transactionBuilder.AddOperation(trustOperation.Build());
            }

            var optionOperationBuilder = new SetOptionsOperation.Builder()
                                         .SetMasterKeyWeight(0)
                                         .SetLowThreshold(majority)
                                         .SetMediumThreshold(majority)
                                         .SetHighThreshold(majority);

            transactionBuilder.AddOperation(optionOperationBuilder.Build());

            foreach (var signer in constellationInitInfo.Auditors)
            {
                transactionBuilder.AddOperation(new SetOptionsOperation.Builder().SetSigner(Signer.Ed25519PublicKey(signer), 1).Build());
            }

            var transaction = transactionBuilder.Build();

            transaction.Sign(Context.Settings.KeyPair);

            var result = await Context.StellarDataProvider.SubmitTransaction(transaction);

            if (!result.IsSuccess)
            {
                throw new Exception($"Transaction failed. Result Xdr: {result.ResultXdr}");
            }

            var tx = await Context.StellarDataProvider.GetTransaction(result.Hash);

            return(tx.PagingToken);
        }
Example #5
0
            private MajorityResults CheckMajority(out MessageEnvelope consensus)
            {
                //TODO: remove the item from storage once the majority succeeded of failed.
                int requiredMajority = MajorityHelper.GetMajorityCount(),
                    maxVotes         = MajorityHelper.GetTotalAuditorsCount(),
                    maxConsensus     = 0,
                    totalOpposition  = 0;

                //try to find the majority
                foreach (var pair in storage)
                {
                    var votes = pair.Value.Signatures.Count;
                    //check if we have the majority
                    if (votes >= requiredMajority)
                    {
                        //return the messages for the consensus
                        consensus = pair.Value;
                        return(MajorityResults.Success);
                    }
                    //check whether a current message is a potential consensus candidate
                    if (votes > maxConsensus)
                    {
                        //previous consensus candidate won't be able to get the majority - swap it
                        totalOpposition += maxConsensus;
                        maxConsensus     = votes;
                    }
                }
                //failed to rich consensus
                consensus = null;

                var maxPossibleVotes = (maxVotes - totalOpposition) + maxConsensus;

                if (maxPossibleVotes < requiredMajority)
                {//no chances to reach the majority
                    return(MajorityResults.Unreachable);
                }
                //not enough votes to decided whether the consensus can be reached or not
                return(MajorityResults.Unknown);
            }
Example #6
0
        private static void ValidateSnapshotSignatures(Snapshot snapshot, List <RawPubKey> knownAudiotors)
        {
            var majorityCount   = MajorityHelper.GetMajorityCount(knownAudiotors.Count);
            var validSignatures = 0;

            var signatures = snapshot.Signatures;

            //set Signatures to null, because snapshot hash computes without it
            snapshot.Signatures = null;

            var snapshotHash = snapshot.ComputeHash();

            if (signatures != null)
            {
                foreach (var signature in signatures)
                {
                    if (!knownAudiotors.Contains(signature.Signer))
                    {
                        continue;
                    }

                    if (signature.IsValid(snapshotHash))
                    {
                        validSignatures++;
                    }
                    if (validSignatures >= majorityCount)
                    {
                        break;
                    }
                }
            }

            if (validSignatures < majorityCount)
            {
                throw new Exception("Snapshot has no majority");
            }
        }
Example #7
0
        public static async Task AddAuditorState(RawPubKey pubKey, AuditorState auditorState)
        {
            await semaphoreSlim.WaitAsync();

            try
            {
                if (Global.AppState.State != ApplicationState.Rising)
                {
                    throw new InvalidOperationException("Auditor state messages can be only handled when Alpha is in rising state");
                }

                if (allAuditorStates.TryGetValue(pubKey, out var pendingAuditorState))
                {
                    if (!pendingAuditorState.HasMorePendingQuanta) //check if auditor send all quanta already
                    {
                        return;
                    }
                    allAuditorStates[pubKey].PendingQuanta.AddRange(auditorState.PendingQuanta);
                    allAuditorStates[pubKey].HasMorePendingQuanta = auditorState.HasMorePendingQuanta;
                }
                else
                {
                    allAuditorStates.Add(pubKey, auditorState);
                }
                var currentAuditorState = allAuditorStates[pubKey];

                if (currentAuditorState.HasMorePendingQuanta) //wait while auditor will send all quanta it has
                {
                    return;
                }

                if (IsStateValid(currentAuditorState))
                {
                    validAuditorStates.Add(pubKey, currentAuditorState);
                }

                int majority           = MajorityHelper.GetMajorityCount(),
                    totalAuditorsCount = MajorityHelper.GetTotalAuditorsCount();

                var completedStatesCount = allAuditorStates.Count(s => !s.Value.HasMorePendingQuanta);

                if (completedStatesCount < majority)
                {
                    return;
                }

                var possibleConsensusCount = (totalAuditorsCount - completedStatesCount) + validAuditorStates.Count;
                if (validAuditorStates.Count >= majority)
                {
                    await ApplyAuditorsData();
                }
                else if (possibleConsensusCount < majority)
                {
                    logger.Error("Majority of auditors are connected, but there is no consensus");
                    Global.AppState.State = ApplicationState.Failed;
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc, "Error on adding auditors state");
                Global.AppState.State = ApplicationState.Failed;
            }
            finally
            {
                semaphoreSlim.Release();
            }
        }