Example #1
0
        public void TestGetUncommittedBlockInfo()
        {
            var uncommittedBlockId = TestOpenBlock();

            var messageAllocation = new Span <byte>(new byte[GetBlockInformation.SizeInBytes]);

            var getInfo = new GetBlockInformation(1, 5, _9);

            // Serialize message to put it into the inbox

            MessageSerializers.ClientSerializeGetBlockInformation(getInfo, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            _outbox.Next();
            var result = _outbox.Peek();

            Assert.Equal(MessageType.UncommittedBlockInfo, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeUncommittedBlockInfo(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);

            Assert.Equal(uncommittedBlockId, response.UncommittedBlockId);
            Assert.Equal(_9, response.Alias);
            Assert.Equal(_3, response.Parent);
            Assert.Equal(3, response.BlockHeight);
        }
Example #2
0
        public TempBlockId TestOpenBlock()
        {
            Setup();

            var messageAllocation = new Span <byte>(new byte[OpenBlock.SizeInBytes]);

            var openBlock = new OpenBlock(1, 5, _3);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeOpenBlock(openBlock, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result = _outbox.Peek();

            Assert.Equal(MessageType.OpenedBlock, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeOpenedBlock(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.Equal(_9, response.Alias);

            return(response.UncommittedBlockId);
        }
Example #3
0
        public void TestCommitBlock()
        {
            TestOpenBlock();

            var messageAllocation = new Span <byte>(new byte[CommitBlock.SizeInBytes]);

            var commitBlock = new CommitBlock(1, 5, _9,
                                              new BlockId(new Hash256(0xFFFFFFFFUL, 0xEEEEEEEEUL, 0xDDDDDDDDUL, 0xCCCCCCCEUL)));

            // Serialize message to put it into the inbox

            MessageSerializers.ClientSerializeCommitBlock(commitBlock, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            _outbox.Next();
            var result = _outbox.Peek();

            Assert.Equal(MessageType.EverythingOk, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeEverythingOk(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
        }
Example #4
0
        public void TestGetCommittedBlockInfo()
        {
            Setup();

            var messageAllocation = new Span <byte>(new byte[GetBlockInformation.SizeInBytes]);

            var getInfo = new GetBlockInformation(1, 5, _1);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeGetBlockInformation(getInfo, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result = _outbox.Peek();

            Assert.Equal(MessageType.CommittedBlockInfo, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeCommittedBlockInfo(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);

            Assert.Equal(BlockId.Genesis, response.BlockId);
            Assert.Equal(_1, response.Alias);
            Assert.Equal(0u, response.Parent.Value);
            Assert.Equal(0, response.BlockHeight);
        }
Example #5
0
        public void TestGetCommittedBlockHandle()
        {
            Setup();

            var messageAllocation = new Span <byte>(new byte[GetBlockHandle.SizeInBytes]);

            var getHandle =
                new GetBlockHandle(1, 5,
                                   new BlockId(new Hash256(0xFFFFFFFFUL, 0xEEEEEEEEUL, 0xDDDDDDDDUL, 0xCCCCCCCCUL)));

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeGetBlockHandle(getHandle, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result = _outbox.Peek();

            Assert.Equal(MessageType.BlockHandle, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeBlockHandleResponse(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);

            Assert.Equal(_3, response.BlockHandle);
        }
Example #6
0
        public void TestGetUncommittedBlockHandle()
        {
            var uncommitedBlockId = TestOpenBlock();

            var messageAllocation = new Span <byte>(new byte[GetUncommittedBlockHandle.SizeInBytes]);

            var getHandle = new GetUncommittedBlockHandle(1, 5, uncommitedBlockId);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeGetUncommittedBlockHandle(getHandle, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            _outbox.Next(); // because we did the TestOpenBlock in the beginning
            var result = _outbox.Peek();

            Assert.Equal(MessageType.BlockHandle, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeBlockHandleResponse(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.Equal(_9, response.BlockHandle);
        }
Example #7
0
        public void TestOpenFirstBlock()
        {
            _controller = new ControllerThread(_chain, default(OptimizedLineage), _inbox = BoundedInbox.Create(),
                                               _outbox = BoundedInbox.Create());

            var messageAllocation = new Span <byte>(new byte[OpenBlock.SizeInBytes]);

            var openBlock = new OpenBlock(1, 5, BlockAlias.GenesisParent);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeOpenBlock(openBlock, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result = _outbox.Peek();

            Assert.Equal(MessageType.OpenedBlock, ClientServerMessage.GetMessageType(result));
            var response = MessageSerializers.ClientDeserializeOpenedBlock(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.Equal(_1, response.Alias);

            var tmpId = response.UncommittedBlockId;

            Console.WriteLine(tmpId);
        }
Example #8
0
        //Метод, вытягивающий информацию о мастерах из базы данных
        private static ClientServerMessage GetMasters(ClientServerMessage request)
        {
            var masterType = (WorkType)Int32.Parse(request.Arguments["master"]);
            var args       = new Dictionary <string, string>();

            args.Add("result", "success");
            ClientServerMessage response;
            List <Employee>     mastersToSend = new List <Employee>();

            using (DbContext context = new DbContext(DbConnectionString))
            {
                var masters = context.Masters;
                if (masters != null)
                {
                    mastersToSend = masters.Where(x => x.Specialization == masterType).ToList();
                }
                if (mastersToSend == null)
                {
                    args["result"] = "failed";
                }
                else
                {
                    args.Add("masters", JsonConvert.SerializeObject(mastersToSend));
                }
            }
            response = new ClientServerMessage(args);

            return(response);
        }
Example #9
0
        public void TestClientIdField()
        {
            Span <byte> expectedAsHex = stackalloc byte[] { 0x21, 0x22, 0x23, 0x24 };
            ClientId    expected      = ClientId.ReadFrom(expectedAsHex);

            Assert.Equal(expected, ClientServerMessage.GetClientId(_bytes));
            Assert.Throws <ArgumentException>(() => ClientServerMessage.GetClientId(new Span <byte>(_bytes, 0, 11)));
        }
Example #10
0
        // TODO: [vermorel] Almost but not quite like other 'Iterator' in solution. Align designs.

        /// <summary>
        /// Provides the next unread message.
        /// </summary>
        /// <remarks>
        /// Returned span is only valid until the next call to
        /// <see cref="ReceiveNext"/>.
        /// </remarks>
        public Span <byte> ReceiveNext()
        {
            // Delete first message and copy everything else to the beginning
            var length = InputMessageLength();

            if (length > 0)
            {
                Array.Copy(_bufferIn, length, _bufferIn, 0, _endIn - length);
                _endIn -= length;
            }

            // Try to receive more data from socket
            if (IsConnected && 0 != _socket.Available() && _bufferIn.Length != _endIn)
            {
                _endIn += _socket.Receive(new Span <byte>(_bufferIn).Slice(_endIn));
            }

            length = InputMessageLength();
            if (length > 0)
            {
                var message = new Span <byte>(_bufferIn, 0, length);

                var messageStatus = PassesVerifications(message);

                if (messageStatus != MessageType.EverythingOk)
                {
                    switch (messageStatus)
                    {
                    case MessageType.ClientIdFieldNotEmpty:
                        new Span <byte>(_errorSpan).EmitClientIdFieldNotEmpty(message);
                        _socket.Send(_errorSpan);
                        // see whether a valid message is waiting in the inbox
                        return(ReceiveNext());
                    }
                }
                else // write client ID into message
                {
                    ConnectionId.WriteTo(message.Slice(8));
                }
                return(new Span <byte>(_bufferIn, 0, length));
            }
            else
            {
                return(Span <byte> .Empty);
            }

            // TODO: [vermorel] The intent of this method must be clarified.
            MessageType PassesVerifications(Span <byte> message)
            {
                // Maybe other verifications are going to be added over time
                if (message.Length >= ClientServerMessage.PayloadStart && ClientServerMessage.GetClientId(message).IsSpecified)
                {
                    return(MessageType.ClientIdFieldNotEmpty);
                }

                return(MessageType.EverythingOk);
            }
        }
Example #11
0
        public void TestSharded()
        {
            _bytes[12] = 0x85;
            Assert.True(ClientServerMessage.IsSharded(_bytes));

            _bytes[12] = 0x71;
            Assert.False(ClientServerMessage.IsSharded(_bytes));

            Assert.Throws <ArgumentException>(() => ClientServerMessage.IsSharded(new Span <byte>(_bytes, 0, 11)));
        }
Example #12
0
        public static void EmitRequestTooShort(this Span <byte> buffer, ReadOnlySpan <byte> request)
        {
            if (buffer.Length < ClientServerMessage.PayloadStart)
            {
                throw new ArgumentException($"Output buffer length {buffer.Length} too short.", nameof(buffer));
            }

            ClientServerMessage.SetHeader(
                buffer,
                length: ClientServerMessage.PayloadStart,
                id: UInt64.MaxValue, // TODO: [vermorel] Very odd. Why not 'GetId(request)'?
                isSharded: 0,
                response: MessageType.RequestTooShort);
        }
Example #13
0
        // TODO: [vermorel] Don't pass 'request', pass 'GetId(request)' instead
        public static void EmitOutBufferFull(this Span <byte> buffer, ReadOnlySpan <byte> request)
        {
            if (buffer.Length < ClientServerMessage.PayloadStart)
            {
                throw new ArgumentException($"Output buffer length {buffer.Length} too short.", nameof(buffer));
            }

            ClientServerMessage.SetHeader(
                buffer,
                length: ClientServerMessage.PayloadStart,
                id: ClientServerMessage.GetId(request),
                isSharded: 0,
                response: MessageType.OutBufferFull);
        }
Example #14
0
        // TODO: [vermorel] Method named 'listen' but actually 'remove'?. Intent to be clarified.
        public void ListenToConnections()
        {
            // TODO: [vermorel] Directly initialize, it will remove two test conditions below, perf overhead should be insignificant.
            List <ClientId> toRemove = null;

            foreach (var kv in _activeConnections)
            {
                if (!kv.Value.IsConnected)
                {
                    if (toRemove == null)
                    {
                        toRemove = new List <ClientId>();
                    }
                    toRemove.Add(kv.Key);
                    continue;
                }

                kv.Value.Send();

                // TODO: [vermorel] Almost but not quite like an iterator. Design should be aligned with other iterators.
                var nextMessage = kv.Value.ReceiveNext();
                while (nextMessage.Length != 0)
                {
                    var toWriteInto = ClientServerMessage.IsSharded(nextMessage)
                        ? _workerInboxes[
                        // TODO: [vermorel] Do not keep the shardling logic inline, isolate with a helper.
                        ClientServerMessage.FirstKeyByte(nextMessage) % _workerInboxes.Length]
                        : _controllerInbox;

                    if (!toWriteInto.TryWrite(nextMessage))
                    {
                        // TODO: [vermorel] Oddly written statement, to be rewritten.
                        new Span <byte>(_errorBuffer).EmitWorkersBusy(nextMessage);
                        kv.Value.TryWrite(_errorBuffer);
                    }

                    nextMessage = kv.Value.ReceiveNext();
                }
            }

            // Delete connections that were found unconnected
            if (toRemove != null)
            {
                foreach (var clientId in toRemove)
                {
                    _activeConnections.Remove(clientId);
                }
            }
        }
Example #15
0
        public void SendResponses()
        {
            var toSend = _outbox.Peek();

            while (toSend.Length != 0)
            {
                if (_activeConnections.TryGetValue(ClientServerMessage.GetClientId(toSend), out var client))
                {
                    client.TryWrite(toSend);
                }

                _outbox.Next();
                toSend = _outbox.Peek();
            }
        }
Example #16
0
        //Метод, добавляющий поступивший заказ в базу данных
        private static ClientServerMessage AddAppointment(ClientServerMessage request)
        {
            var appointment = JsonConvert.DeserializeObject <Appointment>(request.Arguments["appointment"]);
            var master      = JsonConvert.DeserializeObject <Employee>(request.Arguments["master"]);

            using (DbContext context = new DbContext(DbConnectionString))
            {
                int id = context.UploadAppointment(appointment);
                appointment.Id = id;
                master.Appointments.Add(appointment);
                context.UpdateMasterAppointments(master);
            }

            return(new ClientServerMessage("success;true"));
        }
Example #17
0
        public void TestIsAncestor()
        {
            Setup();

            var messageAllocation = new Span <byte>(new byte[IsAncestor.SizeInBytes]);

            var isAncestorReq = new IsAncestor(1, 5, _3, _1);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeIsAncestor(isAncestorReq, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result = _outbox.Peek();

            Assert.Equal(MessageType.AncestorResponse, ClientServerMessage.GetMessageType(result));
            Assert.True(ClientServerMessage.TryGetLength(result, out int responseSize));
            Assert.Equal(AncestorResponse.SizeInBytes, responseSize);

            var response = MessageSerializers.ClientDeserializeAncestorResponse(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.True(response.Answer);

            // get a wrong ancestor
            isAncestorReq = new IsAncestor(1, 5, _3, _5);
            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeIsAncestor(isAncestorReq, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            _outbox.Next();
            result = _outbox.Peek();
            var response2 = MessageSerializers.ClientDeserializeAncestorResponse(result);

            Assert.Equal(1U, response2.RequestId);
            Assert.Equal(5U, response2.ClientId);
            Assert.Equal(MessageType.AncestorResponse, response2.ResponseType);

            Assert.False(response2.Answer);
        }
Example #18
0
        // TODO: [vermorel] Should probably be renamed 'GetInputMessageLenght()'.
        private int InputMessageLength()
        {
            if (_endIn < sizeof(int))
            {
                return(0);
            }

            if (!ClientServerMessage.TryGetLength(_bufferIn, out var length))
            {
                // TODO: [vermorel] Pattern below is bizarelly written, to be rewritten.
                new Span <byte>(_errorSpan).EmitRequestTooShort(_bufferIn);

                if (_socket.Connected())
                {
                    _socket.Send(_errorSpan);
                    _socket.Close();
                }

                return(0);
            }

            if (length > ClientServerMessage.MaxSizeInBytes || length < ClientServerMessage.MinSizeInBytes)
            {
                // TODO: [vermorel] Pattern below is bizarelly written, to be rewritten.
                new Span <byte>(_errorSpan).EmitRequestTooLong(_bufferIn);

                if (_socket.Connected())
                {
                    _socket.Send(_errorSpan);
                    _socket.Close();
                }

                return(0);
            }

            // TODO: [vermorel] Clarify what is the edge-case here. Unclear.
            if (_endIn < length)
            {
                return(0);
            }

            return(length);
        }
Example #19
0
        public void TestIsPruneable()
        {
            Setup();

            var messageAllocation = new Span <byte>(new byte[IsPruneable.SizeInBytes]);

            var isPruneableReq = new IsPruneable(1, 5, _3);

            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeIsPruneable(isPruneableReq, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            var result   = _outbox.Peek();
            var response = MessageSerializers.ClientDeserializePruneableResponse(result);

            Assert.Equal(MessageType.PruneableResponse, ClientServerMessage.GetMessageType(result));

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.False(response.Answer);

            _outbox.Next();

            isPruneableReq = new IsPruneable(1, 5, _4);
            // Serialize message to put it into the inbox
            MessageSerializers.ClientSerializeIsPruneable(isPruneableReq, messageAllocation);

            _inbox.TryWrite(messageAllocation);

            _controller.DoWork();

            result = _outbox.Peek();
            Assert.Equal(MessageType.PruneableResponse, ClientServerMessage.GetMessageType(result));
            var response2 = MessageSerializers.ClientDeserializePruneableResponse(result);

            Assert.Equal(1U, response.RequestId);
            Assert.Equal(5U, response.ClientId);
            Assert.True(response2.Answer);
        }
Example #20
0
        //Метод получения работ определенного типа с сервера
        public List <Work> GetWorks(WorkType masterType)
        {
            string masterJson = ((int)masterType).ToString();
            string command    = "GET_MASTER_WORKS";
            Dictionary <string, string> args = new Dictionary <string, string>();

            args.Add("cmd", command);
            args.Add("master", masterJson);

            ClientServerMessage receivedMessage = SendMessage(new ClientServerMessage(args));

            if (CheckReceivedMessage(receivedMessage) && receivedMessage.Arguments.ContainsKey("works"))
            {
                return(JsonConvert.DeserializeObject <List <Work> >(receivedMessage.Arguments["works"]));
            }
            else
            {
                return(null);
            }
        }
Example #21
0
        //Метод, принимающий запрос и отдающий ответ
        public static string GetResponse(string request)
        {
            ClientServerMessage requestMessage = new ClientServerMessage(request);

            ClientServerMessage response = new ClientServerMessage(new Dictionary <string, string>()
            {
                { "result", "failed" }
            });

            //Обработка запроса в зависимости от команды, прижедшей с клиента
            switch (requestMessage.Arguments["cmd"].ToUpper())
            {
            case "GET_MASTER_WORKS": response = GetMasterWorks(requestMessage); break;

            case "GET_MASTERS": response = GetMasters(requestMessage); break;

            case "ADD_APPOINTMENT": response = AddAppointment(requestMessage); break;
            }

            return(response.Message);
        }
Example #22
0
        public void TestRequestTypes()
        {
            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.OpenBlock);
            Assert.Equal(MessageType.OpenBlock, ClientServerMessage.GetMessageType(_bytes));

            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.CommitBlock);
            Assert.Equal(MessageType.CommitBlock, ClientServerMessage.GetMessageType(_bytes));

            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.Authenticate);
            Assert.Equal(MessageType.Authenticate, ClientServerMessage.GetMessageType(_bytes));

            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.GetBlockHandle);
            Assert.Equal(MessageType.GetBlockHandle, ClientServerMessage.GetMessageType(_bytes));

            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.IsAncestor);
            Assert.Equal(MessageType.IsAncestor, ClientServerMessage.GetMessageType(_bytes));

            BitConverter.TryWriteBytes(new Span <byte>(_bytes, ClientServerMessage.MessageTypeStart, sizeof(int)), (int)MessageType.IsPruneable);
            Assert.Equal(MessageType.IsPruneable, ClientServerMessage.GetMessageType(_bytes));

            Assert.Throws <ArgumentException>(() => ClientServerMessage.GetMessageType(new Span <byte>(_bytes, 0, ClientServerMessage.PayloadStart - 1)));
        }
Example #23
0
        //Метод, вытягивающий информацию о работах, соответствующих данному типу мастера
        private static ClientServerMessage GetMasterWorks(ClientServerMessage request)
        {
            var masterType = (WorkType)Int32.Parse(request.Arguments["master"]);
            var args       = new Dictionary <string, string>();

            args.Add("result", "success");
            ClientServerMessage response;

            using (DbContext context = new DbContext(DbConnectionString))
            {
                List <Work> works = context.Works.Where(x => x.Type == masterType).ToList();
                if (works == null)
                {
                    args["result"] = "failed";
                }
                else
                {
                    args.Add("works", JsonConvert.SerializeObject(works));
                }
            }
            response = new ClientServerMessage(args);

            return(response);
        }
Example #24
0
        //Метод отправки сообщения на сервер и ожидания ответа
        private ClientServerMessage SendMessage(ClientServerMessage message)
        {
            byte[] bytes = new byte[4096];
            //Конфигурируем точку, к которой будем обращаться
            IPHostEntry ipHost     = Dns.GetHostEntry(URL);
            IPAddress   iPAddress  = ipHost.AddressList[0];
            IPEndPoint  iPEndPoint = new IPEndPoint(iPAddress, Port);
            //Открываем сокет в конечной точке и соединяемся с ним
            var sender = new Socket(iPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            sender.Connect(iPEndPoint);
            //Отправляем сообщение на сервер
            byte[] msg = Encoding.UTF8.GetBytes(message.Message);
            sender.Send(msg);
            //Принимаем сообщение с сервера
            int bytesReceived = sender.Receive(bytes);
            ClientServerMessage receivedMessage = new ClientServerMessage(Encoding.UTF8.GetString(bytes, 0, bytesReceived));

            //Закрываем соединение
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();
            //Возвращаем сообщение, полученное с сервера
            return(receivedMessage);
        }
Example #25
0
        public void FillShardedInboxes()
        {
            var queue   = new ConcurrentQueue <ClientConnection>();
            var socket  = new MockSocket();
            var client1 = new ClientConnection(socket, ClientId.Next(), 100);
            var client2 = new ClientConnection(socket, ClientId.Next(), 100);

            BoundedInbox[] threadInboxes =
            {
                BoundedInbox.Create(), BoundedInbox.Create()
            };

            var dispatcher = new Dispatcher(queue, 3, BoundedInbox.Create(),
                                            threadInboxes, BoundedInbox.Create());

            // Client1 sharded message
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => LargeMessageSize);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(LargeMessageSize).CopyTo(data);
                data[ClientServerMessage.ShardedIndStart] = 0xFF; // 0xFF: all bits set to one, so "sharded" is set to 1 for sure
                data[ClientServerMessage.PayloadStart]    = 0x01;
                return(LargeMessageSize);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            // Client2 sharded message
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => LargeMessageSize);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(LargeMessageSize).CopyTo(data);
                data[12] = 0xFF;
                return(LargeMessageSize);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            // Client1 sharded message, fills up first sharded inbox
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => LargeMessageSize);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(LargeMessageSize).CopyTo(data);
                data[ClientServerMessage.ShardedIndStart] = 0xFF; // 0xFF: all bits set to one, so "sharded" is set to 1 for sure
                data[ClientServerMessage.PayloadStart]    = 0x00;
                return(LargeMessageSize);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            // Client2 sharded message, fills up second sharded inbox
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => LargeMessageSize);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(LargeMessageSize).CopyTo(data);
                data[ClientServerMessage.ShardedIndStart] = 0xFF; // 0xFF: all bits set to one, so "sharded" is set to 1 for sure
                data[ClientServerMessage.PayloadStart]    = 0x01;
                return(LargeMessageSize);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            // Read and get error message server busy writing into second sharded inbox
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 20);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(20).CopyTo(data);
                data[ClientServerMessage.ShardedIndStart] = 0xFF;
                data[ClientServerMessage.PayloadStart]    = 0x01;
                return(20);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectSend(data =>
            {
                Assert.Equal(ClientServerMessage.PayloadStart, data.Length);
                Assert.Equal(data[13], (byte)MessageType.ServerBusy);
                return(ClientServerMessage.PayloadStart);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            // Read and get error message server busy writing into first sharded inbox
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 20);
            socket.ExpectReceive(data =>
            {
                data.Clear();
                BitConverter.GetBytes(20).CopyTo(data);
                data[ClientServerMessage.ShardedIndStart] = 0xFF; // 0xFF: all bits set to one, so "sharded" is set to 1 for sure
                data[ClientServerMessage.PayloadStart]    = 0x00;
                return(20);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectSend(data =>
            {
                Assert.Equal(ClientServerMessage.PayloadStart, data.Length);
                Assert.Equal(MessageType.ServerBusy, ClientServerMessage.GetMessageType(data));
                return(ClientServerMessage.PayloadStart);
            });
            socket.ExpectConnected(() => true);
            socket.ExpectAvailable(() => 0);

            queue.Enqueue(client1);
            queue.Enqueue(client2);
            dispatcher.DequeueNewClients();
            // Client1 into sharded inbox 1, Client2 into sharded inbox 2
            dispatcher.ListenToConnections();
            // Client1 filling up sharded inbox 2, Client2 filling up sharded inbox 1
            dispatcher.ListenToConnections();
            // Errors when trying to write into any inbox
            dispatcher.ListenToConnections();

            socket.ExpectAllDone();
        }
Example #26
0
 public void TestLengthField()
 {
     ClientServerMessage.TryGetLength(_bytes, out var length);
     Assert.Equal(0x14131211, length);
     Assert.False(ClientServerMessage.TryGetLength(new Span <byte>(_bytes, 0, 3), out length));
 }
Example #27
0
 public void TestRequestIdField()
 {
     Assert.Equal(0x18171615U, ClientServerMessage.GetRequestId(_bytes));
     Assert.Throws <ArgumentException>(() => ClientServerMessage.GetRequestId(new Span <byte>(_bytes, 0, 7)));
 }
Example #28
0
        public void DoWork()
        // TODO: [vermorel] method should return 'true' if any work has been done
        {
            var nextMessage = _inbox.Peek();

            if (nextMessage.Length != 0)
            {
                // get message type and deserialize accordingly
                var reqType = ClientServerMessage.GetMessageType(nextMessage);
                switch (reqType)
                {
// TODO: [vermorel] I don't like to too much the code below, it's highly repetitive, factorization is needed.

                case MessageType.OpenBlock:
                    var openBlock = MessageSerializers.DeserializeOpenBlock(nextMessage);
                    UncommittedBlock block;
                    if (openBlock.ParentHandle == BlockAlias.GenesisParent && _chain.BlockchainLength == 0)
                    {
                        block = _chain.OpenFirstBlock();
                    }
                    else
                    {
                        block = _chain.OpenBlock(openBlock.ParentHandle);
                    }
                    var blockHandle =
                        new OpenedBlock(openBlock.RequestId, openBlock.ClientId, block.BlockId, block.Alias);
                    MessageSerializers.SerializeOpenedBlock(blockHandle, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, OpenedBlock.SizeInBytes));
                    break;

                case MessageType.GetBlockHandle:
                    var getBlockHandle  = MessageSerializers.DeserializeGetBlockHandle(nextMessage);
                    var retrievedHandle = _chain.RetrieveAlias(getBlockHandle.BlockId);
                    var returnMessage   = new BlockHandleResponse(getBlockHandle.RequestId, getBlockHandle.ClientId,
                                                                  retrievedHandle);
                    MessageSerializers.SerializeBlockHandleResponse(returnMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, BlockHandleResponse.SizeInBytes));
                    break;

                case MessageType.GetUncommittedBlockHandle:
                    var getUBlockHandle  = MessageSerializers.DeserializeGetUncommittedBlockHandle(nextMessage);
                    var retrievedUHandle = _chain.RetrieveAlias(getUBlockHandle.UncommittedBlockId);
                    var returnMes        = new BlockHandleResponse(getUBlockHandle.RequestId, getUBlockHandle.ClientId,
                                                                   retrievedUHandle);
                    MessageSerializers.SerializeBlockHandleResponse(returnMes, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, BlockHandleResponse.SizeInBytes));
                    break;

                case MessageType.CommitBlock:
                    var commitBlock = MessageSerializers.DeserializeCommitBlock(nextMessage);
                    _chain.CommitBlock(commitBlock.BlockHandle, commitBlock.BlockId);
                    var committedMessage =
                        new EverythingOkResponse(commitBlock.RequestId, commitBlock.ClientId);
                    MessageSerializers.SerializeEverythingOk(committedMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, EverythingOkResponse.SizeInBytes));
                    break;

                case MessageType.IsAncestor:
                    var isAncestor        = MessageSerializers.DeserializeIsAncestor(nextMessage);
                    var res               = _opti.IsAncestor(isAncestor.BlockHandle, isAncestor.MaybeAncestorHandle);
                    var isAncestorMessage = new AncestorResponse(isAncestor.RequestId, isAncestor.ClientId, res);
                    MessageSerializers.SerializeAncestorResponse(isAncestorMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, AncestorResponse.SizeInBytes));
                    break;

                case MessageType.IsPruneable:
                    var isPruneable        = MessageSerializers.DeserializeIsPruneable(nextMessage);
                    var result             = _opti.IsPruneable(isPruneable.BlockHandle);
                    var isPruneableMessage = new PruneableResponse(isPruneable.RequestId, isPruneable.ClientId, result);
                    MessageSerializers.SerializePruneableResponse(isPruneableMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, PruneableResponse.SizeInBytes));
                    break;

                case MessageType.GetBlockInfo:
                    var blockInfoReq = MessageSerializers.DeserializeGetBlockInfo(nextMessage);

                    // TODO: [vermorel] clarify the purpose of this test, unclear
                    if (_chain.RetrieveCommittedBlock(blockInfoReq.BlockHandle, out var blockInfoC))
                    {
                        var blockInfo =
                            new CommittedBlockInformation(blockInfoReq.RequestId, blockInfoReq.ClientId,
                                                          blockInfoC.BlockId, blockInfoC.Alias, blockInfoC.BlockHeight, blockInfoC.Parent);
                        MessageSerializers.SerializeCommittedBlockInfo(blockInfo, _responseBuffer);
                        _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, CommittedBlockInformation.SizeInBytes));
                        break;
                    }
                    else
                    {
                        _chain.RetrieveUncommittedBlock(blockInfoReq.BlockHandle, out var blockInfoU);
                        var blockInfo =
                            new UncommittedBlockInformation(blockInfoReq.RequestId, blockInfoReq.ClientId,
                                                            blockInfoU.BlockId, blockInfoU.Alias, blockInfoU.BlockHeight, blockInfoU.Parent);
                        MessageSerializers.SerializeUncommittedBlockInfo(blockInfo, _responseBuffer);
                        _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, UncommittedBlockInformation.SizeInBytes));
                        break;
                    }

// TODO: [vermorel] the 'default:' case should be covered with an NotSupportedException.
                }
                _inbox.Next();
                // TODO: errors are not yet handled.
            }
        }
Example #29
0
 public void TestFirstKeyByte()
 {
     Assert.Equal(_bytes[ClientServerMessage.PayloadStart], ClientServerMessage.FirstKeyByte(_bytes));
     Assert.Throws <ArgumentException>(() => ClientServerMessage.FirstKeyByte(new Span <byte>(_bytes, 0, ClientServerMessage.PayloadStart)));
 }
Example #30
0
 //Проверка сообщения на присутствие аргумента result в значении success
 private bool CheckReceivedMessage(ClientServerMessage message)
 {
     return(message.Arguments.ContainsKey("result") && message.Arguments["result"] == "success");
 }