From a47a259135082a6044e5be53546e07f14cd1a6e5 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Fri, 7 Nov 2025 19:53:16 +0900 Subject: [PATCH 1/7] Fixing interface issues and GajuDesk startup call --- ebin/gajumine.app | 2 +- src/gajumine.erl | 2 +- src/gmc_con.erl | 30 +++++++----------------------- src/gmc_conf.erl | 26 +++++++++++++++----------- src/gmc_gui.erl | 30 +++++++++++++++++------------- src/gmc_sup.erl | 2 +- zomp.meta | 2 +- 7 files changed, 43 insertions(+), 51 deletions(-) diff --git a/ebin/gajumine.app b/ebin/gajumine.app index 7915aa9..5c1e5b6 100644 --- a/ebin/gajumine.app +++ b/ebin/gajumine.app @@ -3,6 +3,6 @@ {registered,[]}, {included_applications,[]}, {applications,[stdlib,kernel]}, - {vsn,"0.3.6"}, + {vsn,"0.4.0"}, {modules,[gajumine,gmc_con,gmc_conf,gmc_gui,gmc_sup]}, {mod,{gajumine,[]}}]}. diff --git a/src/gajumine.erl b/src/gajumine.erl index 911a222..08aaf06 100644 --- a/src/gajumine.erl +++ b/src/gajumine.erl @@ -3,7 +3,7 @@ %%% @end -module(gajumine). --vsn("0.3.6"). +-vsn("0.4.0"). -behavior(application). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/src/gmc_con.erl b/src/gmc_con.erl index c99fb0d..9e7d5e8 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -3,7 +3,7 @@ %%% @end -module(gmc_con). --vsn("0.3.6"). +-vsn("0.4.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). @@ -204,10 +204,7 @@ terminate(Reason, State) -> do_stop() -> - case is_pid(whereis(gd_con)) of - false -> zx:stop(); - true -> application:stop(gajumine) - end. + zx:stop(). %%% Doers @@ -251,7 +248,7 @@ do_start_stop(#s{acc = PubKey, keys = Keys, network = Network, max_cores = MaxCo ok = gmc_gui:message({notice, "Starting..."}), ok = gmc_gui:message({notice, ["Miner: ", Miner]}), {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 = gmc_gui:message({notice, Started}), Events = @@ -344,23 +341,10 @@ win_mem() -> do_gajudesk() -> - ok = tell(info, "Running gajudesk"), - PID = spawn(fun run_gajudesk/0), - tell(info, "GajuDesk launched at PID: ~p", [PID]). - -run_gajudesk() -> - R = "otpr", - N = "gajudesk", - {ok, V} = zx:latest({R, N}), - {ok, PackageString} = zx_lib:package_string({R, N, V}), - try - case zx:run(PackageString, []) of - ok -> ok; - Error -> tell(error, "gajudesk died with: ~p", [Error]) - end - catch - E:R -> tell(error, "gajudesk died with: ~p", [{E, R}]) - end. + ok = log(info, "Running gajudesk"), + Command = "zx run gajudesk", + Out = os:cmd(Command), + log(info, "os:cmd(~w) -> ~w", [Command, Out]). run_gmc_conf(State = #s{gmc_conf = none, network = Net, acc = Acc, keys = Keys, diff --git a/src/gmc_conf.erl b/src/gmc_conf.erl index c5d1a12..b092ca6 100644 --- a/src/gmc_conf.erl +++ b/src/gmc_conf.erl @@ -3,7 +3,7 @@ %%% @end -module(gmc_conf). --vsn("0.3.6"). +-vsn("0.4.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). @@ -60,27 +60,30 @@ init({Prefs, {Net, Acc, Keys, {AProcs, AMem, MProcs, MMem}}}) -> WX = wx:new(), 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), - AccSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("GajuMining Account ID")}]), - AccTx = wxTextCtrl:new(Frame, ?wxID_ANY, [{value, acc(Acc)}]), + AccSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("GajuMining Account ID")}]), + AccTx = wxTextCtrl:new(Panel, ?wxID_ANY, [{value, acc(Acc)}]), _ = wxStaticBoxSizer:add(AccSz, AccTx, wide(5)), - KeysSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Additional Account IDs (optional)")}]), - KeysTx = wxTextCtrl:new(Frame, ?wxID_ANY, [{style, ?wxTE_MULTILINE}, {value, keys(Keys)}]), + KeysSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Additional Account IDs (optional)")}]), + KeysTx = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, ?wxTE_MULTILINE}, {value, keys(Keys)}]), _ = 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), MProcsS = i_to_l(MProcs), AMemS = gigs(AMem), MMemS = gigs(MMem), Labels = [{J("HW Cores"), J("Max Cores"), AProcsS, MProcsS}, {J("Memory (GB)"), J("Max Memory"), AMemS, MMemS}], - {Grid, [CoresTx, MemoryTx]} = display_box(Frame, Labels), - Network = wxRadioBox:new(Frame, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]), + {Grid, [CoresTx, MemoryTx]} = display_box(Panel, Labels), + Network = wxRadioBox:new(Panel, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]), ok = wxRadioBox:setSelection(Network, net_num(Net)), ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Frame, ?wxID_OK), - Cancel = wxButton:new(Frame, ?wxID_CANCEL), + Affirm = wxButton:new(Panel, ?wxID_OK), + Cancel = wxButton:new(Panel, ?wxID_CANCEL), _ = wxBoxSizer:add(StatSz, Grid, wide(5)), _ = wxBoxSizer:add(ButtSz, Affirm, 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, Network, 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 = wxFrame:connect(Frame, command_button_clicked), ok = wxFrame:connect(Frame, close_window), diff --git a/src/gmc_gui.erl b/src/gmc_gui.erl index e3560cc..17e9eff 100644 --- a/src/gmc_gui.erl +++ b/src/gmc_gui.erl @@ -3,7 +3,7 @@ %%% @end -module(gmc_gui). --vsn("0.3.6"). +-vsn("0.4.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). @@ -99,18 +99,21 @@ init(Prefs) -> VSN = proplists:get_value(vsn, ?MODULE:module_info(attributes)), WX = wx:new(), 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), LeftRight = wxBoxSizer:new(?wxHORIZONTAL), Left = wxBoxSizer:new(?wxVERTICAL), Right = wxBoxSizer:new(?wxVERTICAL), - Labels = [J("ID"), J("Target"), J("Maps/s"), J("Candidate"), J("Height"), J("BlockHash")], - {Grid, [ID_C, DiffC, PerfC, CandyC, HeightC, BlockC]} = display_box(Frame, Labels), + Labels = [J("ID"), J("Target"), J("Graphs/s"), J("Candidate"), J("Height"), J("BlockHash")], + {Grid, [ID_C, DiffC, PerfC, CandyC, HeightC, BlockC]} = display_box(Panel, Labels), Style = ?wxTE_MULTILINE bor ?wxTE_READONLY, - MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Messages")}]), - MessC = wxTextCtrl:new(Frame, ?wxID_ANY, [{style, Style}]), - _ = wxStaticBoxSizer:add(MessSz, MessC, zxw:flags(wide)), + MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Messages")}]), + MessC = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, Style}]), + _ = wxStaticBoxSizer:add(MessSz, MessC, zxw:flags({wide, 5})), ButtonTemplates = [{start_stop, J("Start")}, @@ -121,26 +124,27 @@ init(Prefs) -> MakeButton = 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} end, Buttons = lists:map(MakeButton, ButtonTemplates), - _ = wxBoxSizer:add(Left, Grid, zxw:flags(base)), - _ = wxBoxSizer:add(Left, MessSz, zxw:flags(wide)), + _ = wxBoxSizer:add(Left, Grid, zxw:flags({base, 5})), + _ = wxBoxSizer:add(Left, MessSz, zxw:flags({wide, 5})), Add = fun(#w{wx = Button}) -> wxBoxSizer:add(Right, Button, zxw:flags(wide)) end, ok = lists:foreach(Add, Buttons), _ = wxBoxSizer:add(LeftRight, Left, zxw:flags(wide)), _ = 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 = wxSizer:layout(MainSz), + ok = wxWindow:setSizer(Panel, MainSz), + ok = wxFrame:setSizer(Frame, TopSz), + ok = wxBoxSizer:layout(MainSz), ok = wxFrame:connect(Frame, command_button_clicked), ok = wxFrame:connect(Frame, close_window), - ok = wxFrame:setSize(Frame, {650, 300}), + ok = wxFrame:setSize(Frame, {780, 350}), ok = wxFrame:center(Frame), true = wxFrame:show(Frame), State = diff --git a/src/gmc_sup.erl b/src/gmc_sup.erl index 027f088..ab567b1 100644 --- a/src/gmc_sup.erl +++ b/src/gmc_sup.erl @@ -12,7 +12,7 @@ %%% @end -module(gmc_sup). --vsn("0.3.6"). +-vsn("0.4.0"). -behaviour(supervisor). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/zomp.meta b/zomp.meta index a02c39a..28b9058 100644 --- a/zomp.meta +++ b/zomp.meta @@ -4,7 +4,7 @@ {prefix,"gmc"}. {desc,"Mining client for the Gajumaru Root"}. {author,"Craig Everett"}. -{package_id,{"qpq","gajumine",{0,3,6}}}. +{package_id,{"qpq","gajumine",{0,4,0}}}. {deps,[{"uwiger","gmhive_client",{0,9,3}}, {"uwiger","gmhive_protocol",{0,2,0}}, {"uwiger","gmcuckoo",{1,2,4}}, -- 2.30.2 From 6d0d371d5d5c3d172f535b57dea9159331865a06 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Fri, 7 Nov 2025 19:56:00 +0900 Subject: [PATCH 2/7] Update deps --- zomp.meta | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zomp.meta b/zomp.meta index 28b9058..245d975 100644 --- a/zomp.meta +++ b/zomp.meta @@ -1,11 +1,13 @@ {name,"GajuMine"}. {type,gui}. {modules,[]}. +{author,"Craig Everett"}. {prefix,"gmc"}. {desc,"Mining client for the Gajumaru Root"}. -{author,"Craig Everett"}. {package_id,{"qpq","gajumine",{0,4,0}}}. -{deps,[{"uwiger","gmhive_client",{0,9,3}}, +{deps,[{"otpr","zxwidgets",{1,1,0}}, + {"otpr","hakuzaru",{0,7,0}}, + {"uwiger","gmhive_client",{0,9,3}}, {"uwiger","gmhive_protocol",{0,2,0}}, {"uwiger","gmcuckoo",{1,2,4}}, {"uwiger","gmhive_worker",{0,5,1}}, @@ -14,9 +16,7 @@ {"uwiger","gproc",{1,0,1}}, {"uwiger","enoise",{1,3,0}}, {"uwiger","setup",{2,2,4}}, - {"otpr","hakuzaru",{0,6,1}}, {"otpr","gajudesk",{0,5,3}}, - {"otpr","zxwidgets",{1,0,1}}, {"otpr","ec_utils",{1,0,0}}, {"otpr","eblake2",{1,0,1}}, {"otpr","base58",{0,1,1}}, -- 2.30.2 From 54a70d4b0b82a7bd07738f8adf23ea2468078078 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Wed, 19 Nov 2025 21:17:57 +0900 Subject: [PATCH 3/7] WIP --- src/gmc_con.erl | 91 +++++++++++++++++++++++++++++++++---------------- src/gmc_gui.erl | 80 ++++++++++++++++++++++++++++++++----------- 2 files changed, 123 insertions(+), 48 deletions(-) diff --git a/src/gmc_con.erl b/src/gmc_con.erl index 9e7d5e8..c1b96fc 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -23,15 +23,16 @@ -record(s, - {version = 1 :: integer(), - window = none :: none | wx:wx_object(), - network = <<"mainnet">> :: binary(), % <<"testnet">> | <<"mainnet">> - acc = none :: none | binary(), - keys = [] :: [], - max_cores = 2 :: pos_integer(), - max_mem = 3550722201 :: pos_integer(), - prefs = #{} :: #{}, - gmc_conf = none :: none | reference()}). + {version = 1 :: integer(), + window = none :: none | wx:wx_object(), + network = <<"mainnet">> :: binary(), % <<"testnet">> | <<"mainnet">> + acc = none :: none | binary(), + keys = [] :: [], + max_cores = 2 :: pos_integer(), + max_mem = 3550722201 :: pos_integer(), + prefs = #{} :: #{}, + gmc_conf = none :: none | reference(), + toggle = {stop, 0} :: {start | stop, integer()}}). -type state() :: #s{}. @@ -102,15 +103,15 @@ start_link() -> init(none) -> ok = log(info, "Starting"), {AProcs, AMem} = proc_mem(), - TwoMaps = default_spec(mem) * 2, + TwoGraphs = default_spec(mem) * 2, RProcs = case AProcs >= 2 of true -> 2; false -> 1 end, RMem = - case AMem >= TwoMaps of - true -> TwoMaps; + case AMem >= TwoGraphs of + true -> TwoGraphs; false -> default_spec(mem) end, {Acc, Keys, Network, MaxCores, MaxMem} = @@ -125,6 +126,14 @@ init(none) -> {none, [], <<"mainnet">>, RProcs, RMem} end, 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)}. @@ -155,8 +164,8 @@ handle_call(Unexpected, From, State) -> handle_cast(start_stop, State) -> - ok = do_start_stop(State), - {noreply, State}; + NewState = do_start_stop(State), + {noreply, NewState}; handle_cast(gajudesk, State) -> ok = do_gajudesk(), {noreply, State}; @@ -176,7 +185,7 @@ handle_cast(Unexpected, State) -> handle_info({gproc_ps_event, Event, Data}, State) -> - ok = gmc_gui:message({Event, Data}), + ok = gproc_ps_event({Event, Data}), {noreply, State}; handle_info({'DOWN', Mon, process, PID, Info}, State = #s{gmc_conf = Mon}) -> ok = log(info, "gmc_conf ~p closed with ~p", [PID, Info]), @@ -187,6 +196,15 @@ handle_info(Unexpected, State) -> {noreply, State}. +gproc_ps_event(Info = {disconnect, #{info := #{reconnecting := false, error := #{code := Code, message := Message}}}}) -> + ok = log(error, "Error terminal event received. Code: ~p. Message: ~p", [Code, Message]), + Outcome = application:stop(gmhive_client), + ok = log(info, "application:stop(gmhivie_client) -> ~p", [Outcome]), + gmc_gui:message(Info); +gproc_ps_event(Info) -> + gmc_gui:message(Info). + + code_change(_, State, _) -> {ok, State}. @@ -209,7 +227,20 @@ do_stop() -> %%% 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 - 5, + 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 {Bits, Eureka} = case Network of @@ -251,29 +282,31 @@ do_start_stop(#s{acc = PubKey, keys = Keys, network = Network, max_cores = MaxCo Started = io_lib:format("Apps started:~n ~p", [Apps]), ok = log(info, Started), ok = gmc_gui:message({notice, Started}), - Events = - [pool_notification, - connected, - puzzle, - result, - error, - disconnected], - lists:foreach(fun gmhc_events:ensure_subscribed/1, Events). + State. + + +do_stop(State) -> + ok = + case application:stop(gmhive_client) of + ok -> ok; + Error -> log(warning, "application:stop(gmhive_client) returned: ~p", [Error]) + end, + State. optimize_count(MaxC, MaxM) -> - MapSize = 3550722201, + GraphSize = 3550722201, MaxCores = max(1, MaxC), - MaxMem = max(MapSize, MaxM), + MaxMem = max(GraphSize, MaxM), {Procs, Memory} = proc_mem(), - MeanMaps = min(MaxMem, Memory) div MapSize, - Recommended = min(MaxCores, min(Procs, MeanMaps)), + MeanGraphs = min(MaxMem, Memory) div GraphSize, + Recommended = min(MaxCores, min(Procs, MeanGraphs)), Notice = fun(F, A) -> gmc_gui:message({notice, io_lib:format(F, A)}) end, ok = Notice("Physical Processors: ~p", [Procs]), ok = Notice("Physical Memory: ~p", [Memory]), ok = Notice("Max Processor Commit: ~p", [MaxCores]), 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]), Recommended. diff --git a/src/gmc_gui.erl b/src/gmc_gui.erl index 17e9eff..771f373 100644 --- a/src/gmc_gui.erl +++ b/src/gmc_gui.erl @@ -23,21 +23,23 @@ wx = none :: none | wx:wx_object()}). -record(s, - {wx = none :: none | wx:wx_object(), - frame = none :: none | wx:wx_object(), - lang = en :: en | jp, - j = none :: none | fun(), - id = none :: none | wx:wx_object(), - diff = none :: none | wx:wx_object(), - perf = none :: none | wx:wx_object(), - hist = {ts(), 0} :: {LastTS :: integer(), Average :: integer()}, - candy = none :: none | wx:wx_object(), - height = none :: none | wx:wx_object(), - block = none :: none | wx:wx_object(), - % solved = 0 :: non_neg_integer(), % TODO: Add a widget to show this. Maybe - mess = none :: none | wx:wx_object(), - buff = new_buff() :: buff(), - buttons = [] :: [#w{}]}). + {wx = none :: none | wx:wx_object(), + frame = none :: none | wx:wx_object(), + lang = en :: en | jp, + j = none :: none | fun(), + id = none :: none | wx:wx_object(), + diff = none :: none | wx:wx_object(), + perf = none :: none | wx:wx_object(), + hist = {ts(), 0} :: {LastTS :: integer(), Average :: integer()}, + candy = none :: none | wx:wx_object(), + height = none :: none | wx:wx_object(), + block = none :: none | wx:wx_object(), + % solved = 0 :: non_neg_integer(), % TODO: Add a widget to show this. Maybe + mess = none :: none | wx:wx_object(), + buff = new_buff() :: buff(), + buttons = [] :: [#w{}], + toggle = start :: stop | start, + toggle_t = none :: none | reference()}). ts() -> erlang:system_time(microsecond). @@ -203,6 +205,9 @@ handle_cast(Unexpected, State) -> {noreply, State}. +handle_info(toggle, State) -> + NewState = toggle(State), + {noreply, NewState}; handle_info(Unexpected, State) -> ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]), {noreply, State}. @@ -295,10 +300,29 @@ do_message({pool_notification, #{info := #{msg := MSG}}}, State = #s{height = He do_message2(Entry, State) end; do_message({connected, _}, State) -> - Entry = "\nConnected!", + Entry = "\nConnected", + do_message2(Entry, State); +do_message({disconnected, #{info := #{error := #{code := Code, message := Message}}}}, State = #s{}) -> +% -32000 -> % mining_disabled +% -32001 -> % nyi +% -32002 -> % pool_not_found +% -32003 -> % pool_exists +% -32004 -> % unknown_contract +% -32005 -> % invalid_prefix +% -32006 -> % invalid_encoding +% -32007 -> % outdated +% -32008 -> % solution_mismatch +% -32009 -> % invalid_input +% -32010 -> % session_limit +% -32011 -> % accounts_limit +% -32012 -> % duplicate_accounts +% -32601 -> % unknown_method +% -32603 -> % internal error + Format = "~nAn issue has been reported by the Hive Leader.~nError code: ~p '~s'~nStopping.", + Entry = io_lib:format(Format, [Code, Message]), do_message2(Entry, State); do_message({disconnected, _}, State) -> - Entry = "\nDisconnected!", + Entry = "\nDisconnected", do_message2(Entry, State); do_message({error, #{info := #{info := #{error := get_failed, data := {error, #{code := 404}}, url := URL}}}}, State) -> ID = @@ -372,11 +396,29 @@ add_message2(Entry, {OMax, 0, IMax, 0, []}) -> {append, {OMax, 1, IMax, 1, [[Entry]]}}. -start_stop(State = #s{buttons = Buttons}) -> +start_stop(State = #s{buttons = Buttons, toggle = Last, toggle_t = none}) -> #w{wx = SSB} = lists:keyfind(start_stop, #w.name, Buttons), _ = wxButton:disable(SSB), ok = gmc_con:start_stop(), - State. + Timer = erlang:send_after(5000, self(), toggle), + Next = + case Last of + stop -> start; + start -> stop + end, + State#s{toggle = Next, toggle_t = Timer}. + + +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) -> -- 2.30.2 From 5b95daa27eca3cbdcabc6e8646017fce8d7d0744 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 20 Nov 2025 00:52:19 +0900 Subject: [PATCH 4/7] Interface update. v0.4.0 --- src/gmc_con.erl | 10 +++++----- src/gmc_conf.erl | 33 +++++++++++++++++++++++++++------ src/gmc_gui.erl | 25 +++++++------------------ zomp.meta | 4 ++-- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/gmc_con.erl b/src/gmc_con.erl index c1b96fc..a562d88 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -196,11 +196,10 @@ handle_info(Unexpected, State) -> {noreply, State}. -gproc_ps_event(Info = {disconnect, #{info := #{reconnecting := false, error := #{code := Code, message := Message}}}}) -> +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]), - Outcome = application:stop(gmhive_client), - ok = log(info, "application:stop(gmhivie_client) -> ~p", [Outcome]), - gmc_gui:message(Info); + ok = gmc_gui:message(Info), + gmc_gui:start_stop(); gproc_ps_event(Info) -> gmc_gui:message(Info). @@ -229,7 +228,7 @@ do_stop() -> do_start_stop(State = #s{toggle = {Last, TS}}) -> Now = erlang:system_time(second), - Clicklimit = Now - 5, + Clicklimit = Now - 1, case TS < Clicklimit of true -> case Last of @@ -286,6 +285,7 @@ do_start(State = #s{acc = PubKey, keys = Keys, network = Network, max_cores = Ma do_stop(State) -> + ok = gmc_gui:message({notice, "Stopping."}), ok = case application:stop(gmhive_client) of ok -> ok; diff --git a/src/gmc_conf.erl b/src/gmc_conf.erl index b092ca6..29521ce 100644 --- a/src/gmc_conf.erl +++ b/src/gmc_conf.erl @@ -213,9 +213,34 @@ done(State = #s{net = Network, acc = AccTx, keys = KeysTx, cores = CoresTx, memo MOAR_IDs = wxTextCtrl:getValue(KeysTx), CoreS = wxTextCtrl:getValue(CoresTx), 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). + +% 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("") -> 2; cores(CoreS) -> @@ -225,6 +250,7 @@ cores(CoreS) -> _:_ -> 2 end. + bytes("") -> 3550722201; bytes(GigsS) -> @@ -240,11 +266,6 @@ bytes(GigsS) -> 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(AKID) -> AKID. diff --git a/src/gmc_gui.erl b/src/gmc_gui.erl index 771f373..03be542 100644 --- a/src/gmc_gui.erl +++ b/src/gmc_gui.erl @@ -303,22 +303,7 @@ do_message({connected, _}, State) -> Entry = "\nConnected", do_message2(Entry, State); do_message({disconnected, #{info := #{error := #{code := Code, message := Message}}}}, State = #s{}) -> -% -32000 -> % mining_disabled -% -32001 -> % nyi -% -32002 -> % pool_not_found -% -32003 -> % pool_exists -% -32004 -> % unknown_contract -% -32005 -> % invalid_prefix -% -32006 -> % invalid_encoding -% -32007 -> % outdated -% -32008 -> % solution_mismatch -% -32009 -> % invalid_input -% -32010 -> % session_limit -% -32011 -> % accounts_limit -% -32012 -> % duplicate_accounts -% -32601 -> % unknown_method -% -32603 -> % internal error - Format = "~nAn issue has been reported by the Hive Leader.~nError code: ~p '~s'~nStopping.", + 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_message({disconnected, _}, State) -> @@ -396,11 +381,12 @@ add_message2(Entry, {OMax, 0, IMax, 0, []}) -> {append, {OMax, 1, IMax, 1, [[Entry]]}}. -start_stop(State = #s{buttons = Buttons, toggle = Last, toggle_t = none}) -> +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), _ = wxButton:disable(SSB), ok = gmc_con:start_stop(), - Timer = erlang:send_after(5000, self(), toggle), + Timer = erlang:send_after(2000, self(), toggle), Next = case Last of stop -> start; @@ -408,6 +394,9 @@ start_stop(State = #s{buttons = Buttons, toggle = Last, toggle_t = none}) -> 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), diff --git a/zomp.meta b/zomp.meta index 245d975..70f26a5 100644 --- a/zomp.meta +++ b/zomp.meta @@ -5,9 +5,9 @@ {prefix,"gmc"}. {desc,"Mining client for the Gajumaru Root"}. {package_id,{"qpq","gajumine",{0,4,0}}}. -{deps,[{"otpr","zxwidgets",{1,1,0}}, +{deps,[{"uwiger","gmhive_client",{0,10,0}}, + {"otpr","zxwidgets",{1,1,0}}, {"otpr","hakuzaru",{0,7,0}}, - {"uwiger","gmhive_client",{0,9,3}}, {"uwiger","gmhive_protocol",{0,2,0}}, {"uwiger","gmcuckoo",{1,2,4}}, {"uwiger","gmhive_worker",{0,5,1}}, -- 2.30.2 From 4b6a4372d95cecb908c581d20cdb751cf7c6dc05 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 20 Nov 2025 09:10:52 +0900 Subject: [PATCH 5/7] Fix wallet launch --- src/gmc_con.erl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gmc_con.erl b/src/gmc_con.erl index a562d88..3a90294 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -375,9 +375,19 @@ win_mem() -> do_gajudesk() -> ok = log(info, "Running gajudesk"), - Command = "zx run gajudesk", + GajuDesk = "zx run gajudesk", + Command = + case os:type() of + {unix, _} -> + "setsid sh -c 'exec nohup " ++ GajuDesk ++ " >/dev/null 2>&1' &"; + {win32, nt} -> + "wscript //B //Nologo " + "-e:VBScript " + "-c:\"CreateObject(\"WScript.Shell\").Run \"\"" + " \"" ++ GajuDesk ++ "\", 0, False\"" + end, Out = os:cmd(Command), - log(info, "os:cmd(~w) -> ~w", [Command, Out]). + log(info, "os:cmd(~s) -> ~s", [Command, Out]). run_gmc_conf(State = #s{gmc_conf = none, network = Net, acc = Acc, keys = Keys, -- 2.30.2 From 8ee712e81ad043594695d7c0cd61117ddc16270a Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 20 Nov 2025 10:04:19 +0900 Subject: [PATCH 6/7] Windows works! --- src/gmc_con.erl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gmc_con.erl b/src/gmc_con.erl index 3a90294..e1570c2 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -378,17 +378,19 @@ do_gajudesk() -> GajuDesk = "zx run gajudesk", Command = case os:type() of - {unix, _} -> - "setsid sh -c 'exec nohup " ++ GajuDesk ++ " >/dev/null 2>&1' &"; - {win32, nt} -> - "wscript //B //Nologo " - "-e:VBScript " - "-c:\"CreateObject(\"WScript.Shell\").Run \"\"" - " \"" ++ GajuDesk ++ "\", 0, False\"" + {unix, _} -> detach_unix(GajuDesk); + {win32, nt} -> detach_windows(GajuDesk) end, Out = os:cmd(Command), log(info, "os:cmd(~s) -> ~s", [Command, Out]). +detach_unix(Command) -> + "setsid sh -c 'exec nohup " ++ Command ++ " >/dev/null 2>&1' &". + +detach_windows(Command) -> + PSCmd = "Start-Process -WindowStyle Hidden -FilePath cmd.exe -ArgumentList '/c " ++ Command ++ "'", + "powershell -NoProfile -Command \"" ++ PSCmd ++ "\"". + run_gmc_conf(State = #s{gmc_conf = none, network = Net, acc = Acc, keys = Keys, max_cores = MProcs, max_mem = MMem, -- 2.30.2 From 30dda02cc445a14839f2329ebcd73841661ef67d Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 20 Nov 2025 10:39:26 +0900 Subject: [PATCH 7/7] MacOS works now --- src/gmc_con.erl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gmc_con.erl b/src/gmc_con.erl index e1570c2..00273d2 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -378,12 +378,16 @@ do_gajudesk() -> GajuDesk = "zx run gajudesk", Command = case os:type() of - {unix, _} -> detach_unix(GajuDesk); - {win32, nt} -> detach_windows(GajuDesk) + {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]). +detach_darwin(Command) -> + "nohup " ++ Command ++ " >/dev/null 2>&1 & disown". + detach_unix(Command) -> "setsid sh -c 'exec nohup " ++ Command ++ " >/dev/null 2>&1' &". -- 2.30.2