aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/hotstuff/consensus.h4
-rw-r--r--include/hotstuff/entity.h10
-rw-r--r--include/hotstuff/liveness.h25
m---------salticidae0
-rw-r--r--src/consensus.cpp2
-rw-r--r--src/entity.cpp22
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;
}
}