diff options
-rw-r--r-- | include/hotstuff/consensus.h | 4 | ||||
-rw-r--r-- | include/hotstuff/entity.h | 10 | ||||
-rw-r--r-- | include/hotstuff/liveness.h | 25 | ||||
m--------- | salticidae | 0 | ||||
-rw-r--r-- | src/consensus.cpp | 2 | ||||
-rw-r--r-- | src/entity.cpp | 22 |
6 files changed, 36 insertions, 27 deletions
diff --git a/include/hotstuff/consensus.h b/include/hotstuff/consensus.h index 85c1e8c..a99e6af 100644 --- a/include/hotstuff/consensus.h +++ b/include/hotstuff/consensus.h @@ -81,7 +81,7 @@ class HotStuffCore { * while the others are uncles/aunts */ void on_propose(const std::vector<command_t> &cmds, const std::vector<block_t> &parents, - serializable_bt &&extra = nullptr); + bytearray_t &&extra = bytearray_t()); /* Functions required to construct concrete instances for abstract classes. * */ @@ -114,8 +114,6 @@ class HotStuffCore { virtual quorum_cert_bt parse_quorum_cert(DataStream &s) = 0; /** Create a command object from its serialized form. */ virtual command_t parse_cmd(DataStream &s) = 0; - /** Create the extra data from its serialized form. */ - virtual serializable_bt parse_extra_block_data(DataStream &) { return nullptr; } public: /** Add a replica to the current configuration. This should only be called diff --git a/include/hotstuff/entity.h b/include/hotstuff/entity.h index dc77c81..ce7d9bf 100644 --- a/include/hotstuff/entity.h +++ b/include/hotstuff/entity.h @@ -102,14 +102,12 @@ get_hashes(const std::vector<Hashable> &plist) { return std::move(hashes); } -using serializable_bt = BoxObj<Serializable>; - class Block { friend HotStuffCore; std::vector<uint256_t> parent_hashes; std::vector<command_t> cmds; quorum_cert_bt qc; - serializable_bt extra; + bytearray_t extra; /* the following fields can be derived from above */ uint256_t hash; @@ -125,14 +123,12 @@ class Block { public: Block(): qc(nullptr), - extra(nullptr), qc_ref(nullptr), self_qc(nullptr), height(0), delivered(false), decision(0) {} Block(bool delivered, int8_t decision): qc(nullptr), - extra(nullptr), hash(salticidae::get_hash(*this)), qc_ref(nullptr), self_qc(nullptr), height(0), @@ -141,7 +137,7 @@ class Block { Block(const std::vector<block_t> &parents, const std::vector<command_t> &cmds, quorum_cert_bt &&qc, - serializable_bt &&extra, + bytearray_t &&extra, uint32_t height, const block_t &qc_ref, quorum_cert_bt &&self_qc, @@ -193,7 +189,7 @@ class Block { const block_t &get_qc_ref() const { return qc_ref; } - const serializable_bt &get_extra() const { return extra; } + const bytearray_t &get_extra() const { return extra; } operator std::string () const { DataStream s; diff --git a/include/hotstuff/liveness.h b/include/hotstuff/liveness.h index b8df8ef..3d3137a 100644 --- a/include/hotstuff/liveness.h +++ b/include/hotstuff/liveness.h @@ -208,6 +208,7 @@ class PMStickyProposer: virtual public PaceMaker { } void reg_follower_receive_proposal() { + pm_wait_receive_proposal.reject(); pm_wait_receive_proposal = hsc->async_wait_receive_proposal().then( salticidae::generic_bind( @@ -238,6 +239,7 @@ class PMStickyProposer: virtual public PaceMaker { { auto pm = pending_beats.front(); pending_beats.pop(); + pm_qc_finish.reject(); pm_qc_finish = hsc->async_qc_finish(last_proposed).then([this, pm]() { reset_qc_timer(); @@ -248,6 +250,7 @@ class PMStickyProposer: virtual public PaceMaker { } void reg_proposer_propose() { + pm_wait_propose.reject(); pm_wait_propose = hsc->async_wait_propose().then( salticidae::generic_bind( &PMStickyProposer::proposer_propose, this, _1)); @@ -263,16 +266,22 @@ class PMStickyProposer: virtual public PaceMaker { void candidate_qc_timeout() { pm_qc_finish.reject(); hsc->async_wait_propose().then([this](const block_t &blk) { + pm_qc_finish.reject(); pm_qc_finish = hsc->async_qc_finish(blk).then([this]() { /* managed to collect a QC */ to_proposer(); }); }); reset_qc_timer(); - hsc->on_propose(std::vector<command_t>{}, get_parents()); + DataStream s; + /* FIXME: should extra data be the voter's id? */ + s << hsc->get_id(); + hsc->on_propose(std::vector<command_t>{}, + get_parents(), std::move(s)); } void reg_candidate_receive_proposal() { + pm_wait_receive_proposal.reject(); pm_wait_receive_proposal = hsc->async_wait_receive_proposal().then( salticidae::generic_bind( @@ -282,7 +291,7 @@ class PMStickyProposer: virtual public PaceMaker { void candidate_receive_proposal(const Proposal &prop) { auto proposer = prop.proposer; auto &p = last_proposed_by[proposer]; - HOTSTUFF_LOG_INFO("got block from %d", proposer); + HOTSTUFF_LOG_INFO("got block %s from %d", std::string(*prop.blk).c_str(), proposer); p.reject(); p = hsc->async_qc_finish(prop.blk).then([this, proposer]() { to_follower(proposer); @@ -314,14 +323,14 @@ class PMStickyProposer: virtual public PaceMaker { clear_promises(); role = PROPOSER; proposer = hsc->get_id(); - last_proposed = hsc->get_genesis(); + last_proposed = nullptr; timer = Event(ec, -1, 0, [this](int, short) { /* proposer unable to get a QC in time */ to_candidate(); }); + reset_qc_timer(); /* prepare the variables for the role of a proposer */ - locked = false; - reg_proposer_propose(); + proposer_propose(hsc->get_genesis()); } void to_candidate() { @@ -366,9 +375,9 @@ class PMStickyProposer: virtual public PaceMaker { }); } - promise_t next_proposer(ReplicaID) override { - return promise_t([proposer=proposer](promise_t &pm) { - pm.resolve(proposer); + promise_t next_proposer(ReplicaID last_proposer) override { + return promise_t([this, last_proposer](promise_t &pm) { + pm.resolve(last_proposer); //role == CANDIDATE ? last_proposer : proposer); }); } }; diff --git a/salticidae b/salticidae -Subproject 3f1c768e2d5b5e51dec08499d6a877220f33d7a +Subproject 3073f4a9470da0c7aec0aa0a3b527f25095b5c9 diff --git a/src/consensus.cpp b/src/consensus.cpp index e25558a..6505c20 100644 --- a/src/consensus.cpp +++ b/src/consensus.cpp @@ -110,7 +110,7 @@ bool HotStuffCore::update(const uint256_t &bqc_hash) { void HotStuffCore::on_propose(const std::vector<command_t> &cmds, const std::vector<block_t> &parents, - serializable_bt &&extra) { + bytearray_t &&extra) { if (parents.empty()) throw std::runtime_error("empty parents"); for (const auto &_: parents) tails.erase(_); diff --git a/src/entity.cpp b/src/entity.cpp index a5dc44e..594fdbe 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -4,38 +4,44 @@ namespace hotstuff { void Block::serialize(DataStream &s) const { - s << (uint32_t)parent_hashes.size(); + s << htole((uint32_t)parent_hashes.size()); for (const auto &hash: parent_hashes) s << hash; - s << (uint32_t)cmds.size(); + s << htole((uint32_t)cmds.size()); for (auto cmd: cmds) s << *cmd; if (qc) s << (uint8_t)1 << *qc; else s << (uint8_t)0; - if (extra) - s << (uint8_t)1 << *extra; - else - s << (uint8_t)0; + s << htole((uint32_t)extra.size()) << extra; } void Block::unserialize(DataStream &s, HotStuffCore *hsc) { uint32_t n; uint8_t flag; s >> n; + n = letoh(n); parent_hashes.resize(n); for (auto &hash: parent_hashes) s >> hash; s >> n; + n = letoh(n); cmds.resize(n); for (auto &cmd: cmds) cmd = hsc->parse_cmd(s); s >> flag; qc = flag ? hsc->parse_quorum_cert(s) : nullptr; + s >> n; + n = letoh(n); + if (n == 0) + extra.clear(); + else + { + auto base = s.get_data_inplace(n); + extra = bytearray_t(base, base + n); + } this->hash = salticidae::get_hash(*this); - s >> flag; - extra = flag ? hsc->parse_extra_block_data(s) : nullptr; } } |