From 9e745354fe10f31b829f0c02a2aa464f391ffd19 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 18 Jul 2018 21:44:40 -0400 Subject: ... --- README.rst | 2 +- include/hotstuff/client.h | 15 +++++++++------ include/hotstuff/hotstuff.h | 2 +- src/client.cpp | 8 ++++---- src/hotstuff.cpp | 17 ++++++++++++++--- src/hotstuff_app.cpp | 38 ++++++++++++-------------------------- src/hotstuff_client.cpp | 4 ++-- 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 &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::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) { -- cgit v1.2.3-70-g09d2