aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst1
-rw-r--r--include/hotstuff/hotstuff.h5
-rw-r--r--include/hotstuff/liveness.h28
-rw-r--r--src/hotstuff.cpp11
-rw-r--r--src/hotstuff_app.cpp22
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<hotstuff::HotStuffBase *>(hsc)->do_elected();
+ {
+ auto hs = static_cast<hotstuff::HotStuffBase *>(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<uint256_t> 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<uint256_t> 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<conn_t> 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<opcode_t>::Config clinet_config;