aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2018-08-03 18:09:01 -0400
committerDeterminant <tederminant@gmail.com>2018-08-03 18:09:01 -0400
commitedcadfb47b736e6c9dd6b078689114aecf5c1add (patch)
treeae292e6448e8f078b735ce8b4ff7537986f26a48
parent8b912c47e19353a419c8717f7a839b0d63f5cc6c (diff)
allow extra data in blocks
-rw-r--r--include/hotstuff/consensus.h5
-rw-r--r--include/hotstuff/entity.h14
-rw-r--r--src/consensus.cpp10
-rw-r--r--src/entity.cpp16
4 files changed, 32 insertions, 13 deletions
diff --git a/include/hotstuff/consensus.h b/include/hotstuff/consensus.h
index 1528b40..85c1e8c 100644
--- a/include/hotstuff/consensus.h
+++ b/include/hotstuff/consensus.h
@@ -80,7 +80,8 @@ class HotStuffCore {
* contain at least one block, and the first block is the actual parent,
* while the others are uncles/aunts */
void on_propose(const std::vector<command_t> &cmds,
- const std::vector<block_t> &parents);
+ const std::vector<block_t> &parents,
+ serializable_bt &&extra = nullptr);
/* Functions required to construct concrete instances for abstract classes.
* */
@@ -113,6 +114,8 @@ 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 09b40aa..dc77c81 100644
--- a/include/hotstuff/entity.h
+++ b/include/hotstuff/entity.h
@@ -102,13 +102,17 @@ 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;
- uint256_t hash;
+ serializable_bt extra;
+ /* the following fields can be derived from above */
+ uint256_t hash;
std::vector<block_t> parents;
block_t qc_ref;
quorum_cert_bt self_qc;
@@ -121,12 +125,14 @@ 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),
@@ -134,14 +140,16 @@ class Block {
Block(const std::vector<block_t> &parents,
const std::vector<command_t> &cmds,
- uint32_t height,
quorum_cert_bt &&qc,
+ serializable_bt &&extra,
+ uint32_t height,
const block_t &qc_ref,
quorum_cert_bt &&self_qc,
int8_t decision = 0):
parent_hashes(get_hashes(parents)),
cmds(cmds),
qc(std::move(qc)),
+ extra(std::move(extra)),
hash(salticidae::get_hash(*this)),
parents(parents),
qc_ref(qc_ref),
@@ -185,6 +193,8 @@ class Block {
const block_t &get_qc_ref() const { return qc_ref; }
+ const serializable_bt &get_extra() const { return extra; }
+
operator std::string () const {
DataStream s;
s << "<block "
diff --git a/src/consensus.cpp b/src/consensus.cpp
index 2cac22c..e25558a 100644
--- a/src/consensus.cpp
+++ b/src/consensus.cpp
@@ -109,7 +109,8 @@ bool HotStuffCore::update(const uint256_t &bqc_hash) {
}
void HotStuffCore::on_propose(const std::vector<command_t> &cmds,
- const std::vector<block_t> &parents) {
+ const std::vector<block_t> &parents,
+ serializable_bt &&extra) {
if (parents.empty())
throw std::runtime_error("empty parents");
for (const auto &_: parents) tails.erase(_);
@@ -125,11 +126,10 @@ void HotStuffCore::on_propose(const std::vector<command_t> &cmds,
}
/* create the new block */
block_t bnew = storage->add_blk(
- new Block(
- parents,
- cmds,
+ new Block(parents, cmds,
+ std::move(qc), std::move(extra),
p->height + 1,
- std::move(qc), qc_ref,
+ qc_ref,
nullptr
));
const uint256_t bnew_hash = bnew->get_hash();
diff --git a/src/entity.cpp b/src/entity.cpp
index 80c9cf9..a5dc44e 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -10,15 +10,19 @@ void Block::serialize(DataStream &s) const {
s << (uint32_t)cmds.size();
for (auto cmd: cmds)
s << *cmd;
- if (qc == nullptr)
+ if (qc)
+ s << (uint8_t)1 << *qc;
+ else
s << (uint8_t)0;
+ if (extra)
+ s << (uint8_t)1 << *extra;
else
- s << (uint8_t)1 << *qc;
+ s << (uint8_t)0;
}
void Block::unserialize(DataStream &s, HotStuffCore *hsc) {
uint32_t n;
- uint8_t has_qc;
+ uint8_t flag;
s >> n;
parent_hashes.resize(n);
for (auto &hash: parent_hashes)
@@ -27,9 +31,11 @@ void Block::unserialize(DataStream &s, HotStuffCore *hsc) {
cmds.resize(n);
for (auto &cmd: cmds)
cmd = hsc->parse_cmd(s);
- s >> has_qc;
- qc = has_qc ? hsc->parse_quorum_cert(s) : nullptr;
+ s >> flag;
+ qc = flag ? hsc->parse_quorum_cert(s) : nullptr;
this->hash = salticidae::get_hash(*this);
+ s >> flag;
+ extra = flag ? hsc->parse_extra_block_data(s) : nullptr;
}
}