Compare commits

...

12 Commits

Author SHA1 Message Date
f408af0eb3 Merge pull request 'update deps (gmserialization)' (#7) from uw-update-deps0423 into master
Reviewed-on: #7
2025-04-24 07:02:03 +09:00
Ulf Wiger
e9b027a353 update deps (gmserialization) 2025-04-23 23:51:40 +02:00
ac3c1e52f1 Merge pull request 'update deps' (#6) from uw-update-deps0414 into master
Reviewed-on: #6
2025-04-14 21:46:00 +09:00
Ulf Wiger
4ef670162b update deps 2025-04-14 14:42:05 +02:00
a006410ce6 Merge pull request 'update gmserialization dep' (#5) from uw-update-deps into master
Reviewed-on: #5
2025-04-11 19:43:29 +09:00
Ulf Wiger
e21f8f6fbf update gmserialization dep 2025-04-11 12:39:25 +02:00
fe47d3715c Merge pull request 'Validation results were ignored, and also partly broken' (#4) from uw-fix-validation into master
Reviewed-on: #4
2025-04-11 17:26:36 +09:00
Ulf Wiger
b9681dec88 Validation results were ignored, and also partly broken 2025-04-11 10:23:00 +02:00
b7cf6375fe Merge pull request 'Reduce notification nesting, add 'continue' result' (#3) from uw-msg-format-tweaks into master
Reviewed-on: #3
2025-04-10 17:15:58 +09:00
Ulf Wiger
6fd678b420 Reduce notification nesting, at 'continue' result 2025-04-10 09:09:12 +02:00
abb1bef2b6 report multiple solutions, server change message (#2)
Co-authored-by: Ulf Wiger <ulf@wiger.net>
Reviewed-on: #2
2025-03-24 06:04:29 +09:00
226c4bc53c Merge pull request 'completing the pool-client interaction' (#1) from uw-client-debugging into master
Reviewed-on: #1
2025-03-21 06:52:46 +09:00
3 changed files with 49 additions and 21 deletions

View File

@ -3,7 +3,7 @@
{plugins, [rebar3_hex]}. {plugins, [rebar3_hex]}.
{deps, [ {deps, [
{gmserialization, {git, "https://git.qpq.swiss/QPQ-AG/gmserialization.git", {gmserialization, {git, "https://git.qpq.swiss/QPQ-AG/gmserialization.git",
{ref, "ac64e01b0f"}}} {ref, "0288719ae1"}}}
]}. ]}.
{xref_checks, [undefined_function_calls, undefined_functions, {xref_checks, [undefined_function_calls, undefined_functions,

View File

@ -8,5 +8,5 @@
1}, 1},
{<<"gmserialization">>, {<<"gmserialization">>,
{git,"https://git.qpq.swiss/QPQ-AG/gmserialization.git", {git,"https://git.qpq.swiss/QPQ-AG/gmserialization.git",
{ref,"ac64e01b0f675c1a34c70a827062f381920742db"}}, {ref,"0288719ae15814f3a53114c657502a24376bebfa"}},
0}]. 0}].

View File

@ -60,9 +60,10 @@ validate(#{ connect := #{ pubkey := PK
, versions := Versions , versions := Versions
, pool_id := PoolId , pool_id := PoolId
, extra_pubkeys := Extra , extra_pubkeys := Extra
, type := Type , type := Type0
, nonces := Nonces , nonces := Nonces
}} = Msg, _Vsn) -> }} = Msg, _Vsn) ->
Type = to_atom(Type0),
valid({list, protocol}, Protocols), valid({list, protocol}, Protocols),
valid({list, version} , Versions), valid({list, version} , Versions),
valid(pubkey, PK), valid(pubkey, PK),
@ -91,18 +92,21 @@ validate(#{ candidate := #{ seq := Seq
validate(#{ get_nonces := #{ seq := Seq validate(#{ get_nonces := #{ seq := Seq
, n := N }} = Msg, _Vsn) -> , n := N }} = Msg, _Vsn) ->
valid(seq, Seq), valid(seq, Seq),
valid(pos_integer, N), valid(pos_int, N),
Msg;
validate(#{ new_server := #{ host := Host, port := Port, keep := Keep }} = Msg, _Vsn) ->
valid(string, Host),
valid(pos_ind, Port),
valid(boolean, Keep),
Msg; Msg;
validate(#{ nonces := #{seq := Seq, nonces := Ns}} = Msg, _vsn) -> validate(#{ nonces := #{seq := Seq, nonces := Ns}} = Msg, _vsn) ->
valid(seq, Seq), valid(seq, Seq),
valid(nonces, Ns), valid(nonces, Ns),
Msg; Msg;
validate(#{ solution := #{ seq := Seq validate(#{ solutions := #{ seq := Seq
, nonce := Nonce , found := Solutions } } = Msg, _Vsn) ->
, evidence := Evidence } } = Msg, _Vsn) ->
valid(seq, Seq), valid(seq, Seq),
valid(nonce, Nonce), valid(solutions, Solutions),
valid(evidence, Evidence),
Msg; Msg;
validate(#{ solution_accepted := #{ seq := Seq }} = Msg, _Vsn) -> validate(#{ solution_accepted := #{ seq := Seq }} = Msg, _Vsn) ->
valid(seq, Seq), valid(seq, Seq),
@ -147,7 +151,7 @@ decode(MsgBin, ?PROTOCOL_JSON, Vsn) ->
#{ <<"method">> := Method #{ <<"method">> := Method
, <<"params">> := Params } -> , <<"params">> := Params } ->
%% JSON-RPC notification %% JSON-RPC notification
#{ notification => #{ msg => validate(decode_msg_(Method, Params), Vsn) }}; #{ notification => validate(decode_msg_(Method, Params), Vsn) };
#{ <<"id">> := Id #{ <<"id">> := Id
, <<"result">> := Result } -> , <<"result">> := Result } ->
#{ reply => #{ id => Id #{ reply => #{ id => Id
@ -164,7 +168,7 @@ decode(MsgBin, ?PROTOCOL_JSON, Vsn) ->
encode(#{call := Req0}, P, V) -> encode(#{call := Req0}, P, V) ->
{Id, Req} = maps:take(id, Req0), {Id, Req} = maps:take(id, Req0),
encode_request(Req, Id, P, V); encode_request(Req, Id, P, V);
encode(#{notification := #{msg := Msg}}, P, V) -> encode(#{notification := Msg}, P, V) ->
encode_msg(Msg, P, V); encode_msg(Msg, P, V);
encode(#{reply := Reply0}, P, V) when is_map(Reply0) -> encode(#{reply := Reply0}, P, V) when is_map(Reply0) ->
{Id, Reply} = maps:take(id, Reply0), {Id, Reply} = maps:take(id, Reply0),
@ -201,7 +205,11 @@ encode_reply(Reply, Id, ?PROTOCOL_JSON, _Vsn) ->
ok -> ok ->
#{ <<"jsonrpc">> => <<"2.0">> #{ <<"jsonrpc">> => <<"2.0">>
, <<"id">> => Id , <<"id">> => Id
, <<"result">> => <<"ok">> } , <<"result">> => <<"ok">> };
continue ->
#{ <<"jsonrpc">> => <<"2.0">>
, <<"id">> => Id
, <<"result">> => <<"continue">> }
end, end,
json_encode(Msg). json_encode(Msg).
@ -228,6 +236,7 @@ error_code(unknown_method ) -> -32601;
error_code(_ ) -> -32603. % internal error error_code(_ ) -> -32603. % internal error
decode_result(<<"ok">>, _) -> ok; decode_result(<<"ok">>, _) -> ok;
decode_result(<<"continue">>, _) -> continue;
decode_result(#{<<"connect_ack">> := #{ <<"protocol">> := P decode_result(#{<<"connect_ack">> := #{ <<"protocol">> := P
, <<"version">> := V }}, Vsn) -> , <<"version">> := V }}, Vsn) ->
Msg = #{connect_ack => #{ protocol => P Msg = #{connect_ack => #{ protocol => P
@ -255,6 +264,10 @@ decode_msg_(<<"connect">>, #{ <<"protocols">> := Protos
, type => Type , type => Type
, nonces => Nonces , nonces => Nonces
}}; }};
decode_msg_(<<"new_server">>, #{ <<"host">> := Host
, <<"port">> := Port
, <<"keep">> := Keep }) ->
#{new_server => #{host => Host, port => Port, keep => Keep}};
decode_msg_(<<"get_nonces">>, #{ <<"seq">> := Seq decode_msg_(<<"get_nonces">>, #{ <<"seq">> := Seq
, <<"n">> := N }) -> , <<"n">> := N }) ->
#{get_nonces => #{seq => Seq, n => N}}; #{get_nonces => #{seq => Seq, n => N}};
@ -268,12 +281,15 @@ decode_msg_(<<"candidate">>, #{ <<"candidate">> := C
, nonces => Nonces , nonces => Nonces
, seq => Seq , seq => Seq
, edge_bits => EdgeBits }}; , edge_bits => EdgeBits }};
decode_msg_(<<"solution">>, #{ <<"seq">> := Seq decode_msg_(<<"solutions">>, #{ <<"seq">> := Seq
, <<"nonce">> := Nonce , <<"found">> := Found }) ->
Solutions = lists:map(
fun(#{ <<"nonce">> := Nonce
, <<"evidence">> := Evidence }) -> , <<"evidence">> := Evidence }) ->
#{solution => #{ seq => Seq #{nonce => Nonce, evidence => Evidence}
, nonce => Nonce end, Found),
, evidence => Evidence}}; #{solutions => #{ seq => Seq
, found => Solutions }};
decode_msg_(<<"solution_accepted">>, #{<<"seq">> := Seq}) -> decode_msg_(<<"solution_accepted">>, #{<<"seq">> := Seq}) ->
#{solution_accepted => #{seq => Seq}}; #{solution_accepted => #{seq => Seq}};
decode_msg_(<<"no_solution">>, #{ <<"seq">> := Seq decode_msg_(<<"no_solution">>, #{ <<"seq">> := Seq
@ -282,10 +298,10 @@ decode_msg_(<<"no_solution">>, #{ <<"seq">> := Seq
, nonce => Nonce }}. , nonce => Nonce }}.
valid(Type, Val) -> valid(Type, Val) ->
try valid_(Type, Val) try true = valid_(Type, Val)
catch catch
error:_ -> error:_ ->
false error({invalid, {Type, Val}})
end. end.
valid_({list,T}, Ps) -> lists:all(fun(X) -> valid_(T, X) end, Ps); valid_({list,T}, Ps) -> lists:all(fun(X) -> valid_(T, X) end, Ps);
@ -293,11 +309,18 @@ valid_(protocol, P) -> is_binary(P);
valid_(version, V) -> is_binary(V); valid_(version, V) -> is_binary(V);
valid_(pubkey, PK) -> ok_tuple(gmser_api_encoder:safe_decode(account_pubkey, PK)); valid_(pubkey, PK) -> ok_tuple(gmser_api_encoder:safe_decode(account_pubkey, PK));
valid_(seq, Seq) -> pos_integer(Seq); valid_(seq, Seq) -> pos_integer(Seq);
valid_(nonce, Nonce) -> pos_integer(Nonce);
valid_(target, T) -> pos_integer(T); valid_(target, T) -> pos_integer(T);
valid_(edge_bits, E) -> pos_integer(E); valid_(edge_bits, E) -> pos_integer(E);
valid_(pos_int, I) -> pos_integer(I); valid_(pos_int, I) -> pos_integer(I);
valid_(contract, Id) -> ok_tuple(gmser_api_encoder:safe_defode(contract_pubkey, Id)); valid_(string, S) -> is_binary(S);
valid_(boolean, B) -> is_boolean(B);
valid_(contract, Id) -> ok_tuple(gmser_api_encoder:safe_decode(contract_pubkey, Id));
valid_(type, T) -> lists:member(T, [miner, monitor]); valid_(type, T) -> lists:member(T, [miner, monitor]);
valid_(solutions, S) -> lists:all(fun(#{nonce := N, evidence := Evd}) ->
valid_(pos_int, N),
valid_({list, pos_int}, Evd)
end, S);
valid_(nonces, Ns) -> valid_(nonces, Ns) ->
case Ns of case Ns of
[N] -> pos_integer(N); [N] -> pos_integer(N);
@ -315,3 +338,8 @@ ok_tuple(V) ->
pos_integer(I) -> pos_integer(I) ->
is_integer(I) andalso I >= 0. is_integer(I) andalso I >= 0.
to_atom(A) when is_atom(A) ->
A;
to_atom(B) when is_binary(B) ->
binary_to_existing_atom(B, utf8).