Portfel przestaje się odświeżać, aplikacja zawiesza się na spinnerze, a gdzieś w tle pojawia się komunikat o przekroczeniu limitu. Z twoimi kluczami, saldem i samym łańcuchem wszystko jest w porządku. Operator uznał, że w danym oknie zadałeś więcej pytań, niż pozwala twój plan, i odrzuca wszystko, co przychodzi powyżej tej linii.
Co naprawdę zgłasza błąd limitu
Za portfele i aplikacje, które nie prowadzą własnego węzła, na pytania o łańcuch odpowiada węzeł RPC. Ten, kto go prowadzi, decyduje też, ile pytań może zadać każdy wywołujący, i egzekwuje tę decyzję, odrzucając wszystko powyżej pułapu.
RFC 6585 nadaje takiej odmowie własny kod stanu. Stwierdza, że kod 429 oznacza, iż użytkownik wysłał zbyt wiele żądań w danym czasie, a sam rozdział nazywa ten stan ograniczaniem tempa; dodaje też, że reprezentacje odpowiedzi SHOULD zawierać szczegóły wyjaśniające warunek i MAY zawierać nagłówek Retry-After wskazujący, jak długo czekać przed nowym żądaniem.
Płyną z tego dwa wnioski, oba łatwe do przeoczenia przy zepsutym ekranie. Odmowa dotyczy wywołującego, a nie samego wywołania, więc identyczne żądanie chwilę wcześniej by przeszło. A pułap to polityka jednego operatora, nie właściwość sieci, więc inny endpoint o innej polityce odpowie na to samo żądanie bez sprzeciwu.
Odmowa przychodzi w więcej niż jednej kopercie
Nie każde zdławione wywołanie wraca jako status HTTP. JSON-RPC 2.0 przenosi błędy w treści odpowiedzi, a jego specyfikacja rezerwuje kody od -32000 do -32099 na błędy serwera definiowane przez implementację i właśnie tam może trafić komunikat dostawcy o dławieniu. Warstwa HTTP raportuje wtedy zwykły sukces.
| Gdzie ląduje odmowa | Jak wygląda | Dlaczego bywa przeoczona |
|---|---|---|
| Status HTTP | Odpowiedź 429, czasem z nagłówkiem Retry-After | Niewidoczna dla klienta, który sprawdza tylko, czy połączenie zadziałało |
| Treść JSON-RPC | Obiekt error z kodem błędu serwera definiowanym przez implementację | Status HTTP jest sukcesem, więc kontrola statusu przepuszcza go dalej |
| Sformułowanie klienta | Nieaktualne saldo, spinner albo ogólny błąd sieci | Tekst jest pisany dla człowieka i nie nazywa warstwy, która odmówiła |
Diagnoza zaczyna się więc od rozstrzygnięcia, z którym z tych trzech masz do czynienia. Portfel, który mówi tylko, że nie może się połączyć, nie dowodzi, że odmowy nie było: dowodzi, że jej nie pokazał.
Limity nie zawsze liczy się w żądaniach
Pułap wyrażony w wywołaniach na sekundę to tylko jedna z postaci limitu. Gdy operator waży wywołania zamiast je liczyć, ciężka metoda pobiera z tego samego budżetu więcej niż lekka, a budżet pustoszeje szybciej, niż sugeruje liczba wywołań.
Dlatego „kilka wywołań” i „przekroczyłeś limit” mogą być równie trafnymi opisami tej samej minuty. Zapytanie o logi z szerokiego zakresu bloków to jedno wywołanie w liczeniu i duża wypłata w wadze. Przeczytanie własnego opisu operatora, co liczy jego budżet, jest szybsze niż eksperymentowanie na nim.
Skąd naprawdę bierze się liczba żądań
Wolumen się kumuluje, a nie jest wybierany. Bierze się z pętli, których nikt nie uważa za pętle: ekranu odczytującego saldo na timerze, komponentu pobierającego dane przy każdym renderze, procesu w tle pytającego, czy transakcja już weszła do bloku.
Arytmetyka jest bezlitosna, bo interwał jest mały, a sesja długa. Ekran odświeżający jedno saldo raz na sekundę sam z siebie generuje 43 200 wywołań w dwunastogodzinnej sesji, zanim policzy się jakiekolwiek działanie użytkownika. Wobec planu dopuszczającego 100 000 wywołań dziennie jedna otwarta karta zabrała już sporą część doby.
Ponowienia to drugie źródło i mnożą pierwsze. Klient, który na każdą odmowę odpowiada kolejnym wysłaniem, zamienia jeden przekroczony pułap w strumień odmów, i to dokładnie wtedy, gdy operator najmniej chce go obsłużyć.
Jak ponawiać, nie pogarszając sprawy
Wysyłanie w tym samym interwale, który wywołał odmowę, odtwarza odmowę. Poprawka polega na czekaniu po każdej porażce dłużej, a nie tyle samo, tak by interwał rósł, a pułap został na miejscu, i na zatrzymaniu się po ograniczonej liczbie prób zamiast ponawiania w nieskończoność.
Dodaj do tego czekania losowość. Klienci odrzuceni w tej samej chwili i wycofujący się według tej samej reguły wrócą również w tej samej chwili, więc odzyskanie sprawności przyjdzie jako kolejny skok. Losowe przesunięcie rozprasza czekanie i łamie tę synchronizację, nic przy tym nie kosztując.
Gdy w odpowiedzi jest nagłówek Retry-After, zastępuje on zgadywanie. Operator sam podał, ile czekać, a uszanowanie tej wartości jest szybsze niż wymyślony przez ciebie harmonogram i mniej prawdopodobne, że zostanie ci policzone.
Zmniejszać liczbę żądań zamiast podnosić pułap
Grupowanie to pierwsza redukcja i należy do protokołu, a nie do jednego dostawcy. JSON-RPC 2.0 mówi, że aby wysłać kilka obiektów Request naraz, klient MAY wysłać tablicę wypełnioną obiektami Request, a serwer powinien odpowiedzieć tablicą zawierającą odpowiadające im obiekty Response po przetworzeniu wszystkich obiektów Request z paczki. Złożenie dziesięciu wywołań w jedną tablicę zamienia tamtą sesję 43 200 wywołań w 4 320 żądań.
Buforowanie to druga. Wartości, które nie zmieniają się między blokami, nie wymagają odczytu między blokami: liczba miejsc dziesiętnych tokena, adres kontraktu, potwierdzenie już rozliczonej transakcji. Wszystko, co ostateczne, można trzymać bez ograniczeń czasowych, a ponowny odczyt to czysty wydatek.
Subskrypcje to trzecia, jeśli endpoint je oferuje. Odpytywanie raz za razem pyta, czy coś się zmieniło; subskrypcja pyta raz i dostaje powiadomienie, gdy odpowiedź się zmieni. Niosą tę samą informację, a kosztują bardzo różne części budżetu.
| Co obserwujesz | Gdzie naprawdę jest pułap | Co to zmienia |
|---|---|---|
| Odmowy przy małym ruchu | Ważony budżet wydany przez ciężkie metody | Zawęzić zakresy bloków i podzielić zapytanie |
| Odmowy mnożą się po pierwszej | Ponowienia uderzają w ten sam pułap | Wycofywać się z rosnącym i losowanym czekaniem |
| Odmowy z jednej bezczynnej karty | Pętla odpytywania na timerze | Grupować, buforować albo subskrybować zamiast odpytywać |
| Odmowy tylko w jednej sieci | Polityka przypisana do tego endpointu | Dodać drugi endpoint dla tej sieci |
Kiedy ponowienie nie jest bezpieczne
Odczyty i zapisy nie powtarzają się tak samo. Zapytanie o saldo dwa razy kosztuje jedno dodatkowe wywołanie i nic więcej. Wysłanie podpisanej transakcji dwa razy to inne zdarzenie, a odmowa na endpoincie nie mówi, po której stronie tej granicy transakcja się zatrzymała.
Zanim wyślesz ponownie, ustal, czy pierwsza próba dotarła do mempoolu. Transakcja, którą sieć już trzyma, i nowa transakcja wyrażająca ten sam zamiar nie są wymienne, a traktowanie ich jak jednej rzeczy jest drogą do podwójnej transmisji. W Solanie punkt odniesienia świeżości czyni czas wyraźnym: wysyłka opóźniona długim wycofaniem może trafić na wygasły blockhash i wymagać przebudowania, a nie ponowienia.
Ta sama ostrożność dotyczy tego, w co klient uwierzy potem. Portfel, którego odczyty są odrzucane, porównuje własną liczbę wysłanych transakcji z widokiem, którego nie mógł odświeżyć, a to jedna z dróg do komunikatu nonce zbyt wysoki. Licznik się nie myli; brakuje obrazu, z którym go porównano.
Zmiana endpointu naprawia jedną przyczynę, nie pozostałe
Jeśli pułap należy do operatora, przejście do innego operatora przenosi cię pod inny pułap i zmiana endpointu jest rutynową naprawą właśnie w tym przypadku. Sprawdź chain ID nowego wpisu, zanim cokolwiek przez niego poprowadzisz, i zachowaj wpis, który już działał. Czego zmiana nie dosięga, to tego, co łańcuch już zapisał: transakcja, która wykonała się i została cofnięta, jest reverted, a każdy uczciwy endpoint raportuje to potwierdzenie tak samo.
Jeśli wolumen należy do ciebie, zmiana kupuje czas i nic więcej. Ta sama pętla odpytywania trafi w pułap kolejnego operatora według tego samego harmonogramu, a rotowanie między endpointami, by mieścić się pod kilkoma pułapami naraz, ukrywa pętlę, zamiast ją naprawiać.
Trzeci przypadek warto oddzielić od obu. Dedykowany endpoint z twoim własnym kluczem to nie tylko większy przydział: odgradza cię też od innych wywołujących, którzy dzielili publiczny endpoint, więc odmowa otrzymana potem jest naprawdę twoja do wyjaśnienia.
Podsumowanie
Błąd limitu mówi o tym, ile poprosiłeś, a nie o tym, czy miałeś prawo pytać. Nazywa budżet, okno i operatora, a użyteczna reakcja zaczyna się od ustalenia, które z tych trzech właśnie wiąże.
Czytaj odmowę na tej warstwie, na której wylądowała, honoruj Retry-After, gdy jest podany, i wycofuj się z rosnącym oraz losowanym czekaniem zamiast wysyłać według starego harmonogramu. Potem zmniejszaj wolumen, zamiast gonić za większym pułapem: grupuj to, co może jechać razem, buforuj to, co się nie zmienia, i subskrybuj zamiast odpytywać. Dwa razy większy przydział, zjadany przez tę samą pętlę, skończy się tego samego popołudnia. Aby dalej poznawać podstawy, śledź kolejne materiały Bitbase Academy.
Powiązane artykuły
Inne artykuły Bitbase na ten temat:
- Jak bezpiecznie zmienić endpoint RPC
- Maksymalna opłata za transakcję przekroczona: co oznacza to ostrzeżenie portfela
- Seed phrase vs passphrase: różnica i dlaczego jest ważna
- Czym jest finalność w blockchainie?
Zastrzeżenie: ten artykuł to treść edukacyjna Bitbase Academy, wyłącznie w celach informacyjnych. Nie stanowi porady inwestycyjnej, handlowej, podatkowej ani finansowej. Kryptoaktywa są zmienne — samodzielnie oceń ryzyko. Napisano w wrześniu 2026 r.; sprawdzaj aktualne oficjalne informacje.
Źródła
[1] M. Nottingham, R. Fielding, Additional HTTP Status Codes, RFC 6585, IETF, kwiecień 2012 r. rfc-editor.org
[2] JSON-RPC 2.0 Specification, grupa robocza JSON-RPC, aktualizacja z 4 stycznia 2013 r. jsonrpc.org






