Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

BFT YacGate #1731

Merged
merged 13 commits into from
Oct 22, 2018
Merged

BFT YacGate #1731

merged 13 commits into from
Oct 22, 2018

Conversation

l4l
Copy link
Contributor

@l4l l4l commented Sep 24, 2018

Description of the Change

YacGate that supports rounds and use more precise output on its outcome

Benefits

One more step toward bft consensus

Usage Examples or Tests

For now only yac target can be built

@l4l l4l added the needs-review pr awaits review from maintainers label Sep 24, 2018
@l4l l4l requested review from kamilsa and lebdron September 24, 2018 10:23
@l4l l4l added the consensus label Sep 24, 2018
// update BlockCreator iface according to YacGate
this->vote(
std::shared_ptr<shared_model::interface::Proposal>(
(shared_model::proto::ProtoProposalFactory<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proto should not be used even as a temporary solution. Consider making a dummy interface implementation in the same file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like a good alternative here, since it's even more code which still remain boilerplate

@@ -52,6 +42,9 @@ namespace iroha {
*/
std::string block_hash;

/// Consensus round
ordering::transport::Round round;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to add this field in this pull request if storage and transport logic is unchanged.

@@ -78,7 +71,8 @@ namespace iroha {
* @return hashed value of block
*/
virtual YacHash makeHash(
const shared_model::interface::Block &block) const = 0;
const shared_model::interface::Block &block,
const shared_model::interface::Proposal &proposal) const = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add round parameter here.


/// Reject on block
struct BlockReject {
consensus::yac::YacHash hash;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YacHash is an implementation of consensus, it should not be present in this file

*/

#ifndef IROHA_CONSENSUS_GATE_HPP
#define IROHA_CONSENSUS_GATE_HPP

#include <rxcpp/rx.hpp>

#include "consensus/yac/yac_hash_provider.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this include from interface, because it is a part of implementation.

result.proposal_hash = hex_hash;
result.block_hash = hex_hash;
result.proposal_hash = proposal.hash().hex();
result.block_hash = block.hash().hex();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change this method in this pull request if other parts of Yac are not changed.

return rxcpp::observable<>::create<GateObject>([&](auto subscriber) {
const auto hash = getHash(msg.votes);
if (not hash) {
log_->info("Invalid commit message, hashes are different");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit message cannot be invalid, since it is guaranteed by CommitMessage interface. Consider removing this conditional.


log_->info("Voted for another block, waiting for sync");
subscriber.on_next(network::VoteOther{current_block_});
subscriber.on_completed();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here should be also processing of agreement on none

@l4l l4l changed the title Draft on BFT YacGate BFT YacGate Sep 28, 2018
@l4l l4l requested a review from lebdron October 2, 2018 22:26
Signed-off-by: Kitsu <mail@kitsu.me>
@l4l l4l changed the base branch from trunk/bft_yac to dev October 4, 2018 08:11
@l4l l4l changed the base branch from dev to trunk/bft_yac October 4, 2018 08:12
});
return visit_in_place(
message,
[this](const CommitMessage &msg) { return handleCommit(msg); },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a nested static visitor class instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the profit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No redundant visit_in_place with two proxy methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...will be replaced with redundant visit class with two methods?
I don't notice any profit again, could you describe it?

*/

#ifndef IROHA_CONSENSUS_GATE_HPP
#define IROHA_CONSENSUS_GATE_HPP

#include <rxcpp/rx.hpp>

#include "ordering/on_demand_os_transport.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::shared_ptr<shared_model::interface::Block> block,
Round round) = 0;

using GateObject = boost::variant<PairValid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will require creating a .cpp file for the interface, and another header.

  1. Include variant_fwd.hpp in this header file
  2. Create a separate header with variant.hpp include and `extern template for the variant
  3. Create a .cpp file with variant instantiations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo added

} // namespace shared_model

namespace iroha {
namespace network {
/// Current pair is valid
struct PairValid {
std::shared_ptr<shared_model::interface::Block> block_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for trailing underscore, since it is a public member.


/// Network votes for another pair and round
struct VoteOther {
std::shared_ptr<shared_model::interface::Block> block_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is current block required for synchronizer to load the committed block? Maybe use something else instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really aware of it. I just guessed that Block will be enough.

block->hash().toString());
auto order = orderer_->getOrdering(hash);
void YacGateImpl::vote(
std::shared_ptr<shared_model::interface::Proposal> proposal,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optionals should be used for both proposal and block, because there could be no proposal from the current ordering service, and therefore no block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional sounds redundant, maybe just use (& notice in docs) nullptr as no proposa/block case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, since we guarantee that pointers are not nullable in server code.


rxcpp::observable<YacGateImpl::GateObject> YacGateImpl::handleCommit(
const CommitMessage &msg) {
return rxcpp::observable<>::create<GateObject>([&](auto subscriber) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better not to manually create an observable, but use existing method just to emit a single message, or empty if nothing is emitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify the code and eliminate any possibilty to forget on_completed call.

const CommitMessage &msg) {
return rxcpp::observable<>::create<GateObject>([&](auto subscriber) {
const auto hash = getHash(msg.votes).value();
if (hash.vote_hashes.proposal_hash.size() == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use .empty() instead?


rxcpp::observable<YacGateImpl::GateObject> YacGateImpl::handleReject(
const RejectMessage &msg) {
return rxcpp::observable<>::create<GateObject>([&](auto subscriber) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for using rxcpp::observable<>::just

@@ -24,6 +12,7 @@
#include "consensus/round.hpp"
#include "consensus/yac/storage/yac_common.hpp"
#include "interfaces/common_objects/types.hpp"
#include "ordering/on_demand_os_transport.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This include should not be required in this file.

- Use just/empty instead of observable::create in YacGate
- Replace outdated header with consensus/round.hpp
- Remove underscores in GateObjects fields

Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
@l4l l4l mentioned this pull request Oct 7, 2018
Signed-off-by: Kitsu <mail@kitsu.me>
@@ -78,8 +70,8 @@ namespace iroha {

logger::Logger log_;

std::pair<YacHash, std::shared_ptr<shared_model::interface::Block>>
current_block_;
std::shared_ptr<shared_model::interface::Block> current_block_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> optional<shared_ptr>, same reason as vote arguments

Round round) {
bool is_none = not proposal or not block;
if (is_none) {
current_block_ = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> nullopt

bool is_none = not proposal or not block;
if (is_none) {
current_block_ = nullptr;
current_hash_ = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round should be set here, please leave a comment.

return rxcpp::observable<>::just<GateObject>(
network::VoteOther{current_block_});
}
return rxcpp::observable<>::empty<GateObject>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is unreachable since conditionals cover all the cases, please remove.


// insert the block we voted for to the consensus cache
consensus_result_cache_->insert(block);
if (is_none) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code in this conditional might throw an exception in case there was no block:
https://github.com/hyperledger/iroha/blob/a52ca3e89997bcb45e04d3032dc8258da436673d/irohad/consensus/yac/impl/yac_gate_impl.cpp#L53
Check if this case is covered by the tests and change the conditional.

Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
Signed-off-by: Kitsu <mail@kitsu.me>
@l4l l4l removed the needs-review pr awaits review from maintainers label Oct 22, 2018
@l4l l4l merged commit f868861 into trunk/bft_yac Oct 22, 2018
@l4l l4l deleted the feature/yacgate_bft branch October 22, 2018 22:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging this pull request may close these issues.

None yet

3 participants