Skip to content

Commit

Permalink
shortcut_24_54.
Browse files Browse the repository at this point in the history
  • Loading branch information
niamkik committed Nov 19, 2023
1 parent 0ca65ee commit 9c298fd
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ doc
*~
**.trace
**_build
_build**
_build**
tmp**
4 changes: 4 additions & 0 deletions apps/nostr_relay/src/nostr_relay_app.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @copyright (c) 2023 Erlang Punch
%%% @doc
%%% @end
%%%===================================================================
Expand All @@ -13,6 +15,7 @@
Type :: any(),
Args :: any(),
Return :: supervisor:startlink_ret().

start(_StartType, _StartArgs) ->
% @todo to modify. the current structure is not adapted
% for an erlang release.
Expand All @@ -25,5 +28,6 @@ start(_StartType, _StartArgs) ->
-spec stop(State) -> Return when
State :: any(),
Return :: ok.

stop(_State) ->
ok.
8 changes: 5 additions & 3 deletions apps/nostr_relay/src/nostr_relay_events.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @copyright (c) 2023 Erlang Punch
%%% @doc
%%%
%%% This module requires an important number of optimization to
Expand Down Expand Up @@ -166,7 +168,7 @@ match_event_id(#event{ id = EventId }, #filter{ event_ids = EventIds }) ->

match_event_id_test() ->
Opts = [{year,2020},{month,01},{day, 01},{hour,00},{minute,00},{second,01}],
E = nu_filter:generate_random_event(<<1:256>>, Opts),
E = ?MODULE:generate_random_event(<<1:256>>, Opts),

% a filter with an empty event_ids list should always return
% true (undefined).
Expand Down Expand Up @@ -203,7 +205,7 @@ match_event_author(#event{ public_key = Author }, #filter{ authors = Authors })
match_event_author_test() ->
Opts = [{year,2020},{month,01},{day, 01}
,{hour,00},{minute,00},{second,01}],
E = nu_filter:generate_random_event(<<1:256>>, Opts),
E = ?MODULE:generate_random_event(<<1:256>>, Opts),
{ok, Public} = nostrlib_schnorr:new_publickey(<<1:256>>),

% a filter with an empty authors list must always return true
Expand Down Expand Up @@ -240,7 +242,7 @@ match_event_kind_test() ->
Opts = [{year,2020},{month,01},{day, 01}
,{hour,00},{minute,00},{second,01}
,{kind,text_note}],
E = nu_filter:generate_random_event(<<1:256>>, Opts),
E = ?MODULE:generate_random_event(<<1:256>>, Opts),

% a filter with an empty kinds list must always return true
% here.
Expand Down
1 change: 1 addition & 0 deletions apps/nostr_relay/src/nostr_relay_handler.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @copyright (c) 2023 Erlang Punch
%%% @doc
%%%
%%% `nostr_relay_handler' module is in charge of handling cowboy
Expand Down
25 changes: 20 additions & 5 deletions apps/nostr_relay/src/nostr_relay_listener.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @copyright (c) 2023 Erlang Punch
%%% @doc `nostr_relay_listener' module is a wrapper around cowboy
%%% module to start and stop a cowboy listener. Any message
%%% received on this process will stop the listener.
Expand All @@ -10,7 +11,7 @@
-module(nostr_relay_listener).
-behavior(gen_server).
-export([start_link/1]).
-export([default_state/0, default_pipeline/0]).
-export([modules/0, default_state/0, default_pipeline/0]).
-export([init/1, terminate/2]).
-export([handle_call/3, handle_cast/2, handle_info/2]).

Expand All @@ -24,6 +25,19 @@
, pid :: pid()
}).

%%--------------------------------------------------------------------
%% @doc supported modules.
%% @end
%%--------------------------------------------------------------------
-spec modules() -> [atom()].

modules() ->
[ nostr_relay_module_init
, nostr_relay_module_nip01
, nostr_relay_module_request
, nostr_relay_module_store
].

%%--------------------------------------------------------------------
%% @doc returns the default pipeline used.
%% @end
Expand All @@ -42,10 +56,7 @@ default_pipeline() ->
-spec default_state() -> map().

default_state() ->
#{ websocket_pipeline => [ nostr_relay_module_init
, nostr_relay_module_nip01
]
}.
#{ websocket_pipeline => default_pipeline() }.

%%--------------------------------------------------------------------
%% @doc start a new listener.
Expand Down Expand Up @@ -82,6 +93,10 @@ init(Args) ->
TransportOpts = [{port, Port}],
ProtocolOpts = #{ env => #{ dispatch => Dispatch }},

