FASTER relay

This commit is contained in:
2024-01-12 16:22:38 +00:00
parent a0e59757b5
commit a22122e824
17 changed files with 726 additions and 33 deletions

View File

@ -27,7 +27,7 @@ public class NostrRelay<THandler> where THandler : INostrRelay
private async Task WriteResponse<T>(T obj)
{
var rspJson = JsonConvert.SerializeObject(obj, NostrSerializer.Settings);
_logger.LogDebug("Sending {msg}", rspJson);
_logger.LogTrace("Sending {msg}", rspJson);
await _ctx.WebSocket.SendAsync(Encoding.UTF8.GetBytes(rspJson), WebSocketMessageType.Text, true, _cts.Token);
}
@ -36,10 +36,11 @@ public class NostrRelay<THandler> where THandler : INostrRelay
if (!await _handler.AcceptConnection(_ctx)) return;
var offset = 0;
var mem = MemoryPool<byte>.Shared.Rent(1024 * 1024);
var mem = MemoryPool<byte>.Shared.Rent(1024 * 1024 * 32);
while (!_cts.IsCancellationRequested)
{
var msg = await _ctx.WebSocket.ReceiveAsync(mem.Memory[offset..], _cts.Token);
if (msg.MessageType is WebSocketMessageType.Text)
{
var buff = mem.Memory[..(offset + msg.Count)];
@ -47,49 +48,100 @@ public class NostrRelay<THandler> where THandler : INostrRelay
if (!msg.EndOfMessage) continue;
var str = Encoding.UTF8.GetString(buff.Span);
_logger.LogDebug("Got msg {msg}", str);
if (str.StartsWith("[\"REQ\""))
_logger.LogTrace("Got msg {msg}", str);
try
{
var req = JsonConvert.DeserializeObject<NostrRequest>(str, NostrSerializer.Settings);
if (req != default)
if (str.StartsWith("[\"REQ\""))
{
await foreach (var ev in _handler.HandleRequest(_ctx, req))
var req = JsonConvert.DeserializeObject<NostrInboundRequest>(str, NostrSerializer.Settings);
if (req != default)
{
await WriteResponse(new NostrEventResponse()
await foreach (var ev in _handler.HandleRequest(_ctx, req))
{
MessageType = "EVENT",
Subscription = req.Subscription,
Event = ev
});
await WriteResponse(new NostrEventResponse()
{
MessageType = "EVENT",
Subscription = req.Subscription,
Event = ev
});
}
var rsp = new NostrEoseResponse
{
MessageType = "EOSE",
Subscription = req.Subscription
};
await WriteResponse(rsp);
}
var rsp = new NostrEoseResponse
}
else if (str.StartsWith("[\"EVENT\""))
{
var req = JsonConvert.DeserializeObject<NostrEventRequest>(str, NostrSerializer.Settings);
if (req != default)
{
MessageType = "EOSE",
Subscription = req.Subscription
};
if (!req.Event.IsSignatureValid())
{
var rsp = new NostrOkResponse()
{
MessageType = "OK",
EventId = req.Event.Id,
Accepted = false,
Message = "invalid: sig check failed"
};
await WriteResponse(rsp);
await WriteResponse(rsp);
}
else
{
var result = await _handler.HandleEvent(_ctx, req.Event);
var rsp = new NostrOkResponse()
{
MessageType = "OK",
EventId = req.Event.Id,
Accepted = result.Ok,
Message = result.Message ?? ""
};
await WriteResponse(rsp);
}
}
}
}
else if (str.StartsWith("[\"EVENT\""))
catch (Exception ex)
{
var req = JsonConvert.DeserializeObject<NostrEventRequest>(str, NostrSerializer.Settings);
if (req != default)
{
var result = await _handler.HandleEvent(_ctx, req.Event);
var rsp = new NostrOkResponse()
{
MessageType = "OK",
EventId = req.Event.Id,
Accepted = result.Ok,
Message = result.Message ?? ""
};
await WriteResponse(rsp);
}
_logger.LogWarning("Failed to process msg {error}", ex.Message);
offset = 0;
}
}
}
}
}
[JsonConverter(typeof(ArrayConverter))]
public class NostrInboundRequest
{
public NostrInboundRequest()
{
}
public NostrInboundRequest(string subscription, NostrFilter nostrFilter)
{
this.Subscription = subscription;
this.NostrFilter = nostrFilter;
}
public static implicit operator NostrRequest(NostrInboundRequest req)
{
return new(req.Subscription, req.NostrFilter);
}
[ArrayProperty(0)]
public string Type { get; init; } = "REQ";
[ArrayProperty(1)]
public string Subscription { get; init; }
[ArrayProperty(2)]
public NostrFilter NostrFilter { get; init; }
}