aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/hotstuff/client.h10
-rw-r--r--include/hotstuff/hotstuff.h3
-rw-r--r--include/hotstuff/liveness.h8
-rw-r--r--src/client.cpp3
-rw-r--r--src/hotstuff.cpp6
-rw-r--r--src/hotstuff_app.cpp10
-rw-r--r--src/hotstuff_client.cpp22
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<PaceMaker>;
@@ -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<conn_t> 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<std::string, std::string> 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