From 7a52e54b14eed096acce1c224ab46626f7c8cbaf Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 6 Jul 2019 19:01:33 -0400 Subject: ... --- README.rst | 1 - include/hotstuff/hotstuff.h | 5 +++-- include/hotstuff/liveness.h | 28 ++++++++++++++++++++++------ src/hotstuff.cpp | 11 ----------- src/hotstuff_app.cpp | 22 +++++----------------- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/README.rst b/README.rst index 7c6d7fc..8852e88 100644 --- a/README.rst +++ b/README.rst @@ -53,7 +53,6 @@ section may be incomplete and subject to changes. TODO ==== -- Finish a decent Pacemaker (Round-Robin Pacemaker with exponential backoff) - Add a PoW-based Pacemaker - Branch pruning & swapping (the current implementation stores the entire chain in memory) - Limit the async events (improve robustness) diff --git a/include/hotstuff/hotstuff.h b/include/hotstuff/hotstuff.h index 291f9a7..07f69d9 100644 --- a/include/hotstuff/hotstuff.h +++ b/include/hotstuff/hotstuff.h @@ -224,10 +224,11 @@ class HotStuffBase: public HotStuffCore { bool ec_loop = false); size_t size() const { return peers.size(); } - auto get_decision_waiting() const { return decision_waiting; } + const auto &get_decision_waiting() const { return decision_waiting; } + ThreadCall &get_tcall() { return tcall; } PaceMaker *get_pace_maker() { return pmaker.get(); } void print_stat() const; - virtual void do_elected(); + virtual void do_elected() {} //#ifdef HOTSTUFF_AUTOCLI // virtual void do_demand_commands(size_t) {} //#endif diff --git a/include/hotstuff/liveness.h b/include/hotstuff/liveness.h index 1286c45..a2705d1 100644 --- a/include/hotstuff/liveness.h +++ b/include/hotstuff/liveness.h @@ -227,7 +227,6 @@ class PaceMakerDummyFixed: public PaceMakerDummy { * Simple long-standing round-robin style proposer liveness gadget. */ class PMRoundRobinProposer: virtual public PaceMaker { - double qc_timeout; double base_timeout; double exp_timeout; double prop_delay; @@ -337,7 +336,19 @@ class PMRoundRobinProposer: virtual public PaceMaker { last_proposed = hsc->get_genesis(); proposer_update_last_proposed(); if (proposer == hsc->get_id()) - static_cast(hsc)->do_elected(); + { + auto hs = static_cast(hsc); + hs->do_elected(); + hs->get_tcall().async_call([this, hs](salticidae::ThreadCall::Handle &) { + auto &pending = hs->get_decision_waiting(); + if (!pending.size()) return; + HOTSTUFF_LOG_PROTO("reproposing pending commands"); + std::vector cmds; + for (auto &p: pending) + cmds.push_back(p.first); + hs->on_propose(cmds, get_parents()); + }); + } } protected: @@ -355,8 +366,11 @@ class PMRoundRobinProposer: virtual public PaceMaker { } public: - PMRoundRobinProposer(double qc_timeout, const EventContext &ec): - qc_timeout(qc_timeout), base_timeout(1), prop_delay(1), ec(ec), proposer(0), rotating(false) {} + PMRoundRobinProposer(const EventContext &ec, + double base_timeout, double prop_delay): + base_timeout(base_timeout), + prop_delay(prop_delay), + ec(ec), proposer(0), rotating(false) {} size_t get_pending_size() override { return pending_beats.size(); } @@ -391,8 +405,10 @@ class PMRoundRobinProposer: virtual public PaceMaker { }; struct PaceMakerRR: public PMHighTail, public PMRoundRobinProposer { - PaceMakerRR(int32_t parent_limit, double qc_timeout, EventContext eb): - PMHighTail(parent_limit), PMRoundRobinProposer(qc_timeout, eb) {} + PaceMakerRR(EventContext ec, int32_t parent_limit, + double base_timeout = 1, double prop_delay = 1): + PMHighTail(parent_limit), + PMRoundRobinProposer(ec, base_timeout, prop_delay) {} void init(HotStuffCore *hsc) override { PaceMaker::init(hsc); diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp index 69501c0..5ae0fe6 100644 --- a/src/hotstuff.cpp +++ b/src/hotstuff.cpp @@ -80,17 +80,6 @@ void HotStuffBase::exec_command(uint256_t cmd_hash, commit_cb_t callback) { cmd_pending.enqueue(std::make_pair(cmd_hash, callback)); } -void HotStuffBase::do_elected() { - // TODO: improve this - tcall.async_call([this](salticidae::ThreadCall::Handle &) { - HOTSTUFF_LOG_PROTO("reproposing waiting commands"); - std::vector cmds; - for (auto &p: decision_waiting) - cmds.push_back(p.first); - on_propose(cmds, pmaker->get_parents()); - }); -} - void HotStuffBase::on_fetch_blk(const block_t &blk) { #ifdef HOTSTUFF_BLK_PROFILE blk_profiler.get_tx(blk->get_hash()); diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp index 871bafb..a0fe80b 100644 --- a/src/hotstuff_app.cpp +++ b/src/hotstuff_app.cpp @@ -114,20 +114,6 @@ class HotStuffApp: public HotStuff { resp_queue.enqueue(fin); } - void do_elected() override { - HotStuff::do_elected(); - } - -//#ifdef HOTSTUFF_AUTOCLI -// void do_demand_commands(size_t blk_size) override { -// size_t ncli = client_conns.size(); -// size_t bsize = (blk_size + ncli - 1) / ncli; -// hotstuff::MsgDemandCmd mdc{bsize}; -// for(const auto &conn: client_conns) -// cn.send_msg(mdc, conn); -// } -//#endif - #ifdef HOTSTUFF_MSG_STAT std::unordered_set client_conns; void print_stat() const; @@ -178,7 +164,8 @@ int main(int argc, char **argv) { auto opt_help = Config::OptValFlag::create(false); auto opt_pace_maker = Config::OptValStr::create("dummy"); auto opt_fixed_proposer = Config::OptValInt::create(1); - auto opt_qc_timeout = Config::OptValDouble::create(0.5); + auto opt_base_timeout = Config::OptValDouble::create(1); + auto opt_prop_delay = Config::OptValDouble::create(1); auto opt_imp_timeout = Config::OptValDouble::create(11); auto opt_nworker = Config::OptValInt::create(1); auto opt_repnworker = Config::OptValInt::create(1); @@ -198,7 +185,8 @@ int main(int argc, char **argv) { config.add_opt("tls-cert", opt_tls_cert, Config::SET_VAL); config.add_opt("pace-maker", opt_pace_maker, Config::SET_VAL, 'p', "specify pace maker (dummy, rr)"); config.add_opt("proposer", opt_fixed_proposer, Config::SET_VAL, 'l', "set the fixed proposer (for dummy)"); - config.add_opt("qc-timeout", opt_qc_timeout, Config::SET_VAL, 't', "set QC timeout (for sticky)"); + config.add_opt("base-timeout", opt_base_timeout, Config::SET_VAL, 't', "set the initial timeout for the Round-Robin Pacemaker"); + config.add_opt("prop-delay", opt_prop_delay, Config::SET_VAL, 't', "set the delay that follows the timeout for the Round-Robin Pacemaker"); config.add_opt("imp-timeout", opt_imp_timeout, Config::SET_VAL, 'u', "set impeachment timeout (for sticky)"); config.add_opt("nworker", opt_nworker, Config::SET_VAL, 'n', "the number of threads for verification"); config.add_opt("repnworker", opt_repnworker, Config::SET_VAL, 'm', "the number of threads for replica network"); @@ -247,7 +235,7 @@ int main(int argc, char **argv) { if (opt_pace_maker->get() == "dummy") pmaker = new hotstuff::PaceMakerDummyFixed(opt_fixed_proposer->get(), parent_limit); else - pmaker = new hotstuff::PaceMakerRR(parent_limit, opt_qc_timeout->get(), ec); + pmaker = new hotstuff::PaceMakerRR(ec, parent_limit, opt_base_timeout->get(), opt_prop_delay->get()); HotStuffApp::Net::Config repnet_config; ClientNetwork::Config clinet_config; -- cgit v1.2.3