Skip to content
28 changes: 2 additions & 26 deletions src/preloaded/arweave/dev_arweave.erl
Original file line number Diff line number Diff line change
Expand Up @@ -885,31 +885,7 @@ request(Method, Path, Extra, LogExtra, Opts) ->
<<"cache-control">> => [<<"no-cache">>, <<"no-store">>]
}
),
to_message(Path, Method, best_response(Res), LogExtra, Opts).

%% @doc Select the best response from a list of responses by sorting them
%% ascending by HTTP status code. Returns the first (best) response tuple.
best_response({error, {no_viable_responses, Responses}}) ->
best_response(Responses);
best_response([]) ->
{error, no_viable_responses};
best_response(Responses) when is_list(Responses) ->
Sorted = lists:sort(
fun({_, ResponseA}, {_, ResponseB}) ->
StatusA = response_status(ResponseA),
StatusB = response_status(ResponseB),
StatusA =< StatusB
end,
Responses
),
hd(Sorted);
best_response(Response) ->
Response.

response_status(Response) when is_map(Response) ->
maps:get(<<"status">>, Response, 999);
response_status(_Response) ->
999.
to_message(Path, Method, lib_arweave_common:best_response(Res), LogExtra, Opts).

%% @doc Transform a response from the Arweave node into an AO-Core message.
to_message(Path, Method, {error, #{ <<"status">> := 404 }}, LogExtra, _Opts) ->
Expand Down Expand Up @@ -1206,7 +1182,7 @@ best_response_handles_failed_connect_entries_test_parallel() ->
],
?assertEqual(
{ok, #{ <<"status">> => 200, <<"body">> => <<"OK-2">> }},
best_response(Responses)
lib_arweave_common:best_response(Responses)
).

best_response_non_map_error_round_trips_test_parallel() ->
Expand Down
27 changes: 27 additions & 0 deletions src/preloaded/codec/lib_arweave_common.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
-export([bundle_hint/4, data/3, tags/5, excluded_tags/3]).
-export([to/3, to/6, siginfo/4, fields_to_tx/4]).
-export([bundle_header/2, bundle_header/3]).
-export([best_response/1]).
-include("include/hb.hrl").

-define(ANS104_BASE_FIELDS, [<<"anchor">>, <<"target">>]).
Expand Down Expand Up @@ -770,3 +771,29 @@ read_bundle_header(BundleStartOffset, HeaderSize, FirstChunk, Opts) ->
Error ->
Error
end.

%% @doc Select the best response from a (potentially multi-node) request result
%% by sorting the responses ascending by HTTP status code and returning the
%% first (best) one. Shared by the Arweave devices, which broadcast requests to
%% several nodes and take the most successful reply.
best_response({error, {no_viable_responses, Responses}}) ->
best_response(Responses);
best_response([]) ->
{error, no_viable_responses};
best_response(Responses) when is_list(Responses) ->
Sorted = lists:sort(
fun({_, ResponseA}, {_, ResponseB}) ->
StatusA = response_status(ResponseA),
StatusB = response_status(ResponseB),
StatusA =< StatusB
end,
Responses
),
hd(Sorted);
best_response(Response) ->
Response.

response_status(Response) when is_map(Response) ->
maps:get(<<"status">>, Response, 999);
response_status(_Response) ->
999.
Loading