public void QueueTooManyClients() { var queue = new ConcurrentQueue <ClientConnection>(); var socket = new MockSocket(); var client0 = new ClientConnection(socket, ClientId.Next(), 100); var client1 = new ClientConnection(socket, ClientId.Next(), 100); var client2 = new ClientConnection(socket, ClientId.Next(), 100); var client3 = new ClientConnection(socket, ClientId.Next(), 100); socket.ExpectConnected(() => true); socket.ExpectSend(data => { Console.WriteLine(BitConverter.ToString(data.ToArray())); Console.WriteLine(BitConverter.ToString(MessageCreationHelper.NoMoreSpaceForClientsMessage)); Assert.Equal(MessageCreationHelper.NoMoreSpaceForClientsMessage, data.ToArray()); return(data.Length); }); socket.ExpectClose(); var dispatcher = new Dispatcher(queue, 3, BoundedInbox.Create(), new BoundedInbox[64], BoundedInbox.Create()); queue.Enqueue(client0); queue.Enqueue(client1); queue.Enqueue(client2); queue.Enqueue(client3); dispatcher.DequeueNewClients(); socket.ExpectAllDone(); }
public void RemoveDeadClients() { var queue = new ConcurrentQueue <ClientConnection>(); var socket = new MockSocket(); var client = new ClientConnection(socket, ClientId.Next(), 100); // First normal loop socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Second loop where client is disconnected and therefore deleted socket.ExpectConnected(() => false); // No actions for the third loop which should be empty var dispatcher = new Dispatcher(queue, 3, BoundedInbox.Create(), new BoundedInbox[64], BoundedInbox.Create()); queue.Enqueue(client); dispatcher.DequeueNewClients(); // Normal listen (nothing happens though) dispatcher.ListenToConnections(); // Client is disconnected dispatcher.ListenToConnections(); // Empty loop dispatcher.ListenToConnections(); socket.ExpectAllDone(); }
public void RemoveDeadClients() { var socket = new MockSocket(); var dispatcherInbox = new BoundedInbox(); var client = new ConnectionController(dispatcherInbox, socket, ClientId.Next()); client.OnRequestReceived = () => { }; socket.ExpectConnected(() => false); var dispatcher = new DispatchController(dispatcherInbox, new BoundedInbox(), new BoundedInbox[4], new IdentityHash()); dispatcher.OnConnectionAccepted = (_) => { }; dispatcher.AddConnection(client); dispatcher.HandleNewConnection(); var firstMessage = new byte[100]; var message = new Message(firstMessage); message.Header.ClientId = client.ClientId; message.Header.MessageSizeInBytes = 100; message.Header.MessageKind = MessageKind.CloseConnection; Assert.True(dispatcherInbox.TryWrite(firstMessage)); dispatcher.HandleRequest(); socket.ExpectAllDone(); }
public Pipe RegisterClient(IDataClient client) { var id = ClientId.Next(); Logger.Log("Registering new client with id {0}", id); var pipe = new Pipe(id, this); var result = _clients.TryAdd(id, client); Debug.Assert(result); result = _pipes.TryAdd(id, pipe); Debug.Assert(result); client.Start(); return(pipe); }
public void Setup() { var sharedInboxDispatcherController = BoundedInbox.Create(); var sharedOutboxDispatcherController = BoundedInbox.Create(); var clientQueue = new ConcurrentQueue <ClientConnection>(); _dispatcher = new Dispatcher(clientQueue, 3, sharedOutboxDispatcherController, new BoundedInbox[4], sharedInboxDispatcherController); _chain = new SimpleBlockchain(); _controllerThread = new ControllerThread(_chain, default(OptimizedLineage), sharedInboxDispatcherController, sharedOutboxDispatcherController); _clientConn = new ClientConnection(_socket, ClientId.Next(), ClientServerMessage.MaxSizeInBytes); clientQueue.Enqueue(_clientConn); _dispatcher.DequeueNewClients(); // TODO there should really be three threads, one for each component. However, I do not know how to test this. }
public void Setup() { var dispatchInbox = new BoundedInbox(); var chainInbox = new BoundedInbox(); var coinInboxes = new BoundedInbox[ShardCount]; for (var i = 0; i < coinInboxes.Length; i++) { coinInboxes[i] = new BoundedInbox(); } _dispatcher = new DispatchController( dispatchInbox, chainInbox, coinInboxes, new IdentityHash()); // Configure the wake-up callbacks to do nothing. _dispatcher.OnBlockMessageDispatched = () => { }; for (var i = 0; i < _dispatcher.OnCoinMessageDispatched.Length; i++) { _dispatcher.OnCoinMessageDispatched[i] = () => { } } ; _store = new VolatileChainStore(); _chainController = new ChainController( _store, chainInbox, dispatchInbox, lineage => { }); var c1 = ClientId.Next(); _clientConn = new ConnectionController(dispatchInbox, _socket, c1); _handleMask = c1.Mask; _dispatcher.AddConnection(_clientConn); _dispatcher.OnConnectionAccepted = _ => { }; _dispatcher.HandleNewConnection(); _c0 = new ClientId(0); }
public void Listen(CancellationToken cancel) { // TODO: [vermorel] Use a 'ConnectionId' instead. cancel.Register(() => _listener.Close()); while (!cancel.IsCancellationRequested) { try { var s = _listener.Accept(); _queue.Append(new ClientConnection(s, ClientId.Next(), _bufferOutLength)); } catch { // TODO: [vermorel] We must log exceptions here. // TODO: [vermorel] In debug mode, I would still suggest to crash the server. // An exception is not allowed to kill the accept loop } } }
public void QueueTooManyClients() { var socket = new MockSocket(); var dispatcherInbox = new BoundedInbox(); var dispatcher = new DispatchController(dispatcherInbox, new BoundedInbox(), new BoundedInbox[64], new IdentityHash()); dispatcher.OnConnectionAccepted = (_) => { }; for (var i = 0; i < Constants.MaxActiveConnections; i++) { var client0 = new ConnectionController(dispatcherInbox, socket, ClientId.Next()); client0.OnRequestReceived = () => { }; dispatcher.AddConnection(client0); dispatcher.HandleNewConnection(); } var client1 = new ConnectionController(dispatcherInbox, socket, ClientId.Next()); client1.OnRequestReceived = () => { }; socket.ExpectSend(data => { Assert.Equal(ProtocolErrorResponse.SizeInBytes, data.Length); var errorMessage = new ProtocolErrorResponse(data); Assert.Equal(MessageKind.ProtocolErrorResponse, errorMessage.MessageHeader.MessageKind); Assert.Equal(ProtocolErrorStatus.TooManyActiveClients, errorMessage.Status); return(data.Length); }); dispatcher.AddConnection(client1); dispatcher.HandleNewConnection(); client1.HandleResponse(); socket.ExpectAllDone(); }
public void ReadMultipleMessagesFromClient() { 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); var dispatcher = new Dispatcher(queue, 3, BoundedInbox.Create(), new BoundedInbox[2], BoundedInbox.Create()); // Client1 messages socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 600); socket.ExpectReceive(data => { data.Clear(); // Three messages, of sizes 200, 300 and 100 BitConverter.GetBytes(200).CopyTo(data); BitConverter.GetBytes(300).CopyTo(data.Slice(200)); BitConverter.GetBytes(100).CopyTo(data.Slice(500)); return(600); }); // Reading second message socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Reading third message socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Exiting loop socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Client2 messages socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 100); socket.ExpectReceive(data => { data.Clear(); BitConverter.GetBytes(70).CopyTo(data); BitConverter.GetBytes(30).CopyTo(data.Slice(70)); return(100); }); // Reading second message socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Exiting loop socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Some more messages for Client1 socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 60); socket.ExpectReceive(data => { data.Clear(); // Two messages, of sizes 10 and 40 BitConverter.GetBytes(25).CopyTo(data); BitConverter.GetBytes(35).CopyTo(data.Slice(25)); return(60); }); // Reading second message socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Exiting loop socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // No more messages for Client2 socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); queue.Enqueue(client1); queue.Enqueue(client2); dispatcher.DequeueNewClients(); // Client1 reading 3 messages, Client2 two dispatcher.ListenToConnections(); // Client1 reading 2 more messages, Client2 none dispatcher.ListenToConnections(); socket.ExpectAllDone(); }
public void SendAnswers() { var queue = new ConcurrentQueue <ClientConnection>(); var socket = new MockSocket(); var outbox = BoundedInbox.Create(); var client1 = new ClientConnection(socket, ClientId.Next(), 100); var client2 = new ClientConnection(socket, ClientId.Next(), 100); queue.Enqueue(client1); queue.Enqueue(client2); var dispatcher = new Dispatcher(queue, 3, outbox, new BoundedInbox[2], BoundedInbox.Create()); // Try sending message to one client, doesn't succeed socket.ExpectConnected(() => true); socket.ExpectSend(data => 0); // Try sending message to the other client, doesn't succeed socket.ExpectConnected(() => true); socket.ExpectSend(data => 0); // Try sending message to first client, socket gets closed socket.ExpectConnected(() => true); socket.ExpectClose(); // Try sending message to second client, socket gets closed socket.ExpectConnected(() => true); socket.ExpectClose(); var firstMessage = new byte[100]; BitConverter.GetBytes(100).CopyTo(new Span <byte>(firstMessage)); client2.ConnectionId.WriteTo( // send back to client2 firstMessage.AsSpan(ClientServerMessage.ClientIdStart, ClientServerMessage.ClientIdSizeInBytes)); var secondMessage = new byte[100]; BitConverter.GetBytes(100).CopyTo(new Span <byte>(secondMessage)); client1.ConnectionId.WriteTo( // send back to client1 secondMessage.AsSpan(ClientServerMessage.ClientIdStart, ClientServerMessage.ClientIdSizeInBytes)); var thirdMessage = new byte[50]; BitConverter.GetBytes(50).CopyTo(new Span <byte>(thirdMessage)); client1.ConnectionId.WriteTo( // send back to client1 thirdMessage.AsSpan(ClientServerMessage.ClientIdStart, ClientServerMessage.ClientIdSizeInBytes)); var fourthMessage = new byte[50]; BitConverter.GetBytes(50).CopyTo(new Span <byte>(fourthMessage)); client2.ConnectionId.WriteTo( // send back to client2 fourthMessage.AsSpan(ClientServerMessage.ClientIdStart, ClientServerMessage.ClientIdSizeInBytes)); // Write messages into dispatcher buffer for both clients Assert.True(outbox.TryWrite(firstMessage)); Assert.True(outbox.TryWrite(secondMessage)); dispatcher.DequeueNewClients(); // Try sending the answers, fails dispatcher.SendResponses(); Assert.True(outbox.TryWrite(thirdMessage)); Assert.True(outbox.TryWrite(fourthMessage)); dispatcher.SendResponses(); socket.ExpectAllDone(); }
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 FillControllerInbox() { 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); // Client1 empty inbox socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Client2 unsharded message socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => LargeMessageSize); socket.ExpectReceive(data => { data.Clear(); BitConverter.GetBytes(LargeMessageSize).CopyTo(data); return(LargeMessageSize); }); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Client1 unsharded message, fills up ControllerInbox socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => LargeMessageSize); socket.ExpectReceive(data => { data.Clear(); BitConverter.GetBytes(LargeMessageSize).CopyTo(data); return(LargeMessageSize); }); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); // Client2 unsharded message, gets BufferFull response socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => ClientServerMessage.PayloadStart); // minimal valid message size socket.ExpectReceive(data => { data.Clear(); BitConverter.GetBytes(ClientServerMessage.PayloadStart).CopyTo(data); return(ClientServerMessage.PayloadStart); }); socket.ExpectConnected(() => true); socket.ExpectSend(data => { Assert.Equal(ClientServerMessage.PayloadStart, data.Length); Assert.Equal(data[13], (int)MessageType.ServerBusy); return(ClientServerMessage.PayloadStart); }); socket.ExpectConnected(() => true); socket.ExpectAvailable(() => 0); var dispatcher = new Dispatcher(queue, 3, BoundedInbox.Create(), new BoundedInbox[64], BoundedInbox.Create()); queue.Enqueue(client1); queue.Enqueue(client2); dispatcher.DequeueNewClients(); // Client1 empty inbox, Client2 LargeMessageSize bytes unsharded dispatcher.ListenToConnections(); // Client1 LargeMessageSize bytes unsharded, Client2 10 bytes, error message dispatcher.ListenToConnections(); socket.ExpectAllDone(); }
public ClientConnectionTests() { Socket = new MockSocket(); _cc = new ClientConnection(Socket, ClientId.Next(), 4000); }
public void SendAnswers() { var dispatcherInbox = new BoundedInbox(); var socket1 = new MockSocket(); var socket2 = new MockSocket(); var client1 = new ConnectionController(dispatcherInbox, socket1, ClientId.Next()); var client2 = new ConnectionController(dispatcherInbox, socket2, ClientId.Next()); client1.OnRequestReceived = () => { }; client2.OnRequestReceived = () => { }; var dispatcher = new DispatchController(dispatcherInbox, new BoundedInbox(), new BoundedInbox[2], new IdentityHash()); // Nil handling of notifications dispatcher.OnBlockMessageDispatched = () => { }; for (var i = 0; i < dispatcher.OnCoinMessageDispatched.Length; i++) { dispatcher.OnCoinMessageDispatched[i] = () => { } } ; dispatcher.OnConnectionAccepted = (_) => { }; var firstMessage = new byte[Constants.MaxRequestSize]; var message = new Message(firstMessage); message.Header.ClientId = client2.ClientId; message.Header.MessageSizeInBytes = Constants.MaxRequestSize; message.Header.MessageKind = MessageKind.GetCoinResponse; var secondMessage = new byte[Constants.MaxRequestSize]; message = new Message(secondMessage); message.Header.ClientId = client1.ClientId; message.Header.MessageSizeInBytes = Constants.MaxRequestSize; message.Header.MessageKind = MessageKind.GetCoinResponse; var thirdMessage = new byte[50]; message = new Message(thirdMessage); message.Header.ClientId = client1.ClientId; message.Header.MessageSizeInBytes = 50; message.Header.MessageKind = MessageKind.GetCoinResponse; var fourthMessage = new byte[50]; message = new Message(fourthMessage); message.Header.ClientId = client2.ClientId; message.Header.MessageSizeInBytes = 50; message.Header.MessageKind = MessageKind.GetCoinResponse; dispatcher.AddConnection(client1); dispatcher.AddConnection(client2); dispatcher.HandleNewConnection(); dispatcher.HandleNewConnection(); // Write messages into dispatcher buffer for both clients for (var i = 0; i < Constants.SocketSendBufferSize / Constants.MaxRequestSize; i++) { socket1.ExpectConnected(() => true); socket2.ExpectConnected(() => true); Assert.True(dispatcherInbox.TryWrite(firstMessage)); Assert.True(dispatcherInbox.TryWrite(secondMessage)); // Try sending the answers, fails dispatcher.HandleRequest(); dispatcher.HandleRequest(); } // Try sending message to first client, socket gets closed socket1.ExpectConnected(() => true); socket1.ExpectClose(); // Try sending message to second client, socket gets closed socket2.ExpectConnected(() => true); socket2.ExpectClose(); Assert.True(dispatcherInbox.TryWrite(thirdMessage)); Assert.True(dispatcherInbox.TryWrite(fourthMessage)); dispatcher.HandleRequest(); dispatcher.HandleRequest(); socket1.ExpectAllDone(); socket2.ExpectAllDone(); } }
public void FillChainControllerInbox() { var socket1 = new MockSocket(); var socket2 = new MockSocket(); var dispatcherInbox = new BoundedInbox(); var client1 = new ConnectionController(dispatcherInbox, socket1, ClientId.Next()); var client2 = new ConnectionController(dispatcherInbox, socket2, ClientId.Next()); client1.OnRequestReceived = () => { }; client2.OnRequestReceived = () => { }; Func <int, int, MockSocket.SpanToInt> func = (s1, s2) => { return(data => { data.Clear(); BinaryPrimitives.TryWriteInt32LittleEndian(data, s1); // TODO: [vermorel] PingChainController has been removed, logic need to be upgraded. //MessageKind.PingChainController.WriteTo(data.Slice(MessageHeaderHelper.MessageKindStart)); return s2; }); }; socket2.ExpectReceive(func(LargeMessageSize, MessageHeader.SizeInBytes)); socket2.ExpectReceive(func(LargeMessageSize, LargeMessageSize)); socket1.ExpectReceive(func(LargeMessageSize, MessageHeader.SizeInBytes)); socket1.ExpectReceive(func(LargeMessageSize, LargeMessageSize)); // request too short var bodyStart = sizeof(int) + RequestId.SizeInBytes + ClientId.SizeInBytes + sizeof(MessageKind); socket2.ExpectReceive(func(bodyStart, bodyStart)); socket2.ExpectSend(data => { Assert.Equal(ProtocolErrorResponse.SizeInBytes, data.Length); var message = new ProtocolErrorResponse(data); Assert.Equal(MessageKind.ProtocolErrorResponse, message.MessageHeader.MessageKind); Assert.Equal(ProtocolErrorStatus.RequestTooShort, message.Status); return(ProtocolErrorResponse.SizeInBytes); }); socket2.ExpectConnected(() => true); socket1.ExpectConnected(() => true); var dispatcher = new DispatchController(dispatcherInbox, new BoundedInbox(Constants.MaxResponseSize), Enumerable.Range(0, 32).Select(x => new BoundedInbox()).ToArray(), new IdentityHash()); // Nil handling of notifications dispatcher.OnBlockMessageDispatched = () => { }; for (var i = 0; i < dispatcher.OnCoinMessageDispatched.Length; i++) { dispatcher.OnCoinMessageDispatched[i] = () => { } } ; dispatcher.OnConnectionAccepted = (_) => { }; dispatcher.AddConnection(client1); dispatcher.AddConnection(client2); dispatcher.HandleNewConnection(); dispatcher.HandleNewConnection(); client1.HandleRequest(); client2.HandleRequest(); client2.HandleRequest(); client2.HandleResponse(); dispatcher.HandleRequest(); dispatcher.HandleRequest(); dispatcher.HandleRequest(); socket1.ExpectAllDone(); socket2.ExpectAllDone(); }
public (IChainStore, BoundedInbox, BoundedInbox, ChainController, ClientId) Setup(int pruneLimit = 100) { var store = new VolatileChainStore(); store.BlockPruneLimitDistance = pruneLimit; Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(CommittedBlockId.GenesisParent, out var openedBlock)); var id = openedBlock.Alias; Assert.NotEqual(BlockAlias.GenesisParent, id); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(id, CommittedBlockId.Genesis, out _)); // C(0) Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(CommittedBlockId.Genesis, out var cb1)); Assert.Equal(_1, cb1.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb1.Alias, _id_1, out _)); // C(0) -> C(1) Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_1, out var cb2)); Assert.Equal(_2, cb2.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb2.Alias, _id_2, out _)); // C(0) -> C(1) -> C(2) // Second child for block 2 Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_1, out var cb3)); Assert.Equal(_2_1, cb3.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb3.Alias, _id_2_1, out _)); // C(0) -> C(1) -> C(2) // \-> C(2-1) // main chain prolonged Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_2, out var cb4)); Assert.Equal(_3, cb4.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb4.Alias, _id_3, out _)); // C(0) -> C(1) -> C(2) -> C(3) // \-> C(2-1) // side chain prolonged Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_2_1, out var cb5)); // the new assert Assert.Equal(_3_1, cb5.Alias); // the new assert Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb5.Alias, _id_3_1, out _)); // C(0) -> C(1) -> C(2) -> C(3) // \-> C(2-1) -> C(3-1) // fork on end of main chain Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_3, out var cb6)); Assert.Equal(_4_0, cb6.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb6.Alias, _id_4_0, out _)); Assert.Equal(OpenBlockStatus.Success, store.TryOpenBlock(_id_3, out var cb7)); Assert.Equal(_4_1, cb7.Alias); Assert.Equal(CommitBlockStatus.Success, store.TryCommitBlock(cb7.Alias, _id_4_1, out _)); // C(0) -> C(1) -> C(2) -> C(3) -> C(4) // | \-> C(4-1) // \-> C(2-1) -> C(3-1) var inbox = new BoundedInbox(); var outbox = new BoundedInbox(); var chainController = new ChainController( store, inbox, outbox, lineage => { }); ClientId.Next(); ClientId.Next(); ClientId.Next(); ClientId.Next(); var c5 = ClientId.Next(); return(store, inbox, outbox, chainController, c5); }