Skip to content

Commit

Permalink
GH-1547 Create a seperate quorum_certificate_message type
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Aug 26, 2023
1 parent 2c8720e commit dd9802a
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 153 deletions.
54 changes: 8 additions & 46 deletions libraries/chain/include/eosio/chain/hotstuff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,10 @@ namespace eosio::chain {
std::map<name, fc::crypto::blslib::bls_public_key> bls_pub_keys;
};

struct quorum_certificate {
explicit quorum_certificate(uint32_t finalizer_size = 0) {
reset(NULL_PROPOSAL_ID, finalizer_size);
}

void reset(const fc::sha256& proposal, uint32_t finalizer_size) {
proposal_id = proposal;
boost::dynamic_bitset b;
b.resize(finalizer_size);
boost::to_string(b, active_finalizers);
active_agg_sig = fc::crypto::blslib::bls_signature();
quorum_met = false;
}

boost::dynamic_bitset<> get_active_finalizers() const {
assert(!active_finalizers.empty());
return boost::dynamic_bitset(active_finalizers);
}
void set_active_finalizers(const boost::dynamic_bitset<>& bs) {
assert(!bs.empty());
boost::to_string(bs, active_finalizers);
}
const std::string& get_active_finalizers_string() const { return active_finalizers; }

const fc::sha256& get_proposal_id() const { return proposal_id; }
const fc::crypto::blslib::bls_signature& get_active_agg_sig() const { return active_agg_sig; }
void set_active_agg_sig( const fc::crypto::blslib::bls_signature& sig) { active_agg_sig = sig; }
bool is_quorum_met() const { return quorum_met; }
void set_quorum_met() { quorum_met = true; }

private:
friend struct fc::reflector<quorum_certificate>;
struct quorum_certificate_message {
fc::sha256 proposal_id = NULL_PROPOSAL_ID;
std::string active_finalizers; //bitset encoding, following canonical order
fc::crypto::blslib::bls_signature active_agg_sig;
bool quorum_met = false; // not serialized across network
};

struct hs_vote_message {
Expand All @@ -71,24 +39,23 @@ namespace eosio::chain {
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;
quorum_certificate justify; //justification
quorum_certificate_message justify; //justification
uint8_t phase_counter = 0;

uint32_t block_num() const { return block_header::num_from_id(block_id); }
uint64_t get_height() const { return compute_height(block_header::num_from_id(block_id), phase_counter); };
};

struct hs_new_block_message {
block_id_type block_id = NULL_BLOCK_ID; //new proposal
quorum_certificate justify; //justification
block_id_type block_id = NULL_BLOCK_ID; //new proposal
quorum_certificate_message justify; //justification
};

struct hs_new_view_message {
quorum_certificate high_qc; //justification
quorum_certificate_message high_qc; //justification
};

struct finalizer_state {

bool chained_mode = false;
fc::sha256 b_leaf = NULL_PROPOSAL_ID;
fc::sha256 b_lock = NULL_PROPOSAL_ID;
Expand All @@ -97,8 +64,8 @@ namespace eosio::chain {
block_id_type block_exec = NULL_BLOCK_ID;
block_id_type pending_proposal_block = NULL_BLOCK_ID;
uint32_t v_height = 0;
eosio::chain::quorum_certificate high_qc;
eosio::chain::quorum_certificate current_qc;
eosio::chain::quorum_certificate_message high_qc;
eosio::chain::quorum_certificate_message current_qc;
eosio::chain::extended_schedule schedule;
map<fc::sha256, hs_proposal_message> proposals;

Expand All @@ -110,15 +77,10 @@ namespace eosio::chain {
}
};

using hs_proposal_message_ptr = std::shared_ptr<hs_proposal_message>;
using hs_vote_message_ptr = std::shared_ptr<hs_vote_message>;
using hs_new_view_message_ptr = std::shared_ptr<hs_new_view_message>;
using hs_new_block_message_ptr = std::shared_ptr<hs_new_block_message>;

} //eosio::chain

// // @ignore quorum_met
FC_REFLECT(eosio::chain::quorum_certificate, (proposal_id)(active_finalizers)(active_agg_sig));
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_proposal_message, (proposal_id)(block_id)(parent_id)(final_on_qc)(justify)(phase_counter));
Expand Down
62 changes: 58 additions & 4 deletions libraries/hotstuff/include/eosio/hotstuff/qc_chain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,60 @@ namespace eosio::hotstuff {
using namespace boost::multi_index;
using namespace eosio::chain;

class quorum_certificate {
public:
explicit quorum_certificate(uint32_t finalizer_size = 0) {
active_finalizers.resize(finalizer_size);
}

explicit quorum_certificate(const quorum_certificate_message& msg)
: proposal_id(msg.proposal_id)
, active_finalizers(msg.active_finalizers) // conversion from string
, active_agg_sig(msg.active_agg_sig) {
}

quorum_certificate_message to_msg() const {
return {.proposal_id = proposal_id,
.active_finalizers = [this](){ std::string r; boost::to_string(active_finalizers, r); return r;}(),
.active_agg_sig = active_agg_sig};
}

void reset(const fc::sha256& proposal, uint32_t finalizer_size) {
proposal_id = proposal;
active_finalizers.clear();
active_finalizers.resize(finalizer_size);
active_agg_sig = fc::crypto::blslib::bls_signature();
quorum_met = false;
}

boost::dynamic_bitset<> get_active_finalizers() const {
assert(!active_finalizers.empty());
return boost::dynamic_bitset(active_finalizers);
}
void set_active_finalizers(const boost::dynamic_bitset<>& bs) {
assert(!bs.empty());
active_finalizers = bs;
}
std::string get_active_finalizers_string() const {
std::string r;
boost::to_string(active_finalizers, r);
return r;
}

const fc::sha256& get_proposal_id() const { return proposal_id; }
const fc::crypto::blslib::bls_signature& get_active_agg_sig() const { return active_agg_sig; }
void set_active_agg_sig( const fc::crypto::blslib::bls_signature& sig) { active_agg_sig = sig; }
bool is_quorum_met() const { return quorum_met; }
void set_quorum_met() { quorum_met = true; }

private:
friend struct fc::reflector<quorum_certificate>;
fc::sha256 proposal_id = NULL_PROPOSAL_ID;
boost::dynamic_bitset<> active_finalizers; //bitset encoding, following canonical order
fc::crypto::blslib::bls_signature active_agg_sig;
bool quorum_met = false; // not serialized across network
};

// Concurrency note: qc_chain is a single-threaded and lock-free decision engine.
// All thread synchronization, if any, is external.
class qc_chain {
Expand Down Expand Up @@ -72,7 +126,7 @@ namespace eosio::hotstuff {
bool evaluate_quorum(const extended_schedule& es, const boost::dynamic_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 eosio::chain::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 extended_schedule& schedule, 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
Expand All @@ -90,7 +144,7 @@ namespace eosio::hotstuff {

bool extends(const fc::sha256& descendant, const fc::sha256& ancestor); //verify that a proposal descends from another

bool update_high_qc(const eosio::chain::quorum_certificate& high_qc); //check if update to our high qc is required
bool update_high_qc(const quorum_certificate& high_qc); //check if update to our high qc is required

void leader_rotation_check(); //check if leader rotation is required

Expand Down Expand Up @@ -131,8 +185,8 @@ namespace eosio::hotstuff {
fc::sha256 _b_lock = NULL_PROPOSAL_ID;
fc::sha256 _b_exec = NULL_PROPOSAL_ID;
fc::sha256 _b_finality_violation = NULL_PROPOSAL_ID;
eosio::chain::quorum_certificate _high_qc;
eosio::chain::quorum_certificate _current_qc;
quorum_certificate _high_qc;
quorum_certificate _current_qc;
uint32_t _v_height = 0;
eosio::chain::extended_schedule _schedule;
base_pacemaker* _pacemaker = nullptr;
Expand Down
Loading

0 comments on commit dd9802a

Please sign in to comment.