From 780cfa4ee8faf4c2662f3c739e8a5c9f1c8a1826 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 18 Jul 2018 14:34:43 -0400 Subject: move parent selection to PaceMaker --- src/consensus.cpp | 34 +++++++++++++++------------------- src/hotstuff.cpp | 9 ++++----- src/hotstuff_app.cpp | 9 ++++++--- 3 files changed, 25 insertions(+), 27 deletions(-) (limited to 'src') 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 &cmds) { - size_t nparents = parent_limit < 1 ? tails.size() : parent_limit; - assert(tails.size() > 0); - block_t p = *tails.rbegin(); - std::vector 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 &cmds, + const std::vector &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::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)); -- cgit v1.2.3