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