Example #1
0
        public void XdrReaderPerformanceTest(int rounds, int iterations)
        {
            var testArray = new byte[32];

            Array.Fill(testArray, (byte)100);

            var stream = new XdrBufferWriter();

            for (var i = 0; i < iterations; i++)
            {
                stream.WriteInt32(435);
                stream.WriteString("oiewurouqwe");
                stream.WriteVariable(testArray);
            }
            var serialized = stream.ToArray();

            PerfCounter.MeasureTime(() =>
            {
                for (var r = 0; r < rounds; r++)
                {
                    var reader = new XdrBufferReader(serialized);
                    for (var i = 0; i < iterations; i++)
                    {
                        reader.ReadInt32();
                        reader.ReadString();
                        reader.ReadVariableAsSpan();
                    }
                }
            }, () => $"({rounds} rounds, {iterations} iterations)");
        }
        public static QuantumModel FromQuantumContainer(MessageEnvelope quantum, List <Effect> effects, int[] accounts, byte[] buffer)
        {
            if (quantum == null)
            {
                throw new ArgumentNullException(nameof(quantum));
            }
            if (accounts == null)
            {
                throw new ArgumentNullException(nameof(accounts));
            }
            if (effects == null)
            {
                throw new ArgumentNullException(nameof(effects));
            }

            var quantumMessage = (Quantum)quantum.Message;

            using var writer = new XdrBufferWriter(buffer);
            XdrConverter.Serialize(new QuantumContainer {
                Quantum = quantum, Effects = effects
            }, writer);
            return(new QuantumModel
            {
                Apex = quantumMessage.Apex,
                Accounts = accounts,
                Bin = writer.ToArray()
            });
        }
        public async Task OrderQuantumTest(KeyPair clientKeyPair, KeyPair alphaKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AuditorWebSocketConnection(context, new FakeAuditorConnectionInfo(new FakeWebSocket()))
            {
                ConnectionState = state
            };
            var account       = context.AccountStorage.GetAccount(clientKeyPair);
            var orderEnvelope = new OrderRequest
            {
                Account = account?.Account.Id ?? 0
            }.CreateEnvelope().Sign(clientKeyPair);

            var orderQuantumEnvelope = new RequestQuantum
            {
                RequestEnvelope = orderEnvelope
            }.CreateEnvelope();

            orderQuantumEnvelope.Sign(alphaKeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = orderQuantumEnvelope.ToIncomingMessage(writer);


            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public async Task AuditorStateTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Rising;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = clientKeyPair.PublicKey,
                ConnectionState = state
            };

            var envelope = new AuditorState
            {
                PendingQuanta = new List <MessageEnvelope>(),
                State         = ApplicationState.Running
            }.CreateEnvelope();

            envelope.Sign(clientKeyPair);

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);

            if (excpectedException == null)
            {
                Assert.AreEqual(context.AppState.State, ApplicationState.Running);
            }
        }
        public async Task AuditorPerfStatisticsTest()
        {
            var auditorPerf = new AuditorPerfStatistics
            {
                BatchInfos        = new List <Models.BatchSavedInfo>(),
                QuantaPerSecond   = 1,
                QuantaQueueLength = 2,
                UpdateDate        = DateTime.UtcNow.Ticks
            };

            var envelope = auditorPerf.CreateEnvelope();

            envelope.Sign(TestEnvironment.Auditor1KeyPair);


            var auditorConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey = TestEnvironment.Auditor1KeyPair
            };

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(auditorConnection, inMessage, null);
        }
        public async Task TxCommitQuantumTest(KeyPair alphaKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AuditorWebSocketConnection(context, new FakeAuditorConnectionInfo(new FakeWebSocket()))
            {
                ConnectionState = state
            };

            var ledgerNotification = new TxNotification
            {
                TxCursor = 0,
                Payments = new List <PaymentBase>()
            };

            var envelope = new TxCommitQuantum
            {
                Source = ledgerNotification.CreateEnvelope()
            }.CreateEnvelope();

            envelope.Sign(alphaKeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public static byte[] ToByteArray(this object objToSerialize, XdrBufferWriter writer)
        {
            var bytes = objToSerialize as byte[];

            if (bytes != null)
            {
                return(bytes);
            }

            XdrConverter.Serialize(objToSerialize, writer);
            return(writer.ToArray());
        }
        public async Task AccountRequestRateLimitTest(KeyPair clientKeyPair, int?requestLimit)
        {
            context.AppState.State = ApplicationState.Ready;

            var account = context.AccountStorage.GetAccount(clientKeyPair);

            if (requestLimit.HasValue)
            {
                //TODO: replace it with quantum
                var effect = new RequestRateLimitUpdateEffect
                {
                    Account           = account.Id,
                    AccountWrapper    = account,
                    RequestRateLimits = new RequestRateLimits
                    {
                        HourLimit   = (uint)requestLimit.Value,
                        MinuteLimit = (uint)requestLimit.Value
                    }
                };
                var effectProcessor = new RequestRateLimitUpdateEffectProcessor(effect, context.Constellation.RequestRateLimits);
                effectProcessor.CommitEffect();
            }
            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = clientKeyPair,
                ConnectionState = ConnectionState.Ready,
                Account         = account
            };

            var minuteLimit     = (account.Account.RequestRateLimits ?? context.Constellation.RequestRateLimits).MinuteLimit;
            var minuteIterCount = minuteLimit + 1;

            for (var i = 0; i < minuteIterCount; i++)
            {
                var envelope = new AccountDataRequest
                {
                    Account   = account.Account.Id,
                    RequestId = i + 1
                }.CreateEnvelope();
                envelope.Sign(clientKeyPair);
                using var writer = new XdrBufferWriter();
                var inMessage = envelope.ToIncomingMessage(writer);
                if (i + 1 > minuteLimit)
                {
                    await AssertMessageHandling(clientConnection, inMessage, typeof(TooManyRequestsException));
                }
                else
                {
                    await AssertMessageHandling(clientConnection, inMessage);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Submit message to the constellation.
        /// </summary>
        /// <param name="envelope"></param>
        /// <returns></returns>
        public async Task <QuantumResult> SendMessage(MessageEnvelope envelope)
        {
            if (!envelope.IsSignedBy(Config.ClientKeyPair))
            {
                envelope.Sign(Config.ClientKeyPair);
            }

            QuantumResult result = null;

            if (envelope.Message.MessageId != default)
            {
                result = new QuantumResult(envelope, ConstellationInfo);
                result.ScheduleExpiration(RequestTimeout);
                collator.Add(result);
            }

            using (var writerBuffer = Rent(1024))
            {
                try
                {
                    var writer = new XdrBufferWriter(writerBuffer.Buffer);
                    XdrConverter.Serialize(envelope, writer);
                    await sendMessageSemaphore.WaitAsync();

                    await webSocket.SendAsync(writerBuffer.Buffer.AsMemory(0, writer.Length),
                                              WebSocketMessageType.Binary, true, cancellationTokenSource.Token);
                }
                catch (WebSocketException e)
                {
                    if (result != null)
                    {
                        result.SetException(e);
                    }

                    await CloseConnection(WebSocketCloseStatus.ProtocolError, e.Message);
                }
                catch (Exception e)
                {
                    if (result == null)
                    {
                        throw;
                    }
                    result.SetException(e);
                }
                finally
                {
                    sendMessageSemaphore.Release();
                }
            }

            return(result);
        }
        public static byte[] ComputeHash(this object objToSerialize)
        {
            var bytes = objToSerialize as byte[];

            if (bytes != null)
            {
                return(SHA256.Create().ComputeHash(bytes));
            }
            using var buffer = XdrBufferFactory.Rent();
            using var writer = new XdrBufferWriter(buffer.Buffer);
            XdrConverter.Serialize(objToSerialize, writer);
            var hash = SHA256.Create().ComputeHash(buffer.Buffer, 0, writer.Length);

            return(hash);
        }
        public async Task AlphaStateTest(ApplicationState alphaState)
        {
            context.AppState.State = ApplicationState.Running;

            var clientConnection = new AuditorWebSocketConnection(context, new FakeAuditorConnectionInfo(new FakeWebSocket()));

            var envelope = new AlphaState
            {
                State = alphaState
            }.CreateEnvelope().Sign(TestEnvironment.AlphaKeyPair);

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);
            var isHandled = await context.MessageHandlers.HandleMessage(clientConnection, inMessage);

            Assert.IsTrue(isHandled);
        }
        public async Task QuantaBatchTest(KeyPair alphaKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AuditorWebSocketConnection(context, new FakeAuditorConnectionInfo(new FakeWebSocket()))
            {
                ConnectionState = state
            };
            var orderEnvelope = new QuantaBatch
            {
                Quanta = new List <MessageEnvelope>()
            }.CreateEnvelope();

            orderEnvelope.Sign(alphaKeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = orderEnvelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public async Task SetApexCursorTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = clientKeyPair.PublicKey,
                ConnectionState = state
            };

            var envelope = new SetApexCursor {
                Apex = 1
            }.CreateEnvelope();

            envelope.Sign(clientKeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public virtual async Task SendMessage(MessageEnvelope envelope)
        {
            await sendMessageSemaphore.WaitAsync();

            try
            {
                Global.ExtensionsManager.BeforeSendMessage(this, envelope);
                if (!envelope.IsSignedBy(Global.Settings.KeyPair.PublicKey))
                {
                    envelope.Sign(Global.Settings.KeyPair);
                }

                using var buffer = XdrBufferFactory.Rent();
                using var writer = new XdrBufferWriter(buffer.Buffer);
                XdrConverter.Serialize(envelope, writer);

                if (webSocket == null)
                {
                    throw new ObjectDisposedException(nameof(webSocket));
                }
                if (webSocket.State == WebSocketState.Open)
                {
                    await webSocket.SendAsync(buffer.AsSegment(0, writer.Length), WebSocketMessageType.Binary, true, cancellationToken);
                }
                Global.ExtensionsManager.AfterSendMessage(this, envelope);
            }
            catch (Exception exc)
            {
                if (exc is OperationCanceledException ||
                    exc is WebSocketException socketException && (socketException.WebSocketErrorCode == WebSocketError.InvalidState))
                {
                    return;
                }
                Global.ExtensionsManager.SendMessageFailed(this, envelope, exc);
                throw;
            }
            finally
            {
                sendMessageSemaphore.Release();
            }
        }
Example #15
0
        /// <summary>
        /// Signs an envelope with a given <see cref="KeyPair"/> and appends the signature to the <see cref="MessageEnvelope.Signatures"/>.
        /// </summary>
        /// <param name="messageEnvelope">Envelope to sign</param>
        /// <param name="keyPair">Key pair to use for signing</param>
        /// <param name="buffer">Buffer to use for computing hash code.</param>
        public static MessageEnvelope Sign(this MessageEnvelope messageEnvelope, KeyPair keyPair, byte[] buffer)
        {
            if (messageEnvelope == null)
            {
                throw new ArgumentNullException(nameof(messageEnvelope));
            }
            if (keyPair == null)
            {
                throw new ArgumentNullException(nameof(keyPair));
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            using var writer = new XdrBufferWriter(buffer);
            XdrConverter.Serialize(messageEnvelope.Message, writer);
            var signature = writer.ToArray().ComputeHash().Sign(keyPair);

            messageEnvelope.Signatures.Add(signature);
            return(messageEnvelope);
        }
        public void HandshakeInvalidDataTest()
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1");

            var handshake = new HandshakeData();

            handshake.Randomize();

            var envelope = new HandshakeInit {
                HandshakeData = handshake
            }.CreateEnvelope();

            envelope.Sign(TestEnvironment.Client1KeyPair);

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            Assert.ThrowsAsync <ConnectionCloseException>(async() => await context.MessageHandlers.HandleMessage(clientConnection, inMessage));
        }
        public async Task TxNotificationTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = clientKeyPair.PublicKey,
                ConnectionState = state
            };

            var envelope = new TxNotification
            {
                TxCursor = context.TxCursorManager.TxCursor + 1,
                Payments = new List <PaymentBase>()
            }.CreateEnvelope();

            envelope.Sign(clientKeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public async Task AccountDataRequestTest(ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = TestEnvironment.Client1KeyPair.PublicKey,
                ConnectionState = state
            };

            var account = context.AccountStorage.GetAccount(TestEnvironment.Client1KeyPair);

            var envelope = new AccountDataRequest
            {
                Account   = account.Account.Id,
                RequestId = 1
            }.CreateEnvelope();

            envelope.Sign(TestEnvironment.Client1KeyPair);
            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
        public async Task HandshakeTest(KeyPair clientKeyPair, ApplicationState alphaState, Type expectedException)
        {
            context.AppState.State = alphaState;

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1");

            var message = new HandshakeInit {
                HandshakeData = clientConnection.HandshakeData
            };
            var envelope = message.CreateEnvelope();

            envelope.Sign(clientKeyPair);

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            if (expectedException == null)
            {
                var isHandled = await context.MessageHandlers.HandleMessage(clientConnection, inMessage);

                Assert.IsTrue(isHandled);
                Assert.AreEqual(clientConnection.ClientPubKey, new RawPubKey(clientKeyPair.AccountId));
                if (clientConnection.ClientPubKey.Equals((RawPubKey)TestEnvironment.Auditor1KeyPair))
                {
                    Assert.AreEqual(clientConnection.ConnectionState, ConnectionState.Validated);
                }
                else
                {
                    Assert.AreEqual(clientConnection.ConnectionState, ConnectionState.Ready);
                }
            }
            else
            {
                Assert.ThrowsAsync(expectedException, async() => await context.MessageHandlers.HandleMessage(clientConnection, inMessage));
            }
        }
        public async Task EffectsRequestTest(KeyPair client, ConnectionState state, Type excpectedException)
        {
            context.AppState.State = ApplicationState.Ready;

            var account = context.AccountStorage.GetAccount(client);

            var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1")
            {
                ClientPubKey    = client,
                ConnectionState = state,
                Account         = account
            };

            var envelope = new EffectsRequest {
                Account = account.Account.Id, AccountWrapper = account
            }.CreateEnvelope();

            envelope.Sign(client);

            using var writer = new XdrBufferWriter();
            var inMessage = envelope.ToIncomingMessage(writer);

            await AssertMessageHandling(clientConnection, inMessage, excpectedException);
        }
Example #21
0
        public static IncomingMessage ToIncomingMessage(this MessageEnvelope envelope, XdrBufferWriter writer)
        {
            if (envelope == null)
            {
                throw new ArgumentNullException(nameof(envelope));
            }
            XdrConverter.Serialize(envelope.Message, writer);
            var messageHash = writer.ToArray().ComputeHash();

            return(new IncomingMessage(envelope, messageHash));
        }
Example #22
0
 public static IncomingMessage ToIncomingMessage(this MessageEnvelope envelope, XdrBufferFactory.RentedBuffer rentedBuffer)
 {
     using var writer = new XdrBufferWriter(rentedBuffer.Buffer);
     return(envelope.ToIncomingMessage(writer));
 }
Example #23
0
        public void XdrCompatibilityTest()
        {
            var testArray = new byte[32];

            Array.Fill(testArray, (byte)100);

            //forward compatibility
            var legacyXdrSerializationStream = new XdrDataOutputStream();

            legacyXdrSerializationStream.WriteInt(435);
            legacyXdrSerializationStream.WriteUInt(435);
            legacyXdrSerializationStream.WriteLong(43546345634657565L);
            legacyXdrSerializationStream.WriteDoubleArray(new double[] { 435.15, 64656.11 });
            legacyXdrSerializationStream.WriteString("oiewurouqwe");
            legacyXdrSerializationStream.WriteVarOpaque(32, testArray);

            var bufferReader = new XdrBufferReader(legacyXdrSerializationStream.ToArray());

            Assert.AreEqual(435, bufferReader.ReadInt32());
            Assert.AreEqual((uint)435, bufferReader.ReadUInt32());
            Assert.AreEqual(43546345634657565L, bufferReader.ReadInt64());
            {
                var length = bufferReader.ReadInt32();
                var value  = new double[length];
                for (var i = 0; i < length; i++)
                {
                    value[i] = bufferReader.ReadDouble();
                }
                Assert.AreEqual(new double[] { 435.15, 64656.11 }, value);
            }
            Assert.AreEqual("oiewurouqwe", bufferReader.ReadString());
            Assert.AreEqual(testArray, bufferReader.ReadVariable());

            using var streamReader = new XdrStreamReader(new MemoryStream(legacyXdrSerializationStream.ToArray()));
            Assert.AreEqual(435, streamReader.ReadInt32());
            Assert.AreEqual((uint)435, streamReader.ReadUInt32());
            Assert.AreEqual(43546345634657565L, streamReader.ReadInt64());
            {
                var length = streamReader.ReadInt32();
                var value  = new double[length];
                for (var i = 0; i < length; i++)
                {
                    value[i] = streamReader.ReadDouble();
                }
                Assert.AreEqual(new double[] { 435.15, 64656.11 }, value);
            }
            Assert.AreEqual("oiewurouqwe", streamReader.ReadString());
            Assert.AreEqual(testArray, streamReader.ReadVariable());

            //backward compatibility
            var bufferWriter = new XdrBufferWriter();

            bufferWriter.WriteInt32(435);
            bufferWriter.WriteUInt32((uint)435);
            {
                var arr = new double[] { 435.15, 64656.11 };
                bufferWriter.WriteInt32(arr.Length);
                foreach (var d in arr)
                {
                    bufferWriter.WriteDouble(d);
                }
            }
            bufferWriter.WriteString("oiewurouqwe");
            bufferWriter.WriteVariable(testArray);

            var legacyXdrReader = new XdrDataInputStream(bufferWriter.ToArray());

            Assert.AreEqual(435, legacyXdrReader.ReadInt());
            Assert.AreEqual((uint)435, legacyXdrReader.ReadUInt());
            Assert.AreEqual(new double[] { 435.15, 64656.11 }, legacyXdrReader.ReadDoubleArray());
            Assert.AreEqual("oiewurouqwe", legacyXdrReader.ReadString());
            Assert.AreEqual(testArray, legacyXdrReader.ReadVarOpaque(32));


            using var memoryStream = new MemoryStream();
            var streamWriter = new XdrStreamWriter(memoryStream);

            streamWriter.WriteInt32(435);
            streamWriter.WriteUInt32((uint)435);
            {
                var arr = new double[] { 435.15, 64656.11 };
                streamWriter.WriteInt32(arr.Length);
                foreach (var d in arr)
                {
                    streamWriter.WriteDouble(d);
                }
            }
            streamWriter.WriteString("oiewurouqwe");
            streamWriter.WriteVariable(testArray);
            var res       = memoryStream.ToArray();
            var reference = bufferWriter.ToArray();

            CollectionAssert.AreEqual(reference, res);
        }