Skip to content

Commit

Permalink
fix: throttle ar_nonce_limiter_client:maybe_request_sessions
Browse files Browse the repository at this point in the history
During block validation ar_nonce_limiter can trigger 2 full session queries via
ar_nonce_limiter_client:maybe_request_sessions/1. A full session query is slow whic
can cause a cascading backlog of requests. To avoid this, we'll throttle the full session
queries more severely than other VDF queries.
  • Loading branch information
JamesPiechota committed Feb 22, 2025
1 parent bb4d23d commit 4bee955
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions apps/arweave/src/ar_nonce_limiter_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
-define(PULL_FREQUENCY_MS, 800).
-define(NO_UPDATE_PULL_FREQUENCY_MS, 200).
-define(PULL_THROTTLE_MS, 200).
%% During block validation ar_nonce_limiter can trigger 2 full session queries via
%% ar_nonce_limiter_client:maybe_request_sessions/1. A full session query is slow whic
%% can cause a cascading backlog of requests. To avoid this, we'll throttle the full session
%% queries more severely than other VDF queries.
-define(FULL_SESSION_PULL_THROTTLE_MS, 2000).

%%%===================================================================
%%% Public interface.
Expand Down Expand Up @@ -148,24 +153,31 @@ handle_cast(pull, State) ->

handle_cast({maybe_request_sessions, SessionKey}, State) ->
#state{ remote_servers = Q } = State,
{{value, {RawPeer, _Timestamp}}, Q2} = queue:out(Q),
{{value, {RawPeer, Timestamp}}, Q2} = queue:out(Q),
Now = erlang:system_time(millisecond),
State2 = State#state{ remote_servers = queue:in({RawPeer, Now}, Q2) },
case ar_peers:resolve_and_cache_peer(RawPeer, vdf_server_peer) of
{error, _} ->
%% Push the peer to the back of the queue.
{noreply, State2};
{ok, Peer} ->
case get_latest_session_key(Peer, State) of
SessionKey ->
%% No reason to make extra requests.
{noreply, State};
_ ->
case fetch_and_apply_session_and_previous_session(Peer) of
{error, _} ->
{noreply, State2};
case Now < Timestamp + ?FULL_SESSION_PULL_THROTTLE_MS of
true ->
%% Just skip the request - if needed ar_nonce_limiter will trigger it again the
%% next time it tries to validate a block.
{noreply, State};
false ->
State2 = State#state{ remote_servers = queue:in({RawPeer, Now}, Q2) },
case ar_peers:resolve_and_cache_peer(RawPeer, vdf_server_peer) of
{error, _} ->
%% Push the peer to the back of the queue.
{noreply, State2};
{ok, Peer} ->
case get_latest_session_key(Peer, State) of
SessionKey ->
%% No reason to make extra requests.
{noreply, State};
_ ->
{noreply, State}
case fetch_and_apply_session_and_previous_session(Peer) of
{error, _} ->
{noreply, State2};
_ ->
{noreply, State}
end
end
end
end;
Expand Down

0 comments on commit 4bee955

Please sign in to comment.