Пример #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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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)));
        }
Пример #11
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();
        }
Пример #12
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.
            }
        }