Ejemplo n.º 1
0
        private static void EnsureGenesisExists(ISocketLike socket)
        {
            var openGenesisRequest = OpenBlockRequest.ForGenesis(RequestId.MinRequestId);

            socket.Send(openGenesisRequest.Span);

            var openGenesisResponse = new OpenBlockResponse(new byte[OpenBlockResponse.SizeInBytes]);

            socket.Receive(openGenesisResponse.Span);

            if (openGenesisResponse.Status == OpenBlockStatus.Success)
            {
                var commitGenesisRequest = CommitBlockRequest.From(
                    RequestId.MinRequestId, ClientId.MinClientId, openGenesisResponse.Handle, CommittedBlockId.Genesis);
                socket.Send(commitGenesisRequest.Span);

                var commitGenesisResponse = new CommitBlockResponse(new byte[CommitBlockResponse.SizeInBytes]);
                socket.Receive(commitGenesisResponse.Span);
            }
        }
Ejemplo n.º 2
0
        private static void CommitBlock(BlockHandle handle, CommittedBlockId blockId, ISocketLike socket)
        {
            var request = CommitBlockRequest.From(
                RequestId.MinRequestId, ClientId.MinClientId, handle, blockId);

            socket.Send(request.Span);

            var response = new CommitBlockResponse(new byte[CommitBlockResponse.SizeInBytes]);

            socket.Receive(response.Span);

            if (response.Status != CommitBlockStatus.Success)
            {
                throw new InvalidOperationException("Failed to commit block.");
            }
        }
Ejemplo n.º 3
0
        private static BlockHandle OpenBlock(CommittedBlockId parentId, ISocketLike socket, ILog log)
        {
            var openBlockRequest = OpenBlockRequest.From(
                RequestId.MinRequestId, ClientId.MinClientId, parentId);

            socket.Send(openBlockRequest.Span);

            var openBlockResponse = new OpenBlockResponse(new byte[OpenBlockResponse.SizeInBytes]);

            socket.Receive(openBlockResponse.Span);

            if (openBlockResponse.Status != OpenBlockStatus.Success)
            {
                throw new InvalidOperationException("Failed to open block.");
            }

            log.Log(LogSeverity.Info, "Block opened, writing coins...");

            return(openBlockResponse.Handle);
        }
Ejemplo n.º 4
0
        public bool HandleRequest()
        {
            // Blocking until header is received.
            _socket.Receive(new Span <byte>(_bufferIn, 0, MessageHeader.SizeInBytes));

            var message = new Message(_bufferIn);

            // Request too short
            if (message.SizeInBytes <= MessageHeader.SizeInBytes)
            {
                Span <byte> errorBuffer  = stackalloc byte[ProtocolErrorResponse.SizeInBytes];
                var         errorMessage = new ProtocolErrorResponse(errorBuffer,
                                                                     RequestId.MinRequestId, ClientId.MinClientId, ProtocolErrorStatus.RequestTooShort);

                Send(errorMessage.Span);
                return(false);
            }

            var kind      = message.Header.MessageKind;
            var requestId = message.Header.RequestId;


            // Request too long
            if (message.SizeInBytes >= Constants.MaxRequestSize)
            {
                Span <byte> errorBuffer  = stackalloc byte[ProtocolErrorResponse.SizeInBytes];
                var         errorMessage = new ProtocolErrorResponse(errorBuffer,
                                                                     requestId, ClientId.MinClientId, ProtocolErrorStatus.RequestTooLong);

                Send(errorMessage.Span);
                return(false);
            }

            // Invalid message kind
            if (!kind.IsDefined() || kind.IsResponse())
            {
                // Unknown kind is invalid.
                // Response kind is invalid.
                Span <byte> buffer       = stackalloc byte[ProtocolErrorResponse.SizeInBytes];
                var         errorMessage = new ProtocolErrorResponse(
                    buffer, requestId, ClientId.MinClientId, ProtocolErrorStatus.InvalidMessageKind);

                Send(errorMessage.Span);
                return(false);
            }

            // Blocking until the rest of the message is received.
            _socket.Receive(new Span <byte>(_bufferIn,
                                            MessageHeader.SizeInBytes,
                                            message.SizeInBytes - MessageHeader.SizeInBytes));

            message.Header.ClientId = _clientId;

            // Client request to close the connection.
            if (message.Header.MessageKind == MessageKind.CloseConnection)
            {
                Span <byte> buffer        = stackalloc byte[CloseConnectionResponse.SizeInBytes];
                var         closeResponse = new CloseConnectionResponse(buffer, requestId, ClientId.MinClientId);

                _outbox.TryWrite(closeResponse.Span);
            }

            // Forwards the message to the dispatch controller.
            if (_dispatchInbox.TryWrite(message.Span))
            {
                Interlocked.Increment(ref _requestsInProgress);
                return(true);
            }

            //  The dispatch inbox is full.
            {
                Span <byte> errorBuffer  = stackalloc byte[ProtocolErrorResponse.SizeInBytes];
                var         errorMessage = new ProtocolErrorResponse(errorBuffer,
                                                                     requestId, ClientId.MinClientId, ProtocolErrorStatus.ServerBusy);

                Send(errorMessage.Span);
            }

            return(false);
        }