Watchdog-Heartbeat + LicenseLabrador-Lizenzpruefung eingebunden
Slices W-A/W-B/W-C und L-A aus UMSETZUNGSPLAN-Watchdog-LicenseLabrador-Integration. Watchdog (Dead-Man's-Switch, externer Server): - WatchdogHeartbeatService als BackgroundService + DI-Singleton; jeder Sendeversuch gekapselt, ein Ausfall des Watchdogs beeintraechtigt PolyTrader nie. - Eigene Implementierung statt Test-Client des Fremdprojekts: TLS-Pruefung bleibt aktiv, http:// nur fuer localhost (Agent-Token nicht im Klartext ins Netz). - Status aus dem App-Log abgeleitet (Error mit 5-Minuten-Sticky-Fenster, entprellt), Lifecycle-Events started/stopping. - Konfiguration in ServerSettings; Agent-Token [Browsable(false)] mit maskierter Eingabe + Statusanzeige, bei gesetztem Master-Key verschluesselt (enc:v1:). Lizenz (LicenseLabrador, Ed25519): - LicenseGate.RunStartupGate prueft beim Start; bei ungueltiger Lizenz wird die Modulliste leer gebaut, sodass nur die Core-Shell (Terminal/Einstellungen) startet. Bewusst kein Environment.Exit - ein Trading-Bot darf nicht mitten im Lauf hart sterben. TamperSuspected gilt als nicht nutzbar. - LicenseDialog (partial + .Designer.cs) fuer Start- und Verwalten-Modus, mit Hardware-ID zum Kopieren; Smoke-UI konstruiert beide Modi headless. - Master-Key wird jetzt VOR dem Host-Build geladen, da auch der Lizenzschluessel entschluesselt werden muss; derselbe TerminalLogger wird als Singleton weitergereicht, damit die Startmeldungen im Terminal-Fenster erscheinen. Der Lizenz-SDK-Client wird per Cross-Repo-Projektreferenz auf ..\..\LicenseLabrador eingebunden, damit SDK-Fixes ohne Kopie einfliessen. 484 Zeilen Tests fuer den Heartbeat; Suite gruen (438 Tests). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,81 @@ namespace PolyTraderSharp.Models
|
||||
public bool UsePolymarketWebsockets { get; set; } = false;
|
||||
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Watchdog Enabled")]
|
||||
[Description("Wenn true, sendet PolyTrader im festen Takt einen Heartbeat an den externen " +
|
||||
"Watchdog-Server. Bleiben die Heartbeats aus, alarmiert der Watchdog (Dead-Man's-Switch). " +
|
||||
"Ein nicht erreichbarer Watchdog beeinträchtigt PolyTrader NIE.")]
|
||||
public bool WatchdogEnabled { get; set; } = false;
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Watchdog URL")]
|
||||
[Description("Basis-URL des Watchdog-Servers, z.B. https://watchdog.example.de. " +
|
||||
"HTTPS ist Pflicht – http:// wird nur für localhost akzeptiert, damit der Agent-Token " +
|
||||
"nicht im Klartext über das Netz geht.")]
|
||||
public string WatchdogUrl { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Agent-Token für den Header <c>X-Watchdog-Key</c>. Bewusst NICHT im PropertyGrid sichtbar:
|
||||
/// Setzen erfolgt über den Button „Watchdog-Token setzen …" mit maskierter Eingabe, damit das
|
||||
/// Secret nicht offen im Fenster steht und bei gesetztem Master-Key verschlüsselt
|
||||
/// (<c>enc:v1:…</c>) in der gitignorierten server_settings.xml landet.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public string WatchdogToken { get; set; } = "";
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Agent-Token")]
|
||||
[Description("Status des Agent-Tokens. Setzen/Ändern über den Button „Watchdog-Token setzen …" +
|
||||
"\" in der Werkzeugleiste (maskierte Eingabe).")]
|
||||
[ReadOnly(true)]
|
||||
[XmlIgnore]
|
||||
public string WatchdogTokenStatus =>
|
||||
string.IsNullOrWhiteSpace(WatchdogToken)
|
||||
? "nicht gesetzt"
|
||||
: (WatchdogToken.StartsWith("enc:v1:", System.StringComparison.Ordinal)
|
||||
? "gesetzt (verschlüsselt)"
|
||||
: "gesetzt (Klartext)");
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Source")]
|
||||
[Description("Dienst-Kennung im Watchdog (muss dem dort angelegten Monitor entsprechen), z.B. \"polytrader\".")]
|
||||
public string WatchdogSource { get; set; } = "polytrader";
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Instance")]
|
||||
[Description("Instanz-Kennung, falls mehrere PolyTrader-Instanzen laufen, z.B. \"prod-1\".")]
|
||||
public string WatchdogInstance { get; set; } = "prod-1";
|
||||
|
||||
[Category("Watchdog Monitoring")]
|
||||
[DisplayName("Heartbeat-Intervall (Sekunden)")]
|
||||
[Description("Sende-Takt des Heartbeats. Der Watchdog leitet daraus seine Staleness-Frist ab " +
|
||||
"(Intervall × Faktor + Grace). Minimum 10 s, Empfehlung 60 s.")]
|
||||
public int WatchdogIntervalSeconds { get; set; } = 60;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Lizenzschlüssel (LicenseLabrador). Wie der Watchdog-Token bewusst NICHT im PropertyGrid
|
||||
/// sichtbar; gepflegt über den Button „Lizenzschlüssel setzen …" bzw. den Startdialog. Bei
|
||||
/// gesetztem Master-Key verschlüsselt (<c>enc:v1:…</c>) in der gitignorierten server_settings.xml.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public string LicenseKey { get; set; } = "";
|
||||
|
||||
[Category("Lizenz")]
|
||||
[DisplayName("Lizenzschlüssel")]
|
||||
[Description("Status des Lizenzschlüssels. Setzen/Ändern über den Button „Lizenzschlüssel setzen …\" " +
|
||||
"in der Werkzeugleiste bzw. beim Programmstart, falls keine gültige Lizenz vorliegt.")]
|
||||
[ReadOnly(true)]
|
||||
[XmlIgnore]
|
||||
public string LicenseKeyStatus =>
|
||||
string.IsNullOrWhiteSpace(LicenseKey)
|
||||
? "nicht gesetzt"
|
||||
: (LicenseKey.StartsWith("enc:v1:", System.StringComparison.Ordinal)
|
||||
? "gesetzt (verschlüsselt)"
|
||||
: "gesetzt (Klartext)");
|
||||
|
||||
|
||||
public static ServerSettings Load(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
|
||||
Reference in New Issue
Block a user