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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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))); }
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(); }
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. } }