Kraken: quattro correzioni di affidabilità nei client WebSocket e Futures REST | eSeGeCe Blog

Kraken: quattro correzioni di affidabilità nei client WebSocket e Futures REST

· Componenti

Quattro difetti distinti di Kraken sono confluiti nella 2026.9, e nessuno di essi era del tipo che si individua leggendo il codice una sola volta. Ciascuno si manifesta solo in una condizione specifica: l'endpoint sbagliato al momento della connessione, un corpo della richiesta che non lascia mai la macchina, una riconnessione che avviene qualche centinaio di millisecondi troppo presto. Tutti e quattro sono stati corretti, e vale la pena capirli tutti, perché in ciascun caso la modalità di guasto sembra tutt'altra cosa.

Il client spot parlava v1 con un endpoint v2

TsgcWSAPI_Kraken costruisce e analizza lo schema v1: event, pair, subscription, subscriptionStatus, systemStatus. Questo schema esiste per un motivo preciso: è quello a cui è scritta ogni chiamata di subscribe e ogni event handler di questo componente. L'endpoint a cui si connetteva, tuttavia, puntava di default al WebSocket v2 di Kraken, che parla uno schema completamente diverso: method, params, channel, type. La connessione si apriva senza errori. Semplicemente non produceva mai un solo acknowledgement di sottoscrizione o un evento di stato, perché il server rispondeva in un formato che il client non analizza mai.

Kraken.Version ora ha come valore predefinito 1, e il componente sceglie l'endpoint v1 corrispondente:

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;

Se la vostra applicazione contava in qualche modo sul vecchio valore predefinito, silenziosamente sbagliato, significa che in realtà non riceveva nemmeno eventi v1, quindi non c'è nulla che funzioni oggi da preservare. Impostare esplicitamente Kraken.Version := 2 continua a connettersi all'endpoint v2, con RawMessages abilitato e il payload gestito in OnKrakenData o OnMessage, per chiunque stia sviluppando deliberatamente su quello schema.

Ordini Futures inviati come GET, corpo scartato

Questo è più silenzioso e più serio. Ogni richiesta privata sul client Kraken Futures REST, l'invio di un ordine, la sua modifica, la sua cancellazione, un trasferimento, un prelievo, veniva inviata come una richiesta HTTP GET. Il corpo della richiesta firmato veniva costruito correttamente, calcolato, formattato, pronto per l'invio, e poi scartato, perché una richiesta GET non ha un corpo in cui inserirlo. Kraken riceveva una GET senza parametri e la rifiutava o la ignorava. Nessuna di queste chiamate funzionava.

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 e WithdrawalToSpotWallet passano ora tutti attraverso il percorso POST privato, con il corpo firmato effettivamente allegato alla richiesta.

Sottoscrizioni private perse alla riconnessione

Il WatchDog si riconnette, il log mostra una riconnessione pulita, e da quel momento i vostri canali orders, balance e fills sono semplicemente spariti. Nessun errore. Nessuna riga di log. La riconnessione sembrava del tutto riuscita, perché la connessione in sé aveva effettivamente avuto successo: erano solo le sottoscrizioni private emesse prima della disconnessione a non essere mai state ripristinate in seguito. Questo colpiva sia Kraken spot che Kraken Futures, insieme a diversi altri client di exchange corretti nello stesso intervento. Ora fa parte del normale replay di resubscribe, lo stesso percorso che già ripristina le vostre sottoscrizioni di dati di mercato pubblici dopo una riconnessione.

Futures: nuova sottoscrizione prima che la sessione fosse autenticata

Un difetto strettamente correlato, specifico di Kraken Futures: dopo una riconnessione, il replay delle sottoscrizioni attive poteva essere eseguito prima che l'handshake di autenticazione fosse effettivamente completato. Le richieste di subscribe venivano inviate su una sessione che Kraken non aveva ancora autenticato, quindi quelle private venivano rifiutate, di nuovo senza nulla nel client che indicasse il motivo. Il replay ora attende il completamento dell'autenticazione prima di risottoscrivere.

Aggiornamento

Tutte e quattro le correzioni sono drop-in, non c'è nessuna API da migrare. L'unico cambiamento di comportamento di cui essere consapevoli è l'inversione del valore predefinito di Kraken.Version, dal precedente valore di fatto non funzionante a 1; se il vostro codice imposta già esplicitamente Version := 2, per voi non cambia nulla.

Domande, feedback o aiuto per la migrazione? Contattateci — riceverete una risposta da chi ha scritto il codice.