Esempio n. 1
0
        public async Task LoadEffectsTest(KeyPair accountKey, bool isDesc)
        {
            var account = context.AccountStorage.GetAccount(accountKey);

            var allLimit         = 1000;
            var allEffectsResult = (await context.PersistenceManager.LoadEffects(null, isDesc, allLimit, account.Account.Id)).Items;

            var opositeOrderedResult = (await context.PersistenceManager.LoadEffects(null, !isDesc, allLimit, account.Account.Id)).Items;

            //check ordering
            for (int i = 0, opI = allEffectsResult.Count - 1; i < allEffectsResult.Count; i++, opI--)
            {
                var leftEffect   = allEffectsResult[i].Items;
                var rightEffect  = opositeOrderedResult[opI].Items;
                var effectsCount = leftEffect.Count;
                for (int c = 0, opC = effectsCount - 1; c < effectsCount; c++, opC--)
                {
                    var areEqual = ByteArrayPrimitives.Equals(leftEffect[c].ComputeHash(), rightEffect[opC].ComputeHash());
                    Assert.AreEqual(true, areEqual, "Ordering doesn't work as expected.");
                }
            }

            var zeroCursor = "0";
            //check fetching
            var limit = 1;

            await TestFetching(allEffectsResult, zeroCursor, isDesc, limit, account.Account.Id);

            //check reverse fetching
            allEffectsResult.Reverse();
            allEffectsResult.ForEach(ae => ae.Items.Reverse());
            await TestFetching(allEffectsResult, zeroCursor, !isDesc, limit, account.Account.Id, true);
        }
        private async Task ApplyQuanta(List <MessageEnvelope> quanta)
        {
            var quantaCount = quanta.Count;

            for (var i = 0; i < quantaCount; i++)
            {
                var currentQuantumEnvelope = quanta[i];
                var currentQuantum         = ((Quantum)currentQuantumEnvelope.Message);

                //try to unwrap for Alpha
                if (currentQuantum is RequestQuantum)
                {
                    currentQuantumEnvelope = ((RequestQuantum)currentQuantum).RequestEnvelope;
                }

                var resultMessage = await Context.QuantumHandler.HandleAsync(currentQuantumEnvelope, currentQuantum.Timestamp);

                var processedQuantum = (Quantum)resultMessage.OriginalMessage.Message;
                //TODO: check if we need some extra checks here
                if (!ByteArrayPrimitives.Equals(currentQuantum.ComputeHash(), processedQuantum.ComputeHash()))
                {
                    throw new Exception("Apexes are not equal for a quantum on restore.");
                }
            }
        }
Esempio n. 3
0
        private async Task TestFetching(List <ApexEffects> allEffects, string cursor, bool isDesc, int limit, int account, bool isReverseDirection = false)
        {
            var nextCursor = cursor;
            var totalCount = 0;

            while (nextCursor != null)
            {
                var currentEffectsResult = await context.PersistenceManager.LoadEffects(nextCursor, isDesc, limit, account);

                if (totalCount == allEffects.Count)
                {
                    Assert.AreEqual(0, currentEffectsResult.Items.Count, "Some extra effects were loaded.");
                    nextCursor = null;
                }
                else
                {
                    Assert.AreEqual(1, currentEffectsResult.Items.Count, "Effects are not loaded.");
                    var apexEffects = currentEffectsResult.Items[0].Items;
                    for (var i = 0; i < apexEffects.Count; i++)
                    {
                        var areEqual = ByteArrayPrimitives.Equals(allEffects[totalCount].Items[i].ComputeHash(), apexEffects[i].ComputeHash());
                        Assert.AreEqual(true, areEqual, "Effects are not equal.");
                    }
                    totalCount++;
                    nextCursor = currentEffectsResult.NextPageToken;
                }
            }
            Assert.AreEqual(allEffects.Count, totalCount, "Effects total count are not equal.");
        }
Esempio n. 4
0
        private void ValidateTransaction(Transaction transaction)
        {
            var txSourceAccount = transaction.SourceAccount;

            if (ByteArrayPrimitives.Equals(Global.Constellation.Vault.Data, txSourceAccount.PublicKey))
            {
                throw new BadRequestException("Vault account cannot be used as transaction source.");
            }

            if (transaction.TimeBounds == null || transaction.TimeBounds.MaxTime <= 0)
            {
                throw new BadRequestException("Max time must be set.");
            }

            var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

            if (transaction.TimeBounds.MaxTime - currentTime > 1000)
            {
                throw new BadRequestException("Transaction expiration time is to far.");
            }

            if (transaction.Operations.Any(o => !(o is PaymentOperation)))
            {
                throw new BadRequestException("Only payment operations are allowed.");
            }

            if (transaction.Operations.Length > 100)
            {
                throw new BadRequestException("Too many operations.");
            }
        }
Esempio n. 5
0
 public bool Equals(BinaryData other)
 {
     if (other == null)
     {
         return(false);
     }
     return(ByteArrayPrimitives.Equals(Data, other.Data));
 }
Esempio n. 6
0
 public virtual void AssignResponse(MessageEnvelope envelope)
 {
     if (envelope.Signatures.Count == 1 && envelope.Signatures.All(s => ByteArrayPrimitives.Equals(s.Signer, AlphaPubkey)))
     {
         AssignResponseToSource(acknowledgmentSource, envelope);
     }
     else
     {
         SetException(new RequestException(envelope, "Unknown result"));
     }
 }
