diff --git a/src/hbbft.erl b/src/hbbft.erl index 5447954..f7073fc 100644 --- a/src/hbbft.erl +++ b/src/hbbft.erl @@ -11,6 +11,7 @@ serialize/1, serialize/2, deserialize/2, + status/1, is_serialized/1]). -record(hbbft_data, { @@ -58,6 +59,19 @@ -type rbc_wrapped_output() :: hbbft_utils:unicast({{acs, non_neg_integer()}, {{rbc, non_neg_integer()}, hbbft_rbc:val_msg()}}) | hbbft_utils:multicast({{acs, non_neg_integer()}, {{rbc, non_neg_integer()}, hbbft_rbc:echo_msg() | hbbft_rbc:ready_msg()}}). -type bba_wrapped_output() :: hbbft_utils:multicast({{acs, non_neg_integer()}, hbbft_acs:bba_msg()}). +-spec status(hbbft_data()) -> map(). +status(HBBFTData) -> + #{batch_size => HBBFTData#hbbft_data.batch_size, + buf => length(HBBFTData#hbbft_data.buf), + round => HBBFTData#hbbft_data.round, + acs_init => HBBFTData#hbbft_data.acs_init, + acs => hbbft_acs:status(HBBFTData#hbbft_data.acs), + sent_txns => HBBFTData#hbbft_data.sent_txns, + sent_sig => HBBFTData#hbbft_data.sent_sig, + acs_results => length(HBBFTData#hbbft_data.acs_results), + j => HBBFTData#hbbft_data.j + }. + -spec init(tpke_privkey:privkey(), pos_integer(), non_neg_integer(), non_neg_integer(), pos_integer()) -> hbbft_data(). init(SK, N, F, J, BatchSize) -> #hbbft_data{secret_key=SK, n=N, f=F, j=J, batch_size=BatchSize, acs=hbbft_acs:init(SK, N, F, J)}. diff --git a/src/hbbft_acs.erl b/src/hbbft_acs.erl index 26b3939..122e257 100644 --- a/src/hbbft_acs.erl +++ b/src/hbbft_acs.erl @@ -1,6 +1,6 @@ -module(hbbft_acs). --export([init/4, input/2, handle_msg/3, serialize/1, deserialize/2]). +-export([init/4, input/2, handle_msg/3, serialize/1, deserialize/2, status/1]). -record(rbc_state, { rbc_data :: hbbft_rbc:rbc_data(), @@ -56,6 +56,11 @@ -export_type([acs_data/0, msgs/0, bba_msg/0, acs_serialized_data/0, bba_state/0, rbc_state/0, bba_serialized_state/0, rbc_serialized_state/0]). +-spec status(acs_data()) -> map(). +status(ACSData) -> + #{rbc => maps:map(fun(_K, #rbc_state{rbc_data=RBCData, result=R}) -> #{rbc => hbbft_rbc:status(RBCData), result => is_binary(R)} end, ACSData#acs_data.rbc), + bba => maps:map(fun(_K, #bba_state{bba_data=BBAData, result=R, input=I}) -> #{bba => hbbft_bba:status(BBAData), result => R, input => I} end, ACSData#acs_data.bba)}. + -spec init(tpke_privkey:privkey(), pos_integer(), non_neg_integer(), non_neg_integer()) -> acs_data(). init(SK, N, F, J) -> %% instantiate all the RBCs diff --git a/src/hbbft_bba.erl b/src/hbbft_bba.erl index cc8ac83..f1cb31a 100644 --- a/src/hbbft_bba.erl +++ b/src/hbbft_bba.erl @@ -1,6 +1,6 @@ -module(hbbft_bba). --export([init/3, input/2, handle_msg/3, serialize/1, deserialize/2]). +-export([init/3, input/2, handle_msg/3, serialize/1, deserialize/2, status/1]). -record(bba_data, { state = init :: init | waiting | done, @@ -49,6 +49,22 @@ -export_type([bba_data/0, bba_serialized_data/0, bval_msg/0, aux_msg/0, coin_msg/0, msgs/0, conf_msg/0]). +-spec status(bba_data()) -> map(). +status(BBAData) -> + #{state => BBAData#bba_data.state, + round => BBAData#bba_data.round, + coin => hbbft_cc:status(BBAData#bba_data.coin), + aux_sent => BBAData#bba_data.aux_sent, + conf_sent => BBAData#bba_data.conf_sent, + coin_sent => BBAData#bba_data.coin_sent, + output => BBAData#bba_data.output, + conf_witness => BBAData#bba_data.conf_witness, + aux_witness => BBAData#bba_data.aux_witness, + witness => BBAData#bba_data.witness, + bin_values => BBAData#bba_data.bin_values, + broadcasted => BBAData#bba_data.broadcasted + }. + -spec init(tpke_privkey:privkey(), pos_integer(), non_neg_integer()) -> bba_data(). init(SK, N, F) -> #bba_data{secret_key=SK, n=N, f=F}. @@ -110,7 +126,8 @@ handle_msg(Data = #bba_data{round=R, coin=Coin}, J, {{coin, R}, CMsg}) when Coin case B == Result rem 2 andalso Data#bba_data.output == B of true -> %% we are done - {Data, {result, B}}; + NewData = Data#bba_data{state=done}, + {NewData, {result, B}}; false -> %% increment round and continue NewData = init(Data#bba_data.secret_key, Data#bba_data.n, Data#bba_data.f), @@ -128,7 +145,8 @@ handle_msg(Data = #bba_data{round=R, coin=Coin}, J, {{coin, R}, CMsg}) when Coin handle_msg(Data = #bba_data{round=R, coin=Coin}, J, Msg = {{coin, R}, _CMsg}) when Coin == undefined -> %% we have not called input() yet this round, so we need to manually init the coin handle_msg(Data#bba_data{coin=maybe_init_coin(Data)}, J, Msg); -handle_msg(Data, _J, _Msg) -> +handle_msg(Data = #bba_data{round=R}, J, Msg) -> + error_logger:info_msg("Skipped bba_msg: ~p from ~p for round: ~p~n", [Msg, J, R]), {Data, ok}. %% – upon receiving BVALr (b) messages from f + 1 nodes, if diff --git a/src/hbbft_cc.erl b/src/hbbft_cc.erl index 63ef8b0..58684c7 100644 --- a/src/hbbft_cc.erl +++ b/src/hbbft_cc.erl @@ -1,6 +1,6 @@ -module(hbbft_cc). --export([init/4, get_coin/1, handle_msg/3, serialize/1, deserialize/2]). +-export([init/4, get_coin/1, handle_msg/3, serialize/1, deserialize/2, status/1]). -record(cc_data, { state = waiting :: waiting | done, @@ -27,6 +27,14 @@ -export_type([cc_data/0, cc_serialized_data/0, share_msg/0]). +-spec status(undefined | cc_data()) -> undefined | map(). +status(undefined) -> + undefined; +status(CCData) -> + #{state => CCData#cc_data.state, + shares => serialize_shares(CCData#cc_data.shares) + }. + %% Figure12. Bullet1 %% Trusted Setup Phase: A trusted dealer runs pk, {ski } ← %% ThresholdSetup to generate a common public key, as well as diff --git a/src/hbbft_rbc.erl b/src/hbbft_rbc.erl index 03d4833..443e12d 100644 --- a/src/hbbft_rbc.erl +++ b/src/hbbft_rbc.erl @@ -1,6 +1,6 @@ -module(hbbft_rbc). --export([init/4, input/2, handle_msg/3]). +-export([init/4, input/2, handle_msg/3, status/1]). -record(rbc_data, { state = init :: init | waiting | done, @@ -35,6 +35,16 @@ -export_type([rbc_data/0, val_msg/0, echo_msg/0, ready_msg/0, msgs/0]). %% API. + +-spec status(rbc_data()) -> map(). +status(RBCData) -> + #{state => RBCData#rbc_data.state, + num_echoes => length(maps:values(RBCData#rbc_data.num_echoes)), + num_readies => length(maps:values(RBCData#rbc_data.num_readies)), + ready_sent => RBCData#rbc_data.ready_sent, + leader => RBCData#rbc_data.leader + }. + -spec init(pos_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()) -> rbc_data(). init(N, F, Pid, Leader) -> #rbc_data{n=N, f=F, pid=Pid, leader=Leader}.