예제 #1
0
        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();
        }
예제 #2
0
        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();
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        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.
        }
예제 #6
0
        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);
        }
예제 #7
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
                }
            }
        }
예제 #8
0
        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();
        }
예제 #9
0
        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();
        }
예제 #10
0
        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();
        }
예제 #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 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();
        }
예제 #13
0
 public ClientConnectionTests()
 {
     Socket = new MockSocket();
     _cc    = new ClientConnection(Socket, ClientId.Next(), 4000);
 }
예제 #14
0
        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();
        }
    }
예제 #15
0
        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();
        }
예제 #16
0
        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);
        }