Example #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);
            }
        }
Example #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.");
            }
        }
Example #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);
        }
Example #4
0
        public bool HandleResponse()
        {
            if (!_outbox.CanPeek)
            {
                return(false);
            }

            var next = _outbox.Peek().Span;

            try
            {
                var message = new Message(next);
                var kind    = message.Header.MessageKind;

                // Remove client ID from message
                message.Header.ClientId = default;

                if (_requestsInProgress >= ResponseBatchSize || _responseCountInPool > 0)
                {
                    var nextResponse = _responsePool.GetSpan(next.Length);
                    next.CopyTo(nextResponse);
                    _responseCountInPool++;

                    if (_responseCountInPool >= ResponseBatchSize)
                    {
                        _socket.Send(_responsePool.Allocated());
                        _responsePool.Reset();
                        _responseCountInPool = 0;
                    }
                }
                else
                {
                    _socket.Send(next);
                }

                Interlocked.Decrement(ref _requestsInProgress);

                // Some responses trigger the termination of the controller.
                if (kind == MessageKind.CloseConnectionResponse ||
                    kind == MessageKind.ProtocolErrorResponse)
                {
                    if (kind == MessageKind.ProtocolErrorResponse)
                    {
                        var protocolResponse = new ProtocolErrorResponse(next);
                        _log?.Log(LogSeverity.Info, $"ConnectionController({ClientId}) on protocol error {protocolResponse.Status}.");
                    }

                    if (_responseCountInPool > 0)
                    {
                        _socket.Send(_responsePool.Allocated());
                        _responsePool.Reset();
                        _responseCountInPool = 0;
                    }

                    _tokenSource.Cancel();
                }
            }
            finally
            {
                _outbox.Next();
            }

            return(true);
        }