diff --git a/CMakeLists.txt b/CMakeLists.txt index d67b73096c..b3236b7b34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,11 @@ include_directories( SET(IROHA_ROOT_PROJECT ON) +# Boost uses RTTI to perform some actions (such as type erasure). +# This is slow. This flag forces boost to use other methods, +# which are generally faster +add_definitions(-DBOOST_NO_RTTI) + include(FeatureSummary) include(cmake/functions.cmake) include(cmake/dependencies.cmake) diff --git a/irohad/ametsuchi/impl/postgres_block_query.cpp b/irohad/ametsuchi/impl/postgres_block_query.cpp index 079aa466ad..82e885f82b 100644 --- a/irohad/ametsuchi/impl/postgres_block_query.cpp +++ b/irohad/ametsuchi/impl/postgres_block_query.cpp @@ -53,21 +53,17 @@ namespace iroha { } return rxcpp::observable<>::range(height, to) .flat_map([this](const auto &i) { - auto block = block_store_.get(i) | [](const auto &bytes) { - return shared_model::converters::protobuf::jsonToModel< - shared_model::proto::Block>(bytesToString(bytes)); - }; - if (not block) { - log_->error("error while converting from JSON"); - } - return rxcpp::observable<>::create( - [block{std::move(block)}](const auto &s) { - if (block) { - s.on_next(std::make_shared( - block.value())); - } - s.on_completed(); + [i, this](const auto &block_subscriber) { + block_store_.get(i) | [](const auto &bytes) { + return shared_model::converters::protobuf::jsonToModel< + shared_model::proto::Block>(bytesToString(bytes)); + } | [&block_subscriber](auto &&block) { + block_subscriber.on_next( + std::make_shared( + std::move(block))); + }; + block_subscriber.on_completed(); }); }); } diff --git a/irohad/network/impl/block_loader_impl.cpp b/irohad/network/impl/block_loader_impl.cpp index 1f31f2f612..9d74f17480 100644 --- a/irohad/network/impl/block_loader_impl.cpp +++ b/irohad/network/impl/block_loader_impl.cpp @@ -98,16 +98,15 @@ rxcpp::observable> BlockLoaderImpl::retrieveBlocks( .build(block) .match( // success case - [&subscriber]( - const iroha::expected::Value + [&subscriber](iroha::expected::Value &result) { subscriber.on_next( std::move(std::make_shared( - result.value))); + std::move(result.value)))); }, // fail case [this, - &context](const iroha::expected::Error &error) { + &context](iroha::expected::Error &error) { log_->error(error.error); context.TryCancel(); }); diff --git a/shared_model/backend/protobuf/CMakeLists.txt b/shared_model/backend/protobuf/CMakeLists.txt index 57fd1ede4e..5dee8f6609 100644 --- a/shared_model/backend/protobuf/CMakeLists.txt +++ b/shared_model/backend/protobuf/CMakeLists.txt @@ -4,6 +4,7 @@ # add_library(shared_model_proto_backend + impl/block.cpp impl/permissions.cpp commands/impl/proto_add_asset_quantity.cpp commands/impl/proto_add_peer.cpp diff --git a/shared_model/backend/protobuf/block.hpp b/shared_model/backend/protobuf/block.hpp index bed9ed4952..061c105a78 100644 --- a/shared_model/backend/protobuf/block.hpp +++ b/shared_model/backend/protobuf/block.hpp @@ -23,7 +23,7 @@ #include "backend/protobuf/common_objects/signature.hpp" #include "backend/protobuf/transaction.hpp" #include "backend/protobuf/util.hpp" -#include "common_objects/trivial_proto.hpp" +#include "common_objects/noncopyable_proto.hpp" #include "interfaces/common_objects/types.hpp" #include "block.pb.h" @@ -31,95 +31,57 @@ namespace shared_model { namespace proto { - class Block final : public CopyableProto { + class Block final : public NonCopyableProto { public: - template - explicit Block(BlockType &&block) - : CopyableProto(std::forward(block)) {} + using NonCopyableProto::NonCopyableProto; - Block(const Block &o) : Block(o.proto_) {} - - Block(Block &&o) noexcept : Block(std::move(o.proto_)) {} + Block(Block &&o) noexcept; + Block &operator=(Block &&o) noexcept; interface::types::TransactionsCollectionType transactions() - const override { - return *transactions_; - } + const override; - interface::types::HeightType height() const override { - return payload_.height(); - } + interface::types::HeightType height() const override; - const interface::types::HashType &prevHash() const override { - return *prev_hash_; - } + const interface::types::HashType &prevHash() const override; - const interface::types::BlobType &blob() const override { - return *blob_; - } + const interface::types::BlobType &blob() const override; - interface::types::SignatureRangeType signatures() const override { - return *signatures_; - } + interface::types::SignatureRangeType signatures() const override; - // TODO Alexey Chernyshov - 2018-03-28 - - // rework code duplication after fix protobuf - // https://soramitsu.atlassian.net/browse/IR-1175 bool addSignature(const crypto::Signed &signed_blob, - const crypto::PublicKey &public_key) override { - // if already has such signature - if (std::find_if(signatures_->begin(), - signatures_->end(), - [&public_key](const auto &signature) { - return signature.publicKey() == public_key; - }) - != signatures_->end()) { - return false; - } - - auto sig = proto_->add_signatures(); - sig->set_signature(crypto::toBinaryString(signed_blob)); - sig->set_pubkey(crypto::toBinaryString(public_key)); - - signatures_.invalidate(); - return true; - } - - interface::types::TimestampType createdTime() const override { - return payload_.created_time(); - } - - interface::types::TransactionsNumberType txsNumber() const override { - return payload_.tx_number(); - } - - const interface::types::BlobType &payload() const override { - return *payload_blob_; - } + const crypto::PublicKey &public_key) override; + + interface::types::TimestampType createdTime() const override; + + interface::types::TransactionsNumberType txsNumber() const override; + + const interface::types::BlobType &payload() const override; private: // lazy template using Lazy = detail::LazyInitializer; - const iroha::protocol::Block::Payload &payload_{proto_->payload()}; + iroha::protocol::Block::Payload &payload_{*proto_.mutable_payload()}; - const Lazy> transactions_{[this] { - return std::vector(payload_.transactions().begin(), - payload_.transactions().end()); + Lazy> transactions_{[this] { + return std::vector( + payload_.mutable_transactions()->begin(), + payload_.mutable_transactions()->end()); }}; - const Lazy blob_{ - [this] { return makeBlob(*proto_); }}; + Lazy blob_{ + [this] { return makeBlob(proto_); }}; - const Lazy prev_hash_{[this] { - return interface::types::HashType(proto_->payload().prev_block_hash()); + Lazy prev_hash_{[this] { + return interface::types::HashType(proto_.payload().prev_block_hash()); }}; - const Lazy> signatures_{[this] { - auto signatures = proto_->signatures() + Lazy> signatures_{[this] { + auto signatures = proto_.signatures() | boost::adaptors::transformed([](const auto &x) { return proto::Signature(x); }); @@ -127,7 +89,7 @@ namespace shared_model { signatures.end()); }}; - const Lazy payload_blob_{ + Lazy payload_blob_{ [this] { return makeBlob(payload_); }}; }; } // namespace proto diff --git a/shared_model/backend/protobuf/common_objects/noncopyable_proto.hpp b/shared_model/backend/protobuf/common_objects/noncopyable_proto.hpp new file mode 100644 index 0000000000..1ccb970f67 --- /dev/null +++ b/shared_model/backend/protobuf/common_objects/noncopyable_proto.hpp @@ -0,0 +1,41 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IROHA_NONCOPYABLE_PROTO_HPP +#define IROHA_NONCOPYABLE_PROTO_HPP + +/** + * Generic class for handling proto objects which are not intended to be copied. + * @tparam Iface is interface to inherit from + * @tparam Proto is protobuf container + * @tparam Impl is implementation of Iface + */ +template +class NonCopyableProto : public Iface { + public: + using TransportType = Proto; + + /* + * Construct object from transport. Transport can be moved or copied. + */ + template + NonCopyableProto(Transport &&ref) : proto_(std::forward(ref)){} + + NonCopyableProto(const NonCopyableProto &o) = delete; + NonCopyableProto &operator=(const NonCopyableProto &o) = delete; + + const Proto &getTransport() const { + return proto_; + } + + protected: + typename Iface::ModelType *clone() const override final { + return new Impl(proto_); + } + + Proto proto_; +}; + +#endif // IROHA_NONCOPYABLE_PROTO_HPP diff --git a/shared_model/backend/protobuf/impl/block.cpp b/shared_model/backend/protobuf/impl/block.cpp new file mode 100644 index 0000000000..759c9d8d18 --- /dev/null +++ b/shared_model/backend/protobuf/impl/block.cpp @@ -0,0 +1,80 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "backend/protobuf/block.hpp" + +namespace shared_model { + namespace proto { + Block::Block(Block &&o) noexcept : NonCopyableProto(std::move(o.proto_)) {} + + Block &Block::operator=(Block &&o) noexcept { + proto_ = std::move(o.proto_); + payload_ = *proto_.mutable_payload(); + + transactions_.invalidate(); + blob_.invalidate(); + prev_hash_.invalidate(); + signatures_.invalidate(); + payload_blob_.invalidate(); + + return *this; + } + + interface::types::TransactionsCollectionType Block::transactions() const { + return *transactions_; + } + + interface::types::HeightType Block::height() const { + return payload_.height(); + } + + const interface::types::HashType &Block::prevHash() const { + return *prev_hash_; + } + + const interface::types::BlobType &Block::blob() const { + return *blob_; + } + + interface::types::SignatureRangeType Block::signatures() const { + return *signatures_; + } + + // TODO Alexey Chernyshov - 2018-03-28 - + // rework code duplication from transaction, block after fix protobuf + // https://soramitsu.atlassian.net/browse/IR-1175 + bool Block::addSignature(const crypto::Signed &signed_blob, + const crypto::PublicKey &public_key) { + // if already has such signature + if (std::find_if(signatures_->begin(), + signatures_->end(), + [&public_key](const auto &signature) { + return signature.publicKey() == public_key; + }) + != signatures_->end()) { + return false; + } + + auto sig = proto_.add_signatures(); + sig->set_signature(crypto::toBinaryString(signed_blob)); + sig->set_pubkey(crypto::toBinaryString(public_key)); + + signatures_.invalidate(); + return true; + } + + interface::types::TimestampType Block::createdTime() const { + return payload_.created_time(); + } + + interface::types::TransactionsNumberType Block::txsNumber() const { + return payload_.tx_number(); + } + + const interface::types::BlobType &Block::payload() const { + return *payload_blob_; + } + } // namespace proto +} // namespace shared_model diff --git a/shared_model/builders/protobuf/unsigned_proto.hpp b/shared_model/builders/protobuf/unsigned_proto.hpp index b9d2ca2dd3..fde59bcc43 100644 --- a/shared_model/builders/protobuf/unsigned_proto.hpp +++ b/shared_model/builders/protobuf/unsigned_proto.hpp @@ -28,6 +28,9 @@ namespace shared_model { /** * Class for holding built but still unsigned objects * @tparam T - type of object received from builder + * + * NOTE: finish() moves internal object, so calling methods after + * finish() throws an exception */ template class UnsignedWrapper { @@ -42,6 +45,23 @@ namespace shared_model { explicit UnsignedWrapper(T &&o) : object_(std::move(o)) {} + UnsignedWrapper(UnsignedWrapper &&w) + : object_(std::move(w.object_)), + object_finalized_(w.object_finalized_) { + w.object_finalized_ = true; + } + + UnsignedWrapper &operator=(UnsignedWrapper &&w) { + object_ = std::move(w.object_); + object_finalized_ = w.object_finalized_; + w.object_finalized_ = true; + + return *this; + } + + UnsignedWrapper(const UnsignedWrapper &o) = default; + UnsignedWrapper &operator=(const UnsignedWrapper &w) = default; + /** * Add signature and retrieve signed result * @param signature - signature to add @@ -50,6 +70,9 @@ namespace shared_model { UnsignedWrapper &signAndAddSignature(const crypto::Keypair &keypair) { auto signedBlob = shared_model::crypto::CryptoSigner<>::sign( shared_model::crypto::Blob(object_.payload()), keypair); + if (object_finalized_) { + throw std::runtime_error("object has already been finalized"); + } object_.addSignature(signedBlob, keypair.publicKey()); // TODO: 05.12.2017 luckychess think about false case return *this; @@ -63,7 +86,12 @@ namespace shared_model { if (boost::size(object_.signatures()) == 0) { throw std::invalid_argument("Cannot get object without signatures"); } - return object_; + if (object_finalized_) { + throw std::runtime_error("object has already been finalized"); + } + + object_finalized_ = true; + return std::move(object_); } interface::types::HashType hash() { @@ -80,6 +108,7 @@ namespace shared_model { private: T object_; + bool object_finalized_{false}; }; } // namespace proto } // namespace shared_model diff --git a/shared_model/converters/protobuf/json_proto_converter.hpp b/shared_model/converters/protobuf/json_proto_converter.hpp index 4444a31e17..5854b0728c 100644 --- a/shared_model/converters/protobuf/json_proto_converter.hpp +++ b/shared_model/converters/protobuf/json_proto_converter.hpp @@ -34,7 +34,7 @@ namespace shared_model { * @return json string */ template - std::string modelToJson(T message) { + std::string modelToJson(const T &message) { std::string result; google::protobuf::util::MessageToJsonString(message.getTransport(), &result); diff --git a/shared_model/utils/lazy_initializer.hpp b/shared_model/utils/lazy_initializer.hpp index bdcf135294..f299bde6c8 100644 --- a/shared_model/utils/lazy_initializer.hpp +++ b/shared_model/utils/lazy_initializer.hpp @@ -35,6 +35,23 @@ namespace shared_model { using GeneratorType = std::function; public: + /** + * Default constructor prevents compilation error in pre 7.2 gcc. + * + * Short explanation: gcc needs default constructor + * when the constructor is inherited (via using Base::Base) + * if the inherited class has default initalizers for any of its members. + * This can be found in shared_model/backend/protobuf/protobuf/block.hpp + * where Lazy fields are initialized via default initializers. + * + * Note that this does not result in default constructor being called, so + * the resulting code is still correct. This is an issue of gcc compiler + * which is resolved in 7.2 + * + * For more details: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054 + */ + LazyInitializer(); + template explicit LazyInitializer(T &&generator) : generator_(std::forward(generator)) {} diff --git a/test/benchmark/bm_proto_creation.cpp b/test/benchmark/bm_proto_creation.cpp index a0cdcf9d15..521442eafa 100644 --- a/test/benchmark/bm_proto_creation.cpp +++ b/test/benchmark/bm_proto_creation.cpp @@ -11,8 +11,8 @@ * * The purpose of this benchmark is to keep track of performance costs related * to blocks and proposals copying/moving. - * - * Each benchmark runs transaction() and commands() call to + * + * Each benchmark runs transaction() and commands() call to * initialize possibly lazy fields. */ @@ -97,64 +97,127 @@ void checkLoop(const T &obj) { } } -BENCHMARK_F(BlockBenchmark, CopyTest)(benchmark::State &st) { - auto block = complete_builder.build(); +/** + * Runs a function and updates timer of the given state + */ +template +void runBenchmark(benchmark::State &st, Func &&f) { + auto start = std::chrono::high_resolution_clock::now(); + f(); + auto end = std::chrono::high_resolution_clock::now(); + + auto elapsed_seconds = + std::chrono::duration_cast>( + end - start); + st.SetIterationTime(elapsed_seconds.count()); +} + +/** + * Benchmark block creation by copying protobuf object + */ +BENCHMARK_DEFINE_F(BlockBenchmark, TransportCopyTest)(benchmark::State &st) { while (st.KeepRunning()) { - shared_model::proto::Block copy(block.getTransport()); + auto block = complete_builder.build(); - checkLoop(copy); + runBenchmark(st, [&block] { + shared_model::proto::Block copy(block.getTransport()); + checkLoop(copy); + }); } } -BENCHMARK_F(BlockBenchmark, MoveTest)(benchmark::State &st) { - auto block = complete_builder.build(); - +/** + * Benchmark block creation by moving protobuf object + */ +BENCHMARK_DEFINE_F(BlockBenchmark, TransportMoveTest)(benchmark::State &st) { while (st.KeepRunning()) { - shared_model::proto::Block copy(std::move(block.getTransport())); + auto block = complete_builder.build(); + iroha::protocol::Block proto_block = block.getTransport(); - checkLoop(copy); + runBenchmark(st, [&proto_block] { + shared_model::proto::Block copy(std::move(proto_block)); + checkLoop(copy); + }); } } -BENCHMARK_F(BlockBenchmark, CloneTest)(benchmark::State &st) { - auto block = complete_builder.build(); - +/** + * Benchmark block creation by moving another block + */ +BENCHMARK_DEFINE_F(BlockBenchmark, MoveTest)(benchmark::State &st) { while (st.KeepRunning()) { - auto copy = clone(block); + auto block = complete_builder.build(); - checkLoop(*copy); + runBenchmark(st, [&block] { + shared_model::proto::Block copy = std::move(block); + checkLoop(copy); + }); } } -BENCHMARK_F(ProposalBenchmark, CopyTest)(benchmark::State &st) { - auto proposal = complete_builder.build(); - +/** + * Benchmark block creation by cloning another block + */ +BENCHMARK_DEFINE_F(BlockBenchmark, CloneTest)(benchmark::State &st) { while (st.KeepRunning()) { - shared_model::proto::Proposal copy(proposal.getTransport()); + auto block = complete_builder.build(); - checkLoop(copy); + runBenchmark(st, [&block] { + auto copy = clone(block); + checkLoop(*copy); + }); } } -BENCHMARK_F(ProposalBenchmark, MoveTest)(benchmark::State &state) { - auto proposal = complete_builder.build(); - - while (state.KeepRunning()) { - shared_model::proto::Proposal copy(std::move(proposal.getTransport())); +/** + * Benchmark proposal creation by copying another proposal + */ +BENCHMARK_DEFINE_F(ProposalBenchmark, CopyTest)(benchmark::State &st) { + while (st.KeepRunning()) { + auto proposal = complete_builder.build(); - checkLoop(copy); + runBenchmark(st, [&proposal] { + shared_model::proto::Proposal copy(proposal.getTransport()); + checkLoop(copy); + }); } } -BENCHMARK_F(ProposalBenchmark, CloneTest)(benchmark::State &st) { - auto proposal = complete_builder.build(); +/** + * Benchmark proposal creation by moving another proposal + */ +BENCHMARK_DEFINE_F(ProposalBenchmark, MoveTest)(benchmark::State &st) { + while (st.KeepRunning()) { + auto proposal = complete_builder.build(); + + runBenchmark(st, [&] { + shared_model::proto::Proposal copy(std::move(proposal.getTransport())); + checkLoop(copy); + }); + } +} +/** + * Benchmark proposal creation by cloning another proposal + */ +BENCHMARK_DEFINE_F(ProposalBenchmark, CloneTest)(benchmark::State &st) { while (st.KeepRunning()) { - auto copy = clone(proposal); + auto proposal = complete_builder.build(); - checkLoop(*copy); + runBenchmark(st, [&proposal] { + auto copy = clone(proposal); + checkLoop(*copy); + }); } } +BENCHMARK_REGISTER_F(BlockBenchmark, MoveTest)->UseManualTime(); +BENCHMARK_REGISTER_F(BlockBenchmark, TransportMoveTest)->UseManualTime(); +BENCHMARK_REGISTER_F(BlockBenchmark, TransportCopyTest)->UseManualTime(); +BENCHMARK_REGISTER_F(BlockBenchmark, CloneTest)->UseManualTime(); +BENCHMARK_REGISTER_F(ProposalBenchmark, CopyTest)->UseManualTime(); +BENCHMARK_REGISTER_F(ProposalBenchmark, MoveTest)->UseManualTime(); +BENCHMARK_REGISTER_F(ProposalBenchmark, CloneTest)->UseManualTime(); + BENCHMARK_MAIN(); diff --git a/test/module/irohad/ametsuchi/block_query_test.cpp b/test/module/irohad/ametsuchi/block_query_test.cpp index 471b7d4751..0e38d77b7a 100644 --- a/test/module/irohad/ametsuchi/block_query_test.cpp +++ b/test/module/irohad/ametsuchi/block_query_test.cpp @@ -89,7 +89,7 @@ class BlockQueryTest : public AmetsuchiTest { .prevHash(block1.hash()) .build(); - for (const auto &b : {block1, block2}) { + for (const auto &b : {std::move(block1), std::move(block2)}) { file->add(b.height(), iroha::stringToBytes( shared_model::converters::protobuf::modelToJson(b))); diff --git a/test/module/irohad/network/block_loader_test.cpp b/test/module/irohad/network/block_loader_test.cpp index 36f8bacefd..44af03020a 100644 --- a/test/module/irohad/network/block_loader_test.cpp +++ b/test/module/irohad/network/block_loader_test.cpp @@ -149,8 +149,7 @@ TEST_F(BlockLoaderTest, ValidWhenOneBlock) { EXPECT_CALL(*storage, getTopBlock()) .WillOnce(Return(iroha::expected::makeValue(wBlock(clone(block))))); EXPECT_CALL(*storage, getBlocksFrom(block.height() + 1)) - .WillOnce(Return(rxcpp::observable<>::just(top_block).map( - [](auto &&x) { return wBlock(clone(x)); }))); + .WillOnce(Return(rxcpp::observable<>::just(wBlock(clone(top_block))))); auto wrapper = make_test_subscriber(loader->retrieveBlocks(peer_key), 1); wrapper.subscribe( @@ -215,8 +214,7 @@ TEST_F(BlockLoaderTest, ValidWhenBlockPresent) { EXPECT_CALL(*peer_query, getLedgerPeers()) .WillOnce(Return(std::vector{peer})); EXPECT_CALL(*storage, getBlocksFrom(1)) - .WillOnce(Return(rxcpp::observable<>::just(requested).map( - [](auto &&x) { return wBlock(clone(x)); }))); + .WillOnce(Return(rxcpp::observable<>::just(wBlock(clone(requested))))); auto block = loader->retrieveBlock(peer_key, requested.hash()); ASSERT_TRUE(block); @@ -236,8 +234,7 @@ TEST_F(BlockLoaderTest, ValidWhenBlockMissing) { EXPECT_CALL(*peer_query, getLedgerPeers()) .WillOnce(Return(std::vector{peer})); EXPECT_CALL(*storage, getBlocksFrom(1)) - .WillOnce(Return(rxcpp::observable<>::just(present).map( - [](auto &&x) { return wBlock(clone(x)); }))); + .WillOnce(Return(rxcpp::observable<>::just(wBlock(clone(present))))); auto block = loader->retrieveBlock(peer_key, kPrevHash); ASSERT_FALSE(block); diff --git a/test/module/irohad/validation/chain_validation_test.cpp b/test/module/irohad/validation/chain_validation_test.cpp index f14c4df853..7ecacb8733 100644 --- a/test/module/irohad/validation/chain_validation_test.cpp +++ b/test/module/irohad/validation/chain_validation_test.cpp @@ -135,10 +135,10 @@ TEST_F(ChainValidationTest, FailWhenNoSupermajority) { */ TEST_F(ChainValidationTest, ValidWhenValidateChainFromOnePeer) { // Valid previous hash, has supermajority, correct peers subset => valid - auto block = getBlockBuilder().build(); + auto block = std::make_shared(getBlockBuilder().build()); rxcpp::observable> block_observable = rxcpp::observable<>::just(block).map([](auto &&x) { - return std::shared_ptr(clone(x)); + return std::shared_ptr(x); }); EXPECT_CALL(*supermajority_checker, hasSupermajority(_, _)) @@ -149,10 +149,10 @@ TEST_F(ChainValidationTest, ValidWhenValidateChainFromOnePeer) { EXPECT_CALL( *storage, apply(testing::Truly([&](const shared_model::interface::Block &rhs) { - return rhs == block; + return rhs == *block; }), _)) - .WillOnce(InvokeArgument<1>(ByRef(block), ByRef(*query), ByRef(hash))); + .WillOnce(InvokeArgument<1>(ByRef(*block), ByRef(*query), ByRef(hash))); ASSERT_TRUE(validator->validateChain(block_observable, *storage)); } diff --git a/test/module/shared_model/builders/protobuf/transport_builder_test.cpp b/test/module/shared_model/builders/protobuf/transport_builder_test.cpp index 2a8c932f5d..ec5b7dc1ba 100644 --- a/test/module/shared_model/builders/protobuf/transport_builder_test.cpp +++ b/test/module/shared_model/builders/protobuf/transport_builder_test.cpp @@ -203,10 +203,13 @@ class TransportBuilderTest : public ::testing::Test { * @param successCase function invoking if value exists * @param failCase function invoking when error returned */ - template - void testTransport(T orig_model, - std::function &)> successCase, - std::function &)> failCase) { + template + void testTransport(const T &orig_model, + SuccessCase &&successCase, + FailCase &&failCase) { auto proto_model = orig_model.getTransport(); auto built_model = TransportBuilder().build(proto_model); @@ -238,8 +241,7 @@ class TransportBuilderTest : public ::testing::Test { */ TEST_F(TransportBuilderTest, TransactionCreationTest) { auto orig_model = createTransaction(); - testTransport( + testTransport( orig_model, [&orig_model](const Value &model) { ASSERT_EQ(model.value.getTransport().SerializeAsString(), @@ -258,8 +260,7 @@ TEST_F(TransportBuilderTest, TransactionCreationTest) { */ TEST_F(TransportBuilderTest, InvalidTransactionCreationTest) { auto orig_model = createInvalidTransaction(); - testTransport( + testTransport( orig_model, [](const Value) { FAIL(); }, [](const Error &) { SUCCEED(); }); @@ -274,8 +275,7 @@ TEST_F(TransportBuilderTest, InvalidTransactionCreationTest) { */ TEST_F(TransportBuilderTest, QueryCreationTest) { auto orig_model = createQuery(); - testTransport( + testTransport( orig_model, [&orig_model](const Value &model) { ASSERT_EQ(model.value.getTransport().SerializeAsString(), @@ -291,8 +291,7 @@ TEST_F(TransportBuilderTest, QueryCreationTest) { */ TEST_F(TransportBuilderTest, InvalidQueryCreationTest) { auto orig_model = createInvalidQuery(); - testTransport( + testTransport( orig_model, [](const Value) { FAIL(); }, [](const Error &) { SUCCEED(); }); @@ -307,7 +306,7 @@ TEST_F(TransportBuilderTest, InvalidQueryCreationTest) { */ TEST_F(TransportBuilderTest, BlockCreationTest) { auto orig_model = createBlock(); - testTransport( + testTransport( orig_model, [&orig_model](const Value &model) { ASSERT_EQ(model.value.getTransport().SerializeAsString(), @@ -323,10 +322,10 @@ TEST_F(TransportBuilderTest, BlockCreationTest) { */ TEST_F(TransportBuilderTest, InvalidBlockCreationTest) { auto orig_model = createInvalidBlock(); - testTransport( + testTransport( orig_model, - [](const Value) { FAIL(); }, - [](const Error &) { SUCCEED(); }); + [](const Value> &) { FAIL(); }, + [](const Error &) { SUCCEED(); }); } //-------------------------------------PROPOSAL------------------------------------- @@ -338,7 +337,7 @@ TEST_F(TransportBuilderTest, InvalidBlockCreationTest) { */ TEST_F(TransportBuilderTest, ProposalCreationTest) { auto orig_model = createProposal(); - testTransport( + testTransport( orig_model, [&orig_model](const Value &model) { ASSERT_EQ(model.value.getTransport().SerializeAsString(), @@ -355,7 +354,7 @@ TEST_F(TransportBuilderTest, ProposalCreationTest) { */ TEST_F(TransportBuilderTest, DISABLED_EmptyProposalCreationTest) { auto orig_model = createEmptyProposal(); - testTransport( + testTransport( orig_model, [](const Value) { FAIL(); }, [](const Error &) { SUCCEED(); }); @@ -370,7 +369,7 @@ TEST_F(TransportBuilderTest, DISABLED_EmptyProposalCreationTest) { */ TEST_F(TransportBuilderTest, EmptyBlockCreationTest) { auto orig_model = createEmptyBlock(); - testTransport( + testTransport( orig_model, [&orig_model](const Value &model) { ASSERT_EQ(model.value.getTransport().SerializeAsString(),