From 43d79021cc1656c782fe9e47b8019d38e664b57c Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Mon, 9 Jul 2018 18:41:29 +0300 Subject: [PATCH 01/17] Implement Abstract factory for peer Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- shared_model/backend/protobuf/CMakeLists.txt | 3 ++ .../protobuf/common_objects/CMakeLists.txt | 9 +++++ .../proto_common_objects_factory.cpp | 21 +++++++++++ .../proto_common_objects_factory.hpp | 22 ++++++++++++ .../common_objects/common_objects_factory.hpp | 36 +++++++++++++++++++ .../shared_model/backend_proto/CMakeLists.txt | 8 +++++ .../proto_common_objects_factory_test.cpp | 19 ++++++++++ 7 files changed, 118 insertions(+) create mode 100644 shared_model/backend/protobuf/common_objects/CMakeLists.txt create mode 100644 shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp create mode 100644 shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp create mode 100644 shared_model/interfaces/common_objects/common_objects_factory.hpp create mode 100644 test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp diff --git a/shared_model/backend/protobuf/CMakeLists.txt b/shared_model/backend/protobuf/CMakeLists.txt index 57fd1ede4e..c0e5b2c4ab 100644 --- a/shared_model/backend/protobuf/CMakeLists.txt +++ b/shared_model/backend/protobuf/CMakeLists.txt @@ -3,6 +3,8 @@ # SPDX-License-Identifier: Apache-2.0 # +add_subdirectory(common_objects) + add_library(shared_model_proto_backend impl/permissions.cpp commands/impl/proto_add_asset_quantity.cpp @@ -60,4 +62,5 @@ target_link_libraries(shared_model_proto_backend schema shared_model_interfaces iroha_amount + proto_common_objects ) diff --git a/shared_model/backend/protobuf/common_objects/CMakeLists.txt b/shared_model/backend/protobuf/common_objects/CMakeLists.txt new file mode 100644 index 0000000000..b2fefab9af --- /dev/null +++ b/shared_model/backend/protobuf/common_objects/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright Soramitsu Co., Ltd. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# + +add_library(proto_common_objects + proto_common_objects_factory.cpp) + + diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp new file mode 100644 index 0000000000..c0ed652244 --- /dev/null +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp @@ -0,0 +1,21 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "proto_common_objects_factory.hpp" + +#include "backend/protobuf/common_objects/peer.hpp" + +namespace shared_model { + namespace proto { + std::unique_ptr ProtoCommonObjectsFactory::createPeer( + const interface::types::AddressType &address, + const interface::types::PubkeyType &public_key) { + iroha::protocol::Peer peer; + peer.set_address (address); + peer.set_peer_key(crypto::toBinaryString(public_key)); + return std::make_unique(std::move(peer)); + } + } // namespace proto +} // namespace shared_model diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp new file mode 100644 index 0000000000..8ae9b05b66 --- /dev/null +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -0,0 +1,22 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP +#define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP + +#include "interfaces/common_objects/common_objects_factory.hpp" + +namespace shared_model { + namespace proto { + class ProtoCommonObjectsFactory : public interface::CommonObjectsFactory { + public: + std::unique_ptr createPeer( + const interface::types::AddressType &address, + const interface::types::PubkeyType &public_key) override; + }; + } // namespace proto +} // namespace shared_model + +#endif // IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp new file mode 100644 index 0000000000..6977b4290d --- /dev/null +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -0,0 +1,36 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IROHA_COMMON_OBJECTS_FACTORY_HPP +#define IROHA_COMMON_OBJECTS_FACTORY_HPP + +#include + +#include "interfaces/common_objects/peer.hpp" +#include "interfaces/common_objects/types.hpp" + +namespace shared_model { + namespace interface { + /** + * CommonObjectsFactory provides methods to construct simple objects + * such as peer, account etc. + */ + class CommonObjectsFactory { + public: + /** + * Creates peer instance + * @param address - ip address of the peer + * @param public_key - public key of the peer + */ + virtual std::unique_ptr createPeer( + const types::AddressType &address, + const types::PubkeyType &public_key) = 0; + + virtual ~CommonObjectsFactory() = default; + }; + } // namespace interface +} // namespace shared_model + +#endif // IROHA_COMMONOBJECTSFACTORY_HPP diff --git a/test/module/shared_model/backend_proto/CMakeLists.txt b/test/module/shared_model/backend_proto/CMakeLists.txt index bc1675d33e..be0108424a 100644 --- a/test/module/shared_model/backend_proto/CMakeLists.txt +++ b/test/module/shared_model/backend_proto/CMakeLists.txt @@ -78,3 +78,11 @@ target_link_libraries(permissions_test shared_model_proto_backend ) +addtest(proto_common_objects_test + common_objects/proto_common_objects_factory_test.cpp + ) +target_link_libraries(proto_common_objects_test + proto_common_objects + shared_model_cryptography + schema) + diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp new file mode 100644 index 0000000000..fb43045414 --- /dev/null +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -0,0 +1,19 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" + +#include + +using namespace shared_model; + +TEST(PeerTest, ValidPeerInitialization) { + proto::ProtoCommonObjectsFactory factory; + + auto peer = factory.createPeer("127.0.0.1", interface::types::PubkeyType(shared_model::crypto::Blob::fromHexString("1234"))); + + ASSERT_EQ(peer->address(), "127.0.0.1"); + ASSERT_EQ(peer->pubkey().hex(), "1234"); +} From f7eabe8bf401618cbb0492ad4ae0dfb87e5fc990 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Tue, 10 Jul 2018 12:04:54 +0300 Subject: [PATCH 02/17] Factory returns Result instead of just pointer This allows addition of validator in the future Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- shared_model/backend/protobuf/CMakeLists.txt | 3 --- .../protobuf/common_objects/CMakeLists.txt | 9 -------- .../proto_common_objects_factory.cpp | 21 ------------------- .../proto_common_objects_factory.hpp | 17 +++++++++++++-- .../common_objects/common_objects_factory.hpp | 5 ++++- .../shared_model/backend_proto/CMakeLists.txt | 5 ++--- .../proto_common_objects_factory_test.cpp | 20 ++++++++++++++---- 7 files changed, 37 insertions(+), 43 deletions(-) delete mode 100644 shared_model/backend/protobuf/common_objects/CMakeLists.txt delete mode 100644 shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp diff --git a/shared_model/backend/protobuf/CMakeLists.txt b/shared_model/backend/protobuf/CMakeLists.txt index c0e5b2c4ab..57fd1ede4e 100644 --- a/shared_model/backend/protobuf/CMakeLists.txt +++ b/shared_model/backend/protobuf/CMakeLists.txt @@ -3,8 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 # -add_subdirectory(common_objects) - add_library(shared_model_proto_backend impl/permissions.cpp commands/impl/proto_add_asset_quantity.cpp @@ -62,5 +60,4 @@ target_link_libraries(shared_model_proto_backend schema shared_model_interfaces iroha_amount - proto_common_objects ) diff --git a/shared_model/backend/protobuf/common_objects/CMakeLists.txt b/shared_model/backend/protobuf/common_objects/CMakeLists.txt deleted file mode 100644 index b2fefab9af..0000000000 --- a/shared_model/backend/protobuf/common_objects/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright Soramitsu Co., Ltd. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 -# - -add_library(proto_common_objects - proto_common_objects_factory.cpp) - - diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp deleted file mode 100644 index c0ed652244..0000000000 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "proto_common_objects_factory.hpp" - -#include "backend/protobuf/common_objects/peer.hpp" - -namespace shared_model { - namespace proto { - std::unique_ptr ProtoCommonObjectsFactory::createPeer( - const interface::types::AddressType &address, - const interface::types::PubkeyType &public_key) { - iroha::protocol::Peer peer; - peer.set_address (address); - peer.set_peer_key(crypto::toBinaryString(public_key)); - return std::make_unique(std::move(peer)); - } - } // namespace proto -} // namespace shared_model diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 8ae9b05b66..d5d971f168 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -6,15 +6,28 @@ #ifndef IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP #define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP +#include "backend/protobuf/common_objects/peer.hpp" +#include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" +#include "primitive.pb.h" namespace shared_model { namespace proto { + template class ProtoCommonObjectsFactory : public interface::CommonObjectsFactory { public: - std::unique_ptr createPeer( + FactoryResult> createPeer( const interface::types::AddressType &address, - const interface::types::PubkeyType &public_key) override; + const interface::types::PubkeyType &public_key) override { + iroha::protocol::Peer peer; + peer.set_address(address); + peer.set_peer_key(crypto::toBinaryString(public_key)); + return iroha::expected::makeValue>( + std::make_unique(std::move(peer))); + } + + private: + Validator validator; }; } // namespace proto } // namespace shared_model diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 6977b4290d..de92499fb6 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -10,6 +10,7 @@ #include "interfaces/common_objects/peer.hpp" #include "interfaces/common_objects/types.hpp" +#include "common/result.hpp" namespace shared_model { namespace interface { @@ -19,12 +20,14 @@ namespace shared_model { */ class CommonObjectsFactory { public: + template + using FactoryResult = iroha::expected::Result; /** * Creates peer instance * @param address - ip address of the peer * @param public_key - public key of the peer */ - virtual std::unique_ptr createPeer( + virtual FactoryResult> createPeer( const types::AddressType &address, const types::PubkeyType &public_key) = 0; diff --git a/test/module/shared_model/backend_proto/CMakeLists.txt b/test/module/shared_model/backend_proto/CMakeLists.txt index be0108424a..701016e60b 100644 --- a/test/module/shared_model/backend_proto/CMakeLists.txt +++ b/test/module/shared_model/backend_proto/CMakeLists.txt @@ -78,11 +78,10 @@ target_link_libraries(permissions_test shared_model_proto_backend ) -addtest(proto_common_objects_test +addtest(proto_common_objects_factory_test common_objects/proto_common_objects_factory_test.cpp ) -target_link_libraries(proto_common_objects_test - proto_common_objects +target_link_libraries(proto_common_objects_factory_test shared_model_cryptography schema) diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index fb43045414..67988be7cf 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -4,16 +4,28 @@ */ #include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" +#include "framework/result_fixture.hpp" #include using namespace shared_model; +using namespace framework::expected; TEST(PeerTest, ValidPeerInitialization) { - proto::ProtoCommonObjectsFactory factory; + proto::ProtoCommonObjectsFactory factory; - auto peer = factory.createPeer("127.0.0.1", interface::types::PubkeyType(shared_model::crypto::Blob::fromHexString("1234"))); + auto peer = factory.createPeer( + "127.0.0.1", + interface::types::PubkeyType( + shared_model::crypto::Blob::fromHexString("1234"))); - ASSERT_EQ(peer->address(), "127.0.0.1"); - ASSERT_EQ(peer->pubkey().hex(), "1234"); + peer.match( + [](const ValueOf &v) { + ASSERT_EQ(v.value->address(), "127.0.0.1"); + ASSERT_EQ(v.value->pubkey().hex(), "1234"); + }, + [](const ErrorOf &e) { + FAIL(); + } + ); } From e9049646a804e4a34e910fe10c861466b7694a8d Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Tue, 10 Jul 2018 14:18:11 +0300 Subject: [PATCH 03/17] Add validation logic to factory This allows addition of validator in the future Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 20 ++++++- .../shared_model/backend_proto/CMakeLists.txt | 1 + .../proto_common_objects_factory_test.cpp | 56 ++++++++++++++----- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index d5d971f168..b366248dd7 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -10,6 +10,7 @@ #include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" #include "primitive.pb.h" +#include "validators/answer.hpp" namespace shared_model { namespace proto { @@ -22,12 +23,27 @@ namespace shared_model { iroha::protocol::Peer peer; peer.set_address(address); peer.set_peer_key(crypto::toBinaryString(public_key)); + auto proto_peer = std::make_unique(std::move(peer)); + + shared_model::validation::Answer answer; + + validation::ReasonsGroupType reasons; + this->validator_.validatePeer(reasons, *proto_peer); + + if (not reasons.second.empty()) { + answer.addReason(std::move(reasons)); + } + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + return iroha::expected::makeValue>( - std::make_unique(std::move(peer))); + std::move(proto_peer)); } private: - Validator validator; + Validator validator_; }; } // namespace proto } // namespace shared_model diff --git a/test/module/shared_model/backend_proto/CMakeLists.txt b/test/module/shared_model/backend_proto/CMakeLists.txt index 701016e60b..6577b87634 100644 --- a/test/module/shared_model/backend_proto/CMakeLists.txt +++ b/test/module/shared_model/backend_proto/CMakeLists.txt @@ -83,5 +83,6 @@ addtest(proto_common_objects_factory_test ) target_link_libraries(proto_common_objects_factory_test shared_model_cryptography + shared_model_stateless_validation schema) diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index 67988be7cf..5b9e529a56 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -3,29 +3,55 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" +#include "cryptography/crypto_provider/crypto_defaults.hpp" #include "framework/result_fixture.hpp" - -#include +#include "validators/field_validator.hpp" using namespace shared_model; using namespace framework::expected; -TEST(PeerTest, ValidPeerInitialization) { - proto::ProtoCommonObjectsFactory factory; +class PeerTest : public ::testing::Test { + public: + std::string valid_address = "127.0.0.1:8080"; + crypto::PublicKey valid_pubkey = + crypto::DefaultCryptoAlgorithmType::generateKeypair().publicKey(); + std::string invalid_address = "127.0.0.1"; +}; - auto peer = factory.createPeer( - "127.0.0.1", - interface::types::PubkeyType( - shared_model::crypto::Blob::fromHexString("1234"))); +/** + * @given valid data for peer + * @when peer is created via factory + * @then peer is successfully initialized + */ +TEST_F(PeerTest, ValidPeerInitialization) { + proto::ProtoCommonObjectsFactory factory; + + auto peer = factory.createPeer(valid_address, valid_pubkey); peer.match( - [](const ValueOf &v) { - ASSERT_EQ(v.value->address(), "127.0.0.1"); - ASSERT_EQ(v.value->pubkey().hex(), "1234"); + [&](const ValueOf &v) { + ASSERT_EQ(v.value->address(), valid_address); + ASSERT_EQ(v.value->pubkey().hex(), valid_pubkey.hex()); }, - [](const ErrorOf &e) { - FAIL(); - } - ); + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid data for peer + * @when peer is created via factory + * @then peer is not initialized correctly + */ +TEST_F(PeerTest, InvalidPeerInitialization) { + proto::ProtoCommonObjectsFactory factory; + + auto keypair = crypto::DefaultCryptoAlgorithmType::generateKeypair(); + + auto peer = factory.createPeer(invalid_address, keypair.publicKey()); + + peer.match( + [](const ValueOf &v) { FAIL() << "Expected error case"; }, + [](const ErrorOf &e) { SUCCEED(); }); } From 781cb39a439fe3b2d57f9bd27c046288e730feef Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Tue, 10 Jul 2018 15:12:15 +0300 Subject: [PATCH 04/17] Add account creation to factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 35 +++++++++++++- .../common_objects/common_objects_factory.hpp | 16 +++++-- .../proto_common_objects_factory_test.cpp | 47 +++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index b366248dd7..aa67f4188f 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -6,6 +6,7 @@ #ifndef IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP #define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP +#include "backend/protobuf/common_objects/account.hpp" #include "backend/protobuf/common_objects/peer.hpp" #include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" @@ -28,7 +29,7 @@ namespace shared_model { shared_model::validation::Answer answer; validation::ReasonsGroupType reasons; - this->validator_.validatePeer(reasons, *proto_peer); + validator_.validatePeer(reasons, *proto_peer); if (not reasons.second.empty()) { answer.addReason(std::move(reasons)); @@ -42,6 +43,38 @@ namespace shared_model { std::move(proto_peer)); } + FactoryResult> createAccount( + const interface::types::AccountIdType &account_id, + const interface::types::DomainIdType &domain_id, + interface::types::QuorumType quorum, + const interface::types::JsonType &jsonData) override { + iroha::protocol::Account account; + account.set_account_id(account_id); + account.set_domain_id(domain_id); + account.set_quorum(quorum); + account.set_json_data(jsonData); + + auto proto_account = std::make_unique(std::move(account)); + + shared_model::validation::Answer answer; + + validation::ReasonsGroupType reasons; + validator_.validateAccountId(reasons, account_id); + validator_.validateDomainId(reasons, domain_id); + validator_.validateQuorum(reasons, quorum); + + if (not reasons.second.empty()) { + answer.addReason(std::move(reasons)); + } + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + + return iroha::expected::makeValue>( + std::move(proto_account)); + } + private: Validator validator_; }; diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index de92499fb6..e8a34f90f7 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -8,9 +8,10 @@ #include +#include "common/result.hpp" +#include "interfaces/common_objects/account.hpp" #include "interfaces/common_objects/peer.hpp" #include "interfaces/common_objects/types.hpp" -#include "common/result.hpp" namespace shared_model { namespace interface { @@ -22,15 +23,22 @@ namespace shared_model { public: template using FactoryResult = iroha::expected::Result; + /** - * Creates peer instance - * @param address - ip address of the peer - * @param public_key - public key of the peer + * Create peer instance */ virtual FactoryResult> createPeer( const types::AddressType &address, const types::PubkeyType &public_key) = 0; + /** + * Create account instance + */ + virtual FactoryResult> createAccount( + const types::AccountIdType &account_id, + const types::DomainIdType &domain_id, + types::QuorumType quorum, const types::JsonType &jsonData) = 0; + virtual ~CommonObjectsFactory() = default; }; } // namespace interface diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index 5b9e529a56..18e970a9fb 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -55,3 +55,50 @@ TEST_F(PeerTest, InvalidPeerInitialization) { [](const ValueOf &v) { FAIL() << "Expected error case"; }, [](const ErrorOf &e) { SUCCEED(); }); } + +class AccountTest : public ::testing::Test { + public: + interface::types::AccountIdType valid_account_id = "hello@world"; + interface::types::DomainIdType valid_domain_id = "bit.connect"; + interface::types::QuorumType valid_quorum = 1; + interface::types::JsonType valid_json = R"({"name": "json" })"; + + interface::types::AccountIdType invalid_account_id = "hello123"; +}; + +/** + * @given valid data for account + * @when account is created via factory + * @then account is successfully initialized + */ +TEST_F(AccountTest, ValidAccountInitialization) { + proto::ProtoCommonObjectsFactory factory; + + auto account = factory.createAccount( + valid_account_id, valid_domain_id, valid_quorum, valid_json); + + account.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->accountId(), valid_account_id); + ASSERT_EQ(v.value->domainId(), valid_domain_id); + ASSERT_EQ(v.value->quorum(), valid_quorum); + ASSERT_EQ(v.value->jsonData(), valid_json); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given valid data for account + * @when account is created via factory + * @then account is successfully initialized + */ +TEST_F(AccountTest, InvalidAccountInitialization) { + proto::ProtoCommonObjectsFactory factory; + + auto account = factory.createAccount( + invalid_account_id, valid_domain_id, valid_quorum, valid_json); + + account.match( + [](const ValueOf &v) { FAIL() << "Expected error case"; }, + [](const ErrorOf &e) { SUCCEED(); }); +} From 961fe118300ad4c882efa93ea46e45aebb32eb78 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 11 Jul 2018 14:49:58 +0300 Subject: [PATCH 05/17] Add account asset creation to factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 39 ++++++++++- .../common_objects/common_objects_factory.hpp | 11 +++- .../proto_common_objects_factory_test.cpp | 66 +++++++++++++++---- 3 files changed, 100 insertions(+), 16 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index aa67f4188f..350e9e1445 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -7,6 +7,7 @@ #define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP #include "backend/protobuf/common_objects/account.hpp" +#include "backend/protobuf/common_objects/account_asset.hpp" #include "backend/protobuf/common_objects/peer.hpp" #include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" @@ -59,9 +60,9 @@ namespace shared_model { shared_model::validation::Answer answer; validation::ReasonsGroupType reasons; - validator_.validateAccountId(reasons, account_id); - validator_.validateDomainId(reasons, domain_id); - validator_.validateQuorum(reasons, quorum); + validator_.validateAccountId(reasons, proto_account->accountId()); + validator_.validateDomainId(reasons, proto_account->domainId()); + validator_.validateQuorum(reasons, proto_account->quorum()); if (not reasons.second.empty()) { answer.addReason(std::move(reasons)); @@ -75,6 +76,38 @@ namespace shared_model { std::move(proto_account)); } + FactoryResult> + createAccountAsset(const interface::types::AccountIdType &account_id, + const interface::types::AssetIdType &asset_id, + const interface::Amount &balance) override { + iroha::protocol::AccountAsset asset; + asset.set_account_id(account_id); + asset.set_asset_id(asset_id); + auto proto_balance = asset.mutable_balance(); + convertToProtoAmount(*proto_balance->mutable_value(), + balance.intValue()); + proto_balance->set_precision(balance.precision()); + + auto proto_asset = std::make_unique(std::move(asset)); + + shared_model::validation::Answer answer; + + validation::ReasonsGroupType reasons; + validator_.validateAccountId(reasons, proto_asset->accountId()); + validator_.validateAssetId(reasons, proto_asset->assetId()); + + if (not reasons.second.empty()) { + answer.addReason(std::move(reasons)); + } + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + + return iroha::expected::makeValue< + std::unique_ptr>(std::move(proto_asset)); + } + private: Validator validator_; }; diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index e8a34f90f7..857c373949 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -37,7 +37,16 @@ namespace shared_model { virtual FactoryResult> createAccount( const types::AccountIdType &account_id, const types::DomainIdType &domain_id, - types::QuorumType quorum, const types::JsonType &jsonData) = 0; + types::QuorumType quorum, + const types::JsonType &jsonData) = 0; + + /** + * Create account asset instance + */ + virtual FactoryResult> createAccountAsset( + const types::AccountIdType &account_id, + const types::AssetIdType &asset_id, + const Amount &balance) = 0; virtual ~CommonObjectsFactory() = default; }; diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index 18e970a9fb..a90be9d262 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -5,7 +5,9 @@ #include +#include "backend/protobuf/common_objects/amount.hpp" #include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" +#include "builders/default_builders.hpp" #include "cryptography/crypto_provider/crypto_defaults.hpp" #include "framework/result_fixture.hpp" #include "validators/field_validator.hpp" @@ -13,6 +15,8 @@ using namespace shared_model; using namespace framework::expected; +proto::ProtoCommonObjectsFactory factory; + class PeerTest : public ::testing::Test { public: std::string valid_address = "127.0.0.1:8080"; @@ -27,8 +31,6 @@ class PeerTest : public ::testing::Test { * @then peer is successfully initialized */ TEST_F(PeerTest, ValidPeerInitialization) { - proto::ProtoCommonObjectsFactory factory; - auto peer = factory.createPeer(valid_address, valid_pubkey); peer.match( @@ -45,8 +47,6 @@ TEST_F(PeerTest, ValidPeerInitialization) { * @then peer is not initialized correctly */ TEST_F(PeerTest, InvalidPeerInitialization) { - proto::ProtoCommonObjectsFactory factory; - auto keypair = crypto::DefaultCryptoAlgorithmType::generateKeypair(); auto peer = factory.createPeer(invalid_address, keypair.publicKey()); @@ -69,11 +69,9 @@ class AccountTest : public ::testing::Test { /** * @given valid data for account * @when account is created via factory - * @then account is successfully initialized + * @then peer is successfully initialized */ TEST_F(AccountTest, ValidAccountInitialization) { - proto::ProtoCommonObjectsFactory factory; - auto account = factory.createAccount( valid_account_id, valid_domain_id, valid_quorum, valid_json); @@ -88,17 +86,61 @@ TEST_F(AccountTest, ValidAccountInitialization) { } /** - * @given valid data for account + * @given invalid data for account * @when account is created via factory - * @then account is successfully initialized + * @then account is not initialized correctly */ TEST_F(AccountTest, InvalidAccountInitialization) { - proto::ProtoCommonObjectsFactory factory; - auto account = factory.createAccount( invalid_account_id, valid_domain_id, valid_quorum, valid_json); account.match( - [](const ValueOf &v) { FAIL() << "Expected error case"; }, + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, [](const ErrorOf &e) { SUCCEED(); }); } + +class AccountAssetTest : public ::testing::Test { + public: + interface::types::AccountIdType valid_account_id = "hello@world"; + interface::types::AssetIdType valid_asset_id = "bit#connect"; + std::shared_ptr valid_amount = + val(builder::DefaultAmountBuilder::fromString("10.00"))->value; + + interface::types::AccountIdType invalid_account_id = "hello123"; +}; + +/** + * @given valid data for account asset + * @when account asset is created via factory + * @then account asset is successfully initialized + */ +TEST_F(AccountAssetTest, ValidAccountAssetInitialization) { + auto account_asset = factory.createAccountAsset( + valid_account_id, valid_asset_id, *valid_amount); + + account_asset.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->accountId(), valid_account_id); + ASSERT_EQ(v.value->assetId(), valid_asset_id); + ASSERT_EQ(v.value->balance(), *valid_amount); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid data for account asset + * @when account asset is created via factory + * @then account asset is not initialized correctly + */ +TEST_F(AccountAssetTest, InvalidAccountAssetInitialization) { + auto account_asset = factory.createAccountAsset( + invalid_account_id, valid_asset_id, *valid_amount); + + account_asset.match( + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, + [](const ErrorOf &e) { SUCCEED(); }); +} From a75f7fc51e4ee007eb78e0b88807f73ce23a88aa Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 11 Jul 2018 15:45:14 +0300 Subject: [PATCH 06/17] Add amount creation to factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 81 +++++++++++++------ .../common_objects/common_objects_factory.hpp | 10 +++ .../proto_common_objects_factory_test.cpp | 22 +++++ 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 350e9e1445..8a36478215 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -27,14 +27,10 @@ namespace shared_model { peer.set_peer_key(crypto::toBinaryString(public_key)); auto proto_peer = std::make_unique(std::move(peer)); - shared_model::validation::Answer answer; - - validation::ReasonsGroupType reasons; - validator_.validatePeer(reasons, *proto_peer); - - if (not reasons.second.empty()) { - answer.addReason(std::move(reasons)); - } + auto answer = + validate(*proto_peer, [this](const auto &peer, auto &reasons) { + validator_.validatePeer(reasons, peer); + }); if (answer) { return iroha::expected::makeError(answer.reason()); @@ -57,16 +53,12 @@ namespace shared_model { auto proto_account = std::make_unique(std::move(account)); - shared_model::validation::Answer answer; - - validation::ReasonsGroupType reasons; - validator_.validateAccountId(reasons, proto_account->accountId()); - validator_.validateDomainId(reasons, proto_account->domainId()); - validator_.validateQuorum(reasons, proto_account->quorum()); - - if (not reasons.second.empty()) { - answer.addReason(std::move(reasons)); - } + auto answer = validate( + *proto_account, [this](const auto &account, auto &reasons) { + validator_.validateAccountId(reasons, account.accountId()); + validator_.validateDomainId(reasons, account.domainId()); + validator_.validateQuorum(reasons, account.quorum()); + }); if (answer) { return iroha::expected::makeError(answer.reason()); @@ -90,25 +82,62 @@ namespace shared_model { auto proto_asset = std::make_unique(std::move(asset)); - shared_model::validation::Answer answer; - - validation::ReasonsGroupType reasons; - validator_.validateAccountId(reasons, proto_asset->accountId()); - validator_.validateAssetId(reasons, proto_asset->assetId()); + auto answer = + validate(*proto_asset, [this](const auto &asset, auto &reasons) { + validator_.validateAccountId(reasons, asset.accountId()); + validator_.validateAssetId(reasons, asset.assetId()); + }); - if (not reasons.second.empty()) { - answer.addReason(std::move(reasons)); + if (answer) { + return iroha::expected::makeError(answer.reason()); } + return iroha::expected::makeValue< + std::unique_ptr>(std::move(proto_asset)); + } + + FactoryResult> createAmount( + boost::multiprecision::uint256_t value, + interface::types::PrecisionType precision) override { + iroha::protocol::Amount amount; + amount.set_precision(precision); + convertToProtoAmount(*amount.mutable_value(), value); + + auto proto_amount = std::make_unique(std::move(amount)); + + auto answer = + validate(*proto_amount, [](const auto &, auto &) { + // no validation needed, + // since any amount is valid in general context + }); + if (answer) { return iroha::expected::makeError(answer.reason()); } return iroha::expected::makeValue< - std::unique_ptr>(std::move(proto_asset)); + std::unique_ptr>(std::move(proto_amount)); } private: + /** + * Perform validation of a given object + * @param o - object to be validated + * @param f - function which populates reason parameter with errors. + * second parameter (reasons) must be passed by non-const reference + * @return validation result + */ + template + validation::Answer validate(const T &o, ValidationFunc &&f) const { + shared_model::validation::Answer answer; + validation::ReasonsGroupType reasons; + f(o, reasons); + if (not reasons.second.empty()) { + answer.addReason(std::move(reasons)); + } + return answer; + } + Validator validator_; }; } // namespace proto diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 857c373949..8392a1ba7a 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -48,6 +48,16 @@ namespace shared_model { const types::AssetIdType &asset_id, const Amount &balance) = 0; + /** + * Create amount instance + * + * @param value integer will be divided by 10 * precision, + * so value 123 with precision 2 will become Amount of 1.23 + */ + virtual FactoryResult> createAmount( + boost::multiprecision::uint256_t value, + types::PrecisionType precision) = 0; + virtual ~CommonObjectsFactory() = default; }; } // namespace interface diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index a90be9d262..e5dcf36360 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -144,3 +144,25 @@ TEST_F(AccountAssetTest, InvalidAccountAssetInitialization) { }, [](const ErrorOf &e) { SUCCEED(); }); } + +class AmountTest : public ::testing::Test { + public: + boost::multiprecision::uint256_t valid_value = 123; + interface::types::PrecisionType valid_precision = 2; +}; + +/** + * @given valid data for amount + * @when amount is created via factory + * @then amount is successfully initialized + */ +TEST_F(AmountTest, ValidAccountAssetInitialization) { + auto amount = factory.createAmount(valid_value, valid_precision); + + amount.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->intValue(), valid_value); + ASSERT_EQ(v.value->precision(), valid_precision); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} From 48b760571b6b6e0d41b05239617c84ae6280672f Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 11 Jul 2018 19:17:33 +0300 Subject: [PATCH 07/17] Add asset and domain creation to factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 92 +++++++++++++- .../common_objects/common_objects_factory.hpp | 27 +++- .../proto_common_objects_factory_test.cpp | 120 +++++++++++++++++- 3 files changed, 232 insertions(+), 7 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 8a36478215..8404d30694 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -6,9 +6,13 @@ #ifndef IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP #define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP +#include + #include "backend/protobuf/common_objects/account.hpp" #include "backend/protobuf/common_objects/account_asset.hpp" +#include "backend/protobuf/common_objects/asset.hpp" #include "backend/protobuf/common_objects/peer.hpp" +#include "backend/protobuf/common_objects/domain.hpp" #include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" #include "primitive.pb.h" @@ -105,18 +109,96 @@ namespace shared_model { auto proto_amount = std::make_unique(std::move(amount)); + auto answer = validate(*proto_amount, [](const auto &, auto &) { + // no validation needed, + // since any amount is valid in general context + }); + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + + return iroha::expected::makeValue>( + std::move(proto_amount)); + } + + FactoryResult> createAmount( + std::string amount) override { + // taken from iroha::model::Amount + // check if valid number + const static std::regex e("([0-9]*\\.[0-9]+|[0-9]+)"); + if (!std::regex_match(amount, e)) { + return iroha::expected::makeError("number string is invalid"); + } + + // get precision + auto dot_place = amount.find('.'); + interface::types::PrecisionType precision; + if (dot_place > amount.size()) { + precision = 0; + } else { + precision = amount.size() - dot_place - 1; + // erase dot from the string + amount.erase(std::remove(amount.begin(), amount.end(), '.'), + amount.end()); + } + + auto begin = amount.find_first_not_of('0'); + + // create uint256 value from obtained string + boost::multiprecision::uint256_t value = 0; + if (begin <= amount.size()) { + value = boost::multiprecision::uint256_t(amount.substr(begin)); + } + + return createAmount(value, precision); + } + + FactoryResult> createAsset( + const interface::types::AssetIdType &asset_id, + const interface::types::DomainIdType &domain_id, + interface::types::PrecisionType precision) override { + iroha::protocol::Asset asset; + asset.set_asset_id(asset_id); + asset.set_domain_id(domain_id); + asset.set_precision(precision); + + auto proto_asset = std::make_unique(std::move(asset)); + auto answer = - validate(*proto_amount, [](const auto &, auto &) { - // no validation needed, - // since any amount is valid in general context + validate(*proto_asset, [this](const auto &asset, auto &reasons) { + validator_.validateAssetId(reasons, asset.assetId()); + validator_.validateDomainId(reasons, asset.domainId()); }); if (answer) { return iroha::expected::makeError(answer.reason()); } - return iroha::expected::makeValue< - std::unique_ptr>(std::move(proto_amount)); + return iroha::expected::makeValue>( + std::move(proto_asset)); + } + + FactoryResult> createDomain( + const interface::types::DomainIdType &domain_id, + const interface::types::RoleIdType &default_role) override { + iroha::protocol::Domain domain; + domain.set_domain_id(domain_id); + domain.set_default_role(default_role); + + auto proto_domain = std::make_unique(std::move(domain)); + + auto answer = validate(*proto_domain, [this](const auto &domain, auto &reason) { + validator_.validateDomainId(reason, domain.domainId()); + validator_.validateRoleId(reason, domain.defaultRole()); + }); + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + + return iroha::expected::makeValue>( + std::move(proto_domain)); } private: diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 8392a1ba7a..0755d459ce 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -12,6 +12,7 @@ #include "interfaces/common_objects/account.hpp" #include "interfaces/common_objects/peer.hpp" #include "interfaces/common_objects/types.hpp" +#include "interfaces/common_objects/domain.hpp" namespace shared_model { namespace interface { @@ -49,7 +50,7 @@ namespace shared_model { const Amount &balance) = 0; /** - * Create amount instance + * Create amount instance from string * * @param value integer will be divided by 10 * precision, * so value 123 with precision 2 will become Amount of 1.23 @@ -58,6 +59,30 @@ namespace shared_model { boost::multiprecision::uint256_t value, types::PrecisionType precision) = 0; + /** + * Create amount instance from string + * + * @param value must represent valid number. + * For example: "1.23", "10" etc. + */ + virtual FactoryResult> createAmount( + std::string amount) = 0; + + /** + * Create asset instance + */ + virtual FactoryResult> createAsset( + const types::AssetIdType &asset_id, + const types::DomainIdType &domain_id, + types::PrecisionType precision) = 0; + + /** + * Create domain instance + */ + virtual FactoryResult> createDomain( + const types::DomainIdType &domain_id, + const types::RoleIdType &default_role) = 0; + virtual ~CommonObjectsFactory() = default; }; } // namespace interface diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index e5dcf36360..31e0dc7b51 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -149,6 +149,9 @@ class AmountTest : public ::testing::Test { public: boost::multiprecision::uint256_t valid_value = 123; interface::types::PrecisionType valid_precision = 2; + + std::string valid_amount_str = "1.23"; + std::string invalid_amount_str = "hello there"; }; /** @@ -156,7 +159,7 @@ class AmountTest : public ::testing::Test { * @when amount is created via factory * @then amount is successfully initialized */ -TEST_F(AmountTest, ValidAccountAssetInitialization) { +TEST_F(AmountTest, ValidAmountInitialization) { auto amount = factory.createAmount(valid_value, valid_precision); amount.match( @@ -166,3 +169,118 @@ TEST_F(AmountTest, ValidAccountAssetInitialization) { }, [](const ErrorOf &e) { FAIL() << e.error; }); } + +/** + * @given valid string for amount + * @when amount is created via factory + * @then amount is successfully initialized + */ +TEST_F(AmountTest, ValidStringAmountInitialization) { + auto amount = factory.createAmount(valid_amount_str); + + amount.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->intValue(), valid_value); + ASSERT_EQ(v.value->precision(), valid_precision); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid string for amount + * @when amount is created via factory + * @then amount is not initialized correctly + */ +TEST_F(AmountTest, InvalidStringAmountInitialization) { + auto amount = factory.createAmount(invalid_amount_str); + + amount.match( + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, + [](const ErrorOf &e) { SUCCEED(); }); +} + +class AssetTest : public ::testing::Test { + public: + interface::types::AssetIdType valid_asset_id = "bit#connect"; + interface::types::DomainIdType valid_domain_id = "iroha.com"; + interface::types::PrecisionType valid_precision = 2; + + interface::types::AssetIdType invalid_asset_id = "bit"; +}; + +/** + * @given valid data for asset + * @when asset is created via factory + * @then asset is successfully initialized + */ +TEST_F(AssetTest, ValidAssetInitialization) { + auto asset = + factory.createAsset(valid_asset_id, valid_domain_id, valid_precision); + + asset.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->assetId(), valid_asset_id); + ASSERT_EQ(v.value->domainId(), valid_domain_id); + ASSERT_EQ(v.value->precision(), valid_precision); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid data for asset + * @when asset is created via factory + * @then asset is not initialized correctly + */ +TEST_F(AssetTest, InvalidAssetInitialization) { + auto asset = + factory.createAsset(invalid_asset_id, valid_domain_id, valid_precision); + + asset.match( + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, + [](const ErrorOf &e) { SUCCEED(); }); +} + +class DomainTest : public ::testing::Test { + public: + interface::types::DomainIdType valid_domain_id = "iroha.com"; + interface::types::RoleIdType valid_role_id = "admin"; + + interface::types::DomainIdType invalid_domain_id = "123irohacom"; +}; + +/** + * @given valid data for domain + * @when domain is created via factory + * @then domain is successfully initialized + */ +TEST_F(DomainTest, ValidDomainInitialization) { + auto domain = + factory.createDomain(valid_domain_id, valid_role_id); + + domain.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->domainId(), valid_domain_id); + ASSERT_EQ(v.value->defaultRole(), valid_role_id); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid data for domain + * @when domain is created via factory + * @then domain is not initialized correctly + */ +TEST_F(DomainTest, InvalidDomainInitialization) { + auto domain = + factory.createDomain(invalid_domain_id, valid_role_id); + + domain.match( + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, + [](const ErrorOf &e) { SUCCEED(); }); +} From 34a11ab3ed81439efa497234fa1cf4fa2952e71b Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 11 Jul 2018 19:41:39 +0300 Subject: [PATCH 08/17] Add signature creation to factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 35 ++++++++++++-- .../common_objects/common_objects_factory.hpp | 7 +++ .../proto_common_objects_factory_test.cpp | 46 +++++++++++++++++-- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 8404d30694..ed0de03549 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -11,8 +11,9 @@ #include "backend/protobuf/common_objects/account.hpp" #include "backend/protobuf/common_objects/account_asset.hpp" #include "backend/protobuf/common_objects/asset.hpp" -#include "backend/protobuf/common_objects/peer.hpp" #include "backend/protobuf/common_objects/domain.hpp" +#include "backend/protobuf/common_objects/peer.hpp" +#include "backend/protobuf/common_objects/signature.hpp" #include "common/result.hpp" #include "interfaces/common_objects/common_objects_factory.hpp" #include "primitive.pb.h" @@ -188,10 +189,11 @@ namespace shared_model { auto proto_domain = std::make_unique(std::move(domain)); - auto answer = validate(*proto_domain, [this](const auto &domain, auto &reason) { - validator_.validateDomainId(reason, domain.domainId()); - validator_.validateRoleId(reason, domain.defaultRole()); - }); + auto answer = + validate(*proto_domain, [this](const auto &domain, auto &reason) { + validator_.validateDomainId(reason, domain.domainId()); + validator_.validateRoleId(reason, domain.defaultRole()); + }); if (answer) { return iroha::expected::makeError(answer.reason()); @@ -201,6 +203,29 @@ namespace shared_model { std::move(proto_domain)); } + FactoryResult> createSignature( + const interface::types::PubkeyType &key, + const interface::Signature::SignedType &signed_data) override { + iroha::protocol::Signature signature; + signature.set_pubkey(crypto::toBinaryString(key)); + signature.set_signature(crypto::toBinaryString(signed_data)); + + auto proto_singature = + std::make_unique(std::move(signature)); + + auto answer = validate( + *proto_singature, [this](const auto &signature, auto &reason) { + validator_.validatePubkey(reason, signature.publicKey()); + }); + + if (answer) { + return iroha::expected::makeError(answer.reason()); + } + + return iroha::expected::makeValue< + std::unique_ptr>(std::move(proto_singature)); + } + private: /** * Perform validation of a given object diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 0755d459ce..e79b3cc21b 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -83,6 +83,13 @@ namespace shared_model { const types::DomainIdType &domain_id, const types::RoleIdType &default_role) = 0; + /** + * Create signature instance + */ + virtual FactoryResult> createSignature( + const interface::types::PubkeyType &key, + const interface::Signature::SignedType &signed_data) = 0; + virtual ~CommonObjectsFactory() = default; }; } // namespace interface diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index 31e0dc7b51..b4bec207e4 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -4,6 +4,7 @@ */ #include +#include #include "backend/protobuf/common_objects/amount.hpp" #include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" @@ -47,9 +48,7 @@ TEST_F(PeerTest, ValidPeerInitialization) { * @then peer is not initialized correctly */ TEST_F(PeerTest, InvalidPeerInitialization) { - auto keypair = crypto::DefaultCryptoAlgorithmType::generateKeypair(); - - auto peer = factory.createPeer(invalid_address, keypair.publicKey()); + auto peer = factory.createPeer(invalid_address, valid_pubkey); peer.match( [](const ValueOf &v) { FAIL() << "Expected error case"; }, @@ -284,3 +283,44 @@ TEST_F(DomainTest, InvalidDomainInitialization) { }, [](const ErrorOf &e) { SUCCEED(); }); } + +class SignatureTest : public ::testing::Test { + public: + crypto::PublicKey valid_pubkey = + crypto::DefaultCryptoAlgorithmType::generateKeypair().publicKey(); + crypto::Signed valid_data{"hello"}; + crypto::PublicKey invalid_pubkey{"1234"}; +}; + +/** + * @given valid data for signature + * @when signature is created via factory + * @then signature is successfully initialized + */ +TEST_F(SignatureTest, ValidSignatureInitialization) { + auto signature = + factory.createSignature(valid_pubkey, valid_data); + + signature.match( + [&](const ValueOf &v) { + ASSERT_EQ(v.value->publicKey().hex(), valid_pubkey.hex()); + ASSERT_EQ(v.value->signedData().hex(), valid_data.hex()); + }, + [](const ErrorOf &e) { FAIL() << e.error; }); +} + +/** + * @given invalid data for signature + * @when signature is created via factory + * @then signature is not initialized correctly + */ +TEST_F(SignatureTest, InvalidSignatureInitialization) { + auto signature = + factory.createSignature(invalid_pubkey, valid_data); + + signature.match( + [](const ValueOf &v) { + FAIL() << "Expected error case"; + }, + [](const ErrorOf &e) { SUCCEED(); }); +} From 2f30e41f617f2dab931b564da5f8596d9cf511dd Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Thu, 12 Jul 2018 11:17:55 +0300 Subject: [PATCH 09/17] Add comments Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../common_objects/proto_common_objects_factory.hpp | 6 ++++++ .../interfaces/common_objects/common_objects_factory.hpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index ed0de03549..3776f445c3 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -21,6 +21,12 @@ namespace shared_model { namespace proto { + + /** + * ProtoCommonObjectsFactory constructs protobuf-based objects. + * It performs stateful validation with provided validator + * @tparam Validator + */ template class ProtoCommonObjectsFactory : public interface::CommonObjectsFactory { public: diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index e79b3cc21b..5f8e6a8f84 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -62,7 +62,7 @@ namespace shared_model { /** * Create amount instance from string * - * @param value must represent valid number. + * @param amount must represent valid number. * For example: "1.23", "10" etc. */ virtual FactoryResult> createAmount( From e40cb100a6c8fbf3b5de50870397456f31d1e6e9 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Thu, 12 Jul 2018 13:27:00 +0300 Subject: [PATCH 10/17] Fix review issues Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../proto_common_objects_factory.hpp | 49 +++++++++---------- .../common_objects/common_objects_factory.hpp | 2 +- .../shared_model/backend_proto/CMakeLists.txt | 4 +- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 3776f445c3..bdc5820cef 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -21,7 +21,6 @@ namespace shared_model { namespace proto { - /** * ProtoCommonObjectsFactory constructs protobuf-based objects. * It performs stateful validation with provided validator @@ -38,13 +37,13 @@ namespace shared_model { peer.set_peer_key(crypto::toBinaryString(public_key)); auto proto_peer = std::make_unique(std::move(peer)); - auto answer = + auto errors = validate(*proto_peer, [this](const auto &peer, auto &reasons) { validator_.validatePeer(reasons, peer); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue>( @@ -64,15 +63,15 @@ namespace shared_model { auto proto_account = std::make_unique(std::move(account)); - auto answer = validate( + auto errors = validate( *proto_account, [this](const auto &account, auto &reasons) { validator_.validateAccountId(reasons, account.accountId()); validator_.validateDomainId(reasons, account.domainId()); validator_.validateQuorum(reasons, account.quorum()); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue>( @@ -93,14 +92,14 @@ namespace shared_model { auto proto_asset = std::make_unique(std::move(asset)); - auto answer = + auto errors = validate(*proto_asset, [this](const auto &asset, auto &reasons) { validator_.validateAccountId(reasons, asset.accountId()); validator_.validateAssetId(reasons, asset.assetId()); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue< @@ -116,13 +115,13 @@ namespace shared_model { auto proto_amount = std::make_unique(std::move(amount)); - auto answer = validate(*proto_amount, [](const auto &, auto &) { + auto errors = validate(*proto_amount, [](const auto &, auto &) { // no validation needed, // since any amount is valid in general context }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue>( @@ -172,14 +171,14 @@ namespace shared_model { auto proto_asset = std::make_unique(std::move(asset)); - auto answer = + auto errors = validate(*proto_asset, [this](const auto &asset, auto &reasons) { validator_.validateAssetId(reasons, asset.assetId()); validator_.validateDomainId(reasons, asset.domainId()); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue>( @@ -195,14 +194,14 @@ namespace shared_model { auto proto_domain = std::make_unique(std::move(domain)); - auto answer = + auto errors = validate(*proto_domain, [this](const auto &domain, auto &reason) { validator_.validateDomainId(reason, domain.domainId()); validator_.validateRoleId(reason, domain.defaultRole()); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue>( @@ -219,13 +218,13 @@ namespace shared_model { auto proto_singature = std::make_unique(std::move(signature)); - auto answer = validate( + auto errors = validate( *proto_singature, [this](const auto &signature, auto &reason) { validator_.validatePubkey(reason, signature.publicKey()); }); - if (answer) { - return iroha::expected::makeError(answer.reason()); + if (errors) { + return iroha::expected::makeError(errors.reason()); } return iroha::expected::makeValue< @@ -242,13 +241,13 @@ namespace shared_model { */ template validation::Answer validate(const T &o, ValidationFunc &&f) const { - shared_model::validation::Answer answer; + shared_model::validation::Answer errors; validation::ReasonsGroupType reasons; f(o, reasons); if (not reasons.second.empty()) { - answer.addReason(std::move(reasons)); + errors.addReason(std::move(reasons)); } - return answer; + return errors; } Validator validator_; diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 5f8e6a8f84..0ba8d96cfd 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -17,7 +17,7 @@ namespace shared_model { namespace interface { /** - * CommonObjectsFactory provides methods to construct simple objects + * CommonObjectsFactory provides methods to construct common objects * such as peer, account etc. */ class CommonObjectsFactory { diff --git a/test/module/shared_model/backend_proto/CMakeLists.txt b/test/module/shared_model/backend_proto/CMakeLists.txt index 6577b87634..5a8fa505ae 100644 --- a/test/module/shared_model/backend_proto/CMakeLists.txt +++ b/test/module/shared_model/backend_proto/CMakeLists.txt @@ -84,5 +84,5 @@ addtest(proto_common_objects_factory_test target_link_libraries(proto_common_objects_factory_test shared_model_cryptography shared_model_stateless_validation - schema) - + schema + ) From 8a73c247c71dc0a229433f9647d207b0efd066ae Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Thu, 12 Jul 2018 18:41:43 +0300 Subject: [PATCH 11/17] change ametsuchi interfaces for new factory Signed-off-by: Nikita Alekseev # Conflicts: # test/benchmark/CMakeLists.txt # test/benchmark/bm_proto_creation.cpp --- .../ametsuchi/impl/mutable_storage_impl.cpp | 8 +- .../ametsuchi/impl/mutable_storage_impl.hpp | 5 +- .../ametsuchi/impl/postgres_block_query.cpp | 2 +- .../impl/postgres_result_converter.cpp | 6 + .../impl/postgres_result_converter.hpp | 55 ++++++ .../ametsuchi/impl/postgres_wsv_command.cpp | 2 + irohad/ametsuchi/impl/postgres_wsv_common.hpp | 187 ++++++++---------- irohad/ametsuchi/impl/postgres_wsv_query.cpp | 115 ++++++----- irohad/ametsuchi/impl/postgres_wsv_query.hpp | 18 +- irohad/ametsuchi/impl/storage_impl.cpp | 31 +-- irohad/ametsuchi/impl/storage_impl.hpp | 18 +- irohad/ametsuchi/impl/temporary_wsv_impl.cpp | 8 +- irohad/ametsuchi/impl/temporary_wsv_impl.hpp | 8 +- .../common_objects/common_objects_factory.hpp | 6 +- 14 files changed, 290 insertions(+), 179 deletions(-) create mode 100644 irohad/ametsuchi/impl/postgres_result_converter.cpp create mode 100644 irohad/ametsuchi/impl/postgres_result_converter.hpp diff --git a/irohad/ametsuchi/impl/mutable_storage_impl.cpp b/irohad/ametsuchi/impl/mutable_storage_impl.cpp index 1898653b09..2dbfe1a066 100644 --- a/irohad/ametsuchi/impl/mutable_storage_impl.cpp +++ b/irohad/ametsuchi/impl/mutable_storage_impl.cpp @@ -23,6 +23,7 @@ #include "ametsuchi/impl/postgres_wsv_command.hpp" #include "ametsuchi/impl/postgres_wsv_query.hpp" #include "ametsuchi/wsv_command.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "model/sha3_hash.hpp" namespace iroha { @@ -30,16 +31,17 @@ namespace iroha { MutableStorageImpl::MutableStorageImpl( shared_model::interface::types::HashType top_hash, std::unique_ptr connection, - std::unique_ptr transaction) + std::unique_ptr transaction, + std::shared_ptr factory) : top_hash_(top_hash), connection_(std::move(connection)), transaction_(std::move(transaction)), - wsv_(std::make_unique(*transaction_)), + wsv_(std::make_unique(*transaction_, factory)), executor_(std::make_unique(*transaction_)), block_index_(std::make_unique(*transaction_)), committed(false), log_(logger::log("MutableStorage")) { - auto query = std::make_shared(*transaction_); + auto query = std::make_shared(*transaction_, factory); auto command = std::make_shared(*transaction_); command_executor_ = std::make_shared(CommandExecutor(query, command)); diff --git a/irohad/ametsuchi/impl/mutable_storage_impl.hpp b/irohad/ametsuchi/impl/mutable_storage_impl.hpp index dd65aa9f43..6e4a700684 100644 --- a/irohad/ametsuchi/impl/mutable_storage_impl.hpp +++ b/irohad/ametsuchi/impl/mutable_storage_impl.hpp @@ -24,6 +24,7 @@ #include "ametsuchi/mutable_storage.hpp" #include "execution/command_executor.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "logger/logger.hpp" namespace iroha { @@ -40,7 +41,9 @@ namespace iroha { MutableStorageImpl( shared_model::interface::types::HashType top_hash, std::unique_ptr connection, - std::unique_ptr transaction); + std::unique_ptr transaction, + std::shared_ptr + factory); bool apply( const shared_model::interface::Block &block, diff --git a/irohad/ametsuchi/impl/postgres_block_query.cpp b/irohad/ametsuchi/impl/postgres_block_query.cpp index 079aa466ad..37bb5ca24b 100644 --- a/irohad/ametsuchi/impl/postgres_block_query.cpp +++ b/irohad/ametsuchi/impl/postgres_block_query.cpp @@ -93,7 +93,7 @@ namespace iroha { + transaction_.quote(account_id) + ";") | [&](const auto &result) -> std::vector { - return transform( + return transform( result, [&](const auto &row) { return row.at("height") .template as(); diff --git a/irohad/ametsuchi/impl/postgres_result_converter.cpp b/irohad/ametsuchi/impl/postgres_result_converter.cpp new file mode 100644 index 0000000000..1b747bf23a --- /dev/null +++ b/irohad/ametsuchi/impl/postgres_result_converter.cpp @@ -0,0 +1,6 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "postgres_result_converter.hpp" diff --git a/irohad/ametsuchi/impl/postgres_result_converter.hpp b/irohad/ametsuchi/impl/postgres_result_converter.hpp new file mode 100644 index 0000000000..72e0c790f9 --- /dev/null +++ b/irohad/ametsuchi/impl/postgres_result_converter.hpp @@ -0,0 +1,55 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IROHA_POSTGRES_RESULT_CONVERTER_HPP +#define IROHA_POSTGRES_RESULT_CONVERTER_HPP + +#include "interfaces/common_objects/common_objects_factory.hpp" + +namespace iroha { + namespace ametsuchi { + /** + * This class is used to convert result set obtained from postgres to + * iroha common objects + */ + class PostgresResultConverter { + public: + explicit PostgresResultConverter( + std::shared_ptr + factory) {} + + template + using ConverterResult = + shared_model::interface::CommonObjectsFactory::FactoryResult; + + ConverterResult> + createAccount(const pqxx::row &row); + + ConverterResult> + createAsset(const pqxx::row &row); + + ConverterResult> + createAccountAsset(const pqxx::row &row); + + ConverterResult< + std::vector>> + createAccountAssets(const pqxx::result &result); + + ConverterResult> + createPeer(const pqxx::row &row); + + ConverterResult>> + createPeers(const pqxx::result &result); + + ConverterResult> + createDomain(const pqxx::row &row); + + private: + std::shared_ptr factory_; + }; // namespace ametsuchi + } // namespace ametsuchi +} // namespace iroha + +#endif // IROHA_POSTGRES_RESULT_CONVERTER_HPP diff --git a/irohad/ametsuchi/impl/postgres_wsv_command.cpp b/irohad/ametsuchi/impl/postgres_wsv_command.cpp index 9e89b6ff3a..1dc92fc908 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_command.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_command.cpp @@ -19,6 +19,8 @@ #include #include "backend/protobuf/permissions.hpp" +#include "interfaces/common_objects/asset.hpp" +#include "interfaces/common_objects/account_asset.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_wsv_common.hpp b/irohad/ametsuchi/impl/postgres_wsv_common.hpp index ddc2b2c3f5..6b3e9d985e 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_common.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_common.hpp @@ -22,13 +22,18 @@ #include #include -#include "builders/default_builders.hpp" #include "common/result.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "logger/logger.hpp" namespace iroha { namespace ametsuchi { + template + inline T as(const pqxx::field &field) { + return field.as(); + } + /** * Return function which can execute SQL statements on provided transaction * @param transaction on which to apply statement. @@ -71,17 +76,17 @@ namespace iroha { /** * Transforms pqxx::result to vector of Ts by applying transform_func - * @tparam T - type to transform to - * @tparam Operator - type of transformation function, must return T + * @tparam Operator - type of transformation function * @param result - pqxx::result which contains several rows from the * database - * @param transform_func - function which transforms result row to T - * @return vector of target type + * @param transform_func - function which transforms result row to some type + * @return vector of objects of type returned by transform_func */ - template - std::vector transform(const pqxx::result &result, - Operator &&transform_func) noexcept { - std::vector values; + template + auto transform(const pqxx::result &result, Operator &&transform_func) noexcept { + using ReturnType = decltype(transform_func(*result.begin())); + + std::vector values; values.reserve(result.size()); std::transform(result.begin(), result.end(), @@ -91,87 +96,69 @@ namespace iroha { return values; } - /** - * Execute build function and return error in case it throws - * @tparam T - result value type - * @param f - function which returns BuilderResult - * @return whatever f returns, or error in case exception has been thrown - */ - template - static inline auto tryBuild(BuildFunc &&f) noexcept -> decltype(f()) { - try { - return f(); - } catch (std::exception &e) { - return expected::makeError(std::make_shared(e.what())); - } - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Account> - makeAccount(const pqxx::row &row) noexcept { - return tryBuild([&row] { - return shared_model::builder::DefaultAccountBuilder() - .accountId(row.at("account_id").template as()) - .domainId(row.at("domain_id").template as()) - .quorum( - row.at("quorum") - .template as()) - .jsonData(row.at("data").template as()) - .build(); - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Asset> - makeAsset(const pqxx::row &row) noexcept { - return tryBuild([&row] { - return shared_model::builder::DefaultAssetBuilder() - .assetId(row.at("asset_id").template as()) - .domainId(row.at("domain_id").template as()) - .precision(row.at("precision").template as()) - .build(); - }); - } +// inline shared_model::interface::CommonObjectsFactory::FactoryResult< +// std::unique_ptr> +// makeAccount( +// const pqxx::row &row, +// const shared_model::interface::CommonObjectsFactory &factory) noexcept { +// return factory.createAccount( +// as(row.at("account_id")), +// as(row.at("domain_id")), +// as(row.at("quorum")), +// as(row.at("data"))); +// } - static inline shared_model::builder::BuilderResult< - shared_model::interface::AccountAsset> - makeAccountAsset(const pqxx::row &row) noexcept { - return tryBuild([&row] { - auto balance = shared_model::builder::DefaultAmountBuilder::fromString( - row.at("amount").template as()); - return balance | [&](const auto &balance_ptr) { - return shared_model::builder::DefaultAccountAssetBuilder() - .accountId(row.at("account_id").template as()) - .assetId(row.at("asset_id").template as()) - .balance(*balance_ptr) - .build(); - }; - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Peer> - makePeer(const pqxx::row &row) noexcept { - return tryBuild([&row] { - pqxx::binarystring public_key_str(row.at("public_key")); - shared_model::interface::types::PubkeyType pubkey(public_key_str.str()); - return shared_model::builder::DefaultPeerBuilder() - .pubkey(pubkey) - .address(row.at("address").template as()) - .build(); - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Domain> - makeDomain(const pqxx::row &row) noexcept { - return tryBuild([&row] { - return shared_model::builder::DefaultDomainBuilder() - .domainId(row.at("domain_id").template as()) - .defaultRole(row.at("default_role").template as()) - .build(); - }); - } +// static inline shared_model::builder::BuilderResult< +// shared_model::interface::Asset> +// makeAsset(const pqxx::row &row) noexcept { +// return tryBuild([&row] { +// return shared_model::builder::DefaultAssetBuilder() +// .assetId(row.at("asset_id").template as()) +// .domainId(row.at("domain_id").template as()) +// .precision(row.at("precision").template as()) +// .build(); +// }); +// } +// +// static inline shared_model::builder::BuilderResult< +// shared_model::interface::AccountAsset> +// makeAccountAsset(const pqxx::row &row) noexcept { +// return tryBuild([&row] { +// auto balance = shared_model::builder::DefaultAmountBuilder::fromString( +// row.at("amount").template as()); +// return balance | [&](const auto &balance_ptr) { +// return shared_model::builder::DefaultAccountAssetBuilder() +// .accountId(row.at("account_id").template as()) +// .assetId(row.at("asset_id").template as()) +// .balance(*balance_ptr) +// .build(); +// }; +// }); +// } +// +// static inline shared_model::builder::BuilderResult< +// shared_model::interface::Peer> +// makePeer(const pqxx::row &row) noexcept { +// return tryBuild([&row] { +// pqxx::binarystring public_key_str(row.at("public_key")); +// shared_model::interface::types::PubkeyType pubkey(public_key_str.str()); +// return shared_model::builder::DefaultPeerBuilder() +// .pubkey(pubkey) +// .address(row.at("address").template as()) +// .build(); +// }); +// } +// +// static inline shared_model::builder::BuilderResult< +// shared_model::interface::Domain> +// makeDomain(const pqxx::row &row) noexcept { +// return tryBuild([&row] { +// return shared_model::builder::DefaultDomainBuilder() +// .domainId(row.at("domain_id").template as()) +// .defaultRole(row.at("default_role").template as()) +// .build(); +// }); +// } /** * Transforms result to optional @@ -181,18 +168,16 @@ namespace iroha { * @param result BuilderResult * @return optional */ - template - static inline boost::optional> fromResult( - const shared_model::builder::BuilderResult &result) { - return result.match( - [](const expected::Value> &v) { - return boost::make_optional(v.value); - }, - [](const expected::Error> &e) - -> boost::optional> { - return boost::none; - }); - } +// template +// static inline boost::optional> fromResult( +// const shared_model::builder::BuilderResult &result) { +// return result.match( +// [](const expected::Value> &v) { +// return boost::make_optional(v.value); +// }, +// [](const expected::Error> &e) +// -> boost::optional> { return boost::none; }); +// } } // namespace ametsuchi } // namespace iroha #endif // IROHA_POSTGRES_WSV_COMMON_HPP diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.cpp b/irohad/ametsuchi/impl/postgres_wsv_query.cpp index 47b1eda0cf..cadaf70f67 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.cpp @@ -17,10 +17,47 @@ #include "ametsuchi/impl/postgres_wsv_query.hpp" #include "backend/protobuf/permissions.hpp" +#include "common/result.hpp" namespace iroha { namespace ametsuchi { + namespace { + template + auto fromResult(PostgresResultConverter::ConverterResult &&result) { + // pointer to put into optional + using ReturnPtr = std::shared_ptr; + + return result.match( + [](expected::Value &v) { + return boost::make_optional(ReturnPtr(std::move(v.value))); + }, + [](const expected::Error &) + -> boost::optional { return boost::none; }); + } + + template + auto fromResults(PostgresResultConverter::ConverterResult &&result) { + // pointer to put into optional + using ReturnPtr = std::shared_ptr; + + return result.match( + [](expected::Value &v) { + std::vector elements; + elements.reserve(v.value.size()); + std::transform(v.value.begin(), + v.value.end(), + std::back_inserter(elements), + [](auto &o) { + return ReturnPtr(std::move(o)); + }); + return boost::make_optional(elements); + }, + [](const expected::Error &) + -> boost::optional> { return boost::none; }); + } + } // namespace + using shared_model::interface::types::AccountIdType; using shared_model::interface::types::AssetIdType; using shared_model::interface::types::DomainIdType; @@ -35,15 +72,20 @@ namespace iroha { const std::string kAccountId = "account_id"; const std::string kDomainId = "domain_id"; - PostgresWsvQuery::PostgresWsvQuery(pqxx::nontransaction &transaction) - : transaction_(transaction), + PostgresWsvQuery::PostgresWsvQuery( + pqxx::nontransaction &transaction, + std::shared_ptr factory) + : converter_(std::make_unique(factory)), + transaction_(transaction), log_(logger::log("PostgresWsvQuery")), execute_{makeExecuteOptional(transaction_, log_)} {} PostgresWsvQuery::PostgresWsvQuery( std::unique_ptr connection, - std::unique_ptr transaction) - : connection_ptr_(std::move(connection)), + std::unique_ptr transaction, + std::shared_ptr factory) + : converter_(std::make_unique(factory)), + connection_ptr_(std::move(connection)), transaction_ptr_(std::move(transaction)), transaction_(*transaction_ptr_), log_(logger::log("PostgresWsvQuery")), @@ -72,8 +114,8 @@ namespace iroha { "SELECT role_id FROM account_has_roles WHERE account_id = " + transaction_.quote(account_id) + ";") | [&](const auto &result) { - return transform(result, [](const auto &row) { - return row.at(kRoleId).c_str(); + return transform(result, [](const auto &row) { + return std::string(row.at(kRoleId).c_str()); }); }; } @@ -81,7 +123,8 @@ namespace iroha { boost::optional PostgresWsvQuery::getRolePermissions(const RoleIdType &role_name) { return execute_( - "SELECT permission FROM role_has_permissions WHERE role_id = " + "SELECT permission FROM role_has_permissions WHERE role_id " + "= " + transaction_.quote(role_name) + ";") | [&](const auto &result) -> boost::optional< @@ -97,8 +140,9 @@ namespace iroha { boost::optional> PostgresWsvQuery::getRoles() { return execute_("SELECT role_id FROM role;") | [&](const auto &result) { - return transform( - result, [](const auto &row) { return row.at(kRoleId).c_str(); }); + return transform(result, [](const auto &row) { + return std::string(row.at(kRoleId).c_str()); + }); }; } @@ -106,7 +150,7 @@ namespace iroha { PostgresWsvQuery::getAccount(const AccountIdType &account_id) { return execute_("SELECT * FROM account WHERE account_id = " + transaction_.quote(account_id) + ";") - | [&](const auto &result) + | [&](auto &result) -> boost::optional< std::shared_ptr> { if (result.empty()) { @@ -114,7 +158,7 @@ namespace iroha { return boost::none; } - return fromResult(makeAccount(result.at(0))); + return fromResult(converter_->createAccount(result.at(0))); }; } @@ -147,7 +191,7 @@ namespace iroha { "account_id = " + transaction_.quote(account_id) + ";") | [&](const auto &result) { - return transform(result, [&](const auto &row) { + return transform(result, [&](const auto &row) { pqxx::binarystring public_key_str(row.at(kPublicKey)); return PubkeyType(public_key_str.str()); }); @@ -159,14 +203,14 @@ namespace iroha { pqxx::result result; return execute_("SELECT * FROM asset WHERE asset_id = " + transaction_.quote(asset_id) + ";") - | [&](const auto &result) + | [&]( auto &result) -> boost::optional< std::shared_ptr> { if (result.empty()) { log_->info("Asset {} not found", asset_id); return boost::none; } - return fromResult(makeAsset(result.at(0))); + return fromResult(converter_->createAsset(result.at(0))); }; } @@ -175,24 +219,10 @@ namespace iroha { PostgresWsvQuery::getAccountAssets(const AccountIdType &account_id) { return execute_("SELECT * FROM account_has_asset WHERE account_id = " + transaction_.quote(account_id) + ";") - | [&](const auto &result) + | [&](auto &result) -> boost::optional>> { - auto results = transform>(result, makeAccountAsset); - std::vector> - assets; - for (auto &r : results) { - r.match( - [&](expected::Value< - std::shared_ptr> &v) { - assets.push_back(v.value); - }, - [&](expected::Error> &e) { - log_->info(*e.error); - }); - } - return assets; + return fromResults(converter_->createAccountAssets(result)); }; } boost::optional> @@ -201,7 +231,7 @@ namespace iroha { return execute_("SELECT * FROM account_has_asset WHERE account_id = " + transaction_.quote(account_id) + " AND asset_id = " + transaction_.quote(asset_id) + ";") - | [&](const auto &result) + | [&](auto &result) -> boost::optional< std::shared_ptr> { if (result.empty()) { @@ -209,7 +239,7 @@ namespace iroha { return boost::none; } - return fromResult(makeAccountAsset(result.at(0))); + return fromResult(converter_->createAccountAsset(result.at(0))); }; } @@ -217,37 +247,24 @@ namespace iroha { PostgresWsvQuery::getDomain(const DomainIdType &domain_id) { return execute_("SELECT * FROM domain WHERE domain_id = " + transaction_.quote(domain_id) + ";") - | [&](const auto &result) + | [&](auto &result) -> boost::optional< std::shared_ptr> { if (result.empty()) { log_->info("Domain {} not found", domain_id); return boost::none; } - return fromResult(makeDomain(result.at(0))); + return fromResult(converter_->createDomain(result.at(0))); }; } boost::optional>> PostgresWsvQuery::getPeers() { pqxx::result result; - return execute_("SELECT * FROM peer;") | [&](const auto &result) + return execute_("SELECT * FROM peer;") | [&](auto &result) -> boost::optional>> { - auto results = transform>(result, makePeer); - std::vector> peers; - for (auto &r : results) { - r.match( - [&](expected::Value< - std::shared_ptr> &v) { - peers.push_back(v.value); - }, - [&](expected::Error> &e) { - log_->info(*e.error); - }); - } - return peers; + return fromResults(converter_->createPeers(result)); }; } } // namespace ametsuchi diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.hpp b/irohad/ametsuchi/impl/postgres_wsv_query.hpp index 9a32b38d4c..70fcf7de28 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.hpp @@ -22,15 +22,25 @@ #include +#include "ametsuchi/impl/postgres_result_converter.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "postgres_wsv_common.hpp" namespace iroha { namespace ametsuchi { class PostgresWsvQuery : public WsvQuery { public: - explicit PostgresWsvQuery(pqxx::nontransaction &transaction); - PostgresWsvQuery(std::unique_ptr connection, - std::unique_ptr transaction); + explicit PostgresWsvQuery( + pqxx::nontransaction &transaction, + std::shared_ptr + factory); + + PostgresWsvQuery( + std::unique_ptr connection, + std::unique_ptr transaction, + std::shared_ptr + factory); + boost::optional> getAccountRoles(const shared_model::interface::types::AccountIdType &account_id) override; @@ -73,6 +83,8 @@ namespace iroha { shared_model::interface::permissions::Grantable permission) override; private: + std::unique_ptr converter_; + std::unique_ptr connection_ptr_; std::unique_ptr transaction_ptr_; diff --git a/irohad/ametsuchi/impl/storage_impl.cpp b/irohad/ametsuchi/impl/storage_impl.cpp index 566f008d05..7b5a71fe09 100644 --- a/irohad/ametsuchi/impl/storage_impl.cpp +++ b/irohad/ametsuchi/impl/storage_impl.cpp @@ -37,13 +37,16 @@ namespace iroha { std::unique_ptr block_store) : block_store(std::move(block_store)) {} - StorageImpl::StorageImpl(std::string block_store_dir, - PostgresOptions postgres_options, - std::unique_ptr block_store) + StorageImpl::StorageImpl( + std::string block_store_dir, + PostgresOptions postgres_options, + std::unique_ptr block_store, + std::shared_ptr factory) : block_store_dir_(std::move(block_store_dir)), postgres_options_(std::move(postgres_options)), block_store_(std::move(block_store)), - log_(logger::log("StorageImpl")) {} + log_(logger::log("StorageImpl")), + factory_(factory) {} expected::Result, std::string> StorageImpl::createTemporaryWsv() { @@ -60,7 +63,8 @@ namespace iroha { return expected::makeValue>( std::make_unique(std::move(postgres_connection), - std::move(wsv_transaction))); + std::move(wsv_transaction), + factory_)); } expected::Result, std::string> @@ -88,7 +92,8 @@ namespace iroha { return shared_model::interface::types::HashType(""); }), std::move(postgres_connection), - std::move(wsv_transaction))); + std::move(wsv_transaction), + factory_)); } bool StorageImpl::insertBlock(const shared_model::interface::Block &block) { @@ -214,8 +219,11 @@ DROP TABLE IF EXISTS index_by_id_height_asset; } expected::Result, std::string> - StorageImpl::create(std::string block_store_dir, - std::string postgres_options) { + StorageImpl::create( + std::string block_store_dir, + std::string postgres_options, + std::shared_ptr + factory) { boost::optional string_res = boost::none; PostgresOptions options(postgres_options); @@ -240,7 +248,8 @@ DROP TABLE IF EXISTS index_by_id_height_asset; storage = expected::makeValue(std::shared_ptr( new StorageImpl(block_store_dir, options, - std::move(ctx.value.block_store)))); + std::move(ctx.value.block_store), + factory))); }, [&](expected::Error &error) { storage = error; }); return storage; @@ -275,8 +284,8 @@ DROP TABLE IF EXISTS index_by_id_height_asset; auto wsv_transaction = std::make_unique(*postgres_connection); - return std::make_shared(std::move(postgres_connection), - std::move(wsv_transaction)); + return std::make_shared( + std::move(postgres_connection), std::move(wsv_transaction), factory_); } std::shared_ptr StorageImpl::getBlockQuery() const { diff --git a/irohad/ametsuchi/impl/storage_impl.hpp b/irohad/ametsuchi/impl/storage_impl.hpp index 19633aa97d..058baf0ad4 100644 --- a/irohad/ametsuchi/impl/storage_impl.hpp +++ b/irohad/ametsuchi/impl/storage_impl.hpp @@ -20,12 +20,15 @@ #include "ametsuchi/storage.hpp" -#include #include -#include #include + +#include +#include + #include "ametsuchi/impl/postgres_options.hpp" #include "ametsuchi/key_value_storage.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "logger/logger.hpp" namespace iroha { @@ -50,7 +53,10 @@ namespace iroha { public: static expected::Result, std::string> create( - std::string block_store_dir, std::string postgres_connection); + std::string block_store_dir, + std::string postgres_connection, + std::shared_ptr + factory_); expected::Result, std::string> createTemporaryWsv() override; @@ -89,7 +95,9 @@ namespace iroha { protected: StorageImpl(std::string block_store_dir, PostgresOptions postgres_options, - std::unique_ptr block_store); + std::unique_ptr block_store, + std::shared_ptr + factory_); /** * Folder with raw blocks @@ -110,6 +118,8 @@ namespace iroha { rxcpp::subjects::subject> notifier_; + std::shared_ptr factory_; + protected: static const std::string &init_; }; diff --git a/irohad/ametsuchi/impl/temporary_wsv_impl.cpp b/irohad/ametsuchi/impl/temporary_wsv_impl.cpp index 310e14599a..f657c085f4 100644 --- a/irohad/ametsuchi/impl/temporary_wsv_impl.cpp +++ b/irohad/ametsuchi/impl/temporary_wsv_impl.cpp @@ -25,13 +25,15 @@ namespace iroha { namespace ametsuchi { TemporaryWsvImpl::TemporaryWsvImpl( std::unique_ptr connection, - std::unique_ptr transaction) + std::unique_ptr transaction, + std::shared_ptr + factory) : connection_(std::move(connection)), transaction_(std::move(transaction)), - wsv_(std::make_unique(*transaction_)), + wsv_(std::make_unique(*transaction_, factory)), executor_(std::make_unique(*transaction_)), log_(logger::log("TemporaryWSV")) { - auto query = std::make_shared(*transaction_); + auto query = std::make_shared(*transaction_, factory); auto command = std::make_shared(*transaction_); command_executor_ = std::make_shared(query, command); command_validator_ = std::make_shared(query); diff --git a/irohad/ametsuchi/impl/temporary_wsv_impl.hpp b/irohad/ametsuchi/impl/temporary_wsv_impl.hpp index 6a336ac096..c8eb87621d 100644 --- a/irohad/ametsuchi/impl/temporary_wsv_impl.hpp +++ b/irohad/ametsuchi/impl/temporary_wsv_impl.hpp @@ -23,6 +23,7 @@ #include "ametsuchi/temporary_wsv.hpp" #include "execution/command_executor.hpp" +#include "interfaces/common_objects/common_objects_factory.hpp" #include "logger/logger.hpp" namespace iroha { @@ -30,8 +31,11 @@ namespace iroha { namespace ametsuchi { class TemporaryWsvImpl : public TemporaryWsv { public: - TemporaryWsvImpl(std::unique_ptr connection, - std::unique_ptr transaction); + TemporaryWsvImpl( + std::unique_ptr connection, + std::unique_ptr transaction, + std::shared_ptr + factory); expected::Result apply( const shared_model::interface::Transaction &, diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 0ba8d96cfd..62204d4135 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -10,9 +10,13 @@ #include "common/result.hpp" #include "interfaces/common_objects/account.hpp" +#include "interfaces/common_objects/account_asset.hpp" +#include "interfaces/common_objects/amount.hpp" +#include "interfaces/common_objects/asset.hpp" +#include "interfaces/common_objects/domain.hpp" #include "interfaces/common_objects/peer.hpp" +#include "interfaces/common_objects/signature.hpp" #include "interfaces/common_objects/types.hpp" -#include "interfaces/common_objects/domain.hpp" namespace shared_model { namespace interface { From b6b9b3c914d138253b4034c23feacab4f86a96e8 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Mon, 16 Jul 2018 15:13:42 +0300 Subject: [PATCH 12/17] Fix compilation issues Signed-off-by: Nikita Alekseev --- irohad/main/application.cpp | 7 ++++++- test/module/irohad/ametsuchi/CMakeLists.txt | 1 + test/module/irohad/ametsuchi/ametsuchi_fixture.hpp | 10 +++++++++- test/module/irohad/ametsuchi/ametsuchi_test.cpp | 5 +++-- test/module/irohad/ametsuchi/storage_init_test.cpp | 11 +++++++++-- .../irohad/ametsuchi/wsv_query_command_test.cpp | 4 ++-- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/irohad/main/application.cpp b/irohad/main/application.cpp index e23db789bf..1f1917f057 100644 --- a/irohad/main/application.cpp +++ b/irohad/main/application.cpp @@ -18,6 +18,7 @@ #include "main/application.hpp" #include "ametsuchi/impl/postgres_ordering_service_persistent_state.hpp" #include "ametsuchi/impl/wsv_restorer_impl.hpp" +#include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" #include "consensus/yac/impl/supermajority_checker_impl.hpp" #include "multi_sig_transactions/gossip_propagation_strategy.hpp" #include "multi_sig_transactions/mst_processor_impl.hpp" @@ -25,6 +26,7 @@ #include "multi_sig_transactions/mst_time_provider_impl.hpp" #include "multi_sig_transactions/storage/mst_storage_impl.hpp" #include "multi_sig_transactions/transport/mst_transport_grpc.hpp" +#include "validators/field_validator.hpp" using namespace iroha; using namespace iroha::ametsuchi; @@ -103,7 +105,10 @@ void Irohad::dropStorage() { * Initializing iroha daemon storage */ void Irohad::initStorage() { - auto storageResult = StorageImpl::create(block_store_dir_, pg_conn_); + auto factory = + std::make_shared>(); + auto storageResult = StorageImpl::create(block_store_dir_, pg_conn_, factory); storageResult.match( [&](expected::Value> &_storage) { storage = _storage.value; diff --git a/test/module/irohad/ametsuchi/CMakeLists.txt b/test/module/irohad/ametsuchi/CMakeLists.txt index 197464d502..d6058568c0 100644 --- a/test/module/irohad/ametsuchi/CMakeLists.txt +++ b/test/module/irohad/ametsuchi/CMakeLists.txt @@ -59,4 +59,5 @@ add_library(ametsuchi_fixture INTERFACE) target_link_libraries(ametsuchi_fixture INTERFACE pqxx integration_framework_config_helper + shared_model_proto_backend ) diff --git a/test/module/irohad/ametsuchi/ametsuchi_fixture.hpp b/test/module/irohad/ametsuchi/ametsuchi_fixture.hpp index cddf2e248f..8d7ae6e922 100644 --- a/test/module/irohad/ametsuchi/ametsuchi_fixture.hpp +++ b/test/module/irohad/ametsuchi/ametsuchi_fixture.hpp @@ -24,9 +24,11 @@ #include #include #include "ametsuchi/impl/storage_impl.hpp" +#include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" #include "common/files.hpp" #include "framework/config_helper.hpp" #include "logger/logger.hpp" +#include "validators/field_validator.hpp" namespace iroha { namespace ametsuchi { @@ -57,7 +59,7 @@ namespace iroha { } virtual void connect() { - StorageImpl::create(block_store_path, pgopt_) + StorageImpl::create(block_store_path, pgopt_, factory) .match([&](iroha::expected::Value> &_storage) { storage = _storage.value; }, [](iroha::expected::Error &error) { @@ -82,6 +84,12 @@ namespace iroha { disconnect(); } + std::shared_ptr> + factory = + std::make_shared>(); + std::shared_ptr connection; std::shared_ptr storage; diff --git a/test/module/irohad/ametsuchi/ametsuchi_test.cpp b/test/module/irohad/ametsuchi/ametsuchi_test.cpp index 0dbc69d073..5aebf21ca9 100644 --- a/test/module/irohad/ametsuchi/ametsuchi_test.cpp +++ b/test/module/irohad/ametsuchi/ametsuchi_test.cpp @@ -682,7 +682,7 @@ TEST_F(AmetsuchiTest, TestingStorageWhenDropAll) { "=> insert block " "=> assert that inserted"); std::shared_ptr storage; - auto storageResult = StorageImpl::create(block_store_path, pgopt_); + auto storageResult = StorageImpl::create(block_store_path, pgopt_, factory); storageResult.match( [&](iroha::expected::Value> &_storage) { storage = _storage.value; @@ -709,7 +709,8 @@ TEST_F(AmetsuchiTest, TestingStorageWhenDropAll) { ASSERT_EQ(0, wsv->getPeers().value().size()); std::shared_ptr new_storage; - auto new_storageResult = StorageImpl::create(block_store_path, pgopt_); + auto new_storageResult = + StorageImpl::create(block_store_path, pgopt_, factory); storageResult.match( [&](iroha::expected::Value> &_storage) { new_storage = _storage.value; diff --git a/test/module/irohad/ametsuchi/storage_init_test.cpp b/test/module/irohad/ametsuchi/storage_init_test.cpp index fe3a3e40e1..fd9a402fb2 100644 --- a/test/module/irohad/ametsuchi/storage_init_test.cpp +++ b/test/module/irohad/ametsuchi/storage_init_test.cpp @@ -8,7 +8,9 @@ #include #include #include "ametsuchi/impl/storage_impl.hpp" +#include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" #include "framework/config_helper.hpp" +#include "validators/field_validator.hpp" using namespace iroha::ametsuchi; using namespace iroha::expected; @@ -32,6 +34,11 @@ class StorageInitTest : public ::testing::Test { std::string pg_opt_without_dbname_; std::string pgopt_; + std::shared_ptr> + factory = std::make_shared>(); + void TearDown() override { auto temp_connection = std::make_unique(pg_opt_without_dbname_); @@ -46,7 +53,7 @@ class StorageInitTest : public ::testing::Test { * @then Database is created */ TEST_F(StorageInitTest, CreateStorageWithDatabase) { - StorageImpl::create(block_store_path, pgopt_) + StorageImpl::create(block_store_path, pgopt_, factory) .match([](const Value> &) { SUCCEED(); }, [](const Error &error) { FAIL() << error.error; }); auto temp_connection = @@ -66,7 +73,7 @@ TEST_F(StorageInitTest, CreateStorageWithDatabase) { TEST_F(StorageInitTest, CreateStorageWithInvalidPgOpt) { std::string pg_opt = "host=localhost port=5432 users=nonexistinguser dbname=test"; - StorageImpl::create(block_store_path, pg_opt) + StorageImpl::create(block_store_path, pg_opt, factory) .match( [](const Value> &) { FAIL() << "storage created, but should not"; diff --git a/test/module/irohad/ametsuchi/wsv_query_command_test.cpp b/test/module/irohad/ametsuchi/wsv_query_command_test.cpp index 654060cdb0..c7a3b2716b 100644 --- a/test/module/irohad/ametsuchi/wsv_query_command_test.cpp +++ b/test/module/irohad/ametsuchi/wsv_query_command_test.cpp @@ -58,7 +58,7 @@ namespace iroha { std::make_unique(*postgres_connection); command = std::make_unique(*wsv_transaction); - query = std::make_unique(*wsv_transaction); + query = std::make_unique(*wsv_transaction, factory); wsv_transaction->exec(init_); } @@ -469,7 +469,7 @@ namespace iroha { std::make_unique(*postgres_connection); command = std::make_unique(*wsv_transaction); - query = std::make_unique(*wsv_transaction); + query = std::make_unique(*wsv_transaction, factory); } }; From 69cdd3fbd1d32a906f13588b49009b0f265f6298 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Tue, 17 Jul 2018 12:04:43 +0300 Subject: [PATCH 13/17] Fix merge conflicts Signed-off-by: Nikita Alekseev # Conflicts: # irohad/ametsuchi/impl/mutable_storage_impl.cpp # irohad/ametsuchi/impl/mutable_storage_impl.hpp # irohad/ametsuchi/impl/postgres_block_query.cpp # irohad/ametsuchi/impl/postgres_wsv_common.hpp # irohad/ametsuchi/impl/postgres_wsv_query.cpp # irohad/ametsuchi/impl/postgres_wsv_query.hpp # irohad/ametsuchi/impl/storage_impl.cpp # irohad/ametsuchi/impl/storage_impl.hpp # irohad/ametsuchi/impl/temporary_wsv_impl.cpp # irohad/ametsuchi/impl/temporary_wsv_impl.hpp # test/module/irohad/ametsuchi/CMakeLists.txt # test/module/irohad/ametsuchi/ametsuchi_fixture.hpp # test/module/irohad/ametsuchi/wsv_query_command_test.cpp # test/module/shared_model/backend_proto/CMakeLists.txt --- .../impl/postgres_result_converter.hpp | 2 +- irohad/ametsuchi/impl/postgres_wsv_common.hpp | 101 +++--------------- irohad/ametsuchi/impl/postgres_wsv_query.cpp | 55 +++++----- irohad/ametsuchi/impl/postgres_wsv_query.hpp | 5 +- irohad/ametsuchi/impl/storage_impl.cpp | 3 +- .../proto_common_objects_factory.hpp | 60 ++++++----- .../common_objects/common_objects_factory.hpp | 8 ++ .../irohad/ametsuchi/kv_storage_test.cpp | 2 +- .../ametsuchi/wsv_query_command_test.cpp | 2 +- 9 files changed, 96 insertions(+), 142 deletions(-) diff --git a/irohad/ametsuchi/impl/postgres_result_converter.hpp b/irohad/ametsuchi/impl/postgres_result_converter.hpp index 72e0c790f9..ffba850d38 100644 --- a/irohad/ametsuchi/impl/postgres_result_converter.hpp +++ b/irohad/ametsuchi/impl/postgres_result_converter.hpp @@ -18,7 +18,7 @@ namespace iroha { public: explicit PostgresResultConverter( std::shared_ptr - factory) {} + factory); template using ConverterResult = diff --git a/irohad/ametsuchi/impl/postgres_wsv_common.hpp b/irohad/ametsuchi/impl/postgres_wsv_common.hpp index bf93c85241..a0e535809b 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_common.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_common.hpp @@ -60,14 +60,15 @@ namespace iroha { * @param f - function which returns BuilderResult * @return whatever f returns, or error in case exception has been thrown */ - template - static inline auto tryBuild(BuildFunc &&f) noexcept -> decltype(f()) { - try { - return f(); - } catch (std::exception &e) { - return expected::makeError(std::make_shared(e.what())); - } - } + // template + // static inline auto tryBuild(BuildFunc &&f) noexcept -> decltype(f()) { + // try { + // return f(); + // } catch (std::exception &e) { + // return + // expected::makeError(std::make_shared(e.what())); + // } + // } template void processSoci(soci::statement &st, @@ -85,78 +86,6 @@ namespace iroha { } } - static inline shared_model::builder::BuilderResult< - shared_model::interface::Account> - makeAccount(const std::string &account_id, - const std::string &domain_id, - const shared_model::interface::types::QuorumType &quorum, - const std::string &data) noexcept { - return tryBuild([&] { - return shared_model::builder::DefaultAccountBuilder() - .accountId(account_id) - .domainId(domain_id) - .quorum(quorum) - .jsonData(data) - .build(); - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Asset> - makeAsset(const std::string &asset_id, - const std::string &domain_id, - const int32_t precision) noexcept { - return tryBuild([&] { - return shared_model::builder::DefaultAssetBuilder() - .assetId(asset_id) - .domainId(domain_id) - .precision(precision) - .build(); - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::AccountAsset> - makeAccountAsset(const std::string &account_id, - const std::string &asset_id, - const std::string &amount) noexcept { - return tryBuild([&] { - auto balance = - shared_model::builder::DefaultAmountBuilder::fromString(amount); - return balance | [&](const auto &balance_ptr) { - return shared_model::builder::DefaultAccountAssetBuilder() - .accountId(account_id) - .assetId(asset_id) - .balance(*balance_ptr) - .build(); - }; - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Peer> - makePeer(const soci::row &row) noexcept { - return tryBuild([&row] { - return shared_model::builder::DefaultPeerBuilder() - .pubkey(shared_model::crypto::PublicKey( - shared_model::crypto::Blob::fromHexString( - row.get(0)))) - .address(row.get(1)) - .build(); - }); - } - - static inline shared_model::builder::BuilderResult< - shared_model::interface::Domain> - makeDomain(const std::string &domain_id, const std::string &role) noexcept { - return tryBuild([&domain_id, &role] { - return shared_model::builder::DefaultDomainBuilder() - .domainId(domain_id) - .defaultRole(role) - .build(); - }); - } - /** * Transforms result to optional * value -> optional @@ -166,13 +95,15 @@ namespace iroha { * @return optional */ template - static inline boost::optional> fromResult( - const shared_model::builder::BuilderResult &result) { + inline boost::optional> fromResult( + shared_model::interface::CommonObjectsFactory::FactoryResult< + std::unique_ptr> &&result) { return result.match( - [](const expected::Value> &v) { - return boost::make_optional(v.value); + [](expected::Value> &v) + -> boost::optional> { + return std::shared_ptr(std::move(v.value)); }, - [](const expected::Error> &e) + [](expected::Error) -> boost::optional> { return boost::none; }); } } // namespace ametsuchi diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.cpp b/irohad/ametsuchi/impl/postgres_wsv_query.cpp index e91d864d27..ae0567bc5f 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.cpp @@ -37,17 +37,17 @@ namespace iroha { const std::string kAccountId = "account_id"; const std::string kDomainId = "domain_id"; - PostgresWsvQuery::PostgresWsvQuery(soci::session &sql, - std::shared_ptr factory) - : sql_(sql), - converter_(std::make_unique(factory)), - log_(logger::log("PostgresWsvQuery")) {} - - PostgresWsvQuery::PostgresWsvQuery(std::unique_ptr sql_ptr, - std::shared_ptr factory) + PostgresWsvQuery::PostgresWsvQuery( + soci::session &sql, + std::shared_ptr factory) + : sql_(sql), factory_(factory), log_(logger::log("PostgresWsvQuery")) {} + + PostgresWsvQuery::PostgresWsvQuery( + std::unique_ptr sql_ptr, + std::shared_ptr factory) : sql_ptr_(std::move(sql_ptr)), sql_(*sql_ptr_), - converter_(std::make_unique(factory)), + factory_(factory), log_(logger::log("PostgresWsvQuery")) {} bool PostgresWsvQuery::hasAccountGrantablePermission( @@ -139,8 +139,8 @@ namespace iroha { return boost::none; } - return fromResult( - makeAccount(account_id, domain_id.get(), quorum.get(), data.get())); + return fromResult(factory_->createAccount( + account_id, domain_id.get(), quorum.get(), data.get())); } boost::optional PostgresWsvQuery::getAccountDetail( @@ -227,7 +227,8 @@ namespace iroha { return boost::none; } - return fromResult(makeAsset(asset_id, domain_id.get(), precision.get())); + return fromResult( + factory_->createAsset(asset_id, domain_id.get(), precision.get())); } boost::optional< @@ -240,8 +241,9 @@ namespace iroha { std::vector> assets; for (auto &t : st) { - fromResult(makeAccountAsset(account_id, t.get<1>(), t.get<2>())) | - [&assets](const auto &asset) { assets.push_back(asset); }; + fromResult( + factory_->createAccountAsset(account_id, t.get<1>(), t.get<2>())) + | [&assets](const auto &asset) { assets.push_back(asset); }; } return boost::make_optional(assets); @@ -264,7 +266,8 @@ namespace iroha { return boost::none; } - return fromResult(makeAccountAsset(account_id, asset_id, amount.get())); + return fromResult( + factory_->createAccountAsset(account_id, asset_id, amount.get())); } boost::optional> @@ -281,7 +284,7 @@ namespace iroha { return boost::none; } - return fromResult(makeDomain(domain_id, role.get())); + return fromResult(factory_->createDomain(domain_id, role.get())); } boost::optional>> @@ -290,15 +293,17 @@ namespace iroha { (sql_.prepare << "SELECT public_key, address FROM peer"); std::vector> peers; - auto results = transform< - shared_model::builder::BuilderResult>( - rows, makePeer); - for (auto &r : results) { - r.match( - [&](expected::Value> - &v) { peers.push_back(v.value); }, - [&](expected::Error> &e) { - log_->info(*e.error); + for (auto &row : rows) { + auto address = row.get(1); + auto key = shared_model::crypto::PublicKey( + shared_model::crypto::Blob::fromHexString(row.get(0))); + + auto peer = factory_->createPeer(address, key); + peer.match( + [&](expected::Value> + &v) { peers.push_back(std::move(v.value)); }, + [&](expected::Error &e) { + log_->info(e.error); }); } return peers; diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.hpp b/irohad/ametsuchi/impl/postgres_wsv_query.hpp index 6de69b7ded..db88f2fd6c 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.hpp @@ -20,7 +20,8 @@ #include "ametsuchi/wsv_query.hpp" -#include "ametsuchi/impl/postgres_result_converter.hpp" +//#include + #include "interfaces/common_objects/common_objects_factory.hpp" #include "postgres_wsv_common.hpp" @@ -93,7 +94,7 @@ namespace iroha { private: std::unique_ptr sql_ptr_; soci::session &sql_; - std::unique_ptr converter_; + std::shared_ptr factory_; logger::Logger log_; }; } // namespace ametsuchi diff --git a/irohad/ametsuchi/impl/storage_impl.cpp b/irohad/ametsuchi/impl/storage_impl.cpp index 74e1fbdaed..32c6fd4afa 100644 --- a/irohad/ametsuchi/impl/storage_impl.cpp +++ b/irohad/ametsuchi/impl/storage_impl.cpp @@ -48,7 +48,6 @@ namespace iroha { : block_store_dir_(std::move(block_store_dir)), postgres_options_(std::move(postgres_options)), block_store_(std::move(block_store)), - log_(logger::log("StorageImpl")), connection_(connection), factory_(factory), log_(logger::log("StorageImpl")) {} @@ -278,7 +277,7 @@ DROP TABLE IF EXISTS index_by_id_height_asset; std::shared_ptr StorageImpl::getWsvQuery() const { auto sql = std::make_unique(*connection_); - return std::make_shared(std::move(sql), factory); + return std::make_shared(std::move(sql), factory_); } std::shared_ptr StorageImpl::getBlockQuery() const { diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index bdc5820cef..582218dcb9 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -21,11 +21,11 @@ namespace shared_model { namespace proto { - /** - * ProtoCommonObjectsFactory constructs protobuf-based objects. - * It performs stateful validation with provided validator - * @tparam Validator - */ + /** + * ProtoCommonObjectsFactory constructs protobuf-based objects. + * It performs stateful validation with provided validator + * @tparam Validator + */ template class ProtoCommonObjectsFactory : public interface::CommonObjectsFactory { public: @@ -78,6 +78,28 @@ namespace shared_model { std::move(proto_account)); } + FactoryResult> createAmount( + boost::multiprecision::uint256_t value, + interface::types::PrecisionType precision) override { + iroha::protocol::Amount amount; + amount.set_precision(precision); + convertToProtoAmount(*amount.mutable_value(), value); + + auto proto_amount = std::make_unique(std::move(amount)); + + auto errors = validate(*proto_amount, [](const auto &, auto &) { + // no validation needed, + // since any amount is valid in general context + }); + + if (errors) { + return iroha::expected::makeError(errors.reason()); + } + + return iroha::expected::makeValue>( + std::move(proto_amount)); + } + FactoryResult> createAccountAsset(const interface::types::AccountIdType &account_id, const interface::types::AssetIdType &asset_id, @@ -106,26 +128,14 @@ namespace shared_model { std::unique_ptr>(std::move(proto_asset)); } - FactoryResult> createAmount( - boost::multiprecision::uint256_t value, - interface::types::PrecisionType precision) override { - iroha::protocol::Amount amount; - amount.set_precision(precision); - convertToProtoAmount(*amount.mutable_value(), value); - - auto proto_amount = std::make_unique(std::move(amount)); - - auto errors = validate(*proto_amount, [](const auto &, auto &) { - // no validation needed, - // since any amount is valid in general context - }); - - if (errors) { - return iroha::expected::makeError(errors.reason()); - } - - return iroha::expected::makeValue>( - std::move(proto_amount)); + FactoryResult> + createAccountAsset(const interface::types::AccountIdType &account_id, + const interface::types::AssetIdType &asset_id, + std::string balance) override { + return createAmount(balance) | + [this, &account_id, &asset_id](const auto &amount) { + return createAccountAsset(account_id, asset_id, *amount); + }; } FactoryResult> createAmount( diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 62204d4135..5306871727 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -53,6 +53,14 @@ namespace shared_model { const types::AssetIdType &asset_id, const Amount &balance) = 0; + /** + * Create account asset instance using string + */ + virtual FactoryResult> createAccountAsset( + const types::AccountIdType &account_id, + const types::AssetIdType &asset_id, + std::string balance) = 0; + /** * Create amount instance from string * diff --git a/test/module/irohad/ametsuchi/kv_storage_test.cpp b/test/module/irohad/ametsuchi/kv_storage_test.cpp index 9a52a1240f..b85e071dea 100644 --- a/test/module/irohad/ametsuchi/kv_storage_test.cpp +++ b/test/module/irohad/ametsuchi/kv_storage_test.cpp @@ -38,7 +38,7 @@ class KVTest : public AmetsuchiTest { protected: void SetUp() override { AmetsuchiTest::SetUp(); - auto storageResult = StorageImpl::create(block_store_path, pgopt_); + auto storageResult = StorageImpl::create(block_store_path, pgopt_, factory); storageResult.match( [&](iroha::expected::Value> &_storage) { storage = _storage.value; diff --git a/test/module/irohad/ametsuchi/wsv_query_command_test.cpp b/test/module/irohad/ametsuchi/wsv_query_command_test.cpp index 3dc84fa877..8c6278f1cd 100644 --- a/test/module/irohad/ametsuchi/wsv_query_command_test.cpp +++ b/test/module/irohad/ametsuchi/wsv_query_command_test.cpp @@ -51,7 +51,7 @@ namespace iroha { sql = std::make_unique(soci::postgresql, pgopt_); command = std::make_unique(*sql); - query = std::make_unique(*sql, , factory); + query = std::make_unique(*sql, factory); *sql << init_; } From 257ebe95a931c60eaea153228a06373f128768d6 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 18 Jul 2018 13:42:50 +0300 Subject: [PATCH 14/17] Remove postgres converter Signed-off-by: Nikita Alekseev # Conflicts: # test/module/shared_model/backend_proto/CMakeLists.txt --- .../impl/postgres_result_converter.cpp | 6 -- .../impl/postgres_result_converter.hpp | 55 ------------- irohad/ametsuchi/impl/postgres_wsv_query.cpp | 14 ++-- irohad/ametsuchi/impl/postgres_wsv_query.hpp | 2 +- .../proto_common_objects_factory.hpp | 69 +--------------- .../common_objects/common_objects_factory.hpp | 27 ------- test/module/libs/common/CMakeLists.txt | 3 + .../proto_common_objects_factory_test.cpp | 80 +++---------------- 8 files changed, 21 insertions(+), 235 deletions(-) delete mode 100644 irohad/ametsuchi/impl/postgres_result_converter.cpp delete mode 100644 irohad/ametsuchi/impl/postgres_result_converter.hpp diff --git a/irohad/ametsuchi/impl/postgres_result_converter.cpp b/irohad/ametsuchi/impl/postgres_result_converter.cpp deleted file mode 100644 index 1b747bf23a..0000000000 --- a/irohad/ametsuchi/impl/postgres_result_converter.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "postgres_result_converter.hpp" diff --git a/irohad/ametsuchi/impl/postgres_result_converter.hpp b/irohad/ametsuchi/impl/postgres_result_converter.hpp deleted file mode 100644 index ffba850d38..0000000000 --- a/irohad/ametsuchi/impl/postgres_result_converter.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef IROHA_POSTGRES_RESULT_CONVERTER_HPP -#define IROHA_POSTGRES_RESULT_CONVERTER_HPP - -#include "interfaces/common_objects/common_objects_factory.hpp" - -namespace iroha { - namespace ametsuchi { - /** - * This class is used to convert result set obtained from postgres to - * iroha common objects - */ - class PostgresResultConverter { - public: - explicit PostgresResultConverter( - std::shared_ptr - factory); - - template - using ConverterResult = - shared_model::interface::CommonObjectsFactory::FactoryResult; - - ConverterResult> - createAccount(const pqxx::row &row); - - ConverterResult> - createAsset(const pqxx::row &row); - - ConverterResult> - createAccountAsset(const pqxx::row &row); - - ConverterResult< - std::vector>> - createAccountAssets(const pqxx::result &result); - - ConverterResult> - createPeer(const pqxx::row &row); - - ConverterResult>> - createPeers(const pqxx::result &result); - - ConverterResult> - createDomain(const pqxx::row &row); - - private: - std::shared_ptr factory_; - }; // namespace ametsuchi - } // namespace ametsuchi -} // namespace iroha - -#endif // IROHA_POSTGRES_RESULT_CONVERTER_HPP diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.cpp b/irohad/ametsuchi/impl/postgres_wsv_query.cpp index ae0567bc5f..c9163966cd 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.cpp @@ -241,8 +241,10 @@ namespace iroha { std::vector> assets; for (auto &t : st) { - fromResult( - factory_->createAccountAsset(account_id, t.get<1>(), t.get<2>())) + fromResult(factory_->createAccountAsset( + account_id, + t.get<1>(), + shared_model::interface::Amount(t.get<2>()))) | [&assets](const auto &asset) { assets.push_back(asset); }; } @@ -266,8 +268,8 @@ namespace iroha { return boost::none; } - return fromResult( - factory_->createAccountAsset(account_id, asset_id, amount.get())); + return fromResult(factory_->createAccountAsset( + account_id, asset_id, shared_model::interface::Amount(amount.get()))); } boost::optional> @@ -302,9 +304,7 @@ namespace iroha { peer.match( [&](expected::Value> &v) { peers.push_back(std::move(v.value)); }, - [&](expected::Error &e) { - log_->info(e.error); - }); + [&](expected::Error &e) { log_->info(e.error); }); } return peers; } diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.hpp b/irohad/ametsuchi/impl/postgres_wsv_query.hpp index db88f2fd6c..a23485d406 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.hpp @@ -20,7 +20,7 @@ #include "ametsuchi/wsv_query.hpp" -//#include +#include #include "interfaces/common_objects/common_objects_factory.hpp" #include "postgres_wsv_common.hpp" diff --git a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp index 582218dcb9..bd9d9f6697 100644 --- a/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp +++ b/shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp @@ -78,28 +78,6 @@ namespace shared_model { std::move(proto_account)); } - FactoryResult> createAmount( - boost::multiprecision::uint256_t value, - interface::types::PrecisionType precision) override { - iroha::protocol::Amount amount; - amount.set_precision(precision); - convertToProtoAmount(*amount.mutable_value(), value); - - auto proto_amount = std::make_unique(std::move(amount)); - - auto errors = validate(*proto_amount, [](const auto &, auto &) { - // no validation needed, - // since any amount is valid in general context - }); - - if (errors) { - return iroha::expected::makeError(errors.reason()); - } - - return iroha::expected::makeValue>( - std::move(proto_amount)); - } - FactoryResult> createAccountAsset(const interface::types::AccountIdType &account_id, const interface::types::AssetIdType &asset_id, @@ -107,10 +85,7 @@ namespace shared_model { iroha::protocol::AccountAsset asset; asset.set_account_id(account_id); asset.set_asset_id(asset_id); - auto proto_balance = asset.mutable_balance(); - convertToProtoAmount(*proto_balance->mutable_value(), - balance.intValue()); - proto_balance->set_precision(balance.precision()); + asset.set_balance(balance.toStringRepr()); auto proto_asset = std::make_unique(std::move(asset)); @@ -128,48 +103,6 @@ namespace shared_model { std::unique_ptr>(std::move(proto_asset)); } - FactoryResult> - createAccountAsset(const interface::types::AccountIdType &account_id, - const interface::types::AssetIdType &asset_id, - std::string balance) override { - return createAmount(balance) | - [this, &account_id, &asset_id](const auto &amount) { - return createAccountAsset(account_id, asset_id, *amount); - }; - } - - FactoryResult> createAmount( - std::string amount) override { - // taken from iroha::model::Amount - // check if valid number - const static std::regex e("([0-9]*\\.[0-9]+|[0-9]+)"); - if (!std::regex_match(amount, e)) { - return iroha::expected::makeError("number string is invalid"); - } - - // get precision - auto dot_place = amount.find('.'); - interface::types::PrecisionType precision; - if (dot_place > amount.size()) { - precision = 0; - } else { - precision = amount.size() - dot_place - 1; - // erase dot from the string - amount.erase(std::remove(amount.begin(), amount.end(), '.'), - amount.end()); - } - - auto begin = amount.find_first_not_of('0'); - - // create uint256 value from obtained string - boost::multiprecision::uint256_t value = 0; - if (begin <= amount.size()) { - value = boost::multiprecision::uint256_t(amount.substr(begin)); - } - - return createAmount(value, precision); - } - FactoryResult> createAsset( const interface::types::AssetIdType &asset_id, const interface::types::DomainIdType &domain_id, diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index 5306871727..cb7ce48220 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -53,33 +53,6 @@ namespace shared_model { const types::AssetIdType &asset_id, const Amount &balance) = 0; - /** - * Create account asset instance using string - */ - virtual FactoryResult> createAccountAsset( - const types::AccountIdType &account_id, - const types::AssetIdType &asset_id, - std::string balance) = 0; - - /** - * Create amount instance from string - * - * @param value integer will be divided by 10 * precision, - * so value 123 with precision 2 will become Amount of 1.23 - */ - virtual FactoryResult> createAmount( - boost::multiprecision::uint256_t value, - types::PrecisionType precision) = 0; - - /** - * Create amount instance from string - * - * @param amount must represent valid number. - * For example: "1.23", "10" etc. - */ - virtual FactoryResult> createAmount( - std::string amount) = 0; - /** * Create asset instance */ diff --git a/test/module/libs/common/CMakeLists.txt b/test/module/libs/common/CMakeLists.txt index 203c081310..c84c7262ec 100644 --- a/test/module/libs/common/CMakeLists.txt +++ b/test/module/libs/common/CMakeLists.txt @@ -19,3 +19,6 @@ addtest(result_test result_test.cpp) target_link_libraries(result_test libs_common ) + +add_library(optional_test + optinal_test.cpp) diff --git a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp index b4bec207e4..3f5d92f2a8 100644 --- a/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp +++ b/test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp @@ -3,10 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include -#include "backend/protobuf/common_objects/amount.hpp" #include "backend/protobuf/common_objects/proto_common_objects_factory.hpp" #include "builders/default_builders.hpp" #include "cryptography/crypto_provider/crypto_defaults.hpp" @@ -104,8 +103,7 @@ class AccountAssetTest : public ::testing::Test { public: interface::types::AccountIdType valid_account_id = "hello@world"; interface::types::AssetIdType valid_asset_id = "bit#connect"; - std::shared_ptr valid_amount = - val(builder::DefaultAmountBuilder::fromString("10.00"))->value; + interface::Amount valid_amount = interface::Amount("10.00"); interface::types::AccountIdType invalid_account_id = "hello123"; }; @@ -117,13 +115,13 @@ class AccountAssetTest : public ::testing::Test { */ TEST_F(AccountAssetTest, ValidAccountAssetInitialization) { auto account_asset = factory.createAccountAsset( - valid_account_id, valid_asset_id, *valid_amount); + valid_account_id, valid_asset_id, valid_amount); account_asset.match( [&](const ValueOf &v) { ASSERT_EQ(v.value->accountId(), valid_account_id); ASSERT_EQ(v.value->assetId(), valid_asset_id); - ASSERT_EQ(v.value->balance(), *valid_amount); + ASSERT_EQ(v.value->balance(), valid_amount); }, [](const ErrorOf &e) { FAIL() << e.error; }); } @@ -135,7 +133,7 @@ TEST_F(AccountAssetTest, ValidAccountAssetInitialization) { */ TEST_F(AccountAssetTest, InvalidAccountAssetInitialization) { auto account_asset = factory.createAccountAsset( - invalid_account_id, valid_asset_id, *valid_amount); + invalid_account_id, valid_asset_id, valid_amount); account_asset.match( [](const ValueOf &v) { @@ -144,62 +142,6 @@ TEST_F(AccountAssetTest, InvalidAccountAssetInitialization) { [](const ErrorOf &e) { SUCCEED(); }); } -class AmountTest : public ::testing::Test { - public: - boost::multiprecision::uint256_t valid_value = 123; - interface::types::PrecisionType valid_precision = 2; - - std::string valid_amount_str = "1.23"; - std::string invalid_amount_str = "hello there"; -}; - -/** - * @given valid data for amount - * @when amount is created via factory - * @then amount is successfully initialized - */ -TEST_F(AmountTest, ValidAmountInitialization) { - auto amount = factory.createAmount(valid_value, valid_precision); - - amount.match( - [&](const ValueOf &v) { - ASSERT_EQ(v.value->intValue(), valid_value); - ASSERT_EQ(v.value->precision(), valid_precision); - }, - [](const ErrorOf &e) { FAIL() << e.error; }); -} - -/** - * @given valid string for amount - * @when amount is created via factory - * @then amount is successfully initialized - */ -TEST_F(AmountTest, ValidStringAmountInitialization) { - auto amount = factory.createAmount(valid_amount_str); - - amount.match( - [&](const ValueOf &v) { - ASSERT_EQ(v.value->intValue(), valid_value); - ASSERT_EQ(v.value->precision(), valid_precision); - }, - [](const ErrorOf &e) { FAIL() << e.error; }); -} - -/** - * @given invalid string for amount - * @when amount is created via factory - * @then amount is not initialized correctly - */ -TEST_F(AmountTest, InvalidStringAmountInitialization) { - auto amount = factory.createAmount(invalid_amount_str); - - amount.match( - [](const ValueOf &v) { - FAIL() << "Expected error case"; - }, - [](const ErrorOf &e) { SUCCEED(); }); -} - class AssetTest : public ::testing::Test { public: interface::types::AssetIdType valid_asset_id = "bit#connect"; @@ -257,8 +199,7 @@ class DomainTest : public ::testing::Test { * @then domain is successfully initialized */ TEST_F(DomainTest, ValidDomainInitialization) { - auto domain = - factory.createDomain(valid_domain_id, valid_role_id); + auto domain = factory.createDomain(valid_domain_id, valid_role_id); domain.match( [&](const ValueOf &v) { @@ -274,8 +215,7 @@ TEST_F(DomainTest, ValidDomainInitialization) { * @then domain is not initialized correctly */ TEST_F(DomainTest, InvalidDomainInitialization) { - auto domain = - factory.createDomain(invalid_domain_id, valid_role_id); + auto domain = factory.createDomain(invalid_domain_id, valid_role_id); domain.match( [](const ValueOf &v) { @@ -298,8 +238,7 @@ class SignatureTest : public ::testing::Test { * @then signature is successfully initialized */ TEST_F(SignatureTest, ValidSignatureInitialization) { - auto signature = - factory.createSignature(valid_pubkey, valid_data); + auto signature = factory.createSignature(valid_pubkey, valid_data); signature.match( [&](const ValueOf &v) { @@ -315,8 +254,7 @@ TEST_F(SignatureTest, ValidSignatureInitialization) { * @then signature is not initialized correctly */ TEST_F(SignatureTest, InvalidSignatureInitialization) { - auto signature = - factory.createSignature(invalid_pubkey, valid_data); + auto signature = factory.createSignature(invalid_pubkey, valid_data); signature.match( [](const ValueOf &v) { From c436031d2379e109cfcfd5a7e033a34e2bda6ef7 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Wed, 18 Jul 2018 14:00:48 +0300 Subject: [PATCH 15/17] Fix issues Signed-off-by: Nikita Alekseev # Conflicts: # test/module/shared_model/backend_proto/CMakeLists.txt --- .../ametsuchi/impl/postgres_wsv_command.cpp | 2 +- irohad/ametsuchi/impl/postgres_wsv_common.hpp | 21 ++----------------- irohad/ametsuchi/impl/postgres_wsv_query.hpp | 2 -- test/module/libs/common/CMakeLists.txt | 3 --- 4 files changed, 3 insertions(+), 25 deletions(-) diff --git a/irohad/ametsuchi/impl/postgres_wsv_command.cpp b/irohad/ametsuchi/impl/postgres_wsv_command.cpp index 9474072ee2..fae2254c83 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_command.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_command.cpp @@ -18,9 +18,9 @@ #include "ametsuchi/impl/postgres_wsv_command.hpp" #include + #include "backend/protobuf/permissions.hpp" #include "interfaces/common_objects/asset.hpp" -#include "interfaces/common_objects/account_asset.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_wsv_common.hpp b/irohad/ametsuchi/impl/postgres_wsv_common.hpp index a0e535809b..57a2368550 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_common.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_common.hpp @@ -54,22 +54,6 @@ namespace iroha { return values; } - /** - * Execute build function and return error in case it throws - * @tparam T - result value type - * @param f - function which returns BuilderResult - * @return whatever f returns, or error in case exception has been thrown - */ - // template - // static inline auto tryBuild(BuildFunc &&f) noexcept -> decltype(f()) { - // try { - // return f(); - // } catch (std::exception &e) { - // return - // expected::makeError(std::make_shared(e.what())); - // } - // } - template void processSoci(soci::statement &st, soci::indicator &ind, @@ -99,9 +83,8 @@ namespace iroha { shared_model::interface::CommonObjectsFactory::FactoryResult< std::unique_ptr> &&result) { return result.match( - [](expected::Value> &v) - -> boost::optional> { - return std::shared_ptr(std::move(v.value)); + [](expected::Value> &v) { + return boost::make_optional(std::shared_ptr(std::move(v.value))); }, [](expected::Error) -> boost::optional> { return boost::none; }); diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.hpp b/irohad/ametsuchi/impl/postgres_wsv_query.hpp index a23485d406..ee648b83b2 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.hpp @@ -20,8 +20,6 @@ #include "ametsuchi/wsv_query.hpp" -#include - #include "interfaces/common_objects/common_objects_factory.hpp" #include "postgres_wsv_common.hpp" diff --git a/test/module/libs/common/CMakeLists.txt b/test/module/libs/common/CMakeLists.txt index c84c7262ec..203c081310 100644 --- a/test/module/libs/common/CMakeLists.txt +++ b/test/module/libs/common/CMakeLists.txt @@ -19,6 +19,3 @@ addtest(result_test result_test.cpp) target_link_libraries(result_test libs_common ) - -add_library(optional_test - optinal_test.cpp) From ad1ed98104e1335cdb594570572c4539b3e0f33f Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Thu, 19 Jul 2018 11:17:24 +0300 Subject: [PATCH 16/17] Fix review issues Signed-off-by: Nikita Alekseev # Conflicts: # shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp # shared_model/interfaces/common_objects/common_objects_factory.hpp # test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp --- irohad/ametsuchi/impl/storage_impl.hpp | 3 +-- test/module/irohad/ametsuchi/ametsuchi_test.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/irohad/ametsuchi/impl/storage_impl.hpp b/irohad/ametsuchi/impl/storage_impl.hpp index 836093ca7a..9a07060aed 100644 --- a/irohad/ametsuchi/impl/storage_impl.hpp +++ b/irohad/ametsuchi/impl/storage_impl.hpp @@ -20,11 +20,10 @@ #include "ametsuchi/storage.hpp" -#include -#include #include #include +#include #include #include "ametsuchi/impl/postgres_options.hpp" diff --git a/test/module/irohad/ametsuchi/ametsuchi_test.cpp b/test/module/irohad/ametsuchi/ametsuchi_test.cpp index c2d8e682b6..2296b9577e 100644 --- a/test/module/irohad/ametsuchi/ametsuchi_test.cpp +++ b/test/module/irohad/ametsuchi/ametsuchi_test.cpp @@ -216,7 +216,7 @@ TEST_F(AmetsuchiTest, SampleTest) { .build()})) .height(2) .prevHash(block1.hash()) - .build(); + .build(); apply(storage, block2); validateAccountAsset( From be92c271a422d3b9ca8cddafe5f2d9bb26c32054 Mon Sep 17 00:00:00 2001 From: Nikita Alekseev Date: Thu, 19 Jul 2018 13:15:33 +0300 Subject: [PATCH 17/17] Fix review issues Signed-off-by: Nikita Alekseev # Conflicts: # shared_model/backend/protobuf/common_objects/proto_common_objects_factory.hpp # shared_model/interfaces/common_objects/common_objects_factory.hpp # test/module/shared_model/backend_proto/common_objects/proto_common_objects_factory_test.cpp --- irohad/ametsuchi/CMakeLists.txt | 4 + .../ametsuchi/impl/postgres_block_index.hpp | 2 +- .../ametsuchi/impl/postgres_block_query.hpp | 2 +- ...gres_ordering_service_persistent_state.hpp | 2 +- .../ametsuchi/impl/postgres_wsv_command.cpp | 6 ++ .../ametsuchi/impl/postgres_wsv_command.hpp | 2 +- irohad/ametsuchi/impl/postgres_wsv_common.hpp | 94 ------------------- irohad/ametsuchi/impl/postgres_wsv_query.cpp | 26 +++++ irohad/ametsuchi/impl/postgres_wsv_query.hpp | 4 +- irohad/ametsuchi/impl/soci_utils.hpp | 42 +++++++++ .../common_objects/common_objects_factory.hpp | 5 +- 11 files changed, 87 insertions(+), 102 deletions(-) delete mode 100644 irohad/ametsuchi/impl/postgres_wsv_common.hpp create mode 100644 irohad/ametsuchi/impl/soci_utils.hpp diff --git a/irohad/ametsuchi/CMakeLists.txt b/irohad/ametsuchi/CMakeLists.txt index 0a3be8a12d..cf95605824 100644 --- a/irohad/ametsuchi/CMakeLists.txt +++ b/irohad/ametsuchi/CMakeLists.txt @@ -25,3 +25,7 @@ target_link_libraries(ametsuchi SOCI::core SOCI::postgresql ) + +target_compile_definitions(ametsuchi + PRIVATE SOCI_USE_BOOST HAVE_BOOST + ) diff --git a/irohad/ametsuchi/impl/postgres_block_index.hpp b/irohad/ametsuchi/impl/postgres_block_index.hpp index a2f0e20141..60a917bc83 100644 --- a/irohad/ametsuchi/impl/postgres_block_index.hpp +++ b/irohad/ametsuchi/impl/postgres_block_index.hpp @@ -21,7 +21,7 @@ #include #include "ametsuchi/impl/block_index.hpp" -#include "ametsuchi/impl/postgres_wsv_common.hpp" +#include "ametsuchi/impl/soci_utils.hpp" #include "interfaces/transaction.hpp" #include "logger/logger.hpp" diff --git a/irohad/ametsuchi/impl/postgres_block_query.hpp b/irohad/ametsuchi/impl/postgres_block_query.hpp index cf43616657..1d6e1cd6ca 100644 --- a/irohad/ametsuchi/impl/postgres_block_query.hpp +++ b/irohad/ametsuchi/impl/postgres_block_query.hpp @@ -23,7 +23,7 @@ #include "ametsuchi/block_query.hpp" #include "ametsuchi/impl/flat_file/flat_file.hpp" #include "logger/logger.hpp" -#include "postgres_wsv_common.hpp" +#include "ametsuchi/impl/soci_utils.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_ordering_service_persistent_state.hpp b/irohad/ametsuchi/impl/postgres_ordering_service_persistent_state.hpp index af2013d92f..5c7dc45106 100644 --- a/irohad/ametsuchi/impl/postgres_ordering_service_persistent_state.hpp +++ b/irohad/ametsuchi/impl/postgres_ordering_service_persistent_state.hpp @@ -18,7 +18,7 @@ #ifndef IROHA_POSTGRES_ORDERING_SERVICE_PERSISTENT_STATE_HPP #define IROHA_POSTGRES_ORDERING_SERVICE_PERSISTENT_STATE_HPP -#include "ametsuchi/impl/postgres_wsv_common.hpp" +#include "ametsuchi/impl/soci_utils.hpp" #include "ametsuchi/ordering_service_persistent_state.hpp" #include "common/result.hpp" #include "logger/logger.hpp" diff --git a/irohad/ametsuchi/impl/postgres_wsv_command.cpp b/irohad/ametsuchi/impl/postgres_wsv_command.cpp index fae2254c83..d5b77038af 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_command.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_command.cpp @@ -17,10 +17,16 @@ #include "ametsuchi/impl/postgres_wsv_command.hpp" +#include + #include #include "backend/protobuf/permissions.hpp" +#include "interfaces/common_objects/account.hpp" +#include "interfaces/common_objects/account_asset.hpp" #include "interfaces/common_objects/asset.hpp" +#include "interfaces/common_objects/domain.hpp" +#include "interfaces/common_objects/peer.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_wsv_command.hpp b/irohad/ametsuchi/impl/postgres_wsv_command.hpp index 9785cb98f1..9f1cbe7ae1 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_command.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_command.hpp @@ -20,7 +20,7 @@ #include "ametsuchi/wsv_command.hpp" -#include "ametsuchi/impl/postgres_wsv_common.hpp" +#include "ametsuchi/impl/soci_utils.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_wsv_common.hpp b/irohad/ametsuchi/impl/postgres_wsv_common.hpp deleted file mode 100644 index 57a2368550..0000000000 --- a/irohad/ametsuchi/impl/postgres_wsv_common.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. 2018 All Rights Reserved. - * http://soramitsu.co.jp - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef IROHA_POSTGRES_WSV_COMMON_HPP -#define IROHA_POSTGRES_WSV_COMMON_HPP - -#include - -#define SOCI_USE_BOOST -#define HAVE_BOOST -#include -#include - -#include "common/result.hpp" -#include "interfaces/common_objects/common_objects_factory.hpp" -#include "logger/logger.hpp" - -namespace iroha { - namespace ametsuchi { - - /** - * Transforms soci::rowset to vector of Ts by applying - * transform_func - * @tparam T - type to transform to - * @tparam Operator - type of transformation function, must return T - * @param result - soci::rowset which contains several rows from - * the database - * @param transform_func - function which transforms result row to T - * @return vector of target type - */ - template - std::vector transform(const soci::rowset &result, - Operator &&transform_func) noexcept { - std::vector values; - std::transform(result.begin(), - result.end(), - std::back_inserter(values), - transform_func); - - return values; - } - - template - void processSoci(soci::statement &st, - soci::indicator &ind, - ParamType &row, - Function f) { - while (st.fetch()) { - switch (ind) { - case soci::i_ok: - f(row); - case soci::i_null: - case soci::i_truncated: - break; - } - } - } - - /** - * Transforms result to optional - * value -> optional - * error -> nullopt - * @tparam T type of object inside - * @param result BuilderResult - * @return optional - */ - template - inline boost::optional> fromResult( - shared_model::interface::CommonObjectsFactory::FactoryResult< - std::unique_ptr> &&result) { - return result.match( - [](expected::Value> &v) { - return boost::make_optional(std::shared_ptr(std::move(v.value))); - }, - [](expected::Error) - -> boost::optional> { return boost::none; }); - } - } // namespace ametsuchi -} // namespace iroha -#endif // IROHA_POSTGRES_WSV_COMMON_HPP diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.cpp b/irohad/ametsuchi/impl/postgres_wsv_query.cpp index c9163966cd..224da8775f 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.cpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.cpp @@ -16,9 +16,35 @@ */ #include "ametsuchi/impl/postgres_wsv_query.hpp" + +#include + +#include "ametsuchi/impl/soci_utils.hpp" #include "backend/protobuf/permissions.hpp" #include "common/result.hpp" +namespace { + /** + * Transforms result to optional + * value -> optional + * error -> nullopt + * @tparam T type of object inside + * @param result BuilderResult + * @return optional + */ + template + boost::optional> fromResult( + shared_model::interface::CommonObjectsFactory::FactoryResult< + std::unique_ptr> &&result) { + return result.match( + [](iroha::expected::Value> &v) { + return boost::make_optional(std::shared_ptr(std::move(v.value))); + }, + [](iroha::expected::Error) + -> boost::optional> { return boost::none; }); + } +} // namespace + namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/postgres_wsv_query.hpp b/irohad/ametsuchi/impl/postgres_wsv_query.hpp index ee648b83b2..49795a08dd 100644 --- a/irohad/ametsuchi/impl/postgres_wsv_query.hpp +++ b/irohad/ametsuchi/impl/postgres_wsv_query.hpp @@ -20,8 +20,10 @@ #include "ametsuchi/wsv_query.hpp" +#include + #include "interfaces/common_objects/common_objects_factory.hpp" -#include "postgres_wsv_common.hpp" +#include "logger/logger.hpp" namespace iroha { namespace ametsuchi { diff --git a/irohad/ametsuchi/impl/soci_utils.hpp b/irohad/ametsuchi/impl/soci_utils.hpp new file mode 100644 index 0000000000..6efcab4a87 --- /dev/null +++ b/irohad/ametsuchi/impl/soci_utils.hpp @@ -0,0 +1,42 @@ +/** + * Copyright Soramitsu Co., Ltd. 2018 All Rights Reserved. + * http://soramitsu.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IROHA_POSTGRES_WSV_COMMON_HPP +#define IROHA_POSTGRES_WSV_COMMON_HPP + +#include + +namespace iroha { + namespace ametsuchi { + template + inline void processSoci(soci::statement &st, + soci::indicator &ind, + ParamType &row, + Function f) { + while (st.fetch()) { + switch (ind) { + case soci::i_ok: + f(row); + case soci::i_null: + case soci::i_truncated: + break; + } + } + } + } // namespace ametsuchi +} // namespace iroha +#endif // IROHA_POSTGRES_WSV_COMMON_HPP diff --git a/shared_model/interfaces/common_objects/common_objects_factory.hpp b/shared_model/interfaces/common_objects/common_objects_factory.hpp index e912c91d8d..64161c4361 100644 --- a/shared_model/interfaces/common_objects/common_objects_factory.hpp +++ b/shared_model/interfaces/common_objects/common_objects_factory.hpp @@ -10,13 +10,12 @@ #include "common/result.hpp" #include "interfaces/common_objects/account.hpp" -#include "interfaces/common_objects/peer.hpp" -#include "interfaces/common_objects/types.hpp" -#include "interfaces/common_objects/domain.hpp" #include "interfaces/common_objects/account_asset.hpp" #include "interfaces/common_objects/asset.hpp" #include "interfaces/common_objects/domain.hpp" +#include "interfaces/common_objects/peer.hpp" #include "interfaces/common_objects/signature.hpp" +#include "interfaces/common_objects/types.hpp" namespace shared_model { namespace interface {