% if needed, start all modules to initialize them (useful for
% databases).
nostr_relay_module:start_modules(modules()),

% craft the name containing the name of the module, the host and
% the port of this new server, and start it.
Name = {?MODULE, Host, Port},
Expand Down
24 changes: 23 additions & 1 deletion apps/nostr_relay/src/nostr_relay_module.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,32 @@
%%% @end
%%%====================================================================
-module(nostr_relay_module).
-export([init/2]).
-export([start_modules/1, init/2]).
-include_lib("kernel/include/logger.hrl").
-include_lib("nostrlib/include/nostrlib.hrl").

%%--------------------------------------------------------------------
%% @doc
%% @end
%%--------------------------------------------------------------------
-spec start_modules(Modules) -> Return when
Modules :: [atom()],
Return :: list().

start_modules(Modules) ->
[ try_start(Module) || Module <- Modules ].

%%--------------------------------------------------------------------
%%
%%--------------------------------------------------------------------
try_start(Module) ->
try
?LOG_INFO("start module ~p", [Module]),
{Module, Module:start()}
catch
E:R -> {Module, E, R}
end.

%%--------------------------------------------------------------------
%% @doc forward directly client event to our main loop. We assume the
%% data were correctly parsed.
Expand Down
18 changes: 14 additions & 4 deletions apps/nostr_relay/src/nostr_relay_module_init.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
%%%===================================================================
-module(nostr_relay_module_init).
-export([init/2]).
-include_lib("kernel/include/logger.hrl").
-include_lib("nostrlib/include/nostrlib.hrl").

%%--------------------------------------------------------------------
Expand All @@ -19,17 +20,26 @@
%%--------------------------------------------------------------------
-spec init(any(), any()) -> any().

init({text, Message}, _State) ->
% nostr relay only support text message.
init({text, Message} = Data, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Data, State]}]),
case nostrlib:decode(Message) of
{ok, Decoded, _} ->
{next, Decoded};
_ ->
Error ->
?LOG_ERROR("~p", [{self(), ?MODULE, init, [Data], Error}]),
Return = #notice{ message = <<"command not supported">> },
{stop, Return}
end;
init({binary, _}, _State) ->

% binary messages are not supported there.
init({binary, _} = Data, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Data, State]}]),
Return = #notice{ message = <<"binary not supported">> },
{stop, Return};
init(_Data, _State) ->

% all other types are just dropped
init(Data, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Data, State], unsupported}]),
Return = #notice{ message = <<"unsupported command">> },
{stop, Return}.
13 changes: 9 additions & 4 deletions apps/nostr_relay/src/nostr_relay_module_nip01.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
%%%===================================================================
-module(nostr_relay_module_nip01).
-export([init/2]).
-include_lib("kernel/include/logger.hrl").
-include_lib("nostrlib/include/nostrlib.hrl").

