diff --git a/libraries/chain/include/eosio/chain/hotstuff.hpp b/libraries/chain/include/eosio/chain/hotstuff.hpp index 1cb48cfb5f..2db473827d 100644 --- a/libraries/chain/include/eosio/chain/hotstuff.hpp +++ b/libraries/chain/include/eosio/chain/hotstuff.hpp @@ -10,9 +10,6 @@ namespace eosio::chain { - const block_id_type NULL_BLOCK_ID = block_id_type("00"); - const fc::sha256 NULL_PROPOSAL_ID = fc::sha256("00"); - using hs_bitset = boost::dynamic_bitset; inline uint64_t compute_height(uint32_t block_height, uint32_t phase_counter) { @@ -25,22 +22,22 @@ namespace eosio::chain { }; struct quorum_certificate_message { - fc::sha256 proposal_id = NULL_PROPOSAL_ID; + fc::sha256 proposal_id; std::vector active_finalizers; //bitset encoding, following canonical order fc::crypto::blslib::bls_signature active_agg_sig; }; struct hs_vote_message { - fc::sha256 proposal_id = NULL_PROPOSAL_ID; //vote on proposal + fc::sha256 proposal_id; //vote on proposal name finalizer; fc::crypto::blslib::bls_signature sig; }; struct hs_proposal_message { - fc::sha256 proposal_id = NULL_PROPOSAL_ID; //vote on proposal - block_id_type block_id = NULL_BLOCK_ID; - fc::sha256 parent_id = NULL_PROPOSAL_ID; //new proposal - fc::sha256 final_on_qc = NULL_PROPOSAL_ID; + fc::sha256 proposal_id; //vote on proposal + block_id_type block_id; + fc::sha256 parent_id; //new proposal + fc::sha256 final_on_qc; quorum_certificate_message justify; //justification uint8_t phase_counter = 0; @@ -49,7 +46,7 @@ namespace eosio::chain { }; struct hs_new_block_message { - block_id_type block_id = NULL_BLOCK_ID; //new proposal + block_id_type block_id; //new proposal quorum_certificate_message justify; //justification }; @@ -61,12 +58,12 @@ namespace eosio::chain { struct finalizer_state { bool chained_mode = false; - fc::sha256 b_leaf = NULL_PROPOSAL_ID; - fc::sha256 b_lock = NULL_PROPOSAL_ID; - fc::sha256 b_exec = NULL_PROPOSAL_ID; - fc::sha256 b_finality_violation = NULL_PROPOSAL_ID; - block_id_type block_exec = NULL_BLOCK_ID; - block_id_type pending_proposal_block = NULL_BLOCK_ID; + fc::sha256 b_leaf; + fc::sha256 b_lock; + fc::sha256 b_exec; + fc::sha256 b_finality_violation; + block_id_type block_exec; + block_id_type pending_proposal_block; uint32_t v_height = 0; eosio::chain::quorum_certificate_message high_qc; eosio::chain::quorum_certificate_message current_qc; diff --git a/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp b/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp index 99d173f1f5..c410d7d769 100644 --- a/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp +++ b/libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp @@ -82,8 +82,8 @@ namespace eosio::hotstuff { private: friend struct fc::reflector; - fc::sha256 proposal_id = NULL_PROPOSAL_ID; - hs_bitset active_finalizers; //bitset encoding, following canonical order + fc::sha256 proposal_id; + hs_bitset active_finalizers; //bitset encoding, following canonical order fc::crypto::blslib::bls_signature active_agg_sig; bool quorum_met = false; // not serialized across network }; @@ -183,12 +183,12 @@ namespace eosio::hotstuff { }; bool _chained_mode = false; - block_id_type _block_exec = NULL_BLOCK_ID; - block_id_type _pending_proposal_block = NULL_BLOCK_ID; - fc::sha256 _b_leaf = NULL_PROPOSAL_ID; - fc::sha256 _b_lock = NULL_PROPOSAL_ID; - fc::sha256 _b_exec = NULL_PROPOSAL_ID; - fc::sha256 _b_finality_violation = NULL_PROPOSAL_ID; + block_id_type _block_exec; + block_id_type _pending_proposal_block; + fc::sha256 _b_leaf; + fc::sha256 _b_lock; + fc::sha256 _b_exec; + fc::sha256 _b_finality_violation; quorum_certificate _high_qc; quorum_certificate _current_qc; uint32_t _v_height = 0; diff --git a/libraries/hotstuff/qc_chain.cpp b/libraries/hotstuff/qc_chain.cpp index 88b7a77862..c4bf6407ee 100644 --- a/libraries/hotstuff/qc_chain.cpp +++ b/libraries/hotstuff/qc_chain.cpp @@ -135,7 +135,7 @@ namespace eosio { namespace hotstuff { b_new.parent_id = _b_leaf; b_new.phase_counter = phase_counter; b_new.justify = _high_qc.to_msg(); //or null if no _high_qc upon activation or chain launch - if (b_new.justify.proposal_id != NULL_PROPOSAL_ID){ + if (!b_new.justify.proposal_id.empty()) { std::vector current_qc_chain = get_qc_chain(b_new.justify.proposal_id); size_t chain_length = std::distance(current_qc_chain.begin(), current_qc_chain.end()); if (chain_length>=2){ @@ -236,12 +236,12 @@ namespace eosio { namespace hotstuff { qc_chain::qc_chain(name id, base_pacemaker* pacemaker, std::set my_producers, fc::logger& logger) : _pacemaker(pacemaker), - _id(id), _my_producers(std::move(my_producers)), + _id(id), _logger(logger) { - _high_qc.reset(NULL_PROPOSAL_ID, 21); // TODO: use active schedule size - _current_qc.reset(NULL_PROPOSAL_ID, 21); // TODO: use active schedule size + _high_qc.reset({}, 21); // TODO: use active schedule size + _current_qc.reset({}, 21); // TODO: use active schedule size fc_dlog(_logger, " === ${id} qc chain initialized ${my_producers}", ("my_producers", my_producers)("id", _id)); } @@ -289,7 +289,7 @@ namespace eosio { namespace hotstuff { //auto start = fc::time_point::now(); - if (proposal.justify.proposal_id != NULL_PROPOSAL_ID){ + if (!proposal.justify.proposal_id.empty()) { const hs_proposal_message *jp = get_proposal( proposal.justify.proposal_id ); if (jp == nullptr) { @@ -483,14 +483,14 @@ namespace eosio { namespace hotstuff { fc_tlog(_logger, " === ${id} phase increment on proposal ${proposal_id}", ("proposal_id", vote.proposal_id)("id", _id)); hs_proposal_message proposal_candidate; - if (_pending_proposal_block == NULL_BLOCK_ID) + if (_pending_proposal_block.empty()) proposal_candidate = new_proposal_candidate( p->block_id, p->phase_counter + 1 ); else proposal_candidate = new_proposal_candidate( _pending_proposal_block, 0 ); reset_qc(proposal_candidate.proposal_id); fc_tlog(_logger, " === ${id} setting _pending_proposal_block to null (process_vote)", ("id", _id)); - _pending_proposal_block = NULL_BLOCK_ID; + _pending_proposal_block = {}; _b_leaf = proposal_candidate.proposal_id; send_hs_proposal_msg(proposal_candidate); @@ -536,7 +536,7 @@ namespace eosio { namespace hotstuff { auto increment_version = fc::make_scoped_exit([this]() { ++_state_version; }); - if (_current_qc.get_proposal_id() != NULL_PROPOSAL_ID && _current_qc.is_quorum_met() == false) { + if (!_current_qc.get_proposal_id().empty() && !_current_qc.is_quorum_met()) { fc_tlog(_logger, " === ${id} pending proposal found ${proposal_id} : quorum met ${quorum_met}", ("id", _id) @@ -558,7 +558,7 @@ namespace eosio { namespace hotstuff { fc_tlog(_logger, " === ${id} setting _pending_proposal_block to null (process_new_block)", ("id", _id)); - _pending_proposal_block = NULL_BLOCK_ID; + _pending_proposal_block = {}; _b_leaf = proposal_candidate.proposal_id; send_hs_proposal_msg(proposal_candidate); @@ -667,8 +667,7 @@ namespace eosio { namespace hotstuff { // if new high QC is higher than current, update to new - if (_high_qc.get_proposal_id() == NULL_PROPOSAL_ID){ - + if (_high_qc.get_proposal_id().empty()) { _high_qc = high_qc; _b_leaf = _high_qc.get_proposal_id(); @@ -715,11 +714,11 @@ namespace eosio { namespace hotstuff { //leader changed, we send our new_view message - reset_qc(NULL_PROPOSAL_ID); + reset_qc({}); fc_tlog(_logger, " === ${id} setting _pending_proposal_block to null (leader_rotation_check)", ("id", _id)); - _pending_proposal_block = NULL_BLOCK_ID; + _pending_proposal_block = {}; hs_new_view_message new_view; @@ -741,9 +740,9 @@ namespace eosio { namespace hotstuff { fc::sha256 upcoming_commit; - if (proposal.justify.proposal_id == NULL_PROPOSAL_ID && _b_lock == NULL_PROPOSAL_ID) + if (proposal.justify.proposal_id.empty() && _b_lock.empty()) { final_on_qc_check = true; //if chain just launched or feature just activated - else { + } else { std::vector current_qc_chain = get_qc_chain(proposal.justify.proposal_id); @@ -780,7 +779,7 @@ namespace eosio { namespace hotstuff { monotony_check = true; } - if (_b_lock != NULL_PROPOSAL_ID){ + if (!_b_lock.empty()) { //Safety check : check if this proposal extends the chain I'm locked on if (extends(proposal.proposal_id, _b_lock)) { @@ -788,7 +787,7 @@ namespace eosio { namespace hotstuff { } //Liveness check : check if the height of this proposal's justification is higher than the height of the proposal I'm locked on. This allows restoration of liveness if a replica is locked on a stale block. - if (proposal.justify.proposal_id == NULL_PROPOSAL_ID && _b_lock == NULL_PROPOSAL_ID) { + if (proposal.justify.proposal_id.empty() && _b_lock.empty()) { liveness_check = true; //if there is no justification on the proposal and I am not locked on anything, means the chain just launched or feature just activated } else { const hs_proposal_message *b_lock = get_proposal( _b_lock ); @@ -851,7 +850,7 @@ namespace eosio { namespace hotstuff { void qc_chain::update(const hs_proposal_message& proposal) { //fc_tlog(_logger, " === update internal state ==="); //if proposal has no justification, means we either just activated the feature or launched the chain, or the proposal is invalid - if (proposal.justify.proposal_id == NULL_PROPOSAL_ID){ + if (proposal.justify.proposal_id.empty()) { fc_dlog(_logger, " === ${id} proposal has no justification ${proposal_id}", ("proposal_id", proposal.proposal_id)("id", _id)); return; } @@ -861,7 +860,7 @@ namespace eosio { namespace hotstuff { size_t chain_length = std::distance(current_qc_chain.begin(), current_qc_chain.end()); const hs_proposal_message *b_lock = get_proposal( _b_lock ); - EOS_ASSERT( b_lock != nullptr || _b_lock == NULL_PROPOSAL_ID , chain_exception, "expected hs_proposal ${id} not found", ("id", _b_lock) ); + EOS_ASSERT( b_lock != nullptr || _b_lock.empty(), chain_exception, "expected hs_proposal ${id} not found", ("id", _b_lock) ); //fc_tlog(_logger, " === update_high_qc : proposal.justify ==="); update_high_qc(quorum_certificate{proposal.justify}); @@ -897,8 +896,7 @@ namespace eosio { namespace hotstuff { ("b_lock_phase", b_lock->phase_counter)); } - if (_b_lock == NULL_PROPOSAL_ID || b_1.get_height() > b_lock->get_height()){ - + if (_b_lock.empty() || b_1.get_height() > b_lock->get_height()) { fc_tlog(_logger, "setting _b_lock to ${proposal_id}", ("proposal_id",b_1.proposal_id )); _b_lock = b_1.proposal_id; //commit phase on b1 @@ -923,7 +921,7 @@ namespace eosio { namespace hotstuff { //direct parent relationship verification if (b_2.parent_id == b_1.proposal_id && b_1.parent_id == b.proposal_id){ - if (_b_exec!= NULL_PROPOSAL_ID){ + if (!_b_exec.empty()) { const hs_proposal_message *b_exec = get_proposal( _b_exec ); EOS_ASSERT( b_exec != nullptr , chain_exception, "expected hs_proposal ${id} not found", ("id", _b_exec) ); @@ -1014,7 +1012,7 @@ namespace eosio { namespace hotstuff { bool exec_height_check = false; const hs_proposal_message *last_exec_prop = get_proposal( _b_exec ); - EOS_ASSERT( last_exec_prop != nullptr || _b_exec == NULL_PROPOSAL_ID, chain_exception, "expected hs_proposal ${id} not found", ("id", _b_exec) ); + EOS_ASSERT( last_exec_prop != nullptr || _b_exec.empty(), chain_exception, "expected hs_proposal ${id} not found", ("id", _b_exec) ); if (last_exec_prop != nullptr) { fc_tlog(_logger, " === _b_exec proposal #${block_num} ${proposal_id} block_id : ${block_id} phase : ${phase_counter} parent_id : ${parent_id}", @@ -1035,13 +1033,13 @@ namespace eosio { namespace hotstuff { ("phase_counter_2", proposal.phase_counter)); } - if (_b_exec == NULL_PROPOSAL_ID) + if (_b_exec.empty()) { exec_height_check = true; - else + } else { exec_height_check = last_exec_prop->get_height() < proposal.get_height(); + } - if (exec_height_check){ - + if (exec_height_check) { const hs_proposal_message *p = get_proposal( proposal.parent_id ); if (p != nullptr) { //fc_tlog(_logger, " === recursively committing" ); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 67ff4fdb6d..e09b6d6aab 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -835,10 +835,10 @@ class read_only : public api_base { get_consensus_parameters_results get_consensus_parameters(const get_consensus_parameters_params&, const fc::time_point& deadline) const; struct hs_complete_proposal_message { - fc::sha256 proposal_id = chain::NULL_PROPOSAL_ID; - chain::block_id_type block_id = chain::NULL_BLOCK_ID; - fc::sha256 parent_id = chain::NULL_PROPOSAL_ID; - fc::sha256 final_on_qc = chain::NULL_PROPOSAL_ID; + fc::sha256 proposal_id; + chain::block_id_type block_id; + fc::sha256 parent_id; + fc::sha256 final_on_qc; chain::quorum_certificate_message justify; uint8_t phase_counter = 0; uint32_t block_height = 0; @@ -859,12 +859,12 @@ class read_only : public api_base { using get_finalizer_state_params = empty; struct get_finalizer_state_results { bool chained_mode = false; - fc::sha256 b_leaf = chain::NULL_PROPOSAL_ID; - fc::sha256 b_lock = chain::NULL_PROPOSAL_ID; - fc::sha256 b_exec = chain::NULL_PROPOSAL_ID; - fc::sha256 b_finality_violation = chain::NULL_PROPOSAL_ID; - chain::block_id_type block_exec = chain::NULL_BLOCK_ID; - chain::block_id_type pending_proposal_block = chain::NULL_BLOCK_ID; + fc::sha256 b_leaf; + fc::sha256 b_lock; + fc::sha256 b_exec; + fc::sha256 b_finality_violation; + chain::block_id_type block_exec; + chain::block_id_type pending_proposal_block; uint32_t v_height = 0; chain::quorum_certificate_message high_qc; chain::quorum_certificate_message current_qc;