diff --git a/libraries/chain/include/eosio/chain/hotstuff.hpp b/libraries/chain/include/eosio/chain/hotstuff.hpp index b580387d51..eee4e63bc9 100644 --- a/libraries/chain/include/eosio/chain/hotstuff.hpp +++ b/libraries/chain/include/eosio/chain/hotstuff.hpp @@ -30,7 +30,7 @@ namespace eosio::chain { struct hs_vote_message { fc::sha256 proposal_id; //vote on proposal - name finalizer; + fc::crypto::blslib::bls_public_key finalizer_key; fc::crypto::blslib::bls_signature sig; }; @@ -84,7 +84,7 @@ namespace eosio::chain { // // @ignore quorum_met FC_REFLECT(eosio::chain::quorum_certificate_message, (proposal_id)(active_finalizers)(active_agg_sig)); FC_REFLECT(eosio::chain::extended_schedule, (producer_schedule)(bls_pub_keys)); -FC_REFLECT(eosio::chain::hs_vote_message, (proposal_id)(finalizer)(sig)); +FC_REFLECT(eosio::chain::hs_vote_message, (proposal_id)(finalizer_key)(sig)); FC_REFLECT(eosio::chain::hs_proposal_message, (proposal_id)(block_id)(parent_id)(final_on_qc)(justify)(phase_counter)); FC_REFLECT(eosio::chain::hs_new_block_message, (block_id)(justify)); FC_REFLECT(eosio::chain::hs_new_view_message, (high_qc)); diff --git a/libraries/hotstuff/chain_pacemaker.cpp b/libraries/hotstuff/chain_pacemaker.cpp index 2940f08cc8..02afcce12f 100644 --- a/libraries/hotstuff/chain_pacemaker.cpp +++ b/libraries/hotstuff/chain_pacemaker.cpp @@ -106,7 +106,7 @@ namespace eosio { namespace hotstuff { bls_key_map_t finalizer_keys, fc::logger& logger) : _chain(chain), - _qc_chain("default"_n, this, std::move(my_producers), std::move(finalizer_keys), logger), + _qc_chain(std::string("default"), this, std::move(my_producers), std::move(finalizer_keys), logger), _logger(logger) { _accepted_block_connection = chain->accepted_block.connect( [this]( const block_state_ptr& blk ) { @@ -260,23 +260,38 @@ namespace eosio { namespace hotstuff { return n; } - std::vector chain_pacemaker::get_finalizers() { + std::vector chain_pacemaker::get_finalizer_keys() { -#warning FIXME: Use _active_finalizer_set in pacemaker/qc_chain. +//#warning FIXME: Use _active_finalizer_set in pacemaker/qc_chain. // _active_finalizer_set should be used std::unique_lock g( _chain_state_mutex ); block_state_ptr hbs = _head_block_state; g.unlock(); - // Old code: get eosio::name from the producer schedule + std::vector active_pub_keys; + active_pub_keys.reserve(_active_finalizer_set.finalizers.size()); + + std::transform(_active_finalizer_set.finalizers.begin(), _active_finalizer_set.finalizers.end(), active_pub_keys.begin(), [](finalizer_authority f_auth) { + return f_auth.public_key; + }); + + return active_pub_keys; + +/* // Old code: get eosio::name from the producer schedule const std::vector& pa_list = hbs->active_schedule.producers; std::vector pn_list; pn_list.reserve(pa_list.size()); std::transform(pa_list.begin(), pa_list.end(), std::back_inserter(pn_list), [](const producer_authority& p) { return p.producer_name; }); - return pn_list; + return pn_list;*/ + + //_active_finalizer_set.finalizers + + + + } block_id_type chain_pacemaker::get_current_block_id() { @@ -297,19 +312,19 @@ namespace eosio { namespace hotstuff { prof.core_out(); } - void chain_pacemaker::send_hs_proposal_msg(const hs_proposal_message& msg, name id) { + void chain_pacemaker::send_hs_proposal_msg(const hs_proposal_message& msg, const std::string& id) { bcast_hs_message(msg); } - void chain_pacemaker::send_hs_vote_msg(const hs_vote_message& msg, name id) { + void chain_pacemaker::send_hs_vote_msg(const hs_vote_message& msg, const std::string& id) { bcast_hs_message(msg); } - void chain_pacemaker::send_hs_new_block_msg(const hs_new_block_message& msg, name id) { + void chain_pacemaker::send_hs_new_block_msg(const hs_new_block_message& msg, const std::string& id) { bcast_hs_message(msg); } - void chain_pacemaker::send_hs_new_view_msg(const hs_new_view_message& msg, name id) { + void chain_pacemaker::send_hs_new_view_msg(const hs_new_view_message& msg, const std::string& id) { bcast_hs_message(msg); } diff --git a/libraries/hotstuff/include/eosio/hotstuff/base_pacemaker.hpp b/libraries/hotstuff/include/eosio/hotstuff/base_pacemaker.hpp index 7fce189948..c12dbd8f2f 100644 --- a/libraries/hotstuff/include/eosio/hotstuff/base_pacemaker.hpp +++ b/libraries/hotstuff/include/eosio/hotstuff/base_pacemaker.hpp @@ -3,6 +3,8 @@ #include #include +#include + #include namespace eosio::chain { @@ -33,13 +35,15 @@ namespace eosio::hotstuff { virtual chain::name get_proposer() = 0; virtual chain::name get_leader() = 0; virtual chain::name get_next_leader() = 0; - virtual std::vector get_finalizers() = 0; + // virtual std::vector get_finalizers() = 0; + virtual std::vector get_finalizer_keys() = 0; + //outbound communications; 'id' is the producer name (can be ignored if/when irrelevant to the implementer) - virtual void send_hs_proposal_msg(const chain::hs_proposal_message& msg, chain::name id) = 0; - virtual void send_hs_vote_msg(const chain::hs_vote_message& msg, chain::name id) = 0; - virtual void send_hs_new_view_msg(const chain::hs_new_view_message& msg, chain::name id) = 0; - virtual void send_hs_new_block_msg(const chain::hs_new_block_message& msg, chain::name id) = 0; + virtual void send_hs_proposal_msg(const chain::hs_proposal_message& msg, const std::string& id) = 0; + virtual void send_hs_vote_msg(const chain::hs_vote_message& msg, const std::string& id) = 0; + virtual void send_hs_new_view_msg(const chain::hs_new_view_message& msg, const std::string& id) = 0; + virtual void send_hs_new_block_msg(const chain::hs_new_block_message& msg, const std::string& id) = 0; }; } // namespace eosio::hotstuff diff --git a/libraries/hotstuff/include/eosio/hotstuff/chain_pacemaker.hpp b/libraries/hotstuff/include/eosio/hotstuff/chain_pacemaker.hpp index c2c2331278..c636dbf59e 100644 --- a/libraries/hotstuff/include/eosio/hotstuff/chain_pacemaker.hpp +++ b/libraries/hotstuff/include/eosio/hotstuff/chain_pacemaker.hpp @@ -37,16 +37,17 @@ namespace eosio::hotstuff { name get_proposer(); name get_leader() ; name get_next_leader() ; - std::vector get_finalizers(); + //std::vector get_finalizers(); + std::vector get_finalizer_keys(); block_id_type get_current_block_id(); uint32_t get_quorum_threshold(); - void send_hs_proposal_msg(const hs_proposal_message& msg, name id); - void send_hs_vote_msg(const hs_vote_message& msg, name id); - void send_hs_new_view_msg(const hs_new_view_message& msg, name id); - void send_hs_new_block_msg(const hs_new_block_message& msg, name id); + void send_hs_proposal_msg(const hs_proposal_message& msg, const std::string& id); + void send_hs_vote_msg(const hs_vote_message& msg, const std::string& id); + void send_hs_new_view_msg(const hs_new_view_message& msg, const std::string& id); + void send_hs_new_block_msg(const hs_new_block_message& msg, const std::string& id); private: void on_accepted_block( const block_state_ptr& blk ); diff --git a/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp b/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp index e696280009..4e658fc1e0 100644 --- a/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp +++ b/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp @@ -95,14 +95,14 @@ namespace eosio::hotstuff { qc_chain() = delete; - qc_chain(name id, base_pacemaker* pacemaker, + qc_chain(std::string id, base_pacemaker* pacemaker, std::set my_producers, chain::bls_key_map_t finalizer_keys, fc::logger& logger); uint64_t get_state_version() const { return _state_version; } // calling this w/ thread sync is optional - name get_id_i() const { return _id; } // so far, only ever relevant in a test environment (no sync) + std::string get_id_i() const { return _id; } // so far, only ever relevant in a test environment (no sync) // Calls to the following methods should be thread-synchronized externally: @@ -124,16 +124,16 @@ namespace eosio::hotstuff { uint32_t positive_bits_count(const hs_bitset& finalizers); - hs_bitset update_bitset(const hs_bitset& finalizer_set, name finalizer); + hs_bitset update_bitset(const hs_bitset& finalizer_set, fc::crypto::blslib::bls_public_key finalizer_key); digest_type get_digest_to_sign(const block_id_type& block_id, uint8_t phase_counter, const fc::sha256& final_on_qc); //get digest to sign from proposal data void reset_qc(const fc::sha256& proposal_id); //reset current internal qc - bool evaluate_quorum(const extended_schedule& es, const hs_bitset& finalizers, const fc::crypto::blslib::bls_signature& agg_sig, const hs_proposal_message& proposal); //evaluate quorum for a proposal + bool evaluate_quorum(const hs_bitset& finalizers, const fc::crypto::blslib::bls_signature& agg_sig, const hs_proposal_message& proposal); //evaluate quorum for a proposal // qc.quorum_met has to be updated by the caller (if it wants to) based on the return value of this method - bool is_quorum_met(const quorum_certificate& qc, const extended_schedule& schedule, const hs_proposal_message& proposal); //check if quorum has been met over a proposal + bool is_quorum_met(const quorum_certificate& qc, const hs_proposal_message& proposal); //check if quorum has been met over a proposal hs_proposal_message new_proposal_candidate(const block_id_type& block_id, uint8_t phase_counter); //create new proposal message hs_new_block_message new_block_candidate(const block_id_type& block_id); //create new block message @@ -147,7 +147,7 @@ namespace eosio::hotstuff { void process_new_view(const hs_new_view_message& msg); //handles new view void process_new_block(const hs_new_block_message& msg); //handles new block - hs_vote_message sign_proposal(const hs_proposal_message& proposal, name finalizer); //sign proposal + hs_vote_message sign_proposal(const hs_proposal_message& proposal, const fc::crypto::blslib::bls_private_key& finalizer_priv_key, const fc::crypto::blslib::bls_public_key& finalizer_pub_key); bool extends(const fc::sha256& descendant, const fc::sha256& ancestor); //verify that a proposal descends from another @@ -169,15 +169,6 @@ namespace eosio::hotstuff { void gc_proposals(uint64_t cutoff); //garbage collection of old proposals -#warning remove. bls12-381 key used for testing purposes - //todo : remove. bls12-381 key used for testing purposes - std::vector _seed = - { 0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, - 19, 18, 12, 89, 6, 220, 18, 102, 58, 209, 82, - 12, 62, 89, 110, 182, 9, 44, 20, 254, 22 }; - - fc::crypto::blslib::bls_private_key _private_key = fc::crypto::blslib::bls_private_key(_seed); - enum msg_type { new_view = 1, new_block = 2, @@ -195,11 +186,11 @@ namespace eosio::hotstuff { quorum_certificate _high_qc; quorum_certificate _current_qc; uint32_t _v_height = 0; - eosio::chain::extended_schedule _schedule; + //eosio::chain::extended_schedule _schedule; base_pacemaker* _pacemaker = nullptr; std::set _my_producers; chain::bls_key_map_t _my_finalizer_keys; - name _id; + std::string _id; mutable std::atomic _state_version = 1; diff --git a/libraries/hotstuff/include/eosio/hotstuff/test_pacemaker.hpp b/libraries/hotstuff/include/eosio/hotstuff/test_pacemaker.hpp index 567eb44465..3088b7642f 100644 --- a/libraries/hotstuff/include/eosio/hotstuff/test_pacemaker.hpp +++ b/libraries/hotstuff/include/eosio/hotstuff/test_pacemaker.hpp @@ -9,9 +9,9 @@ namespace eosio { namespace hotstuff { //class-specific functions - bool is_qc_chain_active(const name & qcc_name) { return _qcc_deactivated.find(qcc_name) == _qcc_deactivated.end(); } + bool is_qc_chain_active(const name& qcc_name) { return _qcc_deactivated.find(qcc_name) == _qcc_deactivated.end(); } - using hotstuff_message = std::pair>; + using hotstuff_message = std::pair>; void set_proposer(name proposer); @@ -19,7 +19,7 @@ namespace eosio { namespace hotstuff { void set_next_leader(name next_leader); - void set_finalizers(std::vector finalizers); + void set_finalizer_keys(std::vector finalizers); void set_current_block_id(block_id_type id); @@ -41,26 +41,26 @@ namespace eosio { namespace hotstuff { void beat(); - void on_hs_vote_msg(const hs_vote_message & msg, name id); //confirmation msg event handler - void on_hs_proposal_msg(const hs_proposal_message & msg, name id); //consensus msg event handler - void on_hs_new_view_msg(const hs_new_view_message & msg, name id); //new view msg event handler - void on_hs_new_block_msg(const hs_new_block_message & msg, name id); //new block msg event handler + void on_hs_vote_msg(const hs_vote_message & msg, const std::string& id); //confirmation msg event handler + void on_hs_proposal_msg(const hs_proposal_message & msg, const std::string& id); //consensus msg event handler + void on_hs_new_view_msg(const hs_new_view_message & msg, const std::string& id); //new view msg event handler + void on_hs_new_block_msg(const hs_new_block_message & msg, const std::string& id); //new block msg event handler //base_pacemaker interface functions name get_proposer(); name get_leader(); name get_next_leader(); - std::vector get_finalizers(); + std::vector get_finalizer_keys(); block_id_type get_current_block_id(); uint32_t get_quorum_threshold(); - void send_hs_proposal_msg(const hs_proposal_message & msg, name id); - void send_hs_vote_msg(const hs_vote_message & msg, name id); - void send_hs_new_block_msg(const hs_new_block_message & msg, name id); - void send_hs_new_view_msg(const hs_new_view_message & msg, name id); + void send_hs_proposal_msg(const hs_proposal_message & msg, const std::string& id); + void send_hs_vote_msg(const hs_vote_message & msg, const std::string& id); + void send_hs_new_block_msg(const hs_new_block_message & msg, const std::string& id); + void send_hs_new_view_msg(const hs_new_view_message & msg, const std::string& id); std::vector _pending_message_queue; @@ -78,11 +78,10 @@ namespace eosio { namespace hotstuff { name _leader; name _next_leader; - std::vector _finalizers; + std::vector _finalizer_keys; block_id_type _current_block_id; - std::vector _unique_replicas; #warning calculate from schedule uint32_t _quorum_threshold = 15; //todo : calculate from schedule }; diff --git a/libraries/hotstuff/qc_chain.cpp b/libraries/hotstuff/qc_chain.cpp index e62381fb0e..12f68675c9 100644 --- a/libraries/hotstuff/qc_chain.cpp +++ b/libraries/hotstuff/qc_chain.cpp @@ -64,7 +64,6 @@ namespace eosio::hotstuff { fs.v_height = _v_height; fs.high_qc = _high_qc.to_msg(); fs.current_qc = _current_qc.to_msg(); - fs.schedule = _schedule; #ifdef QC_CHAIN_SIMPLE_PROPOSAL_STORE ps_height_iterator psh_it = _proposal_stores_by_height.begin(); while (psh_it != _proposal_stores_by_height.end()) { @@ -91,23 +90,25 @@ namespace eosio::hotstuff { return finalizers.count(); // the number of bits in this bitset that are set. } - hs_bitset qc_chain::update_bitset(const hs_bitset& finalizer_set, name finalizer ) { + hs_bitset qc_chain::update_bitset(const hs_bitset& finalizer_set, fc::crypto::blslib::bls_public_key finalizer_key ) { hs_bitset b(finalizer_set ); - vector finalizers = _pacemaker->get_finalizers(); - for (size_t i = 0; i < finalizers.size();i++) { - if (finalizers[i] == finalizer) { + + vector finalizer_keys = _pacemaker->get_finalizer_keys(); + + for (size_t i = 0; i < finalizer_keys.size();i++) { + if (finalizer_keys[i] == finalizer_key) { b.set(i); fc_tlog(_logger, " === finalizer found ${finalizer} new value : ${value}", - ("finalizer", finalizer)("value", [&](){ std::string r; boost::to_string(b, r); return r; }())); + ("finalizer_keys", finalizer_keys)("value", [&](){ std::string r; boost::to_string(b, r); return r; }())); return b; } } - fc_tlog(_logger, " *** finalizer not found ${finalizer}", - ("finalizer", finalizer)); - throw std::runtime_error("qc_chain internal error: finalizer not found"); + fc_tlog(_logger, " *** finalizer_key not found ${finalizer_key}", + ("finalizer_key", finalizer_key)); + throw std::runtime_error("qc_chain internal error: finalizer_key not found"); } digest_type qc_chain::get_digest_to_sign(const block_id_type& block_id, uint8_t phase_counter, const fc::sha256& final_on_qc){ @@ -182,8 +183,7 @@ namespace eosio::hotstuff { return b; } - bool qc_chain::evaluate_quorum(const extended_schedule& es, const hs_bitset& finalizers, const fc::crypto::blslib::bls_signature& agg_sig, const hs_proposal_message& proposal) { - + bool qc_chain::evaluate_quorum(const hs_bitset& finalizers, const fc::crypto::blslib::bls_signature& agg_sig, const hs_proposal_message& proposal) { if (positive_bits_count(finalizers) < _pacemaker->get_quorum_threshold()){ return false; @@ -191,26 +191,20 @@ namespace eosio::hotstuff { fc::crypto::blslib::bls_public_key agg_key; + std::vector pks =_pacemaker->get_finalizer_keys(); + bool first = true; for (hs_bitset::size_type i = 0; i < finalizers.size(); ++i) { if (finalizers[i]){ //adding finalizer's key to the aggregate pub key if (first) { first = false; - agg_key = _private_key.get_public_key(); + agg_key = pks[i]; } else { - agg_key = fc::crypto::blslib::aggregate({agg_key, _private_key.get_public_key()}); + agg_key = fc::crypto::blslib::aggregate({agg_key, pks[i]}); } } } -#warning fix todo - // **************************************************************************************************** - // FIXME/TODO: I removed this since it doesn't seem to be doing anything at the moment - // **************************************************************************************************** - // - //fc::crypto::blslib::bls_signature justification_agg_sig; - // - //if (proposal.justify.proposal_id != NULL_PROPOSAL_ID) justification_agg_sig = proposal.justify.active_agg_sig; digest_type digest = get_digest_to_sign(proposal.block_id, proposal.phase_counter, proposal.final_on_qc); @@ -221,7 +215,7 @@ namespace eosio::hotstuff { return ok; } - bool qc_chain::is_quorum_met(const quorum_certificate& qc, const extended_schedule& schedule, const hs_proposal_message& proposal) { + bool qc_chain::is_quorum_met(const quorum_certificate& qc, const hs_proposal_message& proposal) { if (qc.is_quorum_met()) { return true; //skip evaluation if we've already verified quorum was met @@ -230,12 +224,13 @@ namespace eosio::hotstuff { fc_tlog(_logger, " === qc : ${qc}", ("qc", qc.to_msg())); // If the caller wants to update the quorum_met flag on its "qc" object, it will have to do so // based on the return value of this method, since "qc" here is const. - return evaluate_quorum(schedule, qc.get_active_finalizers(), qc.get_active_agg_sig(), proposal); + return evaluate_quorum(qc.get_active_finalizers(), qc.get_active_agg_sig(), proposal); } } - qc_chain::qc_chain(name id, base_pacemaker* pacemaker, + qc_chain::qc_chain(std::string id, + base_pacemaker* pacemaker, std::set my_producers, bls_key_map_t finalizer_keys, fc::logger& logger) @@ -266,34 +261,31 @@ namespace eosio::hotstuff { } bool qc_chain::am_i_finalizer(){ - std::vector finalizers = _pacemaker->get_finalizers(); - auto mf_itr = _my_producers.begin(); - while(mf_itr!=_my_producers.end()){ - name n = *mf_itr; - auto prod_itr = std::find_if(finalizers.begin(), finalizers.end(), [&](const auto& f){ return f == n; }); - if (prod_itr!=finalizers.end()) return true; - mf_itr++; + std::vector finalizers = _pacemaker->get_finalizer_keys(); + auto mfk_itr = _my_finalizer_keys.begin(); + while(mfk_itr!=_my_finalizer_keys.end()){ + auto fin_itr = std::find(finalizers.begin(), finalizers.end(), mfk_itr->first); + if (fin_itr!=finalizers.end()) return true; + mfk_itr++; } return false; } - hs_vote_message qc_chain::sign_proposal(const hs_proposal_message & proposal, name finalizer){ + hs_vote_message qc_chain::sign_proposal(const hs_proposal_message& proposal, const fc::crypto::blslib::bls_private_key& finalizer_priv_key, const fc::crypto::blslib::bls_public_key& finalizer_pub_key){ _v_height = proposal.get_height(); digest_type digest = get_digest_to_sign(proposal.block_id, proposal.phase_counter, proposal.final_on_qc); std::vector h = std::vector(digest.data(), digest.data() + 32); -#warning use appropriate private key for each producer - fc::crypto::blslib::bls_signature sig = _private_key.sign(h); //FIXME/TODO: use appropriate private key for each producer - hs_vote_message v_msg = {proposal.proposal_id, finalizer, sig}; + fc::crypto::blslib::bls_signature sig = finalizer_priv_key.sign(h); + + hs_vote_message v_msg = {proposal.proposal_id, finalizer_pub_key, sig}; return v_msg; } void qc_chain::process_proposal(const hs_proposal_message & proposal){ - //auto start = fc::time_point::now(); - if (!proposal.justify.proposal_id.empty()) { const hs_proposal_message *jp = get_proposal( proposal.justify.proposal_id ); @@ -307,7 +299,6 @@ namespace eosio::hotstuff { if (p != nullptr) { fc_elog(_logger, " *** ${id} proposal received twice : ${proposal_id}", ("id",_id)("proposal_id", proposal.proposal_id)); - if (p->justify.proposal_id != proposal.justify.proposal_id) { fc_elog(_logger, " *** ${id} two identical proposals (${proposal_id}) have different justifications : ${justify_1} vs ${justify_2}", @@ -338,7 +329,6 @@ namespace eosio::hotstuff { { const hs_proposal_message & existing_proposal = *hgt_itr; #endif - fc_elog(_logger, " *** ${id} received a different proposal at the same height (${block_num}, ${phase_counter})", ("id",_id) ("block_num", existing_proposal.block_num()) @@ -378,19 +368,18 @@ namespace eosio::hotstuff { std::vector msgs; if (signature_required){ + //iterate over all my finalizer keys and sign / broadcast for each that is in the schedule + std::vector finalizers = _pacemaker->get_finalizer_keys(); - //iterate over all my finalizers and sign / broadcast for each that is in the schedule - std::vector finalizers = _pacemaker->get_finalizers(); - - auto mf_itr = _my_producers.begin(); + auto mfk_itr = _my_finalizer_keys.begin(); - while(mf_itr!=_my_producers.end()){ + while(mfk_itr!=_my_finalizer_keys.end()){ - auto prod_itr = std::find(finalizers.begin(), finalizers.end(), *mf_itr); + auto fin_itr = std::find(finalizers.begin(), finalizers.end(), mfk_itr->first); - if (prod_itr!=finalizers.end()) { + if (fin_itr!=finalizers.end()) { - hs_vote_message v_msg = sign_proposal(proposal, *prod_itr); + hs_vote_message v_msg = sign_proposal(proposal, mfk_itr->second, mfk_itr->first); fc_tlog(_logger, " === ${id} signed proposal : block_num ${block_num} phase ${phase_counter} : proposal_id ${proposal_id}", ("id", _id) @@ -398,12 +387,11 @@ namespace eosio::hotstuff { ("phase_counter", proposal.phase_counter) ("proposal_id", proposal.proposal_id)); - //send_hs_vote_msg(v_msg); msgs.push_back(v_msg); }; - mf_itr++; + mfk_itr++; } } @@ -437,8 +425,8 @@ namespace eosio::hotstuff { if (!am_leader) return; - fc_tlog(_logger, " === Process vote from ${finalizer} : current bitset ${value}" , - ("finalizer", vote.finalizer)("value", _current_qc.get_active_finalizers_string())); + fc_tlog(_logger, " === Process vote from ${finalizer_key} : current bitset ${value}" , + ("finalizer_key", vote.finalizer_key)("value", _current_qc.get_active_finalizers_string())); // only leader need to take action on votes if (vote.proposal_id != _current_qc.get_proposal_id()) return; @@ -461,11 +449,10 @@ namespace eosio::hotstuff { _current_qc.set_active_agg_sig(fc::crypto::blslib::aggregate({_current_qc.get_active_agg_sig(), vote.sig })); else _current_qc.set_active_agg_sig(vote.sig); + fc_tlog(_logger, " === update bitset ${value} ${finalizer_key}", ("value", _current_qc.get_active_finalizers_string())("finalizer_key", vote.finalizer_key)); + _current_qc.set_active_finalizers(update_bitset(finalizer_set, vote.finalizer_key)); - fc_tlog(_logger, " === update bitset ${value} ${finalizer}", ("value", _current_qc.get_active_finalizers_string())("finalizer", vote.finalizer)); - _current_qc.set_active_finalizers(update_bitset(finalizer_set, vote.finalizer)); - - quorum_met = is_quorum_met(_current_qc, _schedule, *p); + quorum_met = is_quorum_met(_current_qc, *p); if (quorum_met){ @@ -688,7 +675,7 @@ namespace eosio::hotstuff { return false; if (new_high_qc_prop->get_height() > old_high_qc_prop->get_height() - && is_quorum_met(high_qc, _schedule, *new_high_qc_prop)) + && is_quorum_met(high_qc, *new_high_qc_prop)) { // "The caller does not need this updated on their high_qc structure" -- g //high_qc.quorum_met = true; diff --git a/libraries/hotstuff/test/test_hotstuff.cpp b/libraries/hotstuff/test/test_hotstuff.cpp index 997708fe91..0027799fcf 100644 --- a/libraries/hotstuff/test/test_hotstuff.cpp +++ b/libraries/hotstuff/test/test_hotstuff.cpp @@ -11,6 +11,7 @@ #include #include +#include #include using namespace eosio::hotstuff; @@ -35,6 +36,29 @@ std::vector unique_replicas { "bpp"_n, "bpq"_n, "bpr"_n, "bps"_n, "bpt"_n, "bpu"_n }; +std::vector unique_replica_keys { + "PVT_BLS_r4ZpChd87ooyzl6MIkw23k7PRX8xptp7TczLJHCIIW88h/hS", + "PVT_BLS_/l7xzXANaB+GrlTsbZEuTiSOiWTtpBoog+TZnirxUUSaAfCo", + "PVT_BLS_3FoY73Q/gED3ejyg8cvnGqHrMmx4cLKwh/e0sbcsCxpCeqn3", + "PVT_BLS_warwI76e+pPX9wLFZKPFagngeFM8bm6J8D5w0iiHpxW7PiId", + "PVT_BLS_iZFwiqdogOl9RNr1Hv1z+Rd6AwD9BIoxZcU1EPX+XFSFmm5p", + "PVT_BLS_Hmye7lyiCrdF54/nF/HRU0sY/Hrse1ls/yqojIUOVQsxXUIK", + "PVT_BLS_jglKDzpvyI+LFJ4xJG2MRylH9KiAEj//M9sgI+AM5mhLASBs", + "PVT_BLS_OWemmo0YkDNEYcMnbvAHI7qS6YIJTVBc+3LCAi9u8QmMe3V/", + "PVT_BLS_xYhEMbBy6Z4TYGha/qYaUwiwv4UVX9qNWf4ivRjAyCLCG7/G", + "PVT_BLS_ETZDiw3qd1Kpu3L5hH9fPKR4tg0meCkRUsRE2KpW8WP5SU2l", + "PVT_BLS_KuL3oMYpBrqmIMqoBIsA4UX1jYyXzn7et93J+m+ctk8FAY0I", + "PVT_BLS_bNz9W9QkxeREp966ntnUV4mN4dLOB4DNSghf2Y85o1YI+p7t", + "PVT_BLS_uP48z/V66g7wU7BwNN1xhNnZOyf3mv8yxGFT2eoIK3HLL5aw", + "PVT_BLS_/HIa+nJWSCgVNs6rZ3LUhqp1chRkxyaUxumvN3HSTAE4VIql", + "PVT_BLS_Aq4tqxG/sDEwGMZUa/Vhznc2i3B4wHNopGV3bJpTNW6FauCN", + "PVT_BLS_U3QCa0uwzeeK4w1hI2IvUzgF9+hk496LyODdvgYpUBmgZiwu", + "PVT_BLS_WyyJ26tRpjpzmwke/sGJr0YUIyB/zSNsbo/99PwDHh4pvo5V", + "PVT_BLS_t2xBqsJKO0RHQMvsIYHFpvuy+IkBrCVeZl1NxThKEwwvUbiP", + "PVT_BLS_94/Vo26YNQV1P7zWmkDnh02P0ZcPM5xQlLG3LiUCOUUgMpEi", + "PVT_BLS_uQ9ONJ/oJlj+yRIjE3tiLcoIXTMEuCwMuAFL1WUDY28N97gF", + "PVT_BLS_2qtUuz8cYjbu/shyUPxIwKrBMSSbvolv4iJJvykUMRFl4hGt"}; + fc::logger hotstuff_logger; class hotstuff_test_handler { @@ -42,7 +66,7 @@ class hotstuff_test_handler { std::vector>> _qc_chains; - void initialize_qc_chains(test_pacemaker& tpm, std::vector replicas){ + void initialize_qc_chains(test_pacemaker& tpm, std::vector replicas, std::vector replica_keys){ _qc_chains.clear(); @@ -52,14 +76,21 @@ class hotstuff_test_handler { //_qc_chains.reserve( 15 ); //_qc_chains.reserve( replicas.size() ); - for (name r : replicas) { - qc_chain *qcc_ptr = new qc_chain(r, &tpm, {r}, {}, hotstuff_logger); + //for (fc::crypto::blslib::bls_private_key r : replicas) { + for (size_t i = 0 ; i < replicas.size() ; i++){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(replica_keys[i]); + + bls_key_map_t keys{{sk.get_public_key(), sk}}; + + qc_chain *qcc_ptr = new qc_chain(replica_keys[i].to_string(), &tpm, {replicas[i]}, keys, hotstuff_logger); std::shared_ptr qcc_shared_ptr(qcc_ptr); - _qc_chains.push_back( std::make_pair(r, qcc_shared_ptr) ); + _qc_chains.push_back( std::make_pair(replicas[i], qcc_shared_ptr) ); - tpm.register_qc_chain( r, qcc_shared_ptr ); + tpm.register_qc_chain(replicas[i], qcc_shared_ptr ); } + } void print_msgs(std::vector msgs ){ @@ -124,16 +155,16 @@ class hotstuff_test_handler { const hs_proposal_message *lock = fs.get_proposal( fs.b_lock ); const hs_proposal_message *exec = fs.get_proposal( fs.b_exec ); - if (leaf != nullptr) std::cout << " - " << bp.to_string() << " current _b_leaf is : " << fs.b_leaf.str() << " block_num : " << leaf->block_num() << ", phase : " << unsigned(leaf->phase_counter) << "\n"; + if (leaf != nullptr) std::cout << " - " << bp << " current _b_leaf is : " << fs.b_leaf.str() << " block_num : " << leaf->block_num() << ", phase : " << unsigned(leaf->phase_counter) << "\n"; else std::cout << " - No b_leaf value " << "\n"; - if (qc != nullptr) std::cout << " - " << bp.to_string() << " current high_qc is : " << fs.high_qc.proposal_id.str() << " block_num : " << qc->block_num() << ", phase : " << unsigned(qc->phase_counter) << "\n"; + if (qc != nullptr) std::cout << " - " << bp << " current high_qc is : " << fs.high_qc.proposal_id.str() << " block_num : " << qc->block_num() << ", phase : " << unsigned(qc->phase_counter) << "\n"; else std::cout << " - No high_qc value " << "\n"; - if (lock != nullptr) std::cout << " - " << bp.to_string() << " current _b_lock is : " << fs.b_lock.str() << " block_num : " << lock->block_num() << ", phase : " << unsigned(lock->phase_counter) << "\n"; + if (lock != nullptr) std::cout << " - " << bp << " current _b_lock is : " << fs.b_lock.str() << " block_num : " << lock->block_num() << ", phase : " << unsigned(lock->phase_counter) << "\n"; else std::cout << " - No b_lock value " << "\n"; - if (exec != nullptr) std::cout << " - " << bp.to_string() << " current _b_exec is : " << fs.b_exec.str() << " block_num : " << exec->block_num() << ", phase : " << unsigned(exec->phase_counter) << "\n"; + if (exec != nullptr) std::cout << " - " << bp << " current _b_exec is : " << fs.b_exec.str() << " block_num : " << exec->block_num() << ", phase : " << unsigned(exec->phase_counter) << "\n"; else std::cout << " - No b_exec value " << "\n"; std::cout << "\n"; @@ -181,12 +212,26 @@ BOOST_AUTO_TEST_CASE(hotstuff_1) try { hotstuff_test_handler ht; - ht.initialize_qc_chains(tpm, unique_replicas); + std::vector sks; + std::vector pks; + + + for (auto urk : unique_replica_keys){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks.push_back(sk); + pks.push_back(pk); + } + + + ht.initialize_qc_chains(tpm, unique_replicas, sks); tpm.set_proposer("bpa"_n); tpm.set_leader("bpa"_n); tpm.set_next_leader("bpa"_n); - tpm.set_finalizers(unique_replicas); + tpm.set_finalizer_keys(pks); auto qcc_bpa = std::find_if(ht._qc_chains.begin(), ht._qc_chains.end(), [&](const auto& q){ return q.first == "bpa"_n; }); finalizer_state fs_bpa; @@ -195,7 +240,7 @@ BOOST_AUTO_TEST_CASE(hotstuff_1) try { finalizer_state fs_bpb; qcc_bpb->second->get_state(fs_bpb); - ht.print_bp_state("bpa"_n, ""); + //ht.print_bp_state("bpa"_n, ""); tpm.set_current_block_id(ids[0]); //first block @@ -203,7 +248,7 @@ BOOST_AUTO_TEST_CASE(hotstuff_1) try { tpm.dispatch(""); //send proposal to replicas (prepare on first block) - ht.print_bp_state("bpa"_n, ""); + //ht.print_bp_state("bpa"_n, ""); qcc_bpa->second->get_state(fs_bpa); BOOST_CHECK_EQUAL(fs_bpa.b_leaf.str(), std::string("a252070cd26d3b231ab2443b9ba97f57fc72e50cca04a020952e45bc7e2d27a8")); @@ -215,12 +260,16 @@ BOOST_AUTO_TEST_CASE(hotstuff_1) try { tpm.dispatch(""); //send proposal to replicas (precommit on first block) + //ht.print_bp_state("bpa"_n, ""); + qcc_bpa->second->get_state(fs_bpa); BOOST_CHECK_EQUAL(fs_bpa.b_leaf.str(), std::string("4b43fb144a8b5e874777f61f3b37d7a8b06c33fbc48db464ce0e8788ff4edb4f")); BOOST_CHECK_EQUAL(fs_bpa.high_qc.proposal_id.str(), std::string("a252070cd26d3b231ab2443b9ba97f57fc72e50cca04a020952e45bc7e2d27a8")); BOOST_CHECK_EQUAL(fs_bpa.b_lock.str(), std::string("0000000000000000000000000000000000000000000000000000000000000000")); BOOST_CHECK_EQUAL(fs_bpa.b_exec.str(), std::string("0000000000000000000000000000000000000000000000000000000000000000")); + + tpm.dispatch(""); //propagating votes on new proposal (precommitQC on first block) tpm.dispatch(""); //send proposal to replicas (commit on first block) @@ -311,12 +360,26 @@ BOOST_AUTO_TEST_CASE(hotstuff_2) try { hotstuff_test_handler ht; - ht.initialize_qc_chains(tpm, unique_replicas); + std::vector sks; + std::vector pks; + + + for (auto urk : unique_replica_keys){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks.push_back(sk); + pks.push_back(pk); + } + + + ht.initialize_qc_chains(tpm, unique_replicas, sks); tpm.set_proposer("bpa"_n); tpm.set_leader("bpa"_n); tpm.set_next_leader("bpa"_n); - tpm.set_finalizers(unique_replicas); + tpm.set_finalizer_keys(pks); auto qcc_bpa = std::find_if(ht._qc_chains.begin(), ht._qc_chains.end(), [&](const auto& q){ return q.first == "bpa"_n; }); finalizer_state fs_bpa; @@ -409,12 +472,25 @@ BOOST_AUTO_TEST_CASE(hotstuff_3) try { hotstuff_test_handler ht; - ht.initialize_qc_chains(tpm, unique_replicas); + std::vector sks; + std::vector pks; + + + for (auto urk : unique_replica_keys){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks.push_back(sk); + pks.push_back(pk); + } + + ht.initialize_qc_chains(tpm, unique_replicas, sks); tpm.set_proposer("bpa"_n); tpm.set_leader("bpa"_n); tpm.set_next_leader("bpa"_n); - tpm.set_finalizers(unique_replicas); + tpm.set_finalizer_keys(pks); auto qcc_bpa = std::find_if(ht._qc_chains.begin(), ht._qc_chains.end(), [&](const auto& q){ return q.first == "bpa"_n; }); finalizer_state fs_bpa; @@ -541,12 +617,26 @@ BOOST_AUTO_TEST_CASE(hotstuff_4) try { hotstuff_test_handler ht; - ht.initialize_qc_chains(tpm, unique_replicas); + std::vector sks; + std::vector pks; + + + for (auto urk : unique_replica_keys){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks.push_back(sk); + pks.push_back(pk); + } + + + ht.initialize_qc_chains(tpm, unique_replicas, sks); tpm.set_proposer("bpa"_n); tpm.set_leader("bpa"_n); tpm.set_next_leader("bpa"_n); - tpm.set_finalizers(unique_replicas); + tpm.set_finalizer_keys(pks); auto qcc_bpa = std::find_if(ht._qc_chains.begin(), ht._qc_chains.end(), [&](const auto& q){ return q.first == "bpa"_n; }); finalizer_state fs_bpa; @@ -720,6 +810,69 @@ BOOST_AUTO_TEST_CASE(hotstuff_5) try { "bps"_n, "bpt"_n }; + std::vector honest_replica_set_keys_1 { + "PVT_BLS_/l7xzXANaB+GrlTsbZEuTiSOiWTtpBoog+TZnirxUUSaAfCo", + "PVT_BLS_iZFwiqdogOl9RNr1Hv1z+Rd6AwD9BIoxZcU1EPX+XFSFmm5p", + "PVT_BLS_OWemmo0YkDNEYcMnbvAHI7qS6YIJTVBc+3LCAi9u8QmMe3V/", + "PVT_BLS_KuL3oMYpBrqmIMqoBIsA4UX1jYyXzn7et93J+m+ctk8FAY0I", + "PVT_BLS_/HIa+nJWSCgVNs6rZ3LUhqp1chRkxyaUxumvN3HSTAE4VIql", + "PVT_BLS_WyyJ26tRpjpzmwke/sGJr0YUIyB/zSNsbo/99PwDHh4pvo5V"}; + + std::vector honest_replica_set_keys_2 { + "PVT_BLS_r4ZpChd87ooyzl6MIkw23k7PRX8xptp7TczLJHCIIW88h/hS", + "PVT_BLS_warwI76e+pPX9wLFZKPFagngeFM8bm6J8D5w0iiHpxW7PiId", + "PVT_BLS_jglKDzpvyI+LFJ4xJG2MRylH9KiAEj//M9sgI+AM5mhLASBs", + "PVT_BLS_ETZDiw3qd1Kpu3L5hH9fPKR4tg0meCkRUsRE2KpW8WP5SU2l", + "PVT_BLS_uP48z/V66g7wU7BwNN1xhNnZOyf3mv8yxGFT2eoIK3HLL5aw", + "PVT_BLS_U3QCa0uwzeeK4w1hI2IvUzgF9+hk496LyODdvgYpUBmgZiwu"}; + + std::vector byzantine_keys_set { + "PVT_BLS_3FoY73Q/gED3ejyg8cvnGqHrMmx4cLKwh/e0sbcsCxpCeqn3", + "PVT_BLS_Hmye7lyiCrdF54/nF/HRU0sY/Hrse1ls/yqojIUOVQsxXUIK", + "PVT_BLS_xYhEMbBy6Z4TYGha/qYaUwiwv4UVX9qNWf4ivRjAyCLCG7/G", + "PVT_BLS_bNz9W9QkxeREp966ntnUV4mN4dLOB4DNSghf2Y85o1YI+p7t", + "PVT_BLS_Aq4tqxG/sDEwGMZUa/Vhznc2i3B4wHNopGV3bJpTNW6FauCN", + "PVT_BLS_t2xBqsJKO0RHQMvsIYHFpvuy+IkBrCVeZl1NxThKEwwvUbiP", + "PVT_BLS_94/Vo26YNQV1P7zWmkDnh02P0ZcPM5xQlLG3LiUCOUUgMpEi", + "PVT_BLS_uQ9ONJ/oJlj+yRIjE3tiLcoIXTMEuCwMuAFL1WUDY28N97gF", + "PVT_BLS_2qtUuz8cYjbu/shyUPxIwKrBMSSbvolv4iJJvykUMRFl4hGt"}; + + std::vector sks1; + std::vector pks1; + + std::vector sks2; + std::vector pks2; + + std::vector sks3; + std::vector pks3; + + for (auto urk : honest_replica_set_keys_1){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks1.push_back(sk); + pks1.push_back(pk); + } + + for (auto urk : honest_replica_set_keys_2){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks2.push_back(sk); + pks2.push_back(pk); + } + + for (auto urk : byzantine_keys_set){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks3.push_back(sk); + pks3.push_back(pk); + } + std::vector replica_set_1; std::vector replica_set_2; @@ -732,6 +885,30 @@ BOOST_AUTO_TEST_CASE(hotstuff_5) try { replica_set_2.insert( replica_set_2.end(), honest_replica_set_2.begin(), honest_replica_set_2.end() ); replica_set_2.insert( replica_set_2.end(), byzantine_set.begin(), byzantine_set.end() ); + std::vector replica_pkeys_set_1; + std::vector replica_pkeys_set_2; + + std::vector replica_skeys_set_1; + std::vector replica_skeys_set_2; + + replica_pkeys_set_1.reserve( pks1.size() + pks3.size() ); + replica_pkeys_set_2.reserve( pks2.size() + pks3.size() ); + + replica_pkeys_set_1.insert( replica_pkeys_set_1.end(), pks1.begin(), pks1.end() ); + replica_pkeys_set_1.insert( replica_pkeys_set_1.end(), pks3.begin(), pks3.end() ); + + replica_pkeys_set_2.insert( replica_pkeys_set_2.end(), pks2.begin(), pks2.end() ); + replica_pkeys_set_2.insert( replica_pkeys_set_2.end(), pks3.begin(), pks3.end() ); + + replica_skeys_set_1.reserve( sks1.size() + sks3.size() ); + replica_skeys_set_2.reserve( sks2.size() + sks3.size() ); + + replica_skeys_set_1.insert( replica_skeys_set_1.end(), sks1.begin(), sks1.end() ); + replica_skeys_set_1.insert( replica_skeys_set_1.end(), sks3.begin(), sks3.end() ); + + replica_skeys_set_2.insert( replica_skeys_set_2.end(), sks2.begin(), sks2.end() ); + replica_skeys_set_2.insert( replica_skeys_set_2.end(), sks3.begin(), sks3.end() ); + //simulating a fork, where test_pacemaker tpm1; test_pacemaker tpm2; @@ -739,19 +916,19 @@ BOOST_AUTO_TEST_CASE(hotstuff_5) try { hotstuff_test_handler ht1; hotstuff_test_handler ht2; - ht1.initialize_qc_chains(tpm1, replica_set_1); + ht1.initialize_qc_chains(tpm1, replica_set_1, replica_skeys_set_1); - ht2.initialize_qc_chains(tpm2, replica_set_2); + ht2.initialize_qc_chains(tpm2, replica_set_2, replica_skeys_set_2); tpm1.set_proposer("bpe"_n); //honest leader tpm1.set_leader("bpe"_n); tpm1.set_next_leader("bpe"_n); - tpm1.set_finalizers(replica_set_1); + tpm1.set_finalizer_keys(replica_pkeys_set_1); tpm2.set_proposer("bpf"_n); //byzantine leader tpm2.set_leader("bpf"_n); tpm2.set_next_leader("bpf"_n); - tpm2.set_finalizers(replica_set_2); + tpm2.set_finalizer_keys(replica_pkeys_set_2); auto qcc_bpe = std::find_if(ht1._qc_chains.begin(), ht1._qc_chains.end(), [&](const auto& q){ return q.first == "bpe"_n; }); finalizer_state fs_bpe; @@ -888,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(hotstuff_5) try { } FC_LOG_AND_RETHROW(); -BOOST_AUTO_TEST_CASE(hotstuff_6) try { + BOOST_AUTO_TEST_CASE(hotstuff_6) try { //test simple separation between the (single) proposer and the leader; includes one leader rotation @@ -896,12 +1073,24 @@ BOOST_AUTO_TEST_CASE(hotstuff_6) try { hotstuff_test_handler ht; - ht.initialize_qc_chains(tpm, unique_replicas); + std::vector sks; + std::vector pks; + + for (auto urk : unique_replica_keys){ + + fc::crypto::blslib::bls_private_key sk = fc::crypto::blslib::bls_private_key(urk); + fc::crypto::blslib::bls_public_key pk = sk.get_public_key(); + + sks.push_back(sk); + pks.push_back(pk); + } + + ht.initialize_qc_chains(tpm, unique_replicas, sks); - tpm.set_proposer("bpg"_n); // can be any proposer that's not the leader for this test + tpm.set_proposer("bpg"_n); tpm.set_leader("bpa"_n); tpm.set_next_leader("bpa"_n); - tpm.set_finalizers(unique_replicas); + tpm.set_finalizer_keys(pks); auto qcc_bpa = std::find_if(ht._qc_chains.begin(), ht._qc_chains.end(), [&](const auto& q){ return q.first == "bpa"_n; }); finalizer_state fs_bpa; diff --git a/libraries/hotstuff/test/test_pacemaker.cpp b/libraries/hotstuff/test/test_pacemaker.cpp index de42e32ff1..62628e3989 100644 --- a/libraries/hotstuff/test/test_pacemaker.cpp +++ b/libraries/hotstuff/test/test_pacemaker.cpp @@ -15,8 +15,8 @@ namespace eosio::hotstuff { _next_leader = next_leader; }; - void test_pacemaker::set_finalizers(std::vector finalizers) { - _finalizers = finalizers; + void test_pacemaker::set_finalizer_keys(std::vector finalizer_keys) { + _finalizer_keys = finalizer_keys; }; void test_pacemaker::set_current_block_id(block_id_type id) { @@ -130,10 +130,10 @@ namespace eosio::hotstuff { return _next_leader; }; - std::vector test_pacemaker::get_finalizers() { - return _finalizers; + std::vector test_pacemaker::get_finalizer_keys() { + return _finalizer_keys; }; - + block_id_type test_pacemaker::get_current_block_id() { return _current_block_id; }; @@ -158,62 +158,66 @@ namespace eosio::hotstuff { _qcc_store.emplace( name, qcc_ptr ); }; - void test_pacemaker::send_hs_proposal_msg(const hs_proposal_message& msg, name id) { + void test_pacemaker::send_hs_proposal_msg(const hs_proposal_message& msg, const std::string& id) { _pending_message_queue.push_back(std::make_pair(id, msg)); }; - void test_pacemaker::send_hs_vote_msg(const hs_vote_message& msg, name id) { + void test_pacemaker::send_hs_vote_msg(const hs_vote_message& msg, const std::string& id) { _pending_message_queue.push_back(std::make_pair(id, msg)); }; - void test_pacemaker::send_hs_new_block_msg(const hs_new_block_message& msg, name id) { + void test_pacemaker::send_hs_new_block_msg(const hs_new_block_message& msg, const std::string& id) { _pending_message_queue.push_back(std::make_pair(id, msg)); }; - void test_pacemaker::send_hs_new_view_msg(const hs_new_view_message& msg, name id) { + void test_pacemaker::send_hs_new_view_msg(const hs_new_view_message& msg, const std::string& id) { _pending_message_queue.push_back(std::make_pair(id, msg)); }; - void test_pacemaker::on_hs_proposal_msg(const hs_proposal_message& msg, name id) { + void test_pacemaker::on_hs_proposal_msg(const hs_proposal_message& msg, const std::string& id) { auto qc_itr = _qcc_store.begin(); while (qc_itr != _qcc_store.end()){ const name & qcc_name = qc_itr->first; std::shared_ptr & qcc_ptr = qc_itr->second; - if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ) + if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ){ qcc_ptr->on_hs_proposal_msg(msg); + } qc_itr++; } } - void test_pacemaker::on_hs_vote_msg(const hs_vote_message& msg, name id) { + void test_pacemaker::on_hs_vote_msg(const hs_vote_message& msg, const std::string& id) { auto qc_itr = _qcc_store.begin(); while (qc_itr != _qcc_store.end()) { const name & qcc_name = qc_itr->first; std::shared_ptr & qcc_ptr = qc_itr->second; - if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ) + if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ){ qcc_ptr->on_hs_vote_msg(msg); + } qc_itr++; } } - void test_pacemaker::on_hs_new_block_msg(const hs_new_block_message& msg, name id) { + void test_pacemaker::on_hs_new_block_msg(const hs_new_block_message& msg, const std::string& id) { auto qc_itr = _qcc_store.begin(); while (qc_itr != _qcc_store.end()) { const name & qcc_name = qc_itr->first; std::shared_ptr & qcc_ptr = qc_itr->second; - if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ) + if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ){ qcc_ptr->on_hs_new_block_msg(msg); + } qc_itr++; } } - void test_pacemaker::on_hs_new_view_msg(const hs_new_view_message& msg, name id) { + void test_pacemaker::on_hs_new_view_msg(const hs_new_view_message& msg, const std::string& id) { auto qc_itr = _qcc_store.begin(); while (qc_itr != _qcc_store.end()){ const name & qcc_name = qc_itr->first; std::shared_ptr & qcc_ptr = qc_itr->second; - if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ) + if (qcc_ptr->get_id_i() != id && is_qc_chain_active(qcc_name) ){ qcc_ptr->on_hs_new_view_msg(msg); + } qc_itr++; } } diff --git a/libraries/libfc/test/test_bls.cpp b/libraries/libfc/test/test_bls.cpp index 3faa6d42e2..87ffd86b19 100644 --- a/libraries/libfc/test/test_bls.cpp +++ b/libraries/libfc/test/test_bls.cpp @@ -157,6 +157,31 @@ BOOST_AUTO_TEST_CASE(bls_agg_tree_verif) try { } FC_LOG_AND_RETHROW(); +// temp +BOOST_AUTO_TEST_CASE(bls_multi_key_gen) try { + + cout << "multi key" << "\n"; + + for (int i = 0; i < 21 ;i ++){ + + bls_private_key sk = bls_private_key::generate(); + bls_public_key pk = sk.get_public_key(); + + cout << sk.to_string() << "\n"; + + bls_signature signature = sk.sign(message_1); + + // Verify the signature + bool ok = verify(pk, message_1, signature); + + BOOST_CHECK_EQUAL(ok, true); + + } + + cout << "/multi key" << "\n"; + +} FC_LOG_AND_RETHROW(); + //test random key generation, signature + verification BOOST_AUTO_TEST_CASE(bls_key_gen) try {