From 83173996d94c5d725fa8a4187aa2ba3d94262c21 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 12 Mar 2021 08:23:12 -0800 Subject: [PATCH] Improve dkg status out to be more concise and readable --- src/dkg_hybriddkg.erl | 52 +++++++++++++++++++++++++++++++------------ src/dkg_hybridvss.erl | 30 +++++++++++++++++-------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/dkg_hybriddkg.erl b/src/dkg_hybriddkg.erl index d62ee3c..a47f12d 100644 --- a/src/dkg_hybriddkg.erl +++ b/src/dkg_hybriddkg.erl @@ -650,21 +650,45 @@ result_name(Key) when is_atom(Key) -> status(DKG) -> #{id => DKG#dkg.id, shares_map => maps:map(fun(_K, Shares) -> dkg_hybridvss:status(Shares) end, DKG#dkg.shares_map), - shares_results_from => maps:keys(DKG#dkg.shares_results), + missing_shares_results_from => lists:seq(1, DKG#dkg.n) -- maps:keys(DKG#dkg.shares_results), echoes_required => ceil(( DKG#dkg.n + DKG#dkg.t + 1 )/2), - echoes_detail => maps:map(fun(_K, Echoes) -> - lists:foldl(fun({Sender, {signed_echo, Shares}}, Acc) -> - [#{sender => Sender, - echo_counts => count_echo(DKG, Shares), - echo => lists:sort([X || {X, _} <- get_echo(DKG, Shares)])} | Acc] - end, [], Echoes) - end, DKG#dkg.echo_counts), - readies_details => maps:map(fun(_K, Readies) -> - lists:foldl(fun({Sender, {signed_ready, Shares}}, Acc) -> - [#{sender => Sender, - ready_counts => count_ready(DKG, Shares), - ready => lists:sort([X || {X, _} <- get_ready(DKG, Shares)])} | Acc] - end, [], Readies) + echoes_details => maps:map(fun({_Leader, SelectedShares}, Echoes) -> + {_Sender, {signed_echo, Shares}} = hd(Echoes), + M = #{ echo_counts => count_echo(DKG, Shares), + shares => + lists:foldl(fun(K, Acc) -> + maps:put(K, #{ + acked => lists:member(K, DKG#dkg.shares_acked), + has_share => maps:is_key(K, DKG#dkg.shares_results) + }, Acc) + end, #{}, SelectedShares) + }, + case count_echo(DKG, Shares) >= ceil(( DKG#dkg.n + DKG#dkg.t + 1 )/2) of + true -> + M; + false -> + maps:put(missing_echoes, lists:seq(1, DKG#dkg.n) -- lists:sort([X || {X, _} <- get_echo(DKG, Shares)]), M) + end + end, DKG#dkg.echo_counts), + readies_details => maps:map(fun({_Leader, SelectedShares}, Readies) -> + {_Sender, {signed_ready, Shares}} = hd(Readies), + M = #{ ready_counts => count_ready(DKG, Shares), + missing_readies => lists:seq(1, DKG#dkg.n) -- lists:sort([X || {X, _} <- get_ready(DKG, Shares)]), + shares => + lists:foldl(fun(K, Acc) -> + maps:put(K, #{ + acked => lists:member(K, DKG#dkg.shares_acked), + has_share => maps:is_key(K, DKG#dkg.shares_results) + }, Acc) + end, #{}, SelectedShares) + }, + case count_ready(DKG, Shares) >= (DKG#dkg.t + 1 ) of + true -> + M; + false -> + maps:put(missing_readies, lists:seq(1, DKG#dkg.n) -- lists:sort([X || {X, _} <- get_ready(DKG, Shares)]), M) + end + end, DKG#dkg.ready_counts), readies_required => (DKG#dkg.t + 1), leader_changing => DKG#dkg.leader_changing, diff --git a/src/dkg_hybridvss.erl b/src/dkg_hybridvss.erl index 46e49ee..e8d55e3 100644 --- a/src/dkg_hybridvss.erl +++ b/src/dkg_hybridvss.erl @@ -23,6 +23,8 @@ received_commitment = false :: boolean(), commitments = #{} :: #{binary() => dkg_commitment:commitment()}, callback = false :: boolean(), + sent_echoes = [] :: [integer()], + sent_readies = [] :: [integer()], signfun :: signfun(), verifyfun :: verifyfun() }). @@ -103,7 +105,7 @@ handle_msg(VSS=#vss{n=N, id=Id, session=Session, received_commitment=false, call Msgs = lists:map(fun(Node) -> erlang_pbc:element_to_binary(dkg_polynomial:evaluate(A, Node)) end, dkg_util:allnodes(N)), - {store_commitment(Commitment, VSS#vss{received_commitment=true}), {send, [{callback, {echo, {Session, SerializedCommitmentMatrix0, Msgs}}}]}}; + {store_commitment(Commitment, echo, VSS#vss{received_commitment=true}), {send, [{callback, {echo, {Session, SerializedCommitmentMatrix0, Msgs}}}]}}; false -> {VSS, ok} end; @@ -115,7 +117,7 @@ handle_msg(VSS=#vss{n=N, id=Id, session=Session, received_commitment=false}, Sen Msgs = lists:map(fun(Node) -> {unicast, Node, {echo, {Session, SerializedCommitmentMatrix0, erlang_pbc:element_to_binary(dkg_polynomial:evaluate(A, Node))}}} end, dkg_util:allnodes(N)), - {store_commitment(Commitment, VSS#vss{received_commitment=true}), {send, Msgs}}; + {store_commitment(Commitment, echo, VSS#vss{received_commitment=true}), {send, Msgs}}; false -> {VSS, ok} end; @@ -145,7 +147,7 @@ handle_msg(VSS=#vss{id=Id, n=N, t=T, session=Session, done=false, callback=CB}, Msgs = lists:map(fun(Node) -> erlang_pbc:element_to_binary(lists:nth(Node+1, Subshares)) end, dkg_util:allnodes(N)), - {store_commitment(NewCommitment, VSS), {send, [{callback, {ready, {Session, SerializedCommitmentMatrix0, Msgs, ReadyProof}}}]}}; + {store_commitment(NewCommitment, ready, VSS), {send, [{callback, {ready, {Session, SerializedCommitmentMatrix0, Msgs, ReadyProof}}}]}}; true -> %% not in callback mode Subshares = dkg_commitment:interpolate(NewCommitment, echo, dkg_util:allnodes(N)), @@ -153,7 +155,7 @@ handle_msg(VSS=#vss{id=Id, n=N, t=T, session=Session, done=false, callback=CB}, Msgs = lists:map(fun(Node) -> {unicast, Node, {ready, {Session, SerializedCommitmentMatrix0, erlang_pbc:element_to_binary(lists:nth(Node+1, Subshares)), ReadyProof}}} end, dkg_util:allnodes(N)), - {store_commitment(NewCommitment, VSS), {send, Msgs}}; + {store_commitment(NewCommitment, ready, VSS), {send, Msgs}}; false -> {store_commitment(NewCommitment, VSS), ok} end; @@ -191,7 +193,7 @@ handle_msg(VSS=#vss{n=N, t=T, f=F, id=Id, done=false, callback=CB}, Sender, {rea Msgs = lists:map(fun(Node) -> erlang_pbc:element_to_binary(lists:nth(Node+1, SubShares)) end, dkg_util:allnodes(N)), - NewVSS = store_commitment(NewCommitment, VSS), + NewVSS = store_commitment(NewCommitment, ready, VSS), {NewVSS, {send, [{callback, {ready, {Session, SerializedCommitmentMatrix0, Msgs, MyReadyProof}}}]}}; true -> %% not in callback mode @@ -200,7 +202,7 @@ handle_msg(VSS=#vss{n=N, t=T, f=F, id=Id, done=false, callback=CB}, Sender, {rea Msgs = lists:map(fun(Node) -> {unicast, Node, {ready, {Session, SerializedCommitmentMatrix0, erlang_pbc:element_to_binary(lists:nth(Node+1, SubShares)), MyReadyProof}}} end, dkg_util:allnodes(N)), - NewVSS = store_commitment(NewCommitment, VSS), + NewVSS = store_commitment(NewCommitment, ready, VSS), {NewVSS, {send, Msgs}}; false -> case dkg_commitment:num_readies(NewCommitment) == (N-T-F) andalso @@ -289,12 +291,14 @@ status(VSS) -> #{id => VSS#vss.id, session => VSS#vss.session, received_commitment => VSS#vss.received_commitment, - commitments => maps:map(fun(_, C) -> + commitments => maps:map(fun(Id, C) -> #{ num_echoes => dkg_commitment:num_echoes(C), num_readies => dkg_commitment:num_readies(C), - echoes => maps:keys(dkg_commitment:echoes(C)), - readies => maps:keys(dkg_commitment:ready_proofs(C)) + missing_echoes => lists:seq(1, VSS#vss.n) -- maps:keys(dkg_commitment:echoes(C)), + missing_readies => lists:seq(1, VSS#vss.n) -- maps:keys(dkg_commitment:ready_proofs(C)), + sent_echo => lists:member(Id, VSS#vss.sent_echoes), + sent_ready => lists:member(Id, VSS#vss.sent_readies) } end, VSS#vss.commitments), done => VSS#vss.done @@ -314,6 +318,14 @@ store_commitment(Commitment, VSS) -> Key = erlang:phash2(dkg_commitment:binary_matrix(Commitment)), VSS#vss{commitments=maps:put(Key, Commitment, VSS#vss.commitments)}. +store_commitment(Commitment, ready, VSS) -> + Key = erlang:phash2(dkg_commitment:binary_matrix(Commitment)), + VSS#vss{commitments=maps:put(Key, Commitment, VSS#vss.commitments), sent_readies=[Key|VSS#vss.sent_readies]}; +store_commitment(Commitment, echo, VSS) -> + Key = erlang:phash2(dkg_commitment:binary_matrix(Commitment)), + VSS#vss{commitments=maps:put(Key, Commitment, VSS#vss.commitments), sent_echoes=[Key|VSS#vss.sent_echoes]}. + + construct_proof(#vss{id=Id, session={Dealer, Round}, signfun=SignFun}) -> %% Construct and sign a proof %% XXX See the notes on the construction of 'Round' above