From a7b17a37f2cf52fb6adb410e9ffb2f0ba87d34ef Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Fri, 14 Mar 2025 23:15:12 +0100 Subject: [PATCH 1/4] add target info to candidate msg --- src/gmmpp_msgs.erl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gmmpp_msgs.erl b/src/gmmpp_msgs.erl index a8d03ad..44dd220 100644 --- a/src/gmmpp_msgs.erl +++ b/src/gmmpp_msgs.erl @@ -74,9 +74,11 @@ validate(#{ connect_ack := #{ protocol := Protocol Msg; validate(#{ candidate := #{ seq := Seq , candidate := C + , target := Target , nonces := Nonces , edge_bits := EdgeBits } } = Msg, _Vsn) -> valid(candidate, C), + valid(target, Target), valid(nonces, Nonces), valid(seq, Seq), valid(edge_bits, EdgeBits), @@ -226,10 +228,12 @@ decode_msg_(<<"get_nonces">>, #{ <<"seq">> := Seq , <<"n">> := N }) -> #{get_nonces => #{seq => Seq, n => N}}; decode_msg_(<<"candidate">>, #{ <<"candidate">> := C + , <<"target">> := Target , <<"nonces">> := Nonces , <<"seq">> := Seq , <<"edge_bits">> := EdgeBits }) -> #{candidate => #{ candidate => C + , target => Target , nonces => Nonces , seq => Seq , edge_bits => EdgeBits }}; @@ -256,6 +260,7 @@ valid_(protocol, P) -> is_binary(P); valid_(version, V) -> is_binary(V); valid_(pubkey, PK) -> ok_tuple(gmser_api_encoder:safe_decode(account_pubkey, PK)); valid_(seq, Seq) -> pos_integer(Seq); +valid_(target, T) -> pos_integer(T); valid_(edge_bits, E) -> pos_integer(E); valid_(pos_int, I) -> pos_integer(I); valid_(contract, Id) -> ok_tuple(gmser_api_encoder:safe_defode(contract_pubkey, Id)); From b03b89ef397ccbe27640412d4f30acfa81400d0b Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Sun, 16 Mar 2025 17:30:38 +0100 Subject: [PATCH 2/4] Continuous mining works --- src/gmmpp_msgs.erl | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/gmmpp_msgs.erl b/src/gmmpp_msgs.erl index 44dd220..25f97a3 100644 --- a/src/gmmpp_msgs.erl +++ b/src/gmmpp_msgs.erl @@ -9,6 +9,7 @@ -export([ validate/2 + , encode/3 , decode/3 , encode_request/4 , encode_reply/4 @@ -59,6 +60,7 @@ validate(#{ connect := #{ pubkey := PK , versions := Versions , pool_id := PoolId , extra_pubkeys := Extra + , nonces := Nonces }} = Msg, _Vsn) -> valid({list, protocol}, Protocols), valid({list, version} , Versions), @@ -66,6 +68,7 @@ validate(#{ connect := #{ pubkey := PK valid(contract, PoolId), valid(pubkey, PK), valid({list, pubkey}, Extra), + valid(pos_int, Nonces), Msg; validate(#{ connect_ack := #{ protocol := Protocol , version := Version }} = Msg, _Vsn) -> @@ -88,6 +91,10 @@ validate(#{ get_nonces := #{ seq := Seq valid(seq, Seq), valid(pos_integer, N), Msg; +validate(#{ nonces := #{seq := Seq, nonces := Ns}} = Msg, _vsn) -> + valid(seq, Seq), + valid(nonces, Ns), + Msg; validate(#{ solution := #{ seq := Seq , nonce := Nonce , evidence := Evidence } } = Msg, _Vsn) -> @@ -95,6 +102,9 @@ validate(#{ solution := #{ seq := Seq valid(nonce, Nonce), valid(evidence, Evidence), Msg; +validate(#{ solution_accepted := #{ seq := Seq }} = Msg, _Vsn) -> + valid(seq, Seq), + Msg; validate(#{ no_solution := #{ seq := Seq , nonce := Nonce } } = Msg, _Vsn) -> valid(seq, Seq), @@ -147,6 +157,15 @@ decode(MsgBin, ?PROTOCOL_JSON, Vsn) -> end end. +encode(#{call := Req0}, P, V) -> + {Id, Req} = maps:take(id, Req0), + encode_request(Req, Id, P, V); +encode(#{notification := #{msg := Msg}}, P, V) -> + encode_msg(Msg, P, V); +encode(#{reply := Reply0}, P, V) when is_map(Reply0) -> + {Id, Reply} = maps:take(id, Reply0), + encode_reply(Reply, Id, P, V). + encode_msg(Msg0, ?PROTOCOL_JSON, Vsn) -> Msg = validate(Msg0, Vsn), [{Method, Args}] = maps:to_list(Msg), @@ -192,13 +211,14 @@ encode_error(Reason) -> , <<"message">> => Reason }. error_code(mining_disabled ) -> -32000; -error_code(pool_exists ) -> -32001; +error_code(nyi ) -> -32001; %% random.org uses this code for nyi error_code(pool_not_found ) -> -32002; -error_code(unknown_contract ) -> -32003; -error_code(invalid_prefix ) -> -32004; -error_code(invalid_encoding ) -> -32005; -error_code(outdated ) -> -32006; -error_code(solution_mismatch) -> -32007; +error_code(pool_exists ) -> -32003; +error_code(unknown_contract ) -> -32004; +error_code(invalid_prefix ) -> -32005; +error_code(invalid_encoding ) -> -32006; +error_code(outdated ) -> -32007; +error_code(solution_mismatch) -> -32008; error_code(unknown_method ) -> -32601; error_code(_ ) -> -32603. % internal error @@ -208,21 +228,25 @@ decode_result(#{<<"connect_ack">> := #{ <<"protocol">> := P Msg = #{connect_ack => #{ protocol => P , version => V }}, validate(Msg, Vsn); -decode_result(#{<<"nonces">> := Nonces}, _) -> +decode_result(#{<<"nonces">> := #{ <<"seq">> := Seq + , <<"nonces">> := Nonces}}, _) -> + valid(seq, Seq), valid(nonces, Nonces), - #{nonces => Nonces}. + #{nonces => #{seq => Seq, nonces => Nonces}}. %% Mapping types decode_msg_(<<"connect">>, #{ <<"protocols">> := Protos , <<"versions">> := Vsns , <<"pool_id">> := PoolId , <<"pubkey">> := PK - , <<"extra_pubkeys">> := Extra }) -> + , <<"extra_pubkeys">> := Extra + , <<"nonces">> := Nonces }) -> #{connect => #{ protocols => Protos , versions => Vsns , pool_id => PoolId , pubkey => PK , extra_pubkeys => Extra + , nonces => Nonces }}; decode_msg_(<<"get_nonces">>, #{ <<"seq">> := Seq , <<"n">> := N }) -> @@ -243,6 +267,8 @@ decode_msg_(<<"solution">>, #{ <<"seq">> := Seq #{solution => #{ seq => Seq , nonce => Nonce , evidence => Evidence}}; +decode_msg_(<<"solution_accepted">>, #{<<"seq">> := Seq}) -> + #{solution_accepted => #{seq => Seq}}; decode_msg_(<<"no_solution">>, #{ <<"seq">> := Seq , <<"nonce">> := Nonce }) -> #{no_solution => #{ seq => Seq From d2880b475bf7a127bc0995e453cb95113ce17a1e Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Sun, 16 Mar 2025 17:39:45 +0100 Subject: [PATCH 3/4] Add invalid_input error code --- src/gmmpp_msgs.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gmmpp_msgs.erl b/src/gmmpp_msgs.erl index 25f97a3..e93707b 100644 --- a/src/gmmpp_msgs.erl +++ b/src/gmmpp_msgs.erl @@ -219,6 +219,7 @@ error_code(invalid_prefix ) -> -32005; error_code(invalid_encoding ) -> -32006; error_code(outdated ) -> -32007; error_code(solution_mismatch) -> -32008; +error_code(invalid_input ) -> -32009; error_code(unknown_method ) -> -32601; error_code(_ ) -> -32603. % internal error From 68064b14690c6a943d53bc906c4daf794641c74d Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Thu, 20 Mar 2025 22:48:27 +0100 Subject: [PATCH 4/4] Handle monitor clients --- src/gmmpp_msgs.erl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gmmpp_msgs.erl b/src/gmmpp_msgs.erl index e93707b..5eb0f21 100644 --- a/src/gmmpp_msgs.erl +++ b/src/gmmpp_msgs.erl @@ -60,6 +60,7 @@ validate(#{ connect := #{ pubkey := PK , versions := Versions , pool_id := PoolId , extra_pubkeys := Extra + , type := Type , nonces := Nonces }} = Msg, _Vsn) -> valid({list, protocol}, Protocols), @@ -68,6 +69,7 @@ validate(#{ connect := #{ pubkey := PK valid(contract, PoolId), valid(pubkey, PK), valid({list, pubkey}, Extra), + valid(type, Type), valid(pos_int, Nonces), Msg; validate(#{ connect_ack := #{ protocol := Protocol @@ -113,11 +115,13 @@ validate(#{ no_solution := #{ seq := Seq validate(#{ stop_mining := #{} } = Msg, _Vsn) -> Msg. -encode_connect(#{ protocols := _Protocols - , versions := _Versions - , pool_id := _PoolId - , pubkey := _Pubkey - , signature := _Sig } = Params, Id) -> +encode_connect(#{ protocols := _Protocols + , versions := _Versions + , pool_id := _PoolId + , pubkey := _Pubkey + , extra_pubkeys := _Extra + , type := _Type + , signature := _Sig } = Params, Id) -> encode_request(#{connect => Params}, Id, connect_protocol(), connect_version()). decode_connect(MsgBin) -> @@ -241,12 +245,14 @@ decode_msg_(<<"connect">>, #{ <<"protocols">> := Protos , <<"pool_id">> := PoolId , <<"pubkey">> := PK , <<"extra_pubkeys">> := Extra + , <<"type">> := Type , <<"nonces">> := Nonces }) -> #{connect => #{ protocols => Protos , versions => Vsns , pool_id => PoolId , pubkey => PK , extra_pubkeys => Extra + , type => Type , nonces => Nonces }}; decode_msg_(<<"get_nonces">>, #{ <<"seq">> := Seq @@ -291,6 +297,7 @@ valid_(target, T) -> pos_integer(T); valid_(edge_bits, E) -> pos_integer(E); valid_(pos_int, I) -> pos_integer(I); valid_(contract, Id) -> ok_tuple(gmser_api_encoder:safe_defode(contract_pubkey, Id)); +valid_(type, T) -> lists:member(T, [miner, monitor]); valid_(nonces, Ns) -> case Ns of [N] -> pos_integer(N);