V0.4.1 (#9)
* Add ec_utils dep * Add base58 dep. Add search tags to zomp package. * Add nonsensical TLS feature. * Minor verup. Adding TLS support. * Correct option name * Patch increase
This commit is contained in:
@@ -3,6 +3,6 @@
|
|||||||
{registered,[]},
|
{registered,[]},
|
||||||
{included_applications,[]},
|
{included_applications,[]},
|
||||||
{applications,[stdlib,kernel]},
|
{applications,[stdlib,kernel]},
|
||||||
{vsn,"0.3.1"},
|
{vsn,"0.4.1"},
|
||||||
{modules,[vanillae,vanillae_fetcher,vanillae_man,vanillae_sup]},
|
{modules,[vanillae,vanillae_fetcher,vanillae_man,vanillae_sup]},
|
||||||
{mod,{vanillae,[]}}]}.
|
{mod,{vanillae,[]}}]}.
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(vanillae).
|
-module(vanillae).
|
||||||
-vsn("0.3.1").
|
-vsn("0.4.1").
|
||||||
-behavior(application).
|
-behavior(application).
|
||||||
-author("Craig Everett <ceverett@tsuriai.jp>").
|
-author("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
% Get/Set admin functions.
|
% Get/Set admin functions.
|
||||||
-export([network_id/0, network_id/1,
|
-export([network_id/0, network_id/1,
|
||||||
ae_nodes/0, ae_nodes/1,
|
ae_nodes/0, ae_nodes/1,
|
||||||
|
tls/0, tls/1,
|
||||||
timeout/0, timeout/1]).
|
timeout/0, timeout/1]).
|
||||||
|
|
||||||
% AE node JSON query interface functions
|
% AE node JSON query interface functions
|
||||||
@@ -269,6 +270,24 @@ ae_nodes(List) when is_list(List) ->
|
|||||||
vanillae_man:ae_nodes(List).
|
vanillae_man:ae_nodes(List).
|
||||||
|
|
||||||
|
|
||||||
|
-spec tls() -> boolean().
|
||||||
|
%% @doc
|
||||||
|
%% Check whether TLS is in use.
|
||||||
|
|
||||||
|
tls() ->
|
||||||
|
vanillae_man:tls().
|
||||||
|
|
||||||
|
|
||||||
|
-spec tls(boolean()) -> ok.
|
||||||
|
%% @doc
|
||||||
|
%% Set TLS true or false. That's what a boolean is, by the way, `true' or `false'.
|
||||||
|
%% This is a condescending comment. That means I am talking down to you.
|
||||||
|
|
||||||
|
tls(Boolean) ->
|
||||||
|
vanillae_man:tls(Boolean).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-spec timeout() -> Timeout
|
-spec timeout() -> Timeout
|
||||||
when Timeout :: pos_integer() | infinity.
|
when Timeout :: pos_integer() | infinity.
|
||||||
%% @doc
|
%% @doc
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
%%% @private
|
%%% @private
|
||||||
|
|
||||||
-module(vanillae_fetcher).
|
-module(vanillae_fetcher).
|
||||||
-vsn("0.3.1").
|
-vsn("0.4.1").
|
||||||
-author("Craig Everett <ceverett@tsuriai.jp>").
|
-author("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
-license("MIT").
|
-license("MIT").
|
||||||
|
|
||||||
-export([connect/4]).
|
-export([connect/4, slowly_connect/4]).
|
||||||
|
|
||||||
-include("$zx_include/zx_logger.hrl").
|
-include("$zx_include/zx_logger.hrl").
|
||||||
|
|
||||||
@@ -208,3 +208,33 @@ read_hval(Socket, <<>>, Val, Key, Headers) ->
|
|||||||
read_hval(_, Received, _, _, _) ->
|
read_hval(_, Received, _, _, _) ->
|
||||||
log(info, "~p Headers died at: ~p", [?LINE, Received]),
|
log(info, "~p Headers died at: ~p", [?LINE, Received]),
|
||||||
{error, headers}.
|
{error, headers}.
|
||||||
|
|
||||||
|
|
||||||
|
slowly_connect(Node, {get, Path}, From, Timeout) ->
|
||||||
|
HttpOptions = [{connect_timeout, 3000}, {timeout, Timeout}],
|
||||||
|
URL = lists:flatten(url(Node, Path)),
|
||||||
|
Request = {URL, []},
|
||||||
|
Result =
|
||||||
|
case httpc:request(get, Request, HttpOptions, []) of
|
||||||
|
{ok, {{_, 200, _}, _, JSON}} -> zj:decode(JSON);
|
||||||
|
{ok, {{_, BAD, _}, _, _}} -> {error, BAD};
|
||||||
|
BAD -> {error, BAD}
|
||||||
|
end,
|
||||||
|
gen_server:reply(From, Result);
|
||||||
|
slowly_connect(Node, {post, Path, Payload}, From, Timeout) ->
|
||||||
|
HttpOptions = [{connect_timeout, 3000}, {timeout, Timeout}],
|
||||||
|
URL = lists:flatten(url(Node, Path)),
|
||||||
|
Request = {URL, [], "application/json", Payload},
|
||||||
|
Result =
|
||||||
|
case httpc:request(post, Request, HttpOptions, []) of
|
||||||
|
{ok, {{_, 200, _}, _, JSON}} -> zj:decode(JSON);
|
||||||
|
{ok, {{_, BAD, _}, _, _}} -> {error, BAD};
|
||||||
|
BAD -> {error, BAD}
|
||||||
|
end,
|
||||||
|
gen_server:reply(From, Result).
|
||||||
|
|
||||||
|
|
||||||
|
url({Node, Port}, Path) when is_list(Node) ->
|
||||||
|
["https://", Node, ":", integer_to_list(Port), Path];
|
||||||
|
url({Node, Port}, Path) when is_tuple(Node) ->
|
||||||
|
["https://", inet:ntoa(Node), ":", integer_to_list(Port), Path].
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(vanillae_man).
|
-module(vanillae_man).
|
||||||
-vsn("0.3.1").
|
-vsn("0.4.1").
|
||||||
-behavior(gen_server).
|
-behavior(gen_server).
|
||||||
-author("Craig Everett <ceverett@tsuriai.jp>").
|
-author("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
-copyright("Craig Everett <ceverett@tsuriai.jp>").
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
%% Admin functions
|
%% Admin functions
|
||||||
-export([network_id/0, network_id/1,
|
-export([network_id/0, network_id/1,
|
||||||
|
tls/0, tls/1,
|
||||||
ae_nodes/0, ae_nodes/1,
|
ae_nodes/0, ae_nodes/1,
|
||||||
timeout/0, timeout/1]).
|
timeout/0, timeout/1]).
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
|
|
||||||
-record(s,
|
-record(s,
|
||||||
{network_id = "ae_mainnet" :: string(),
|
{network_id = "ae_mainnet" :: string(),
|
||||||
|
tls = false :: boolean(),
|
||||||
ae_nodes = {[], []} :: {[vanillae:ae_node()], [vanillae:ae_node()]},
|
ae_nodes = {[], []} :: {[vanillae:ae_node()], [vanillae:ae_node()]},
|
||||||
fetchers = [] :: [#fetcher{}],
|
fetchers = [] :: [#fetcher{}],
|
||||||
timeout = 5000 :: pos_integer()}).
|
timeout = 5000 :: pos_integer()}).
|
||||||
@@ -69,6 +71,18 @@ network_id(Name) ->
|
|||||||
gen_server:cast(?MODULE, {network_id, Name}).
|
gen_server:cast(?MODULE, {network_id, Name}).
|
||||||
|
|
||||||
|
|
||||||
|
-spec tls() -> boolean().
|
||||||
|
|
||||||
|
tls() ->
|
||||||
|
gen_server:call(?MODULE, tls).
|
||||||
|
|
||||||
|
|
||||||
|
-spec tls(boolean()) -> ok.
|
||||||
|
|
||||||
|
tls(Boolean) ->
|
||||||
|
gen_server:cast(?MODULE, {tls, Boolean}).
|
||||||
|
|
||||||
|
|
||||||
-spec ae_nodes() -> Used
|
-spec ae_nodes() -> Used
|
||||||
when Used :: [vanillae:ae_nodes()].
|
when Used :: [vanillae:ae_nodes()].
|
||||||
|
|
||||||
@@ -150,6 +164,8 @@ handle_call({request, Request}, From, State) ->
|
|||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_call(network_id, _, State = #s{network_id = Name}) ->
|
handle_call(network_id, _, State = #s{network_id = Name}) ->
|
||||||
{reply, Name, State};
|
{reply, Name, State};
|
||||||
|
handle_call(tls, _, State = #s{tls = TLS}) ->
|
||||||
|
{reply, TLS, State};
|
||||||
handle_call(ae_nodes, _, State = #s{ae_nodes = {Wait, Used}}) ->
|
handle_call(ae_nodes, _, State = #s{ae_nodes = {Wait, Used}}) ->
|
||||||
Nodes = lists:append(Wait, Used),
|
Nodes = lists:append(Wait, Used),
|
||||||
{reply, Nodes, State};
|
{reply, Nodes, State};
|
||||||
@@ -162,6 +178,9 @@ handle_call(Unexpected, From, State) ->
|
|||||||
|
|
||||||
handle_cast({network_id, Name}, State) ->
|
handle_cast({network_id, Name}, State) ->
|
||||||
{noreply, State#s{network_id = Name}};
|
{noreply, State#s{network_id = Name}};
|
||||||
|
handle_cast({tls, Boolean}, State) ->
|
||||||
|
NewState = do_tls(Boolean, State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_cast({ae_nodes, []}, State) ->
|
handle_cast({ae_nodes, []}, State) ->
|
||||||
{noreply, State#s{ae_nodes = none}};
|
{noreply, State#s{ae_nodes = none}};
|
||||||
handle_cast({ae_nodes, ToUse}, State) ->
|
handle_cast({ae_nodes, ToUse}, State) ->
|
||||||
@@ -220,12 +239,22 @@ terminate(_, _) ->
|
|||||||
|
|
||||||
%%% Doer Functions
|
%%% Doer Functions
|
||||||
|
|
||||||
|
do_tls(true, State) ->
|
||||||
|
ok = ssl:start(),
|
||||||
|
State#s{tls = true};
|
||||||
|
do_tls(false, State) ->
|
||||||
|
State#s{tls = false};
|
||||||
|
do_tls(_, State) ->
|
||||||
|
State.
|
||||||
|
|
||||||
|
|
||||||
do_request(_, From, State = #s{ae_nodes = {[], []}}) ->
|
do_request(_, From, State = #s{ae_nodes = {[], []}}) ->
|
||||||
ok = gen_server:reply(From, {error, no_nodes}),
|
ok = gen_server:reply(From, {error, no_nodes}),
|
||||||
State;
|
State;
|
||||||
do_request(Request,
|
do_request(Request,
|
||||||
From,
|
From,
|
||||||
State = #s{fetchers = Fetchers,
|
State = #s{tls = false,
|
||||||
|
fetchers = Fetchers,
|
||||||
ae_nodes = {[Node | Rest], Used},
|
ae_nodes = {[Node | Rest], Used},
|
||||||
timeout = Timeout}) ->
|
timeout = Timeout}) ->
|
||||||
Now = erlang:system_time(nanosecond),
|
Now = erlang:system_time(nanosecond),
|
||||||
@@ -238,6 +267,22 @@ do_request(Request,
|
|||||||
from = From,
|
from = From,
|
||||||
req = Request},
|
req = Request},
|
||||||
State#s{fetchers = [New | Fetchers], ae_nodes = {Rest, [Node | Used]}};
|
State#s{fetchers = [New | Fetchers], ae_nodes = {Rest, [Node | Used]}};
|
||||||
|
do_request(Request,
|
||||||
|
From,
|
||||||
|
State = #s{tls = true,
|
||||||
|
fetchers = Fetchers,
|
||||||
|
ae_nodes = {[Node | Rest], Used},
|
||||||
|
timeout = Timeout}) ->
|
||||||
|
Now = erlang:system_time(nanosecond),
|
||||||
|
Fetcher = fun() -> vanillae_fetcher:slowly_connect(Node, Request, From, Timeout) end,
|
||||||
|
{PID, Mon} = spawn_monitor(Fetcher),
|
||||||
|
New = #fetcher{pid = PID,
|
||||||
|
mon = Mon,
|
||||||
|
time = Now,
|
||||||
|
node = Node,
|
||||||
|
from = From,
|
||||||
|
req = Request},
|
||||||
|
State#s{fetchers = [New | Fetchers], ae_nodes = {Rest, [Node | Used]}};
|
||||||
do_request(Request, From, State = #s{ae_nodes = {[], Used}}) ->
|
do_request(Request, From, State = #s{ae_nodes = {[], Used}}) ->
|
||||||
Fresh = lists:reverse(Used),
|
Fresh = lists:reverse(Used),
|
||||||
do_request(Request, From, State#s{ae_nodes = {Fresh, []}}).
|
do_request(Request, From, State#s{ae_nodes = {Fresh, []}}).
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(vanillae_sup).
|
-module(vanillae_sup).
|
||||||
-vsn("0.3.1").
|
-vsn("0.4.1").
|
||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
-author("Craig Everett <zxq9@zxq9.com>").
|
-author("Craig Everett <zxq9@zxq9.com>").
|
||||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
{author,"Craig Everett"}.
|
{author,"Craig Everett"}.
|
||||||
{c_email,"ceverett@tsuriai.jp"}.
|
{c_email,"ceverett@tsuriai.jp"}.
|
||||||
{copyright,"Craig Everett"}.
|
{copyright,"Craig Everett"}.
|
||||||
{deps,[{"otpr","aebytecode",{3,2,1}},
|
{deps,[{"otpr","erl_base58",{0,1,0}},
|
||||||
|
{"otpr","ec_utils",{1,0,0}},
|
||||||
|
{"otpr","aebytecode",{3,2,1}},
|
||||||
{"otpr","aesophia",{7,1,2}},
|
{"otpr","aesophia",{7,1,2}},
|
||||||
{"otpr","aeserialization",{0,1,0}},
|
{"otpr","aeserialization",{0,1,0}},
|
||||||
{"otpr","zj",{1,1,0}},
|
{"otpr","zj",{1,1,0}},
|
||||||
@@ -14,9 +16,9 @@
|
|||||||
{license,"MIT"}.
|
{license,"MIT"}.
|
||||||
{modules,[]}.
|
{modules,[]}.
|
||||||
{name,"Vanillae for Erlang"}.
|
{name,"Vanillae for Erlang"}.
|
||||||
{package_id,{"otpr","vanillae",{0,3,1}}}.
|
{package_id,{"otpr","vanillae",{0,4,1}}}.
|
||||||
{prefix,"v"}.
|
{prefix,"v"}.
|
||||||
{repo_url,"https://github.com/aeternity/Vanillae"}.
|
{repo_url,"https://github.com/aeternity/Vanillae"}.
|
||||||
{tags,[]}.
|
{tags,["aeternity","blockchain","crypto","ae","defi"]}.
|
||||||
{type,app}.
|
{type,app}.
|
||||||
{ws_url,"https://github.com/aeternity/Vanillae"}.
|
{ws_url,"https://github.com/aeternity/Vanillae"}.
|
||||||
|
|||||||
Reference in New Issue
Block a user