start spy process
This commit is contained in:
parent
8a9f060b2d
commit
be6aceb41a
177
src/fd_spy.erl
Normal file
177
src/fd_spy.erl
Normal file
@ -0,0 +1,177 @@
|
||||
% @doc spy: knows constraints {recipient, amount, payload}
|
||||
%
|
||||
% spies the chain for transactions that satisfy that constraint
|
||||
%
|
||||
-module(fd_spy).
|
||||
-vsn("0.2.0").
|
||||
|
||||
% MVP: register search patterns
|
||||
% simply print to console when one of them is found
|
||||
|
||||
-behavior(gen_server).
|
||||
|
||||
-export_type([
|
||||
]).
|
||||
|
||||
-export([
|
||||
%% caller context
|
||||
reg/3,
|
||||
|
||||
%% api
|
||||
start_link/0,
|
||||
|
||||
%% process context
|
||||
init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
code_change/3, terminate/2
|
||||
]).
|
||||
|
||||
% recipient is a string
|
||||
-type pubkey32() :: <<_:256>>.
|
||||
|
||||
-record(sp,
|
||||
{recipient :: pubkey32(),
|
||||
amount :: pos_integer(),
|
||||
payload :: binary()}).
|
||||
-type search_pattern() :: #sp{}.
|
||||
|
||||
-record(s,
|
||||
{searching_for = [] :: search_pattern()}).
|
||||
|
||||
-type state() :: #s{}.
|
||||
|
||||
-include("$zx_include/zx_logger.hrl").
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% caller context
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
-spec reg(Recipient, Amount, Payload) -> ok | {error, Reason}
|
||||
when Recipient :: pubkey32(),
|
||||
Amount :: pos_integer(),
|
||||
Payload :: binary(),
|
||||
Reason :: any().
|
||||
|
||||
reg(R, A, P) when is_binary(R), byte_size(R) =:= 32,
|
||||
is_integer(A), A >= 0,
|
||||
is_binary(P) ->
|
||||
gen_server:call(?MODULE, {reg, R, A, P}).
|
||||
|
||||
|
||||
|
||||
%% gen_server callbacks
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, none, []).
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% process context below this line
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
%% gen_server callbacks
|
||||
|
||||
-spec init(none) -> {ok, state()}.
|
||||
|
||||
init(none) ->
|
||||
tell("starting fd_spy"),
|
||||
InitState = #s{},
|
||||
{ok, InitState}.
|
||||
|
||||
|
||||
|
||||
-spec handle_call(Msg, From, State) -> Result
|
||||
when Msg :: any(),
|
||||
From :: {pid(), reference()},
|
||||
State :: state(),
|
||||
Result :: {reply, Reply, NewState}
|
||||
| {noreply, NewState},
|
||||
Reply :: any(),
|
||||
NewState :: state().
|
||||
|
||||
handle_call({reg, Recipient, Amount, Payload}, _From, State) ->
|
||||
{Reply, NewState} = do_reg(Recipient, Amount, Payload, State),
|
||||
{reply, Reply, NewState};
|
||||
handle_call(Unexpected, From, State) ->
|
||||
tell("~tp: unexpected call from ~tp: ~tp", [?MODULE, Unexpected, From]),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
|
||||
handle_cast(Unexpected, State) ->
|
||||
tell("~tp: unexpected cast: ~tp", [?MODULE, Unexpected]),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
|
||||
handle_info(Unexpected, State) ->
|
||||
tell("~tp: unexpected info: ~tp", [?MODULE, Unexpected]),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
|
||||
code_change(_, State, _) ->
|
||||
{ok, State}.
|
||||
|
||||
|
||||
|
||||
terminate(_, _) ->
|
||||
ok.
|
||||
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% internals
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
-spec do_reg(Recipient, Amount, Payload, State) -> {Reply, NewState}
|
||||
when Recipient :: pubkey32(),
|
||||
Amount :: pos_integer(),
|
||||
Payload :: binary(),
|
||||
State :: state(),
|
||||
Reply :: ok
|
||||
| {error, Reason},
|
||||
Reason :: any(),
|
||||
NewState :: state().
|
||||
|
||||
do_reg(Recipient, Amount, Payload, State) ->
|
||||
case already_registered(Recipient, Payload, State) of
|
||||
true -> {error, already_registered};
|
||||
false -> really_register(Recipient, Amount, Payload, State)
|
||||
end.
|
||||
|
||||
|
||||
|
||||
-spec already_registered(Recipient, Payload, State) -> boolean()
|
||||
when Recipient :: pubkey32(),
|
||||
Payload :: binary(),
|
||||
State :: state().
|
||||
|
||||
already_registered(Recipient, Payload, _State = #s{searching_for = SPs}) ->
|
||||
ar(Recipient, Payload, SPs).
|
||||
|
||||
ar(Recipient, Payload, [#sp{recipient=Recipient, payload=Payload} | _]) ->
|
||||
true;
|
||||
ar(Recipient, Payload, [_ | Rest]) ->
|
||||
ar(Recipient, Payload, Rest);
|
||||
ar(_, _, []) ->
|
||||
false.
|
||||
|
||||
|
||||
|
||||
-spec really_register(Recipient, Amount, Payload, State) -> {Reply, NewState}
|
||||
when Recipient :: pubkey32(),
|
||||
Amount :: pos_integer(),
|
||||
Payload :: binary(),
|
||||
State :: state(),
|
||||
Reply :: ok
|
||||
| {error, Reason},
|
||||
Reason :: any(),
|
||||
NewState :: state().
|
||||
|
||||
really_register(R, A, P, State = #s{searching_for = SPs}) ->
|
||||
NewSearchPattern = #sp{recipient = R,
|
||||
amount = A,
|
||||
payload = P},
|
||||
tell("~tp: really_register(~tp,~tp,~tp)", [?MODULE, R, A, P]),
|
||||
NewSearchPatterns = [NewSearchPattern | SPs],
|
||||
NewState = State#s{searching_for = NewSearchPatterns},
|
||||
{reply, ok, NewState}.
|
||||
@ -36,6 +36,12 @@ start_link() ->
|
||||
|
||||
init([]) ->
|
||||
RestartStrategy = {one_for_one, 1, 60},
|
||||
Spy = {fd_spy,
|
||||
{fd_spy, start_link, []},
|
||||
permanent,
|
||||
5000,
|
||||
worker,
|
||||
[fd_spy]},
|
||||
GridsD = {fd_gridsd,
|
||||
{fd_gridsd, start_link, []},
|
||||
permanent,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user