%%--------------------------------------------------------------------
Expand All @@ -21,21 +22,25 @@
% when an event request is received, we assume it's a valid one and it
% is directly forwarded to another module to be stored in the
% database.
init(#event{} = Event, _State) ->
init(#event{} = Event, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Event, State]}]),
{{next, nostr_relay_module_store}, Event};

% a request for subscription, when it arrives, it should already be a
% valid one and then is forwarded to the module in cahrge of the
% subscriptions.
init(#request{} = Request, _State) ->
init(#request{} = Request, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Request, State]}]),
{{next, nostr_relay_module_request}, Request};

% a close message is received and should then be forwarded to the
% module in charge of the subscriptions
init(#close{} = Close, _State) ->
init(#close{} = Close, State) ->
?LOG_DEBUG("~p", [{self(), ?MODULE, init, [Close, State]}]),
{{next, nostr_relay_module_request}, Close};

% At this time, we just assume we don't support this message.
init(_Data, _State) ->
init(Data, _State) ->
?LOG_ERROR("~p", [{self(), ?MODULE, init, [Data]}]),
Notice = #notice{ message = <<"command not supported">> },
{stop, Notice}.
65 changes: 42 additions & 23 deletions apps/nostr_relay/src/nostr_relay_module_store.erl
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @copyright (c) 2023 Erlang Punch
%%% @doc An example of nip01 implementation as module callback.
%%% @end
%%%===================================================================
-module(nostr_relay_module_store).
% nostr callback
-export([start/0]).
-export([init/2]).
-export([list_events/0, get_event/1, create_event/1]).
% store api
-export([list_events/0, get_event/1, exist_event/1, create_event/1]).
-include_lib("kernel/include/logger.hrl").
-include_lib("nostrlib/include/nostrlib.hrl").

Expand Down Expand Up @@ -35,29 +39,44 @@ start() ->
%%--------------------------------------------------------------------
-spec init(any(), any()) -> any().

init(#event{} = Event, _State) ->
init(#event{} = Event, State) ->
case create_event(Event) of
% @todo create dedicated functions for each case.
{error, exist} ->
Message = #ok{ event_id = Event#event.id
, accepted = true
, prefix = <<"duplicate">>
, message = <<"already have this event">>
},
{stop, Message};
{ok, _} ->
Message = #ok{ event_id = Event#event.id
, accepted = true },
{stop, Message};
_ ->
Message = #ok{ event_id = Event#event.id
, accepted = false
, prefix = <<"error">>
, message = <<"could not connect to the database">>
},
{stop, Message}
{error, exist} -> duplicated_event(Event, State);
{ok, _} -> inserted_event(Event, State);
_ -> database_error(Event, State)
end.

%%--------------------------------------------------------------------
%%
%%--------------------------------------------------------------------
database_error(Event, _State) ->
Message = #ok{ event_id = Event#event.id
, accepted = false
, prefix = <<"error">>
, message = <<"could not connect to the database">>
},
{stop, Message}.

%%--------------------------------------------------------------------
%%
%%--------------------------------------------------------------------
inserted_event(Event, _State) ->
Message = #ok{ event_id = Event#event.id
, accepted = true },
{stop, Message}.

%%--------------------------------------------------------------------
%%
%%--------------------------------------------------------------------
duplicated_event(Event, _State) ->
Message = #ok{ event_id = Event#event.id
, accepted = true
, prefix = <<"duplicate">>
, message = <<"already have this event">>
},
{stop, Message}.


%%--------------------------------------------------------------------
%% @doc returns one element from the database using an event record.
%% @end
Expand Down Expand Up @@ -100,10 +119,10 @@ list_events() ->
-spec create_event(event()) -> any().

create_event(#event{} = Event) ->
Fun = fun() ->
Fun = fun() ->
case exist_event(Event) of
true -> exist;
false -> mnesia:write(Event)
false -> mnesia:write(Event)
end
end,
case mnesia:transaction(Fun) of
Expand Down
20 changes: 9 additions & 11 deletions apps/nostr_relay/src/nostr_relay_sup.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
%%%===================================================================
%%% @author Mathieu Kerjouan <contact at erlang-punch.com>
%%% @doc DRAFT
%%% @copyright (c) 2023 Erlang Punch
%%% @doc This supervisor start automatically one listener, listening
%%% by default on ws://localhost:4000.
%%%
%%% @todo improve start_relay_listener/2 function
%%% @end
Expand All @@ -21,6 +23,7 @@
-spec start_link(Args) -> Return when
Args :: proplists:proplists(),
Return :: supervisor:startlink_ret().

start_link(Args) ->
supervisor:start_link(?MODULE, Args).

Expand All @@ -33,6 +36,7 @@ start_link(Args) ->
Return :: {ok,{SupFlags,[ChildSpec]}} | ignore,
SupFlags :: supervisor:sup_flags(),
ChildSpec :: supervisor:child_spec().

init(Args) ->
Children = children(Args),
State = {supervisor(), Children},
Expand All @@ -42,14 +46,8 @@ init(Args) ->
%% @doc
%% @end
%%--------------------------------------------------------------------
children(Args) ->
[ spec_relay_listener(Args)
, spec_relay_store(Args)
, spec_relay_subscription_sup(Args)
, #{ id => pg
, start => {pg, start_link, [nostr_relay]}
, type => worker
}
children(_) ->
[ spec_relay_listener(#{})
].

%%--------------------------------------------------------------------
Expand All @@ -67,9 +65,9 @@ supervisor() ->
-spec spec_relay_listener(Args) -> Return when
Args :: proplists:proplists(),
Return :: supervisor:child_spec().

spec_relay_listener(Args) ->
Port = proplists:get_value(port, Args, 4000),
#{ id => {nostr_relay_listener, Port}
#{ id => nostr_relay_listener
, start => {nostr_relay_listener, start_link, [Args]}
, type => worker
}.
Expand Down
Loading

0 comments on commit 9c298fd

Please sign in to comment.