aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2018-07-18 14:34:43 -0400
committerDeterminant <tederminant@gmail.com>2018-07-18 14:34:43 -0400
commit780cfa4ee8faf4c2662f3c739e8a5c9f1c8a1826 (patch)
treee54d5ecbb11634e9f2c211dd4cddd8903cda86d9 /src
parente08bf4e6a40cf82822c50b1433a573d0d8800f80 (diff)
move parent selection to PaceMaker
Diffstat (limited to 'src')
-rw-r--r--src/consensus.cpp34
-rw-r--r--src/hotstuff.cpp9
-rw-r--r--src/hotstuff_app.cpp9
3 files changed, 25 insertions, 27 deletions
diff --git a/src/consensus.cpp b/src/consensus.cpp
index e42fb49..688c450 100644
--- a/src/consensus.cpp
+++ b/src/consensus.cpp
@@ -10,11 +10,10 @@
namespace hotstuff {
-/* The core logic of HotStuff, is farily simple :) */
+/* The core logic of HotStuff, is fairly simple :). */
/*** begin HotStuff protocol logic ***/
HotStuffCore::HotStuffCore(ReplicaID id,
- privkey_bt &&priv_key,
- int32_t parent_limit):
+ privkey_bt &&priv_key):
b0(new Block(true, 1)),
bqc(b0),
bexec(b0),
@@ -22,7 +21,6 @@ HotStuffCore::HotStuffCore(ReplicaID id,
priv_key(std::move(priv_key)),
tails{bqc},
id(id),
- parent_limit(parent_limit),
storage(new EntityStorage()) {
storage->add_blk(b0);
b0->qc_ref = b0;
@@ -110,20 +108,12 @@ bool HotStuffCore::update(const uint256_t &bqc_hash) {
return true;
}
-void HotStuffCore::on_propose(const std::vector<command_t> &cmds) {
- size_t nparents = parent_limit < 1 ? tails.size() : parent_limit;
- assert(tails.size() > 0);
- block_t p = *tails.rbegin();
- std::vector<block_t> parents{p};
- tails.erase(p);
- nparents--;
- /* add the rest of tails as "uncles/aunts" */
- while (nparents--)
- {
- auto it = tails.begin();
- parents.push_back(*it);
- tails.erase(it);
- }
+void HotStuffCore::on_propose(const std::vector<command_t> &cmds,
+ const std::vector<block_t> &parents) {
+ if (parents.empty())
+ throw std::runtime_error("empty parents");
+ for (const auto &_: parents) tails.erase(_);
+ block_t p = parents[0];
quorum_cert_bt qc = nullptr;
block_t qc_ref = nullptr;
if (p != b0 && p->voted.size() >= config.nmajority)
@@ -211,7 +201,13 @@ void HotStuffCore::on_receive_vote(const Vote &vote) {
size_t qsize = blk->voted.size();
if (qsize <= config.nmajority)
{
- blk->self_qc->add_part(vote.voter, *vote.cert);
+ auto &qc = blk->self_qc;
+ if (qc == nullptr)
+ {
+ LOG_WARN("vote for block not proposed by itself");
+ qc = create_quorum_cert(blk->get_hash());
+ }
+ qc->add_part(vote.voter, *vote.cert);
if (qsize == config.nmajority)
on_qc_finish(blk);
}
diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp
index f4454d4..d0b42c3 100644
--- a/src/hotstuff.cpp
+++ b/src/hotstuff.cpp
@@ -84,7 +84,7 @@ ReplicaID HotStuffBase::add_command(command_t cmd) {
cmd_pending.pop();
}
pmaker->beat().then([this, cmds = std::move(cmds)]() {
- on_propose(cmds);
+ on_propose(cmds, pmaker->get_parents());
});
}
return proposer;
@@ -383,13 +383,12 @@ promise_t HotStuffBase::async_decide(const uint256_t &cmd_hash) {
}
HotStuffBase::HotStuffBase(uint32_t blk_size,
- int32_t parent_limit,
ReplicaID rid,
privkey_bt &&priv_key,
NetAddr listen_addr,
- EventContext eb,
- pacemaker_bt pmaker):
- HotStuffCore(rid, std::move(priv_key), parent_limit),
+ pacemaker_bt pmaker,
+ EventContext eb):
+ HotStuffCore(rid, std::move(priv_key)),
listen_addr(listen_addr),
blk_size(blk_size),
eb(eb),
diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp
index 5f21fec..e1eec1b 100644
--- a/src/hotstuff_app.cpp
+++ b/src/hotstuff_app.cpp
@@ -61,6 +61,7 @@ class HotStuffApp: public HotStuff {
Event ev_stat_timer;
/** the binding address for client RPC */
NetAddr clisten_addr;
+ int32_t parent_limit;
using conn_client_t = MsgNetwork<MsgClient>::conn_t;
@@ -209,12 +210,14 @@ HotStuffApp::HotStuffApp(uint32_t blk_size,
NetAddr plisten_addr,
NetAddr clisten_addr,
const EventContext &eb):
- HotStuff(blk_size, parent_limit, idx, raw_privkey,
- plisten_addr, eb, new hotstuff::PaceMakerDummyFixed(1)),
+ HotStuff(blk_size, idx, raw_privkey,
+ plisten_addr,
+ new hotstuff::PaceMakerDummyFixed(1, parent_limit), eb),
stat_period(stat_period),
eb(eb),
cn(eb),
- clisten_addr(clisten_addr) {
+ clisten_addr(clisten_addr),
+ parent_limit(parent_limit) {
/* register the handlers for msg from clients */
cn.reg_handler(hotstuff::REQ_CMD, std::bind(&HotStuffApp::client_request_cmd_handler, this, _1, _2));
cn.reg_handler(hotstuff::CHK_CMD, std::bind(&HotStuffApp::client_check_cmd_handler, this, _1, _2));