From cbfda8ccc88789cd3c83c63b6e18693e7dea718d Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 17 Apr 2019 14:54:24 -0400 Subject: support auto client command for evaluation --- include/hotstuff/client.h | 10 ++++++++++ include/hotstuff/hotstuff.h | 3 +++ include/hotstuff/liveness.h | 8 ++++++++ src/client.cpp | 3 +++ src/hotstuff.cpp | 6 ++++++ src/hotstuff_app.cpp | 10 ++++++++++ src/hotstuff_client.cpp | 22 ++++++++++++++++++---- 7 files changed, 58 insertions(+), 4 deletions(-) diff --git a/include/hotstuff/client.h b/include/hotstuff/client.h index 95bcacb..37a3a17 100644 --- a/include/hotstuff/client.h +++ b/include/hotstuff/client.h @@ -50,6 +50,16 @@ struct MsgRespCmd { } }; +#ifdef HOTSTUFF_AUTOCLI +struct MsgDemandCmd { + static const opcode_t opcode = 0x6; + DataStream serialized; + size_t ncmd; + MsgDemandCmd(size_t ncmd) { serialized << ncmd; } + MsgDemandCmd(DataStream &&s) { s >> ncmd; } +}; +#endif + class CommandDummy: public Command { uint32_t cid; uint32_t n; diff --git a/include/hotstuff/hotstuff.h b/include/hotstuff/hotstuff.h index 10dcb84..03e5528 100644 --- a/include/hotstuff/hotstuff.h +++ b/include/hotstuff/hotstuff.h @@ -217,6 +217,9 @@ class HotStuffBase: public HotStuffCore { size_t size() const { return peers.size(); } PaceMaker &get_pace_maker() { return *pmaker; } void print_stat() const; +#ifdef HOTSTUFF_AUTOCLI + virtual void do_demand_commands(size_t) {} +#endif /* Helper functions */ /** Returns a promise resolved (with command_t cmd) when Command is fetched. */ diff --git a/include/hotstuff/liveness.h b/include/hotstuff/liveness.h index 6d3c3cf..f4027a2 100644 --- a/include/hotstuff/liveness.h +++ b/include/hotstuff/liveness.h @@ -51,6 +51,7 @@ class PaceMaker { virtual promise_t beat_resp(ReplicaID last_proposer) = 0; /** Impeach the current proposer. */ virtual void impeach() {} + virtual size_t get_pending_size() = 0; }; using pacemaker_bt = BoxObj; @@ -166,6 +167,9 @@ class PMWaitQC: public virtual PaceMaker { } public: + + size_t get_pending_size() override { return pending_beats.size(); } + void init() { last_proposed = hsc->get_genesis(); locked = false; @@ -455,6 +459,8 @@ class PMStickyProposer: virtual public PaceMaker { PMStickyProposer(double qc_timeout, const EventContext &ec): qc_timeout(qc_timeout), ec(ec) {} + size_t get_pending_size() override { return pending_beats.size(); } + void init() { to_candidate(); } ReplicaID get_proposer() override { @@ -706,6 +712,8 @@ class PMRoundRobinProposer: virtual public PaceMaker { PMRoundRobinProposer(double qc_timeout, const EventContext &ec): qc_timeout(qc_timeout), ec(ec), proposer(0) {} + size_t get_pending_size() override { return pending_beats.size(); } + void init() { to_candidate(); } diff --git a/src/client.cpp b/src/client.cpp index c1b571c..ee4b7dd 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -20,5 +20,8 @@ namespace hotstuff { const opcode_t MsgReqCmd::opcode; const opcode_t MsgRespCmd::opcode; +#ifdef HOTSTUFF_AUTOCLI +const opcode_t MsgDemandCmd::opcode; +#endif } diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp index aeae2e2..2cc3821 100644 --- a/src/hotstuff.cpp +++ b/src/hotstuff.cpp @@ -115,7 +115,13 @@ promise_t HotStuffBase::exec_command(uint256_t cmd_hash) { } } else + { on_propose(cmds, pmaker->get_parents()); +#ifdef HOTSTUFF_AUTOCLI + for (size_t i = pmaker->get_pending_size(); i < 1; i++) + do_demand_commands(blk_size); +#endif + } }); } return pm; diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp index 30d127b..be9d3cd 100644 --- a/src/hotstuff_app.cpp +++ b/src/hotstuff_app.cpp @@ -110,6 +110,16 @@ class HotStuffApp: public HotStuff { */ } +#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; diff --git a/src/hotstuff_client.cpp b/src/hotstuff_client.cpp index 97bacab..8eeb8e5 100644 --- a/src/hotstuff_client.cpp +++ b/src/hotstuff_client.cpp @@ -80,8 +80,8 @@ void set_proposer(ReplicaID rid) { // conns.insert(std::make_pair(rid, mn.connect(replicas[rid]))); } -void try_send() { - while (waiting.size() < max_async_num && max_iter_num) +bool try_send(bool check = true) { + if ((!check || waiting.size() < max_async_num) && max_iter_num) { auto cmd = new CommandDummy(cid, cnt++); //mn.send_msg(MsgReqCmd(*cmd), *conns.at(proposer)); @@ -95,7 +95,9 @@ void try_send() { cmd->get_hash(), Request(proposer, cmd))); if (max_iter_num > 0) max_iter_num--; + return true; } + return false; } void client_resp_cmd_handler(MsgRespCmd &&msg, const Net::conn_t &) { @@ -134,9 +136,18 @@ void client_resp_cmd_handler(MsgRespCmd &&msg, const Net::conn_t &) { elapsed.push_back(std::make_pair(tv, et.elapsed_sec)); #endif waiting.erase(it); - try_send(); +#ifndef HOTSTUFF_AUTOCLI + while (try_send()); +#endif } +#ifdef HOTSTUFF_AUTOCLI +void client_demand_cmd_handler(hotstuff::MsgDemandCmd &&msg, const Net::conn_t &) { + for (size_t i = 0; i < msg.ncmd; i++) + try_send(false); +} +#endif + std::pair split_ip_port_cport(const std::string &s) { auto ret = salticidae::trim_all(salticidae::split(s, ";")); return std::make_pair(ret[0], ret[1]); @@ -158,6 +169,9 @@ int main(int argc, char **argv) { ev_sigterm.add(SIGTERM); mn.reg_handler(client_resp_cmd_handler); +#ifdef HOTSTUFF_AUTOCLI + mn.reg_handler(client_demand_cmd_handler); +#endif mn.start(); config.add_opt("idx", opt_idx, Config::SET_VAL); @@ -192,7 +206,7 @@ int main(int argc, char **argv) { HOTSTUFF_LOG_INFO("nfaulty = %zu", nfaulty); connect_all(); set_proposer(idx); - try_send(); + while (try_send()); ec.dispatch(); #ifdef HOTSTUFF_ENABLE_BENCHMARK -- cgit v1.2.3