aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst2
-rw-r--r--include/hotstuff/client.h15
-rw-r--r--include/hotstuff/hotstuff.h2
-rw-r--r--src/client.cpp8
-rw-r--r--src/hotstuff.cpp17
-rw-r--r--src/hotstuff_app.cpp38
-rw-r--r--src/hotstuff_client.cpp4
7 files changed, 43 insertions, 43 deletions
diff --git a/README.rst b/README.rst
index ffe3e6e..d76a7c5 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
HotStuff
-========
+--------
HotStuff is a general-purpose BFT state machine replication library with
modularity and simplicity, suitable for building hybrid consensus
diff --git a/include/hotstuff/client.h b/include/hotstuff/client.h
index 2127595..87e60b7 100644
--- a/include/hotstuff/client.h
+++ b/include/hotstuff/client.h
@@ -17,20 +17,23 @@ enum {
struct Finality: public Serializable {
ReplicaID rid;
int8_t decision;
+ uint256_t cmd_hash;
uint256_t blk_hash;
public:
Finality() = default;
- Finality(ReplicaID rid, int8_t decision, uint256_t blk_hash):
- rid(rid), decision(decision), blk_hash(blk_hash) {}
+ Finality(ReplicaID rid, int8_t decision,
+ uint256_t cmd_hash, uint256_t blk_hash):
+ rid(rid), decision(decision),
+ cmd_hash(cmd_hash), blk_hash(blk_hash) {}
void serialize(DataStream &s) const override {
- s << rid << decision;
+ s << rid << decision << cmd_hash;
if (decision == 1) s << blk_hash;
}
void unserialize(DataStream &s) override {
- s >> rid >> decision;
+ s >> rid >> decision >> cmd_hash;
if (decision == 1) s >> blk_hash;
}
};
@@ -40,8 +43,8 @@ struct MsgClient: public salticidae::MsgBase<> {
void gen_reqcmd(const Command &cmd);
void parse_reqcmd(command_t &cmd, HotStuffCore *hsc) const;
- void gen_respcmd(const uint256_t &cmd_hash, const Finality &fin);
- void parse_respcmd(uint256_t &cmd_hash, Finality &fin) const;
+ void gen_respcmd(const Finality &fin);
+ void parse_respcmd(Finality &fin) const;
void gen_chkcmd(const uint256_t &cmd_hash);
void parse_chkcmd(uint256_t &cmd_hash) const;
diff --git a/include/hotstuff/hotstuff.h b/include/hotstuff/hotstuff.h
index 0aa83de..c8d8b5d 100644
--- a/include/hotstuff/hotstuff.h
+++ b/include/hotstuff/hotstuff.h
@@ -168,7 +168,7 @@ class HotStuffBase: public HotStuffCore {
/* the API for HotStuffBase */
/* Submit the command to be decided. */
- ReplicaID add_command(command_t cmd);
+ promise_t exec_command(command_t cmd);
void add_replica(ReplicaID idx, const NetAddr &addr, pubkey_bt &&pub_key);
void start(bool eb_loop = false);
diff --git a/src/client.cpp b/src/client.cpp
index 486594a..bc790bc 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -16,16 +16,16 @@ void MsgClient::parse_reqcmd(command_t &cmd, HotStuffCore *hsc) const {
cmd = hsc->parse_cmd(s);
}
-void MsgClient::gen_respcmd(const uint256_t &cmd_hash, const Finality &fin) {
+void MsgClient::gen_respcmd(const Finality &fin) {
DataStream s;
set_opcode(RESP_CMD);
- s << cmd_hash << fin;
+ s << fin;
set_payload(std::move(s));
}
-void MsgClient::parse_respcmd(uint256_t &cmd_hash, Finality &fin) const {
+void MsgClient::parse_respcmd(Finality &fin) const {
DataStream s(get_payload());
- s >> cmd_hash >> fin;
+ s >> fin;
}
void MsgClient::gen_chkcmd(const uint256_t &cmd_hash) {
diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp
index ed15cc1..6230d06 100644
--- a/src/hotstuff.cpp
+++ b/src/hotstuff.cpp
@@ -1,4 +1,5 @@
#include "hotstuff/hotstuff.h"
+#include "hotstuff/client.h"
using salticidae::static_pointer_cast;
@@ -70,10 +71,14 @@ void MsgHotStuff::parse_rfetchblk(std::vector<block_t> &blks, HotStuffCore *hsc)
}
}
-ReplicaID HotStuffBase::add_command(command_t cmd) {
+promise_t HotStuffBase::exec_command(command_t cmd) {
ReplicaID proposer = pmaker->get_proposer();
+ /* not the proposer */
if (proposer != get_id())
- return proposer;
+ return promise_t([proposer, cmd](promise_t &pm) {
+ pm.resolve(Finality(proposer, -1,
+ cmd->get_hash(), uint256_t()));
+ });
cmd_pending.push(storage->add_cmd(cmd));
if (cmd_pending.size() >= blk_size)
{
@@ -87,7 +92,13 @@ ReplicaID HotStuffBase::add_command(command_t cmd) {
on_propose(cmds, pmaker->get_parents());
});
}
- return proposer;
+ return async_decide(cmd->get_hash()).then([this](const command_t &cmd) {
+ block_t blk = cmd->get_container();
+ return Finality(get_id(),
+ cmd->get_decision(),
+ cmd->get_hash(),
+ blk->get_hash());
+ });
}
void HotStuffBase::add_replica(ReplicaID idx, const NetAddr &addr,
diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp
index 28f02fc..1a63776 100644
--- a/src/hotstuff_app.cpp
+++ b/src/hotstuff_app.cpp
@@ -71,10 +71,12 @@ class HotStuffApp: public HotStuff {
/** checks if a cmd is decided */
inline void client_check_cmd_handler(const MsgClient &, conn_client_t);
- Finality get_finality(const command_t &cmd) const {
- hotstuff::block_t blk = cmd->get_container();
+ Finality get_finality(const uint256_t cmd_hash) const {
+ command_t cmd = storage->find_cmd(cmd_hash);
+ hotstuff::block_t blk = cmd ? cmd->get_container() : nullptr;
return Finality(get_id(),
- cmd->get_decision(),
+ cmd ? cmd->get_decision() : 0,
+ cmd_hash,
blk ? blk->get_hash() : uint256_t());
}
@@ -235,34 +237,22 @@ void HotStuffApp::client_request_cmd_handler(const MsgClient &msg, conn_client_t
#ifndef HOTSTUFF_DISABLE_TX_VERIFY
flag &= cmd->verify();
#endif
+ const uint256_t cmd_hash = cmd->get_hash();
if (!flag)
{
LOG_WARN("invalid client cmd");
MsgClient resp;
- resp.gen_respcmd(cmd->get_hash(), Finality(get_id(), -1, uint256_t()));
+ resp.gen_respcmd(Finality(get_id(), -1, cmd_hash, uint256_t()));
cn.send_msg(resp, addr);
}
else
{
- const uint256_t cmd_hash = cmd->get_hash();
- ReplicaID rid = add_command(cmd);
- if (rid == get_id())
- {
- /** wait for the decision of tx */
- LOG_DEBUG("processing client cmd %.10s", get_hex(cmd_hash).c_str());
- async_decide(cmd_hash).then([this, addr](command_t cmd) {
- MsgClient resp;
- resp.gen_respcmd(cmd->get_hash(), get_finality(cmd));
- cn.send_msg(resp, addr);
- });
- }
- else
- {
- LOG_INFO("redirect");
+ LOG_DEBUG("processing client cmd %.10s", get_hex(cmd_hash).c_str());
+ exec_command(cmd).then([this, addr](Finality fin) {
MsgClient resp;
- resp.gen_respcmd(cmd_hash, Finality(rid, 0, cmd_hash));
+ resp.gen_respcmd(fin);
cn.send_msg(resp, addr);
- }
+ });
}
}
@@ -272,14 +262,10 @@ void HotStuffApp::client_check_cmd_handler(const MsgClient &msg, conn_client_t c
uint256_t cmd_hash;
msg.parse_chkcmd(cmd_hash);
MsgClient resp;
- command_t cmd = storage->find_cmd(cmd_hash);
- Finality fin;
- if (cmd) fin = get_finality(cmd);
- resp.gen_respcmd(cmd_hash, fin);
+ resp.gen_respcmd(get_finality(cmd_hash));
cn.send_msg(resp, addr);
}
-
void HotStuffApp::start() {
ev_stat_timer = Event(eb, -1, 0,
std::bind(&HotStuffApp::print_stat_cb, this, _1, _2));
diff --git a/src/hotstuff_client.cpp b/src/hotstuff_client.cpp
index 1363f39..f9bfb94 100644
--- a/src/hotstuff_client.cpp
+++ b/src/hotstuff_client.cpp
@@ -68,12 +68,12 @@ void try_send() {
}
void on_receive(const MsgClient &msg, MsgNetwork<MsgClient>::conn_t) {
- uint256_t cmd_hash;
Finality fin;
HOTSTUFF_LOG_DEBUG("got %s", std::string(msg).c_str());
if (!msg.verify_checksum())
HOTSTUFF_LOG_ERROR("incorrect checksum %08x", msg.get_checksum());
- msg.parse_respcmd(cmd_hash, fin);
+ msg.parse_respcmd(fin);
+ const uint256_t &cmd_hash = fin.cmd_hash;
auto it = waiting.find(cmd_hash);
if (fin.rid != proposer)
{