diff options
Diffstat (limited to 'include/hotstuff')
-rw-r--r-- | include/hotstuff/client.h | 46 | ||||
-rw-r--r-- | include/hotstuff/consensus.h | 3 | ||||
-rw-r--r-- | include/hotstuff/entity.h | 27 | ||||
-rw-r--r-- | include/hotstuff/hotstuff.h | 28 | ||||
-rw-r--r-- | include/hotstuff/liveness.h | 46 |
5 files changed, 79 insertions, 71 deletions
diff --git a/include/hotstuff/client.h b/include/hotstuff/client.h index 00ec77d..2127595 100644 --- a/include/hotstuff/client.h +++ b/include/hotstuff/client.h @@ -4,6 +4,7 @@ #include "salticidae/msg.h" #include "hotstuff/type.h" #include "hotstuff/entity.h" +#include "hotstuff/consensus.h" namespace hotstuff { @@ -13,6 +14,39 @@ enum { CHK_CMD = 0x6 }; +struct Finality: public Serializable { + ReplicaID rid; + int8_t decision; + 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) {} + + void serialize(DataStream &s) const override { + s << rid << decision; + if (decision == 1) s << blk_hash; + } + + void unserialize(DataStream &s) override { + s >> rid >> decision; + if (decision == 1) s >> blk_hash; + } +}; + +struct MsgClient: public salticidae::MsgBase<> { + using MsgBase::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_chkcmd(const uint256_t &cmd_hash); + void parse_chkcmd(uint256_t &cmd_hash) const; +}; + class CommandDummy: public Command { static uint64_t cnt; uint64_t n; @@ -49,18 +83,6 @@ class CommandDummy: public Command { } }; -struct MsgClient: public salticidae::MsgBase<> { - using MsgBase::MsgBase; - void gen_reqcmd(const Command &cmd); - void parse_reqcmd(CommandDummy &cmd) const; - - void gen_respcmd(const uint256_t &cmd_hash, const Finality &fin); - void parse_respcmd(uint256_t &cmd_hash, Finality &fin) const; - - void gen_chkcmd(const uint256_t &cmd_hash); - void parse_chkcmd(uint256_t &cmd_hash) const; -}; - } #endif diff --git a/include/hotstuff/consensus.h b/include/hotstuff/consensus.h index 18e891e..cb18db5 100644 --- a/include/hotstuff/consensus.h +++ b/include/hotstuff/consensus.h @@ -1,6 +1,7 @@ #ifndef _HOTSTUFF_CONSENSUS_H #define _HOTSTUFF_CONSENSUS_H +#include <cassert> #include <set> #include <unordered_map> @@ -125,7 +126,7 @@ class HotStuffCore { block_t get_genesis() { return b0; } const ReplicaConfig &get_config() { return config; } int8_t get_cmd_decision(const uint256_t &cmd_hash); - ReplicaID get_id() { return id; } + ReplicaID get_id() const { return id; } operator std::string () const; }; diff --git a/include/hotstuff/entity.h b/include/hotstuff/entity.h index 00c64a6..03aff06 100644 --- a/include/hotstuff/entity.h +++ b/include/hotstuff/entity.h @@ -73,26 +73,6 @@ class HotStuffCore; using block_t = salticidae::RcObj<Block>; using block_weak_t = salticidae::WeakObj<Block>; -struct Finality: public Serializable { - int8_t decision; - uint256_t blk_hash; - - public: - Finality(): decision(0) {} - Finality(int8_t decision, uint256_t blk_hash): - decision(decision), blk_hash(blk_hash) {} - - void serialize(DataStream &s) const override { - s << decision; - if (decision == 1) s << blk_hash; - } - - void unserialize(DataStream &s) override { - s >> decision; - if (decision == 1) s >> blk_hash; - } -}; - class Command: public Serializable { friend HotStuffCore; block_weak_t container; @@ -101,7 +81,6 @@ class Command: public Serializable { virtual const uint256_t &get_hash() const = 0; virtual bool verify() const = 0; inline int8_t get_decision() const; - inline Finality get_finality() const; block_t get_container() const { return container; } @@ -220,12 +199,6 @@ int8_t Command::get_decision() const { return cptr ? cptr->get_decision() : 0; } -Finality Command::get_finality() const { - block_t blk = get_container(); - return Finality(get_decision(), - blk ? blk->get_hash() : uint256_t()); -} - class EntityStorage { std::unordered_map<const uint256_t, block_t> blk_cache; std::unordered_map<const uint256_t, command_t> cmd_cache; diff --git a/include/hotstuff/hotstuff.h b/include/hotstuff/hotstuff.h index 9546216..9d1a8a8 100644 --- a/include/hotstuff/hotstuff.h +++ b/include/hotstuff/hotstuff.h @@ -153,6 +153,7 @@ class HotStuffBase: public HotStuffCore { void do_broadcast_proposal(const Proposal &) override; void do_vote(ReplicaID, const Vote &) override; void do_decide(const command_t &) override; + void do_forward(const uint256_t &cmd_hash, ReplicaID rid); public: HotStuffBase(uint32_t blk_size, @@ -160,30 +161,15 @@ class HotStuffBase: public HotStuffCore { ReplicaID rid, privkey_bt &&priv_key, NetAddr listen_addr, - EventContext eb = EventContext(), - pacemaker_bt pmaker = nullptr); + EventContext eb, + pacemaker_bt pmaker); ~HotStuffBase(); /* the API for HotStuffBase */ /* Submit the command to be decided. */ - void add_command(command_t cmd) { - cmd_pending.push(storage->add_cmd(cmd)); - if (cmd_pending.size() >= blk_size) - { - std::vector<command_t> cmds; - for (uint32_t i = 0; i < blk_size; i++) - { - cmds.push_back(cmd_pending.front()); - cmd_pending.pop(); - } - pmaker->beat().then([this, cmds = std::move(cmds)]() { - on_propose(cmds); - }); - } - } - + ReplicaID add_command(command_t cmd); void add_replica(ReplicaID idx, const NetAddr &addr, pubkey_bt &&pub_key); void start(bool eb_loop = false); @@ -238,13 +224,15 @@ class HotStuff: public HotStuffBase { ReplicaID rid, const bytearray_t &raw_privkey, NetAddr listen_addr, - EventContext eb = nullptr): + EventContext eb = EventContext(), + pacemaker_bt pmaker = new PaceMakerDummy()): HotStuffBase(blk_size, parent_limit, rid, new PrivKeyType(raw_privkey), listen_addr, - eb) {} + eb, + std::move(pmaker)) {} void add_replica(ReplicaID idx, const NetAddr &addr, const bytearray_t &pubkey_raw) { DataStream s(pubkey_raw); diff --git a/include/hotstuff/liveness.h b/include/hotstuff/liveness.h index f8d3c50..b23d4c2 100644 --- a/include/hotstuff/liveness.h +++ b/include/hotstuff/liveness.h @@ -7,13 +7,16 @@ namespace hotstuff { /** Abstraction for liveness gadget (oracle). */ class PaceMaker { + protected: + HotStuffCore *hsc; public: virtual ~PaceMaker() = default; + virtual void init(HotStuffCore *_hsc) { hsc = _hsc; } /** Get a promise resolved when the pace maker thinks it is a *good* time - * to issue new commands. When promise is resolved with the ID of itself, - * the replica should propose the command, otherwise it will forward the - * command to the proposer indicated by the ID. */ + * to issue new commands. When promise is resolved, the replica should + * propose the command. */ virtual promise_t beat() = 0; + virtual ReplicaID get_proposer() = 0; /** Get a promise resolved when the pace maker thinks it is a *good* time * to vote for a block. The promise is resolved with the next proposer's ID * */ @@ -24,7 +27,6 @@ using pacemaker_bt = BoxObj<PaceMaker>; /** A pace maker that waits for the qc of the last proposed block. */ class PaceMakerDummy: public PaceMaker { - HotStuffCore *hsc; std::queue<promise_t> pending_beats; block_t last_proposed; bool locked; @@ -34,9 +36,8 @@ class PaceMakerDummy: public PaceMaker { { auto pm = pending_beats.front(); pending_beats.pop(); - hsc->async_qc_finish(last_proposed).then( - [id = hsc->get_id(), pm]() { - pm.resolve(id); + hsc->async_qc_finish(last_proposed).then([this, pm]() { + pm.resolve(get_proposer()); }); locked = true; } @@ -52,13 +53,19 @@ class PaceMakerDummy: public PaceMaker { } public: - PaceMakerDummy(HotStuffCore *hsc): - hsc(hsc), - last_proposed(hsc->get_genesis()), - locked(false) { + PaceMakerDummy() = default; + + void init(HotStuffCore *hsc) override { + PaceMaker::init(hsc); + last_proposed = hsc->get_genesis(); + locked = false; update_last_proposed(); } + ReplicaID get_proposer() override { + return hsc->get_id(); + } + promise_t beat() override { promise_t pm; pending_beats.push(pm); @@ -73,6 +80,23 @@ class PaceMakerDummy: public PaceMaker { } }; +class PaceMakerDummyFixed: public PaceMakerDummy { + ReplicaID proposer; + + public: + ReplicaID get_proposer() override { + return proposer; + } + + PaceMakerDummyFixed(ReplicaID proposer): proposer(proposer) {} + + promise_t next_proposer(ReplicaID) override { + return promise_t([this](promise_t &pm) { + pm.resolve(proposer); + }); + } +}; + } #endif |