public async Task AuditorStateTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { Global.AppState.State = ApplicationState.Rising; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new AuditorState { PendingQuanta = new List <MessageEnvelope>(), State = ApplicationState.Running }.CreateEnvelope(); envelope.Sign(clientKeyPair); await AssertMessageHandling(clientConnection, envelope, excpectedException); if (excpectedException == null) { Assert.AreEqual(Global.AppState.State, ApplicationState.Running); } }
static async Task UnsubscribeAndClose(AlphaWebSocketConnection connection) { Unsubscribe(connection); await connection.CloseConnection(); logger.Trace($"{connection.ClientPubKey} is disconnected."); }
public override Task HandleMessage(AlphaWebSocketConnection connection, IncomingMessage message) { //run it in the separate thread to avoid blocking quanta handling Task.Factory.StartNew(async() => { try { ResultMessage result; try { var request = message.Envelope.Message as EffectsRequest; var effectsResponse = await connection.Context.PersistenceManager.LoadEffects(request.Cursor, request.IsDesc, request.Limit, request.Account); effectsResponse.OriginalMessage = message.Envelope; effectsResponse.Effects = new List <Effect>(); effectsResponse.Status = ResultStatusCodes.Success; result = effectsResponse; } catch (Exception exc) { result = message.Envelope.CreateResult(exc.GetStatusCode()); } await connection.SendMessage(result); } catch (Exception exc) { logger.Error(exc, "Error on sending effects."); } }); return(Task.CompletedTask); }
public async Task AuditorPerfStatisticsTest() { var auditorPerf = new AuditorPerfStatistics { BatchInfos = new List <Models.BatchSavedInfo>(), QuantaPerSecond = 1, QuantaQueueLength = 2, UpdateDate = DateTime.UtcNow.Ticks }; var envelope = auditorPerf.CreateEnvelope(); envelope.Sign(TestEnvironment.Auditor1KeyPair); var auditorConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = TestEnvironment.Auditor1KeyPair }; using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); await AssertMessageHandling(auditorConnection, inMessage, null); }
public async Task AuditorStateTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { context.AppState.State = ApplicationState.Rising; var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new AuditorState { PendingQuanta = new List <MessageEnvelope>(), State = ApplicationState.Running }.CreateEnvelope(); envelope.Sign(clientKeyPair); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); await AssertMessageHandling(clientConnection, inMessage, excpectedException); if (excpectedException == null) { Assert.AreEqual(context.AppState.State, ApplicationState.Running); } }
public async Task HandshakeTest(KeyPair clientKeyPair, ApplicationState alphaState, Type expectedException) { Global.AppState.State = alphaState; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1"); var message = new HandshakeInit { HandshakeData = clientConnection.HandshakeData }; var envelope = message.CreateEnvelope(); envelope.Sign(clientKeyPair); if (expectedException == null) { var isHandled = await MessageHandlers <AlphaWebSocketConnection> .HandleMessage(clientConnection, envelope); Assert.IsTrue(isHandled); Assert.AreEqual(clientConnection.ClientPubKey, new RawPubKey(clientKeyPair.AccountId)); if (clientConnection.ClientPubKey.Equals((RawPubKey)TestEnvironment.Auditor1KeyPair)) { Assert.AreEqual(clientConnection.ConnectionState, ConnectionState.Validated); } else { Assert.AreEqual(clientConnection.ConnectionState, ConnectionState.Ready); } } else { Assert.ThrowsAsync(expectedException, async() => await MessageHandlers <AlphaWebSocketConnection> .HandleMessage(clientConnection, envelope)); } }
private static void EnsureAuditorConnected(AlphaWebSocketConnection connection) { if (Global.Constellation.Auditors.Contains(connection.ClientPubKey)) { AlphaStateManager.AuditorConnected(connection.ClientPubKey); logger.Trace($"Auditor {connection.ClientPubKey} is connected."); } }
public override Task HandleMessage(AlphaWebSocketConnection connection, IncomingMessage message) { var auditor = connection.ClientKPAccountId; var statistics = (AuditorPerfStatistics)message.Envelope.Message; var alphaPerfManager = (AlphaPerformanceStatisticsManager)Context.PerformanceStatisticsManager; _ = Task.Factory.StartNew(() => alphaPerfManager.AddAuditorStatistics(auditor, statistics)); return(Task.CompletedTask); }
//TODO: run result aggregation in separate thread public override Task HandleMessage(AlphaWebSocketConnection connection, MessageEnvelope envelope) { var resultsBatch = (AuditorResultsBatch)envelope.Message; foreach (var result in resultsBatch.AuditorResultMessages) { Global.AuditResultManager.Add(result, connection.ClientPubKey); } return(Task.CompletedTask); }
//TODO: run result aggregation in separate thread public override Task HandleMessage(AlphaWebSocketConnection connection, IncomingMessage message) { var resultsBatch = (AuditorResultsBatch)message.Envelope.Message; foreach (var result in resultsBatch.AuditorResultMessages) { Context.AuditResultManager.Add(result, connection.ClientPubKey); } return(Task.CompletedTask); }
static void AddConnection(AlphaWebSocketConnection connection) { lock (connection) { connections.AddOrUpdate(connection.ClientPubKey, connection, (key, oldConnection) => { RemoveConnection(oldConnection); return(connection); }); logger.Trace($"{connection.ClientPubKey} is connected."); } }
public async Task AccountRequestRateLimitTest(KeyPair clientKeyPair, int?requestLimit) { context.AppState.State = ApplicationState.Ready; var account = context.AccountStorage.GetAccount(clientKeyPair); if (requestLimit.HasValue) { //TODO: replace it with quantum var effect = new RequestRateLimitUpdateEffect { Account = account.Id, AccountWrapper = account, RequestRateLimits = new RequestRateLimits { HourLimit = (uint)requestLimit.Value, MinuteLimit = (uint)requestLimit.Value } }; var effectProcessor = new RequestRateLimitUpdateEffectProcessor(effect, context.Constellation.RequestRateLimits); effectProcessor.CommitEffect(); } var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair, ConnectionState = ConnectionState.Ready, Account = account }; var minuteLimit = (account.Account.RequestRateLimits ?? context.Constellation.RequestRateLimits).MinuteLimit; var minuteIterCount = minuteLimit + 1; for (var i = 0; i < minuteIterCount; i++) { var envelope = new AccountDataRequest { Account = account.Account.Id, RequestId = i + 1 }.CreateEnvelope(); envelope.Sign(clientKeyPair); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); if (i + 1 > minuteLimit) { await AssertMessageHandling(clientConnection, inMessage, typeof(TooManyRequestsException)); } else { await AssertMessageHandling(clientConnection, inMessage); } } }
/// <summary> /// Registers new client websocket connection /// </summary> /// <param name="webSocket">New websocket connection</param> public static async Task OnNewConnection(WebSocket webSocket, string ip) { Global.ExtensionsManager.BeforeNewConnection(webSocket, ip); if (webSocket == null) { throw new ArgumentNullException(nameof(webSocket)); } using (var connection = new AlphaWebSocketConnection(webSocket, ip)) { Subscribe(connection); await connection.Listen(); } }
public async Task HeartbeatTest() { Global.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1"); var envelope = new Heartbeat().CreateEnvelope(); envelope.Sign(TestEnvironment.Client1KeyPair); var isHandled = await MessageHandlers <AlphaWebSocketConnection> .HandleMessage(clientConnection, envelope); Assert.IsTrue(isHandled); }
static void RemoveConnection(AlphaWebSocketConnection connection) { lock (connection) { _ = UnsubscribeAndClose(connection); if (connection.ClientPubKey != null) { connections.TryRemove(connection.ClientPubKey, out _); if (Global.Constellation.Auditors.Contains(connection.ClientPubKey)) { AlphaStateManager.AuditorConnectionClosed(connection.ClientPubKey); } } } }
private async Task HandleClientHandshake(AlphaWebSocketConnection connection, MessageEnvelope envelope) { if (connection.Context.AppState.State != ApplicationState.Ready) { throw new ConnectionCloseException(WebSocketCloseStatus.ProtocolError, "Alpha is not in Ready state."); } connection.Account = connection.Context.AccountStorage.GetAccount(connection.ClientPubKey); if (connection.Account == null) { throw new ConnectionCloseException(WebSocketCloseStatus.NormalClosure, "Account is not registered."); } connection.ConnectionState = ConnectionState.Ready; var result = (HandshakeResult)envelope.CreateResult(ResultStatusCodes.Success); result.AccountId = connection.Account.Account.Id; await connection.SendMessage(result); }
public void HandshakeInvalidDataTest() { Global.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1"); var handshake = new HandshakeData(); handshake.Randomize(); var envelope = new HandshakeInit { HandshakeData = handshake }.CreateEnvelope(); envelope.Sign(TestEnvironment.Client1KeyPair); Assert.ThrowsAsync <ConnectionCloseException>(async() => await MessageHandlers <AlphaWebSocketConnection> .HandleMessage(clientConnection, envelope)); }
public async Task SetApexCursorTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { Global.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new SetApexCursor { Apex = 1 }.CreateEnvelope(); envelope.Sign(clientKeyPair); await AssertMessageHandling(clientConnection, envelope, excpectedException); }
private async Task HandleAuditorHandshake(AlphaWebSocketConnection connection) { connection.SetAuditor(); Message message; if (connection.Context.AppState.State == ApplicationState.Rising) { message = new AuditorStateRequest { TargetApex = await connection.Context.PersistenceManager.GetLastApex() } } ; else { message = connection.Context.GetCurrentState(); } await connection.SendMessage(message); }
private async Task HandleAuditorHandshake(AlphaWebSocketConnection connection) { connection.MaxMessageSize = connection.MaxMessageSize * Global.MaxMessageBatchSize; Message message; if (Global.AppState.State == ApplicationState.Rising) { message = new AuditorStateRequest { TargetApex = await Global.PersistenceManager.GetLastApex() } } ; else { message = AlphaStateHelper.GetCurrentState(); } await connection.SendMessage(message); }
public async Task SetApexCursorTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { context.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new SetApexCursor { Apex = 1 }.CreateEnvelope(); envelope.Sign(clientKeyPair); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); await AssertMessageHandling(clientConnection, inMessage, excpectedException); }
public async Task TxNotificationTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { Global.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new TxNotification { TxCursor = Global.TxCursorManager.TxCursor + 1, Payments = new List <PaymentBase>() }.CreateEnvelope(); envelope.Sign(clientKeyPair); await AssertMessageHandling(clientConnection, envelope, excpectedException); }
public override async Task HandleMessage(AlphaWebSocketConnection connection, IncomingMessage message) { var handshakeInit = message.Envelope.Message as HandshakeInit; if (!ByteArrayPrimitives.Equals(handshakeInit.HandshakeData.Data, connection.HandshakeData.Data)) { throw new ConnectionCloseException(WebSocketCloseStatus.InvalidPayloadData, "Handshake failed"); } connection.ClientPubKey = message.Envelope.Signatures[0].Signer; connection.ConnectionState = ConnectionState.Validated; if (Context.Constellation.Auditors.Contains(connection.ClientPubKey)) { await HandleAuditorHandshake(connection); } else { await HandleClientHandshake(connection, message.Envelope); } }
public void HandshakeInvalidDataTest() { context.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1"); var handshake = new HandshakeData(); handshake.Randomize(); var envelope = new HandshakeInit { HandshakeData = handshake }.CreateEnvelope(); envelope.Sign(TestEnvironment.Client1KeyPair); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); Assert.ThrowsAsync <ConnectionCloseException>(async() => await context.MessageHandlers.HandleMessage(clientConnection, inMessage)); }
public async Task EffectsRequestTest(KeyPair client, ConnectionState state, Type excpectedException) { Global.AppState.State = ApplicationState.Ready; var account = Global.AccountStorage.GetAccount(client); var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1") { ClientPubKey = client, ConnectionState = state, Account = account }; var envelope = new EffectsRequest { Account = account.Account.Id, AccountWrapper = account }.CreateEnvelope(); envelope.Sign(client); await AssertMessageHandling(clientConnection, envelope, excpectedException); }
public async Task AccountDataRequestTest(ConnectionState state, Type excpectedException) { Global.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(new FakeWebSocket(), "127.0.0.1") { ClientPubKey = TestEnvironment.Client1KeyPair.PublicKey, ConnectionState = state }; var account = Global.AccountStorage.GetAccount(TestEnvironment.Client1KeyPair); var envelope = new AccountDataRequest { Account = account.Account.Id, RequestId = 1 }.CreateEnvelope(); envelope.Sign(TestEnvironment.Client1KeyPair); await AssertMessageHandling(clientConnection, envelope, excpectedException); }
public async Task TxNotificationTest(KeyPair clientKeyPair, ConnectionState state, Type excpectedException) { context.AppState.State = ApplicationState.Ready; var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = clientKeyPair.PublicKey, ConnectionState = state }; var envelope = new TxNotification { TxCursor = context.TxCursorManager.TxCursor + 1, Payments = new List <PaymentBase>() }.CreateEnvelope(); envelope.Sign(clientKeyPair); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); await AssertMessageHandling(clientConnection, inMessage, excpectedException); }
public void BlockOnClientExceptionTest() { try { var pubKey = (RawPubKey)KeyPair.Random(); var webSocket = new FakeWebSocket(); var clientConnection = new AlphaWebSocketConnection(webSocket, "127.0.0.1") { ClientPubKey = pubKey }; for (var i = 0; i < 1000; i++) { Global.ExtensionsManager.HandleMessageFailed(clientConnection, null, new ForbiddenException()); } Assert.Fail("Client wasn't block after 1000 connections."); } catch (ConnectionCloseException exc) { Assert.AreEqual(WebSocketCloseStatus.PolicyViolation, exc.Status); } }
public void TooManyConnectionsFromDifferentIpTest() { try { var pubKey = (RawPubKey)KeyPair.Random(); for (var i = 0; i < 1000; i++) { var ip = "127.0.0." + i; var webSocket = new FakeWebSocket(); Global.ExtensionsManager.BeforeNewConnection(webSocket, ip); var clientConnection = new AlphaWebSocketConnection(webSocket, ip) { ClientPubKey = pubKey }; Global.ExtensionsManager.ConnectionValidated(clientConnection); } Assert.Fail("Client wasn't block after 1000 connections."); } catch (ConnectionCloseException exc) { Assert.AreEqual(WebSocketCloseStatus.PolicyViolation, exc.Status); } }
public async Task EffectsRequestTest(KeyPair client, ConnectionState state, Type excpectedException) { context.AppState.State = ApplicationState.Ready; var account = context.AccountStorage.GetAccount(client); var clientConnection = new AlphaWebSocketConnection(context, new FakeWebSocket(), "127.0.0.1") { ClientPubKey = client, ConnectionState = state, Account = account }; var envelope = new EffectsRequest { Account = account.Account.Id, AccountWrapper = account }.CreateEnvelope(); envelope.Sign(client); using var writer = new XdrBufferWriter(); var inMessage = envelope.ToIncomingMessage(writer); await AssertMessageHandling(clientConnection, inMessage, excpectedException); }