Kraken: cztery poprawki niezawodności w klientach WebSocket i Futures REST | eSeGeCe Blog

Kraken: cztery poprawki niezawodności w klientach WebSocket i Futures REST

· Komponenty

Cztery odrębne błędy w Kraken trafiły do 2026.9 i żaden z nich nie należał do tych, które wychwytuje się przy jednorazowej lekturze kodu. Każdy z nich ujawnia się tylko w konkretnych warunkach: niewłaściwy endpoint w momencie połączenia, ciało żądania, które nigdy nie opuszcza maszyny, ponowne połączenie następujące kilkaset milisekund za wcześnie. Wszystkie cztery zostały naprawione i wszystkie cztery warto zrozumieć, ponieważ w każdym przypadku objawy wyglądają na coś zupełnie innego niż faktyczna przyczyna.

Klient spot mówił w wersji v1 do endpointu v2

TsgcWSAPI_Kraken buduje i parsuje schemat v1: event, pair, subscription, subscriptionStatus, systemStatus. Ten schemat istnieje nie bez powodu, to na jego podstawie napisane jest każde wywołanie subskrypcji i każdy handler zdarzeń w tym komponencie. Endpoint, z którym się jednak łączył, domyślnie wskazywał na WebSocket v2 Kraken, który mówi zupełnie innym schematem: method, params, channel, type. Połączenie otwierało się bez błędu. Po prostu nigdy nie generowało ani jednego potwierdzenia subskrypcji, ani jednego zdarzenia statusu, ponieważ serwer odpowiadał w formacie, którego klient w ogóle nie parsuje.

Kraken.Version domyślnie przyjmuje teraz wartość 1, a komponent wybiera odpowiadający jej endpoint v1:

uses
  sgcWebSocket, sgcWebSocket_APIs;

var
  oKraken: TsgcWSAPI_Kraken;
begin
  oKraken := TsgcWSAPI_Kraken.Create(nil);
  oKraken.Client := oClient;
  // Version defaults to 1, matching the event/pair/subscription
  // schema this component already builds and parses.
  oKraken.Kraken.Version := 1;
  oClient.Active := True;
  oKraken.SubscribeTicker('XBT/USD');
end;

Jeśli Twoja aplikacja w jakiś sposób polegała na starej, cicho błędnej wartości domyślnej, oznacza to, że i tak nigdy faktycznie nie odbierała zdarzeń v1, więc nie ma tu nic działającego dziś, co trzeba by zachować. Jawne ustawienie Version := 2 nadal łączy się z endpointem v2, z włączonym RawMessages i obsługą ładunku w OnKrakenData lub OnMessage, dla tych, którzy celowo budują rozwiązanie pod ten schemat.

Zlecenia Futures wysyłane jako GET, ciało żądania odrzucane

Ten błąd jest cichszy i poważniejszy. Każde prywatne żądanie w kliencie REST Kraken Futures, wysłanie zlecenia, edycja zlecenia, anulowanie zlecenia, transfer, wypłata, wychodziło jako HTTP GET. Podpisane ciało żądania było budowane poprawnie, obliczane, formatowane, gotowe do wysłania, a następnie odrzucane, ponieważ żądanie GET nie ma gdzie go umieścić. Kraken otrzymywał GET bez żadnych parametrów i odrzucał je lub ignorował. Żadne z tych wywołań nie działało.

uses
  sgcHTTP_API_Kraken;

var
  oKraken: TsgcHTTP_API_Kraken_Futures_Rest;
  oOrder: TsgcHTTPKrakenFuturesOrder;
begin
  oKraken := TsgcHTTP_API_Kraken_Futures_Rest.Create(nil);
  oKraken.KrakenOptions.ApiKey := 'your_api_key';
  oKraken.KrakenOptions.ApiSecret := 'your_api_secret';

  oOrder := TsgcHTTPKrakenFuturesOrder.Create;
  try
    oOrder.OrderType := kotfLMT;
    oOrder.Symbol := 'PF_XBTUSD';
    oOrder.Side := kosfBuy;
    oOrder.Size := 1;
    oOrder.LimitPrice := 30000;
    // SendOrder now posts through DoHTTP_POST_PRIVATE, body included.
    ShowMessage(oKraken.SendOrder(oOrder));
  finally
    oOrder.Free;
  end;
end;

SendOrder, EditOrderByOrderId, EditOrderByCliOrderId, CancelOrderByOrderId, CancelOrderByCliOrderId, Transfer i WithdrawalToSpotWallet przechodzą teraz przez prywatną ścieżkę POST, z podpisanym ciałem żądania faktycznie dołączonym do żądania.

Prywatne subskrypcje tracone przy ponownym połączeniu

WatchDog łączy się ponownie, log pokazuje czyste ponowne połączenie, a od tego momentu Twoje kanały zleceń, salda i realizacji po prostu znikają. Nic nie zgłasza błędu. Nic nie trafia do logu. Ponowne połączenie wyglądało na w pełni udane, ponieważ samo połączenie faktycznie się udawało, tylko prywatne subskrypcje wydane przed rozłączeniem nigdy potem nie były odtwarzane. Dotyczyło to zarówno Kraken spot, jak i Kraken Futures, a także kilku innych klientów giełdowych naprawionych w tej samej serii poprawek. Jest to teraz część standardowego mechanizmu odtwarzania subskrypcji, tej samej ścieżki, która już wcześniej przywracała publiczne subskrypcje danych rynkowych po ponownym połączeniu.

Futures ponownie subskrybował, zanim sesja została uwierzytelniona

Ściśle powiązany błąd, specyficzny dla Kraken Futures: po ponownym połączeniu odtwarzanie aktywnych subskrypcji mogło uruchomić się, zanim proces uwierzytelniania faktycznie się zakończył. Żądania subskrypcji wychodziły na sesji, której Kraken jeszcze nie uwierzytelnił, więc te prywatne były odrzucane, ponownie bez żadnej wskazówki w kliencie, co jest tego przyczyną. Odtwarzanie czeka teraz na zakończenie uwierzytelniania, zanim ponownie subskrybuje.

Aktualizacja

Wszystkie cztery poprawki są bezpieczne do bezpośredniego wdrożenia, nie ma żadnego API do migracji. Jedyną zmianą w zachowaniu, o której warto wiedzieć, jest zmiana wartości domyślnej Kraken.Version z poprzedniej, faktycznie niedziałającej wartości na 1; jeśli Twój kod już jawnie ustawia Version := 2, nic się dla Ciebie nie zmienia.

Masz pytania, uwagi lub potrzebujesz pomocy z migracją? Skontaktuj się z nami — odpowie Ci osoba, która napisała ten kod.