Esempio n. 7
0
        public static List <WithdrawalWrapperItem> GetWithdrawals(this stellar_dotnet_sdk.Transaction transaction, Account sourceAccount, ConstellationSettings constellationSettings)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }

            if (sourceAccount == null)
            {
                throw new ArgumentNullException(nameof(sourceAccount));
            }

            var payments = transaction.Operations
                           .Where(o => o is stellar_dotnet_sdk.PaymentOperation)
                           .Cast <stellar_dotnet_sdk.PaymentOperation>();

            var withdrawals = new List <WithdrawalWrapperItem>();

            foreach (var payment in payments)
            {
                if (!constellationSettings.TryFindAssetSettings(payment.Asset, out var asset))
                {
                    throw new BadRequestException("Asset is not allowed by constellation.");
                }

                if (!ByteArrayPrimitives.Equals(payment.SourceAccount?.PublicKey, constellationSettings.Vault.Data))
                {
                    throw new BadRequestException("Only vault account can be used as payment source.");
                }
                var amount = stellar_dotnet_sdk.Amount.ToXdr(payment.Amount);
                if (amount < constellationSettings.MinAllowedLotSize)
                {
                    throw new BadRequestException($"Min withdrawal amount is {constellationSettings.MinAllowedLotSize} stroops.");
                }
                if (!(sourceAccount.GetBalance(asset.Id)?.HasSufficientBalance(amount) ?? false))
                {
                    throw new BadRequestException($"Insufficient balance.");
                }

                withdrawals.Add(new WithdrawalWrapperItem
                {
                    Asset       = asset.Id,
                    Amount      = amount,
                    Destination = payment.Destination.PublicKey
                });
            }
            if (withdrawals.GroupBy(w => w.Asset).Any(g => g.Count() > 1))
            {
                throw new BadRequestException("Multiple payments for the same asset.");
            }

            return(withdrawals);
        }
        public override async Task HandleMessage(AlphaWebSocketConnection connection, IncomingMessage message)
        {
            var handshakeInit = message.Envelope.Message as HandshakeInit;

            if (!ByteArrayPrimitives.Equals(handshakeInit.HandshakeData.Data, connection.HandshakeData.Data))
            {
                throw new ConnectionCloseException(WebSocketCloseStatus.InvalidPayloadData, "Handshake failed");
            }

            connection.ClientPubKey    = message.Envelope.Signatures[0].Signer;
            connection.ConnectionState = ConnectionState.Validated;

            if (Context.Constellation.Auditors.Contains(connection.ClientPubKey))
            {
                await HandleAuditorHandshake(connection);
            }
            else
            {
                await HandleClientHandshake(connection, message.Envelope);
            }
        }
        internal void AssignResponse(MessageEnvelope resultEnvelope)
        {
            var resultMessage = resultEnvelope.Message as ResultMessage;

            //handle failed quantum case
            if (resultMessage.Status != ResultStatusCodes.Success)
            {
                SetException(new RequestException(resultEnvelope, resultMessage.Status.ToString()));
                return;
            }

            //handle acknowledgement
            if (resultEnvelope.Signatures.Count == 1 &&
                ByteArrayPrimitives.Equals(resultEnvelope.Signatures[0].Signer, ConstellationInfo.VaultPubKey))
            {
                Acknowledged.TrySetResult(resultEnvelope);
                return;
            }
            //handle quantum result
            try
            {
                if (resultEnvelope.Signatures.Count < 1)
                {
                    throw new RequestException(resultEnvelope, "Result message has no signatures.");
                }
                if (resultEnvelope.Signatures.Distinct().Count() != resultEnvelope.Signatures.Count)
                {
                    throw new RequestException(resultEnvelope, "Duplicate signatures.");
                }
                if (!resultEnvelope.Signatures.Any(s => s.Signer.Equals(ConstellationInfo.VaultPubKey)))
                {
                    throw new RequestException(resultEnvelope, "Result message has not been signed by Alpha.");
                }
                if (!resultEnvelope.Signatures.All(s => ConstellationInfo.AuditorPubKeys.Any(a => s.Signer.Equals(a)) || s.Signer.Equals(ConstellationInfo.VaultPubKey)))
                {
                    throw new RequestException(resultEnvelope, "Unknown signer.");
                }
                if (!(resultMessage is ITransactionResultMessage || resultEnvelope.AreSignaturesValid()))//TODO: remove it after ITransactionResultMessage refactoring
                {
                    throw new RequestException(resultEnvelope, "At least one signature is invalid.");
                }

                if (resultEnvelope.HasMajority(ConstellationInfo.AuditorPubKeys.Length))
                {
                    if (Finalized.Task.IsCompleted)
                    {
                        throw new RequestException(resultEnvelope, "Finalize result message has been already received.");
                    }
                    if (!Acknowledged.Task.IsCompleted) //complete acknowledgment task if it's not completed yet
                    {
                        Acknowledged.TrySetResult(resultEnvelope);
                    }
                    Finalized.TrySetResult(resultEnvelope);
                }
                else
                {
                    if (Acknowledged.Task.IsCompleted)
                    {
                        throw new RequestException(resultEnvelope, "Acknowledgment result message has been already received.");
                    }
                    Acknowledged.TrySetResult(resultEnvelope);
                }
            }
            catch (Exception e)
            {
                Acknowledged.TrySetException(e);
                Finalized.TrySetException(e);
            }
        }
 public void Equals(byte[] left, byte[] right, bool shouldEqual)
 {
     Assert.AreEqual(ByteArrayPrimitives.Equals(left, right), shouldEqual);
 }
Esempio n. 11
0
 public override int GetHashCode()
 {
     return(ByteArrayPrimitives.GetHashCode(Data));
 }