iface #16
@ -3,6 +3,6 @@
|
|||||||
{registered,[]},
|
{registered,[]},
|
||||||
{included_applications,[]},
|
{included_applications,[]},
|
||||||
{applications,[stdlib,kernel]},
|
{applications,[stdlib,kernel]},
|
||||||
{vsn,"0.3.6"},
|
{vsn,"0.4.0"},
|
||||||
{modules,[gajumine,gmc_con,gmc_conf,gmc_gui,gmc_sup]},
|
{modules,[gajumine,gmc_con,gmc_conf,gmc_gui,gmc_sup]},
|
||||||
{mod,{gajumine,[]}}]}.
|
{mod,{gajumine,[]}}]}.
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(gajumine).
|
-module(gajumine).
|
||||||
-vsn("0.3.6").
|
-vsn("0.4.0").
|
||||||
-behavior(application).
|
-behavior(application).
|
||||||
-author("Craig Everett <craigeverett@qpq.swiss>").
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
||||||
|
|||||||
135
src/gmc_con.erl
135
src/gmc_con.erl
@ -3,7 +3,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(gmc_con).
|
-module(gmc_con).
|
||||||
-vsn("0.3.6").
|
-vsn("0.4.0").
|
||||||
-author("Craig Everett <craigeverett@qpq.swiss>").
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
@ -23,15 +23,16 @@
|
|||||||
|
|
||||||
|
|
||||||
-record(s,
|
-record(s,
|
||||||
{version = 1 :: integer(),
|
{version = 1 :: integer(),
|
||||||
window = none :: none | wx:wx_object(),
|
window = none :: none | wx:wx_object(),
|
||||||
network = <<"mainnet">> :: binary(), % <<"testnet">> | <<"mainnet">>
|
network = <<"mainnet">> :: binary(), % <<"testnet">> | <<"mainnet">>
|
||||||
acc = none :: none | binary(),
|
acc = none :: none | binary(),
|
||||||
keys = [] :: [],
|
keys = [] :: [],
|
||||||
max_cores = 2 :: pos_integer(),
|
max_cores = 2 :: pos_integer(),
|
||||||
max_mem = 3550722201 :: pos_integer(),
|
max_mem = 3550722201 :: pos_integer(),
|
||||||
prefs = #{} :: #{},
|
prefs = #{} :: #{},
|
||||||
gmc_conf = none :: none | reference()}).
|
gmc_conf = none :: none | reference(),
|
||||||
|
toggle = {stop, 0} :: {start | stop, integer()}}).
|
||||||
|
|
||||||
-type state() :: #s{}.
|
-type state() :: #s{}.
|
||||||
|
|
||||||
@ -102,15 +103,15 @@ start_link() ->
|
|||||||
init(none) ->
|
init(none) ->
|
||||||
ok = log(info, "Starting"),
|
ok = log(info, "Starting"),
|
||||||
{AProcs, AMem} = proc_mem(),
|
{AProcs, AMem} = proc_mem(),
|
||||||
TwoMaps = default_spec(mem) * 2,
|
TwoGraphs = default_spec(mem) * 2,
|
||||||
RProcs =
|
RProcs =
|
||||||
case AProcs >= 2 of
|
case AProcs >= 2 of
|
||||||
true -> 2;
|
true -> 2;
|
||||||
false -> 1
|
false -> 1
|
||||||
end,
|
end,
|
||||||
RMem =
|
RMem =
|
||||||
case AMem >= TwoMaps of
|
case AMem >= TwoGraphs of
|
||||||
true -> TwoMaps;
|
true -> TwoGraphs;
|
||||||
false -> default_spec(mem)
|
false -> default_spec(mem)
|
||||||
end,
|
end,
|
||||||
{Acc, Keys, Network, MaxCores, MaxMem} =
|
{Acc, Keys, Network, MaxCores, MaxMem} =
|
||||||
@ -125,6 +126,14 @@ init(none) ->
|
|||||||
{none, [], <<"mainnet">>, RProcs, RMem}
|
{none, [], <<"mainnet">>, RProcs, RMem}
|
||||||
end,
|
end,
|
||||||
State = #s{network = Network, acc = Acc, keys = Keys, max_cores = MaxCores, max_mem = MaxMem},
|
State = #s{network = Network, acc = Acc, keys = Keys, max_cores = MaxCores, max_mem = MaxMem},
|
||||||
|
Events =
|
||||||
|
[pool_notification,
|
||||||
|
connected,
|
||||||
|
puzzle,
|
||||||
|
result,
|
||||||
|
error,
|
||||||
|
disconnected],
|
||||||
|
ok = lists:foreach(fun gmhc_events:ensure_subscribed/1, Events),
|
||||||
{ok, start_gui(State)}.
|
{ok, start_gui(State)}.
|
||||||
|
|
||||||
|
|
||||||
@ -155,8 +164,8 @@ handle_call(Unexpected, From, State) ->
|
|||||||
|
|
||||||
|
|
||||||
handle_cast(start_stop, State) ->
|
handle_cast(start_stop, State) ->
|
||||||
ok = do_start_stop(State),
|
NewState = do_start_stop(State),
|
||||||
{noreply, State};
|
{noreply, NewState};
|
||||||
handle_cast(gajudesk, State) ->
|
handle_cast(gajudesk, State) ->
|
||||||
ok = do_gajudesk(),
|
ok = do_gajudesk(),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
@ -176,7 +185,7 @@ handle_cast(Unexpected, State) ->
|
|||||||
|
|
||||||
|
|
||||||
handle_info({gproc_ps_event, Event, Data}, State) ->
|
handle_info({gproc_ps_event, Event, Data}, State) ->
|
||||||
ok = gmc_gui:message({Event, Data}),
|
ok = gproc_ps_event({Event, Data}),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_info({'DOWN', Mon, process, PID, Info}, State = #s{gmc_conf = Mon}) ->
|
handle_info({'DOWN', Mon, process, PID, Info}, State = #s{gmc_conf = Mon}) ->
|
||||||
ok = log(info, "gmc_conf ~p closed with ~p", [PID, Info]),
|
ok = log(info, "gmc_conf ~p closed with ~p", [PID, Info]),
|
||||||
@ -187,6 +196,14 @@ handle_info(Unexpected, State) ->
|
|||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
|
|
||||||
|
gproc_ps_event(Info = {disconnected, #{info := #{reconnecting := false, error := #{code := Code, message := Message}}}}) ->
|
||||||
|
ok = log(error, "Error terminal event received. Code: ~p. Message: ~p", [Code, Message]),
|
||||||
|
ok = gmc_gui:message(Info),
|
||||||
|
gmc_gui:start_stop();
|
||||||
|
gproc_ps_event(Info) ->
|
||||||
|
gmc_gui:message(Info).
|
||||||
|
|
||||||
|
|
||||||
code_change(_, State, _) ->
|
code_change(_, State, _) ->
|
||||||
{ok, State}.
|
{ok, State}.
|
||||||
|
|
||||||
@ -204,15 +221,25 @@ terminate(Reason, State) ->
|
|||||||
|
|
||||||
|
|
||||||
do_stop() ->
|
do_stop() ->
|
||||||
case is_pid(whereis(gd_con)) of
|
zx:stop().
|
||||||
false -> zx:stop();
|
|
||||||
true -> application:stop(gajumine)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
%%% Doers
|
%%% Doers
|
||||||
|
|
||||||
do_start_stop(#s{acc = PubKey, keys = Keys, network = Network, max_cores = MaxCores, max_mem = MaxMem}) ->
|
do_start_stop(State = #s{toggle = {Last, TS}}) ->
|
||||||
|
Now = erlang:system_time(second),
|
||||||
|
Clicklimit = Now - 1,
|
||||||
|
case TS < Clicklimit of
|
||||||
|
true ->
|
||||||
|
case Last of
|
||||||
|
stop -> do_start(State#s{toggle = {start, Now}});
|
||||||
|
start -> do_stop(State#s{toggle = {stop, Now}})
|
||||||
|
end;
|
||||||
|
false -> State
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
do_start(State = #s{acc = PubKey, keys = Keys, network = Network, max_cores = MaxCores, max_mem = MaxMem}) ->
|
||||||
% smrt guy stuff happens here
|
% smrt guy stuff happens here
|
||||||
{Bits, Eureka} =
|
{Bits, Eureka} =
|
||||||
case Network of
|
case Network of
|
||||||
@ -251,32 +278,35 @@ do_start_stop(#s{acc = PubKey, keys = Keys, network = Network, max_cores = MaxCo
|
|||||||
ok = gmc_gui:message({notice, "Starting..."}),
|
ok = gmc_gui:message({notice, "Starting..."}),
|
||||||
ok = gmc_gui:message({notice, ["Miner: ", Miner]}),
|
ok = gmc_gui:message({notice, ["Miner: ", Miner]}),
|
||||||
{ok, Apps} = gmhc_app:start(Profile),
|
{ok, Apps} = gmhc_app:start(Profile),
|
||||||
Started = io_lib:format("Apps started: ~p", [Apps]),
|
Started = io_lib:format("Apps started:~n ~p", [Apps]),
|
||||||
ok = log(info, Started),
|
ok = log(info, Started),
|
||||||
ok = gmc_gui:message({notice, Started}),
|
ok = gmc_gui:message({notice, Started}),
|
||||||
Events =
|
State.
|
||||||
[pool_notification,
|
|
||||||
connected,
|
|
||||||
puzzle,
|
do_stop(State) ->
|
||||||
result,
|
ok = gmc_gui:message({notice, "Stopping."}),
|
||||||
error,
|
ok =
|
||||||
disconnected],
|
case application:stop(gmhive_client) of
|
||||||
lists:foreach(fun gmhc_events:ensure_subscribed/1, Events).
|
ok -> ok;
|
||||||
|
Error -> log(warning, "application:stop(gmhive_client) returned: ~p", [Error])
|
||||||
|
end,
|
||||||
|
State.
|
||||||
|
|
||||||
|
|
||||||
optimize_count(MaxC, MaxM) ->
|
optimize_count(MaxC, MaxM) ->
|
||||||
MapSize = 3550722201,
|
GraphSize = 3550722201,
|
||||||
MaxCores = max(1, MaxC),
|
MaxCores = max(1, MaxC),
|
||||||
MaxMem = max(MapSize, MaxM),
|
MaxMem = max(GraphSize, MaxM),
|
||||||
{Procs, Memory} = proc_mem(),
|
{Procs, Memory} = proc_mem(),
|
||||||
MeanMaps = min(MaxMem, Memory) div MapSize,
|
MeanGraphs = min(MaxMem, Memory) div GraphSize,
|
||||||
Recommended = min(MaxCores, min(Procs, MeanMaps)),
|
Recommended = min(MaxCores, min(Procs, MeanGraphs)),
|
||||||
Notice = fun(F, A) -> gmc_gui:message({notice, io_lib:format(F, A)}) end,
|
Notice = fun(F, A) -> gmc_gui:message({notice, io_lib:format(F, A)}) end,
|
||||||
ok = Notice("Physical Processors: ~p", [Procs]),
|
ok = Notice("Physical Processors: ~p", [Procs]),
|
||||||
ok = Notice("Physical Memory: ~p", [Memory]),
|
ok = Notice("Physical Memory: ~p", [Memory]),
|
||||||
ok = Notice("Max Processor Commit: ~p", [MaxCores]),
|
ok = Notice("Max Processor Commit: ~p", [MaxCores]),
|
||||||
ok = Notice("Max Memory Commit: ~p", [MaxMem]),
|
ok = Notice("Max Memory Commit: ~p", [MaxMem]),
|
||||||
ok = Notice("29-bit Mean Map Space: ~p", [MeanMaps]),
|
ok = Notice("29-bit Mean Graph Space: ~p", [MeanGraphs]),
|
||||||
ok = Notice("Workers: ~p", [Recommended]),
|
ok = Notice("Workers: ~p", [Recommended]),
|
||||||
Recommended.
|
Recommended.
|
||||||
|
|
||||||
@ -344,23 +374,26 @@ win_mem() ->
|
|||||||
|
|
||||||
|
|
||||||
do_gajudesk() ->
|
do_gajudesk() ->
|
||||||
ok = tell(info, "Running gajudesk"),
|
ok = log(info, "Running gajudesk"),
|
||||||
PID = spawn(fun run_gajudesk/0),
|
GajuDesk = "zx run gajudesk",
|
||||||
tell(info, "GajuDesk launched at PID: ~p", [PID]).
|
Command =
|
||||||
|
case os:type() of
|
||||||
|
{unix, darwin} -> detach_darwin(GajuDesk);
|
||||||
|
{unix, _} -> detach_unix(GajuDesk);
|
||||||
|
{win32, nt} -> detach_windows(GajuDesk)
|
||||||
|
end,
|
||||||
|
Out = os:cmd(Command),
|
||||||
|
log(info, "os:cmd(~s) -> ~s", [Command, Out]).
|
||||||
|
|
||||||
run_gajudesk() ->
|
detach_darwin(Command) ->
|
||||||
R = "otpr",
|
"nohup " ++ Command ++ " >/dev/null 2>&1 & disown".
|
||||||
N = "gajudesk",
|
|
||||||
{ok, V} = zx:latest({R, N}),
|
detach_unix(Command) ->
|
||||||
{ok, PackageString} = zx_lib:package_string({R, N, V}),
|
"setsid sh -c 'exec nohup " ++ Command ++ " >/dev/null 2>&1' &".
|
||||||
try
|
|
||||||
case zx:run(PackageString, []) of
|
detach_windows(Command) ->
|
||||||
ok -> ok;
|
PSCmd = "Start-Process -WindowStyle Hidden -FilePath cmd.exe -ArgumentList '/c " ++ Command ++ "'",
|
||||||
Error -> tell(error, "gajudesk died with: ~p", [Error])
|
"powershell -NoProfile -Command \"" ++ PSCmd ++ "\"".
|
||||||
end
|
|
||||||
catch
|
|
||||||
E:R -> tell(error, "gajudesk died with: ~p", [{E, R}])
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
run_gmc_conf(State = #s{gmc_conf = none, network = Net, acc = Acc, keys = Keys,
|
run_gmc_conf(State = #s{gmc_conf = none, network = Net, acc = Acc, keys = Keys,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(gmc_conf).
|
-module(gmc_conf).
|
||||||
-vsn("0.3.6").
|
-vsn("0.4.0").
|
||||||
-author("Craig Everett <craigeverett@qpq.swiss>").
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
@ -60,27 +60,30 @@ init({Prefs, {Net, Acc, Keys, {AProcs, AMem, MProcs, MMem}}}) ->
|
|||||||
|
|
||||||
WX = wx:new(),
|
WX = wx:new(),
|
||||||
Frame = wxFrame:new(WX, ?wxID_ANY, Label),
|
Frame = wxFrame:new(WX, ?wxID_ANY, Label),
|
||||||
|
Panel = wxWindow:new(Frame, ?wxID_ANY),
|
||||||
|
TopSz = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
_ = wxBoxSizer:add(TopSz, Panel, zxw:flags(wide)),
|
||||||
MainSz = wxBoxSizer:new(?wxVERTICAL),
|
MainSz = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
|
||||||
AccSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("GajuMining Account ID")}]),
|
AccSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("GajuMining Account ID")}]),
|
||||||
AccTx = wxTextCtrl:new(Frame, ?wxID_ANY, [{value, acc(Acc)}]),
|
AccTx = wxTextCtrl:new(Panel, ?wxID_ANY, [{value, acc(Acc)}]),
|
||||||
_ = wxStaticBoxSizer:add(AccSz, AccTx, wide(5)),
|
_ = wxStaticBoxSizer:add(AccSz, AccTx, wide(5)),
|
||||||
KeysSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Additional Account IDs (optional)")}]),
|
KeysSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Additional Account IDs (optional)")}]),
|
||||||
KeysTx = wxTextCtrl:new(Frame, ?wxID_ANY, [{style, ?wxTE_MULTILINE}, {value, keys(Keys)}]),
|
KeysTx = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, ?wxTE_MULTILINE}, {value, keys(Keys)}]),
|
||||||
_ = wxStaticBoxSizer:add(KeysSz, KeysTx, wide(5)),
|
_ = wxStaticBoxSizer:add(KeysSz, KeysTx, wide(5)),
|
||||||
StatSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Max System Committment (optional)")}]),
|
StatSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Max System Committment (optional)")}]),
|
||||||
AProcsS = i_to_l(AProcs),
|
AProcsS = i_to_l(AProcs),
|
||||||
MProcsS = i_to_l(MProcs),
|
MProcsS = i_to_l(MProcs),
|
||||||
AMemS = gigs(AMem),
|
AMemS = gigs(AMem),
|
||||||
MMemS = gigs(MMem),
|
MMemS = gigs(MMem),
|
||||||
Labels = [{J("HW Cores"), J("Max Cores"), AProcsS, MProcsS}, {J("Memory (GB)"), J("Max Memory"), AMemS, MMemS}],
|
Labels = [{J("HW Cores"), J("Max Cores"), AProcsS, MProcsS}, {J("Memory (GB)"), J("Max Memory"), AMemS, MMemS}],
|
||||||
{Grid, [CoresTx, MemoryTx]} = display_box(Frame, Labels),
|
{Grid, [CoresTx, MemoryTx]} = display_box(Panel, Labels),
|
||||||
Network = wxRadioBox:new(Frame, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]),
|
Network = wxRadioBox:new(Panel, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]),
|
||||||
ok = wxRadioBox:setSelection(Network, net_num(Net)),
|
ok = wxRadioBox:setSelection(Network, net_num(Net)),
|
||||||
|
|
||||||
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
Affirm = wxButton:new(Frame, ?wxID_OK),
|
Affirm = wxButton:new(Panel, ?wxID_OK),
|
||||||
Cancel = wxButton:new(Frame, ?wxID_CANCEL),
|
Cancel = wxButton:new(Panel, ?wxID_CANCEL),
|
||||||
_ = wxBoxSizer:add(StatSz, Grid, wide(5)),
|
_ = wxBoxSizer:add(StatSz, Grid, wide(5)),
|
||||||
_ = wxBoxSizer:add(ButtSz, Affirm, wide(5)),
|
_ = wxBoxSizer:add(ButtSz, Affirm, wide(5)),
|
||||||
_ = wxBoxSizer:add(ButtSz, Cancel, wide(5)),
|
_ = wxBoxSizer:add(ButtSz, Cancel, wide(5)),
|
||||||
@ -89,7 +92,8 @@ init({Prefs, {Net, Acc, Keys, {AProcs, AMem, MProcs, MMem}}}) ->
|
|||||||
_ = wxBoxSizer:add(MainSz, StatSz, base(5)),
|
_ = wxBoxSizer:add(MainSz, StatSz, base(5)),
|
||||||
_ = wxBoxSizer:add(MainSz, Network, base(5)),
|
_ = wxBoxSizer:add(MainSz, Network, base(5)),
|
||||||
_ = wxBoxSizer:add(MainSz, ButtSz, base(5)),
|
_ = wxBoxSizer:add(MainSz, ButtSz, base(5)),
|
||||||
ok = wxFrame:setSizer(Frame, MainSz),
|
ok = wxWindow:setSizer(Panel, MainSz),
|
||||||
|
ok = wxFrame:setSizer(Frame, TopSz),
|
||||||
ok = wxBoxSizer:layout(MainSz),
|
ok = wxBoxSizer:layout(MainSz),
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
@ -209,9 +213,34 @@ done(State = #s{net = Network, acc = AccTx, keys = KeysTx, cores = CoresTx, memo
|
|||||||
MOAR_IDs = wxTextCtrl:getValue(KeysTx),
|
MOAR_IDs = wxTextCtrl:getValue(KeysTx),
|
||||||
CoreS = wxTextCtrl:getValue(CoresTx),
|
CoreS = wxTextCtrl:getValue(CoresTx),
|
||||||
GigsS = wxTextCtrl:getValue(MemTx),
|
GigsS = wxTextCtrl:getValue(MemTx),
|
||||||
ok = gmc_con:conf({Net, list_to_binary(AccID), binify_keys(MOAR_IDs), cores(CoreS), bytes(GigsS)}),
|
ok = gmc_con:conf({Net, list_to_binary(AccID), binify_keys(AccID, MOAR_IDs), cores(CoreS), bytes(GigsS)}),
|
||||||
buh_bye(State).
|
buh_bye(State).
|
||||||
|
|
||||||
|
|
||||||
|
% NOTE: 32 is space, 12288 is full-width space.
|
||||||
|
binify_keys(AccID, MOAR) ->
|
||||||
|
Unwashed = lists:usort([K || K <- string:lexemes(MOAR, [$\r, $\n, 32, 12288, $\t, $,, $;])]),
|
||||||
|
Scrubbed = lists:delete(AccID, Unwashed),
|
||||||
|
Keys =
|
||||||
|
case lists:partition(fun is_key/1, Scrubbed) of
|
||||||
|
{Cleaned, []} ->
|
||||||
|
Cleaned;
|
||||||
|
{Cleaned, Trash} ->
|
||||||
|
Message = io_lib:format("The following keys are invalid:~n~p", [Trash]),
|
||||||
|
ok = gmc_gui:message({notice, Message}),
|
||||||
|
Cleaned
|
||||||
|
end,
|
||||||
|
lists:map(fun list_to_binary/1, Keys).
|
||||||
|
|
||||||
|
is_key(Mystery) ->
|
||||||
|
try
|
||||||
|
{account_pubkey, _} = gmser_api_encoder:decode(Mystery),
|
||||||
|
true
|
||||||
|
catch
|
||||||
|
_:_ -> false
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
cores("") ->
|
cores("") ->
|
||||||
2;
|
2;
|
||||||
cores(CoreS) ->
|
cores(CoreS) ->
|
||||||
@ -221,6 +250,7 @@ cores(CoreS) ->
|
|||||||
_:_ -> 2
|
_:_ -> 2
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
bytes("") ->
|
bytes("") ->
|
||||||
3550722201;
|
3550722201;
|
||||||
bytes(GigsS) ->
|
bytes(GigsS) ->
|
||||||
@ -236,11 +266,6 @@ bytes(GigsS) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
% NOTE: 32 is space, 12288 is full-width space.
|
|
||||||
binify_keys(MOAR) ->
|
|
||||||
lists:usort([list_to_binary(K) || K <- string:lexemes(MOAR, [$\r, $\n, 32, 12288, $\t, $,, $;])]).
|
|
||||||
|
|
||||||
|
|
||||||
acc(none) -> "";
|
acc(none) -> "";
|
||||||
acc(AKID) -> AKID.
|
acc(AKID) -> AKID.
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(gmc_gui).
|
-module(gmc_gui).
|
||||||
-vsn("0.3.6").
|
-vsn("0.4.0").
|
||||||
-author("Craig Everett <craigeverett@qpq.swiss>").
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
@ -23,21 +23,23 @@
|
|||||||
wx = none :: none | wx:wx_object()}).
|
wx = none :: none | wx:wx_object()}).
|
||||||
|
|
||||||
-record(s,
|
-record(s,
|
||||||
{wx = none :: none | wx:wx_object(),
|
{wx = none :: none | wx:wx_object(),
|
||||||
frame = none :: none | wx:wx_object(),
|
frame = none :: none | wx:wx_object(),
|
||||||
lang = en :: en | jp,
|
lang = en :: en | jp,
|
||||||
j = none :: none | fun(),
|
j = none :: none | fun(),
|
||||||
id = none :: none | wx:wx_object(),
|
id = none :: none | wx:wx_object(),
|
||||||
diff = none :: none | wx:wx_object(),
|
diff = none :: none | wx:wx_object(),
|
||||||
perf = none :: none | wx:wx_object(),
|
perf = none :: none | wx:wx_object(),
|
||||||
hist = {ts(), 0} :: {LastTS :: integer(), Average :: integer()},
|
hist = {ts(), 0} :: {LastTS :: integer(), Average :: integer()},
|
||||||
candy = none :: none | wx:wx_object(),
|
candy = none :: none | wx:wx_object(),
|
||||||
height = none :: none | wx:wx_object(),
|
height = none :: none | wx:wx_object(),
|
||||||
block = none :: none | wx:wx_object(),
|
block = none :: none | wx:wx_object(),
|
||||||
% solved = 0 :: non_neg_integer(), % TODO: Add a widget to show this. Maybe
|
% solved = 0 :: non_neg_integer(), % TODO: Add a widget to show this. Maybe
|
||||||
mess = none :: none | wx:wx_object(),
|
mess = none :: none | wx:wx_object(),
|
||||||
buff = new_buff() :: buff(),
|
buff = new_buff() :: buff(),
|
||||||
buttons = [] :: [#w{}]}).
|
buttons = [] :: [#w{}],
|
||||||
|
toggle = start :: stop | start,
|
||||||
|
toggle_t = none :: none | reference()}).
|
||||||
|
|
||||||
ts() ->
|
ts() ->
|
||||||
erlang:system_time(microsecond).
|
erlang:system_time(microsecond).
|
||||||
@ -99,18 +101,21 @@ init(Prefs) ->
|
|||||||
VSN = proplists:get_value(vsn, ?MODULE:module_info(attributes)),
|
VSN = proplists:get_value(vsn, ?MODULE:module_info(attributes)),
|
||||||
WX = wx:new(),
|
WX = wx:new(),
|
||||||
Frame = wxFrame:new(WX, ?wxID_ANY, AppName ++ " v" ++ VSN),
|
Frame = wxFrame:new(WX, ?wxID_ANY, AppName ++ " v" ++ VSN),
|
||||||
|
Panel = wxWindow:new(Frame, ?wxID_ANY),
|
||||||
|
TopSz = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
_ = wxBoxSizer:add(TopSz, Panel, zxw:flags(wide)),
|
||||||
MainSz = wxBoxSizer:new(?wxVERTICAL),
|
MainSz = wxBoxSizer:new(?wxVERTICAL),
|
||||||
LeftRight = wxBoxSizer:new(?wxHORIZONTAL),
|
LeftRight = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
Left = wxBoxSizer:new(?wxVERTICAL),
|
Left = wxBoxSizer:new(?wxVERTICAL),
|
||||||
Right = wxBoxSizer:new(?wxVERTICAL),
|
Right = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
|
||||||
Labels = [J("ID"), J("Target"), J("Maps/s"), J("Candidate"), J("Height"), J("BlockHash")],
|
Labels = [J("ID"), J("Target"), J("Graphs/s"), J("Candidate"), J("Height"), J("BlockHash")],
|
||||||
{Grid, [ID_C, DiffC, PerfC, CandyC, HeightC, BlockC]} = display_box(Frame, Labels),
|
{Grid, [ID_C, DiffC, PerfC, CandyC, HeightC, BlockC]} = display_box(Panel, Labels),
|
||||||
|
|
||||||
Style = ?wxTE_MULTILINE bor ?wxTE_READONLY,
|
Style = ?wxTE_MULTILINE bor ?wxTE_READONLY,
|
||||||
MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Messages")}]),
|
MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Messages")}]),
|
||||||
MessC = wxTextCtrl:new(Frame, ?wxID_ANY, [{style, Style}]),
|
MessC = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, Style}]),
|
||||||
_ = wxStaticBoxSizer:add(MessSz, MessC, zxw:flags(wide)),
|
_ = wxStaticBoxSizer:add(MessSz, MessC, zxw:flags({wide, 5})),
|
||||||
|
|
||||||
ButtonTemplates =
|
ButtonTemplates =
|
||||||
[{start_stop, J("Start")},
|
[{start_stop, J("Start")},
|
||||||
@ -121,26 +126,27 @@ init(Prefs) ->
|
|||||||
|
|
||||||
MakeButton =
|
MakeButton =
|
||||||
fun({Name, Label}) ->
|
fun({Name, Label}) ->
|
||||||
B = wxButton:new(Frame, ?wxID_ANY, [{label, Label}]),
|
B = wxButton:new(Panel, ?wxID_ANY, [{label, Label}]),
|
||||||
#w{name = Name, id = wxButton:getId(B), wx = B}
|
#w{name = Name, id = wxButton:getId(B), wx = B}
|
||||||
end,
|
end,
|
||||||
|
|
||||||
Buttons = lists:map(MakeButton, ButtonTemplates),
|
Buttons = lists:map(MakeButton, ButtonTemplates),
|
||||||
|
|
||||||
_ = wxBoxSizer:add(Left, Grid, zxw:flags(base)),
|
_ = wxBoxSizer:add(Left, Grid, zxw:flags({base, 5})),
|
||||||
_ = wxBoxSizer:add(Left, MessSz, zxw:flags(wide)),
|
_ = wxBoxSizer:add(Left, MessSz, zxw:flags({wide, 5})),
|
||||||
Add = fun(#w{wx = Button}) -> wxBoxSizer:add(Right, Button, zxw:flags(wide)) end,
|
Add = fun(#w{wx = Button}) -> wxBoxSizer:add(Right, Button, zxw:flags(wide)) end,
|
||||||
ok = lists:foreach(Add, Buttons),
|
ok = lists:foreach(Add, Buttons),
|
||||||
_ = wxBoxSizer:add(LeftRight, Left, zxw:flags(wide)),
|
_ = wxBoxSizer:add(LeftRight, Left, zxw:flags(wide)),
|
||||||
_ = wxBoxSizer:add(LeftRight, Right, zxw:flags(base)),
|
_ = wxBoxSizer:add(LeftRight, Right, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(MainSz, LeftRight, zxw:flags(wide)),
|
_ = wxBoxSizer:add(MainSz, LeftRight, zxw:flags({wide, 5})),
|
||||||
|
|
||||||
ok = wxFrame:setSizer(Frame, MainSz),
|
ok = wxWindow:setSizer(Panel, MainSz),
|
||||||
ok = wxSizer:layout(MainSz),
|
ok = wxFrame:setSizer(Frame, TopSz),
|
||||||
|
ok = wxBoxSizer:layout(MainSz),
|
||||||
|
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
ok = wxFrame:setSize(Frame, {650, 300}),
|
ok = wxFrame:setSize(Frame, {780, 350}),
|
||||||
ok = wxFrame:center(Frame),
|
ok = wxFrame:center(Frame),
|
||||||
true = wxFrame:show(Frame),
|
true = wxFrame:show(Frame),
|
||||||
State =
|
State =
|
||||||
@ -199,6 +205,9 @@ handle_cast(Unexpected, State) ->
|
|||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
|
|
||||||
|
handle_info(toggle, State) ->
|
||||||
|
NewState = toggle(State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_info(Unexpected, State) ->
|
handle_info(Unexpected, State) ->
|
||||||
ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]),
|
ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
@ -291,10 +300,14 @@ do_message({pool_notification, #{info := #{msg := MSG}}}, State = #s{height = He
|
|||||||
do_message2(Entry, State)
|
do_message2(Entry, State)
|
||||||
end;
|
end;
|
||||||
do_message({connected, _}, State) ->
|
do_message({connected, _}, State) ->
|
||||||
Entry = "\nConnected!",
|
Entry = "\nConnected",
|
||||||
|
do_message2(Entry, State);
|
||||||
|
do_message({disconnected, #{info := #{error := #{code := Code, message := Message}}}}, State = #s{}) ->
|
||||||
|
Format = "~nAn issue has been reported by the Hive Leader.~nError code: ~p '~s'",
|
||||||
|
Entry = io_lib:format(Format, [Code, Message]),
|
||||||
do_message2(Entry, State);
|
do_message2(Entry, State);
|
||||||
do_message({disconnected, _}, State) ->
|
do_message({disconnected, _}, State) ->
|
||||||
Entry = "\nDisconnected!",
|
Entry = "\nDisconnected",
|
||||||
do_message2(Entry, State);
|
do_message2(Entry, State);
|
||||||
do_message({error, #{info := #{info := #{error := get_failed, data := {error, #{code := 404}}, url := URL}}}}, State) ->
|
do_message({error, #{info := #{info := #{error := get_failed, data := {error, #{code := 404}}, url := URL}}}}, State) ->
|
||||||
ID =
|
ID =
|
||||||
@ -368,11 +381,33 @@ add_message2(Entry, {OMax, 0, IMax, 0, []}) ->
|
|||||||
{append, {OMax, 1, IMax, 1, [[Entry]]}}.
|
{append, {OMax, 1, IMax, 1, [[Entry]]}}.
|
||||||
|
|
||||||
|
|
||||||
start_stop(State = #s{buttons = Buttons}) ->
|
start_stop(State = #s{buttons = Buttons, toggle = Last, toggle_t = T}) ->
|
||||||
|
ok = cancel_timer(T),
|
||||||
#w{wx = SSB} = lists:keyfind(start_stop, #w.name, Buttons),
|
#w{wx = SSB} = lists:keyfind(start_stop, #w.name, Buttons),
|
||||||
_ = wxButton:disable(SSB),
|
_ = wxButton:disable(SSB),
|
||||||
ok = gmc_con:start_stop(),
|
ok = gmc_con:start_stop(),
|
||||||
State.
|
Timer = erlang:send_after(2000, self(), toggle),
|
||||||
|
Next =
|
||||||
|
case Last of
|
||||||
|
stop -> start;
|
||||||
|
start -> stop
|
||||||
|
end,
|
||||||
|
State#s{toggle = Next, toggle_t = Timer}.
|
||||||
|
|
||||||
|
cancel_timer(none) -> ok;
|
||||||
|
cancel_timer(Time) -> erlang:cancel_timer(Time).
|
||||||
|
|
||||||
|
|
||||||
|
toggle(State = #s{buttons = Buttons, toggle = Next, j = J}) ->
|
||||||
|
#w{wx = SSB} = lists:keyfind(start_stop, #w.name, Buttons),
|
||||||
|
Label =
|
||||||
|
case Next of
|
||||||
|
start -> J("Start");
|
||||||
|
stop -> J("Stop")
|
||||||
|
end,
|
||||||
|
ok = wxButton:setLabel(SSB, Label),
|
||||||
|
_ = wxButton:enable(SSB),
|
||||||
|
State#s{toggle_t = none}.
|
||||||
|
|
||||||
|
|
||||||
gajudesk(State) ->
|
gajudesk(State) ->
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
%%% @end
|
%%% @end
|
||||||
|
|
||||||
-module(gmc_sup).
|
-module(gmc_sup).
|
||||||
-vsn("0.3.6").
|
-vsn("0.4.0").
|
||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
-author("Craig Everett <craigeverett@qpq.swiss>").
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
-copyright("QPQ AG <craigeverett@qpq.swiss>").
|
||||||
|
|||||||
10
zomp.meta
10
zomp.meta
@ -1,11 +1,13 @@
|
|||||||
{name,"GajuMine"}.
|
{name,"GajuMine"}.
|
||||||
{type,gui}.
|
{type,gui}.
|
||||||
{modules,[]}.
|
{modules,[]}.
|
||||||
|
{author,"Craig Everett"}.
|
||||||
{prefix,"gmc"}.
|
{prefix,"gmc"}.
|
||||||
{desc,"Mining client for the Gajumaru Root"}.
|
{desc,"Mining client for the Gajumaru Root"}.
|
||||||
{author,"Craig Everett"}.
|
{package_id,{"qpq","gajumine",{0,4,0}}}.
|
||||||
{package_id,{"qpq","gajumine",{0,3,6}}}.
|
{deps,[{"uwiger","gmhive_client",{0,10,0}},
|
||||||
{deps,[{"uwiger","gmhive_client",{0,9,3}},
|
{"otpr","zxwidgets",{1,1,0}},
|
||||||
|
{"otpr","hakuzaru",{0,7,0}},
|
||||||
{"uwiger","gmhive_protocol",{0,2,0}},
|
{"uwiger","gmhive_protocol",{0,2,0}},
|
||||||
{"uwiger","gmcuckoo",{1,2,4}},
|
{"uwiger","gmcuckoo",{1,2,4}},
|
||||||
{"uwiger","gmhive_worker",{0,5,1}},
|
{"uwiger","gmhive_worker",{0,5,1}},
|
||||||
@ -14,9 +16,7 @@
|
|||||||
{"uwiger","gproc",{1,0,1}},
|
{"uwiger","gproc",{1,0,1}},
|
||||||
{"uwiger","enoise",{1,3,0}},
|
{"uwiger","enoise",{1,3,0}},
|
||||||
{"uwiger","setup",{2,2,4}},
|
{"uwiger","setup",{2,2,4}},
|
||||||
{"otpr","hakuzaru",{0,6,1}},
|
|
||||||
{"otpr","gajudesk",{0,5,3}},
|
{"otpr","gajudesk",{0,5,3}},
|
||||||
{"otpr","zxwidgets",{1,0,1}},
|
|
||||||
{"otpr","ec_utils",{1,0,0}},
|
{"otpr","ec_utils",{1,0,0}},
|
||||||
{"otpr","eblake2",{1,0,1}},
|
{"otpr","eblake2",{1,0,1}},
|
||||||
{"otpr","base58",{0,1,1}},
|
{"otpr","base58",{0,1,1}},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user