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

Add batch parser and transport factory #1750

Merged
merged 10 commits into from
Oct 8, 2018
Merged

Conversation

lebdron
Copy link
Contributor

@lebdron lebdron commented Oct 1, 2018

Description of the Change

Remove transaction sequence usage from irohad, introduce

  • TransactionBatchParser, which splits a list of transactions by possible adjacent batches
  • TransportFactory interface and protobuf implementation, which allows to mock the deserialization step in tests
    One boost header was copied with slight change to allow moving non-copyable parameters in ranges:

Before:

    template<typename Arg>
    R operator()(const Arg& arg) const
    {
        BOOST_ASSERT(m_impl);
        return (*m_impl)(arg);
    }
    template<typename Arg>
    R operator()(Arg& arg) const
    {
        BOOST_ASSERT(m_impl);
        return (*m_impl)(arg);
    }

After:

      template <typename Arg>
      R operator()(Arg &&arg) const {
        BOOST_ASSERT(m_impl);
        return (*m_impl)(std::forward<Arg>(arg));
      }

Benefits

Less hardcoded dependencies

Possible Drawbacks

Code duplication in command service and mst transport, which will hopefully be resolved in another task

Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
@lebdron lebdron requested review from igor-egorov and removed request for muratovv October 2, 2018 13:15
Copy link
Contributor

@igor-egorov igor-egorov left a comment

Choose a reason for hiding this comment

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

Thanks!

kamilsa
kamilsa previously requested changes Oct 2, 2018
return false;
});
})
| boost::adaptors::transformed([&](auto result) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not const ref?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because result contains a unique pointer, which should be moved.


for (auto &batch : batches) {
shared_model::interface::TransactionBatchFactory::createTransactionBatch(
batch, shared_model::validation::DefaultUnsignedTransactionsValidator())
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it true, that we validate transactions twice? At first on line 38 and then on this line insude TransactionsValidator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That will be fixed when hyperledger/iroha#1743 is introduced. Batch factory will only validate batch fields and the order.

auto transactions = boost::copy_range<
shared_model::interface::types::SharedTxsCollectionType>(
request->transactions()
| boost::adaptors::transformed(
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider putting this into separate function. Method Torii becomes very large

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same for mst_transport then

namespace shared_model {
namespace interface {

template <typename Interface, typename Transport>
Copy link
Contributor

Choose a reason for hiding this comment

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

Please drop few comments describing this interface and template parameters

};

virtual iroha::expected::Result<std::unique_ptr<Interface>, Error> build(
Transport transport) 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.

Why not to take const ref of transport?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That will require to copy the argument regardless of the context. Value allows moving the argument if required.

#include "validators/abstract_validator.hpp"
#include "validators/answer.hpp"

#include <gmock/gmock.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

Third party libraries should be above ours

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://google.github.io/styleguide/cppguide.html#Names_and_Order_of_Includes

Use standard order for readability and to avoid hidden dependencies: Related header, C library, C++ library, other libraries' .h, your project's .h.

abstract_validator.hpp is the related header for this file.


namespace {
template <typename InRange, typename OutRange>
auto parseBatchesImpl(InRange in_range, const OutRange &out_range) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hard to read... What are these parameters? Maybe leave some comments here as well?

@l4l l4l added the needs-review pr awaits review from maintainers label Oct 3, 2018
@lebdron lebdron dismissed kamilsa’s stale review October 4, 2018 05:42

Issues addressed

@lebdron lebdron requested a review from kamilsa October 4, 2018 05:42
Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
@@ -149,8 +152,10 @@ void Irohad::initCryptoProvider() {
void Irohad::initValidators() {
auto factory = std::make_unique<shared_model::proto::ProtoProposalFactory<
shared_model::validation::DefaultProposalValidator>>();
batch_parser =
std::make_shared<shared_model::interface::TransactionBatchParserImpl>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure this initValidators is a good place to initialize a parser?

std::unique_ptr<shared_model::validation::AbstractValidator<
shared_model::interface::Transaction>>
transaction_validator = std::make_unique<
shared_model::validation::DefaultUnsignedTransactionValidator>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is that clang-format-ted?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.

@@ -3,70 +3,87 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "common/default_constructible_unary_fn.hpp" // non-copyable value workaround
Copy link
Contributor

Choose a reason for hiding this comment

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

According to what part of codestyle this header is at the top? Just asking

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it has to be included before any boost includes, so that it does not include the header from boost library. This is not a part of codestyle.


shared_model::interface::types::SharedTxsCollectionType
MstTransportGrpc::deserializeTransactions(
const ::iroha::network::transport::MstState *request) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the extra scope resolution :: necessary here?

[&](const auto &tx) { return transaction_factory_->build(tx); })
| boost::adaptors::filtered([&](const auto &result) {
return result.match(
[](const iroha::expected::Value<
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't const auto & work here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will, but is it necessary? When a reader will see auto here, their though will be "OK, this branch might be either value or error", and only later they will see the second branch and deduce the previous branch.

// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
Copy link
Contributor

Choose a reason for hiding this comment

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

Are all copyright issues kept? According to that license, is it permitted to use the file in commercial goals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we include other boost headers which contain the same licence, it should be fine.


virtual ~TransactionBatchParser() = default;
};
} // namespace interface
Copy link
Contributor

Choose a reason for hiding this comment

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

New line, please

Copy link
Contributor Author

Choose a reason for hiding this comment

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

namespace interface {

/**
* Parses a transaction list and return a list of possible batches
Copy link
Contributor

Choose a reason for hiding this comment

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

...and returns a list...

*/
class TransactionBatchParser {
public:
virtual std::vector<types::TransactionsForwardCollectionType>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why have you decided not to put any docs about hose 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.

They all match the description of the class, and argument types describe the differences.

auto parseBatchesImpl(InRange in_range, const OutRange &out_range) {
std::vector<OutRange> result;
auto meta = [](const auto &tx) { return boost::get<0>(tx).batchMeta(); };
auto has_meta = [&](const auto &tx) { return static_cast<bool>(meta(tx)); };
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe [&](const auto &tx) -> bool { will work? More readable than a static_case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This error was fixed previously hyperledger/iroha@3aad956

error: no viable conversion from 'boost::optional<std::shared_ptr<BatchMeta> >' to 'bool'

             begin_has_meta = boost::get<0>(*begin).batchMeta();

             ^                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
@lebdron lebdron merged commit 5ac40fa into dev Oct 8, 2018
@lebdron lebdron deleted the refactor/tx-factory-batch-parser branch October 8, 2018 09:01
bakhtin pushed a commit that referenced this pull request Nov 2, 2018
Signed-off-by: Andrei Lebedev <lebdron@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs-review pr awaits review from maintainers
Development

Successfully merging this pull request may close these issues.

None yet

5 participants