aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2018-09-03 00:13:58 -0400
committerDeterminant <[email protected]>2018-09-03 00:13:58 -0400
commitc3368b286fbb1d6b8c22af8ce21e57b5a5720445 (patch)
tree061de96c58873f642a24a151af1bf7ed937fb1c3 /src
parent2535cd89c13485cc4a8e68145c7cb5e8e9398e5c (diff)
parent17f7fd821cf71717a158e2c38699baa6ab2f2af8 (diff)
Merge branch 'master' of github.com:Determinant/hot-stuff
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp2
-rw-r--r--src/hotstuff.cpp2
-rw-r--r--src/hotstuff_app.cpp68
-rw-r--r--src/hotstuff_client.cpp39
4 files changed, 70 insertions, 41 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 562fab5..7827b7c 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2,8 +2,6 @@
namespace hotstuff {
-uint64_t CommandDummy::cnt = 0;
-
const opcode_t MsgReqCmd::opcode;
MsgReqCmd::MsgReqCmd(const Command &cmd) { serialized << cmd; }
void MsgReqCmd::postponed_parse(HotStuffCore *hsc) {
diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp
index e1e2f81..e235bd8 100644
--- a/src/hotstuff.cpp
+++ b/src/hotstuff.cpp
@@ -25,7 +25,7 @@ void MsgVote::postponed_parse(HotStuffCore *hsc) {
const opcode_t MsgReqBlock::opcode;
MsgReqBlock::MsgReqBlock(const std::vector<uint256_t> &blk_hashes) {
- serialized << (uint32_t)htole(blk_hashes.size());
+ serialized << htole((uint32_t)blk_hashes.size());
for (const auto &h: blk_hashes)
serialized << h;
}
diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp
index ead4e0b..768e81e 100644
--- a/src/hotstuff_app.cpp
+++ b/src/hotstuff_app.cpp
@@ -48,25 +48,22 @@ using hotstuff::promise_t;
using HotStuff = hotstuff::HotStuffSecp256k1;
-#define LOG_INFO HOTSTUFF_LOG_INFO
-#define LOG_DEBUG HOTSTUFF_LOG_DEBUG
-#define LOG_WARN HOTSTUFF_LOG_WARN
-#define LOG_ERROR HOTSTUFF_LOG_ERROR
-
class HotStuffApp: public HotStuff {
double stat_period;
+ double impeach_timeout;
EventContext ec;
/** Network messaging between a replica and its client. */
ClientNetwork<opcode_t> cn;
/** Timer object to schedule a periodic printing of system statistics */
Event ev_stat_timer;
+ /** Timer object to monitor the progress for simple impeachment */
+ Event impeach_timer;
/** The listen address for client RPC */
NetAddr clisten_addr;
using Conn = ClientNetwork<opcode_t>::Conn;
void client_request_cmd_handler(MsgReqCmd &&, Conn &);
- void print_stat_cb(evutil_socket_t, short);
command_t parse_cmd(DataStream &s) override {
auto cmd = new CommandDummy();
@@ -74,15 +71,22 @@ class HotStuffApp: public HotStuff {
return cmd;
}
+ void reset_imp_timer() {
+ impeach_timer.del();
+ impeach_timer.add_with_timeout(impeach_timeout);
+ }
+
void state_machine_execute(const Finality &fin) override {
+ reset_imp_timer();
#ifndef HOTSTUFF_ENABLE_BENCHMARK
- LOG_INFO("replicated %s", std::string(fin).c_str());
+ HOTSTUFF_LOG_INFO("replicated %s", std::string(fin).c_str());
#endif
}
public:
HotStuffApp(uint32_t blk_size,
double stat_period,
+ double impeach_timeout,
ReplicaID idx,
const bytearray_t &raw_privkey,
NetAddr plisten_addr,
@@ -124,15 +128,21 @@ int main(int argc, char **argv) {
auto opt_privkey = Config::OptValStr::create();
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_imp_timeout = Config::OptValDouble::create(11);
config.add_opt("block-size", opt_blk_size, Config::SET_VAL);
config.add_opt("parent-limit", opt_parent_limit, Config::SET_VAL);
config.add_opt("stat-period", opt_stat_period, Config::SET_VAL);
- config.add_opt("replica", opt_replicas, Config::APPEND);
- config.add_opt("idx", opt_idx, Config::SET_VAL);
- config.add_opt("cport", opt_client_port, Config::SET_VAL);
+ config.add_opt("replica", opt_replicas, Config::APPEND, 'a', "add an replica to the list");
+ config.add_opt("idx", opt_idx, Config::SET_VAL, 'i', "specify the index in the replica list");
+ config.add_opt("cport", opt_client_port, Config::SET_VAL, 'c', "specify the port listening for clients");
config.add_opt("privkey", opt_privkey, Config::SET_VAL);
config.add_opt("pace-maker", opt_pace_maker, Config::SET_VAL, 'p', "specify pace maker (sticky, dummy)");
+ 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("imp-timeout", opt_imp_timeout, Config::SET_VAL, 'u', "set impeachment timeout (for sticky)");
config.add_opt("help", opt_help, Config::SWITCH_ON, 'h', "show this help info");
EventContext ec;
@@ -175,12 +185,15 @@ int main(int argc, char **argv) {
auto parent_limit = opt_parent_limit->get();
hotstuff::pacemaker_bt pmaker;
if (opt_pace_maker->get() == "sticky")
- pmaker = new hotstuff::PaceMakerSticky(parent_limit, 0.5, ec);
+ pmaker = new hotstuff::PaceMakerSticky(parent_limit, opt_qc_timeout->get(), ec);
+ else if (opt_pace_maker->get() == "rr")
+ pmaker = new hotstuff::PaceMakerRR(parent_limit, opt_qc_timeout->get(), ec);
else
- pmaker = new hotstuff::PaceMakerDummyFixed(1, parent_limit);
+ pmaker = new hotstuff::PaceMakerDummyFixed(opt_fixed_proposer->get(), parent_limit);
papp = new HotStuffApp(opt_blk_size->get(),
opt_stat_period->get(),
+ opt_imp_timeout->get(),
idx,
hotstuff::from_hex(opt_privkey->get()),
plisten_addr,
@@ -205,6 +218,7 @@ int main(int argc, char **argv) {
HotStuffApp::HotStuffApp(uint32_t blk_size,
double stat_period,
+ double impeach_timeout,
ReplicaID idx,
const bytearray_t &raw_privkey,
NetAddr plisten_addr,
@@ -214,6 +228,7 @@ HotStuffApp::HotStuffApp(uint32_t blk_size,
HotStuff(blk_size, idx, raw_privkey,
plisten_addr, std::move(pmaker), ec),
stat_period(stat_period),
+ impeach_timeout(impeach_timeout),
ec(ec),
cn(ec),
clisten_addr(clisten_addr) {
@@ -227,28 +242,29 @@ void HotStuffApp::client_request_cmd_handler(MsgReqCmd &&msg, Conn &conn) {
msg.postponed_parse(this);
auto cmd = msg.cmd;
std::vector<promise_t> pms;
- LOG_DEBUG("processing %s", std::string(*cmd).c_str());
+ HOTSTUFF_LOG_DEBUG("processing %s", std::string(*cmd).c_str());
exec_command(cmd).then([this, addr](Finality fin) {
cn.send_msg(MsgRespCmd(fin), addr);
});
}
void HotStuffApp::start() {
- ev_stat_timer = Event(ec, -1, 0,
- std::bind(&HotStuffApp::print_stat_cb, this, _1, _2));
+ ev_stat_timer = Event(ec, -1, 0, [this](int, short) {
+ HotStuff::print_stat();
+ //HotStuffCore::prune(100);
+ ev_stat_timer.add_with_timeout(stat_period);
+ });
ev_stat_timer.add_with_timeout(stat_period);
- LOG_INFO("** starting the system with parameters **");
- LOG_INFO("blk_size = %lu", blk_size);
- LOG_INFO("conns = %lu", HotStuff::size());
- LOG_INFO("** starting the event loop...");
+ impeach_timer = Event(ec, -1, 0, [this](int, short) {
+ get_pace_maker().impeach();
+ reset_imp_timer();
+ });
+ impeach_timer.add_with_timeout(impeach_timeout);
+ HOTSTUFF_LOG_INFO("** starting the system with parameters **");
+ HOTSTUFF_LOG_INFO("blk_size = %lu", blk_size);
+ HOTSTUFF_LOG_INFO("conns = %lu", HotStuff::size());
+ HOTSTUFF_LOG_INFO("** starting the event loop...");
HotStuff::start();
/* enter the event main loop */
ec.dispatch();
}
-
-
-void HotStuffApp::print_stat_cb(evutil_socket_t, short) {
- HotStuff::print_stat();
- //HotStuffCore::prune(100);
- ev_stat_timer.add_with_timeout(stat_period);
-}
diff --git a/src/hotstuff_client.cpp b/src/hotstuff_client.cpp
index bee8abd..62b13ed 100644
--- a/src/hotstuff_client.cpp
+++ b/src/hotstuff_client.cpp
@@ -1,4 +1,5 @@
#include <cassert>
+#include <random>
#include "salticidae/type.h"
#include "salticidae/netaddr.h"
#include "salticidae/network.h"
@@ -9,32 +10,31 @@
#include "hotstuff/client.h"
using salticidae::Config;
-using salticidae::ElapsedTime;
-using salticidae::trim_all;
-using salticidae::split;
using salticidae::MsgNetwork;
using hotstuff::ReplicaID;
using hotstuff::NetAddr;
using hotstuff::EventContext;
-using hotstuff::uint256_t;
using hotstuff::MsgReqCmd;
using hotstuff::MsgRespCmd;
using hotstuff::CommandDummy;
-using hotstuff::command_t;
using hotstuff::Finality;
using hotstuff::HotStuffError;
+using hotstuff::uint256_t;
using hotstuff::opcode_t;
+using hotstuff::command_t;
EventContext eb;
ReplicaID proposer;
size_t max_async_num;
int max_iter_num;
+uint32_t cid;
+uint32_t cnt = 0;
struct Request {
ReplicaID rid;
command_t cmd;
- ElapsedTime et;
+ salticidae::ElapsedTime et;
Request(ReplicaID rid, const command_t &cmd):
rid(rid), cmd(cmd) { et.start(); }
};
@@ -54,10 +54,12 @@ void set_proposer(ReplicaID rid) {
void try_send() {
while (waiting.size() < max_async_num && max_iter_num)
{
- auto cmd = CommandDummy::make_cmd();
+ auto cmd = new CommandDummy(cid, cnt++);
mn.send_msg(MsgReqCmd(*cmd), *conns.at(proposer));
+#ifndef HOTSTUFF_ENABLE_BENCHMARK
HOTSTUFF_LOG_INFO("send new cmd %.10s",
get_hex(cmd->get_hash()).c_str());
+#endif
waiting.insert(std::make_pair(
cmd->get_hash(), Request(proposer, cmd)));
if (max_iter_num > 0)
@@ -70,6 +72,9 @@ void client_resp_cmd_handler(MsgRespCmd &&msg, MsgNetwork<opcode_t>::Conn &) {
HOTSTUFF_LOG_DEBUG("got %s", std::string(msg.fin).c_str());
const uint256_t &cmd_hash = fin.cmd_hash;
auto it = waiting.find(cmd_hash);
+ auto &et = it->second.et;
+ if (it == waiting.end()) return;
+ et.stop();
if (fin.rid != proposer)
{
HOTSTUFF_LOG_INFO("reconnect to the new proposer");
@@ -79,20 +84,27 @@ void client_resp_cmd_handler(MsgRespCmd &&msg, MsgNetwork<opcode_t>::Conn &) {
{
mn.send_msg(MsgReqCmd(*(waiting.find(cmd_hash)->second.cmd)),
*conns.at(proposer));
+#ifndef HOTSTUFF_ENABLE_BENCHMARK
HOTSTUFF_LOG_INFO("resend cmd %.10s",
get_hex(cmd_hash).c_str());
- it->second.et.start();
+#endif
+ et.start();
it->second.rid = proposer;
return;
}
- HOTSTUFF_LOG_INFO("got %s", std::string(fin).c_str());
- if (it == waiting.end()) return;
+#ifndef HOTSTUFF_ENABLE_BENCHMARK
+ HOTSTUFF_LOG_INFO("got %s, wall: %.3f, cpu: %.3f",
+ std::string(fin).c_str(),
+ et.elapsed_sec, et.cpu_elapsed_sec);
+#else
+ HOTSTUFF_LOG_INFO("%.6f %.6f", et.elapsed_sec, et.cpu_elapsed_sec);
+#endif
waiting.erase(it);
try_send();
}
std::pair<std::string, std::string> split_ip_port_cport(const std::string &s) {
- auto ret = trim_all(split(s, ";"));
+ auto ret = salticidae::trim_all(salticidae::split(s, ";"));
return std::make_pair(ret[0], ret[1]);
}
@@ -102,11 +114,13 @@ int main(int argc, char **argv) {
auto opt_replicas = Config::OptValStrVec::create();
auto opt_max_iter_num = Config::OptValInt::create(100);
auto opt_max_async_num = Config::OptValInt::create(10);
+ auto opt_cid = Config::OptValInt::create(-1);
mn.reg_handler(client_resp_cmd_handler);
try {
config.add_opt("idx", opt_idx, Config::SET_VAL);
+ config.add_opt("cid", opt_cid, Config::SET_VAL);
config.add_opt("replica", opt_replicas, Config::APPEND);
config.add_opt("iter", opt_max_iter_num, Config::SET_VAL);
config.add_opt("max-async", opt_max_async_num, Config::SET_VAL);
@@ -117,7 +131,7 @@ int main(int argc, char **argv) {
std::vector<std::pair<std::string, std::string>> raw;
for (const auto &s: opt_replicas->get())
{
- auto res = trim_all(split(s, ","));
+ auto res = salticidae::trim_all(salticidae::split(s, ","));
if (res.size() != 2)
throw HotStuffError("format error");
raw.push_back(std::make_pair(res[0], res[1]));
@@ -125,6 +139,7 @@ int main(int argc, char **argv) {
if (!(0 <= idx && (size_t)idx < raw.size() && raw.size() > 0))
throw std::invalid_argument("out of range");
+ cid = opt_cid->get() != -1 ? opt_cid->get() : idx;
for (const auto &p: raw)
{
auto _p = split_ip_port_cport(p.first);