LCOV - code coverage report
Current view: top level - shared_model/builders/protobuf/builder_templates - transaction_template.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 110 110 100.0 %
Date: 2018-12-05 17:11:35 Functions: 318 368 86.4 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       6             : #ifndef IROHA_PROTO_TRANSACTION_BUILDER_TEMPLATE_HPP
       7             : #define IROHA_PROTO_TRANSACTION_BUILDER_TEMPLATE_HPP
       8             : 
       9             : #include "backend/protobuf/transaction.hpp"
      10             : 
      11             : #include <boost/range/algorithm/for_each.hpp>
      12             : 
      13             : #include "commands.pb.h"
      14             : #include "primitive.pb.h"
      15             : #include "transaction.pb.h"
      16             : 
      17             : #include "backend/protobuf/permissions.hpp"
      18             : #include "builders/protobuf/unsigned_proto.hpp"
      19             : #include "interfaces/common_objects/types.hpp"
      20             : #include "interfaces/permissions.hpp"
      21             : #include "validators/default_validator.hpp"
      22             : 
      23             : namespace shared_model {
      24             :   namespace proto {
      25             : 
      26             :     /**
      27             :      * Template tx builder for creating new types of transaction builders by
      28             :      * means of replacing template parameters
      29             :      * @tparam S -- field counter for checking that all required fields are set
      30             :      * @tparam SV -- stateless validator called when build method is invoked
      31             :      * @tparam BT -- build type of built object returned by build method
      32             :      */
      33             :     template <int S = 0,
      34             :               typename SV = validation::DefaultUnsignedTransactionValidator,
      35             :               typename BT = UnsignedWrapper<Transaction>>
      36             :     class DEPRECATED TemplateTransactionBuilder {
      37             :      private:
      38             :       template <int, typename, typename>
      39             :       friend class TemplateTransactionBuilder;
      40             : 
      41             :       enum RequiredFields {
      42             :         Command,
      43             :         CreatorAccountId,
      44             :         CreatedTime,
      45             :         Quorum,
      46             :         TOTAL
      47             :       };
      48             : 
      49             :       template <int s>
      50             :       using NextBuilder = TemplateTransactionBuilder<S | (1 << s), SV, BT>;
      51             : 
      52             :       using ProtoTx = iroha::protocol::Transaction;
      53             :       using ProtoCommand = iroha::protocol::Command;
      54             : 
      55             :       template <int Sp>
      56             :       TemplateTransactionBuilder(
      57             :           const TemplateTransactionBuilder<Sp, SV, BT> &o)
      58         383 :           : transaction_(o.transaction_),
      59         383 :             stateless_validator_(o.stateless_validator_) {}
      60             : 
      61             :       /**
      62             :        * Make transformation on copied content
      63             :        * @tparam Transformation - callable type for changing the copy
      64             :        * @param f - transform function for proto object
      65             :        * @return new builder with updated state
      66             :        */
      67             :       template <int Fields, typename Transformation>
      68             :       auto transform(Transformation t) const {
      69        5816 :         NextBuilder<Fields> copy = *this;
      70        5816 :         t(copy.transaction_);
      71        5816 :         return copy;
      72        5816 :       }
      73             : 
      74             :       /**
      75             :        * Make add command transformation on copied object
      76             :        * @tparam Transformation - callable type for changing command
      77             :        * @param f - transform function for proto command
      78             :        * @return new builder with added command
      79             :        */
      80             :       template <typename Transformation>
      81             :       auto addCommand(Transformation t) const {
      82        5969 :         NextBuilder<Command> copy = *this;
      83        5969 :         t(copy.transaction_.mutable_payload()
      84        5969 :               ->mutable_reduced_payload()
      85        5969 :               ->add_commands());
      86        5969 :         return copy;
      87        5969 :       }
      88             : 
      89             :      public:
      90             :       TemplateTransactionBuilder(const SV &validator = SV())
      91        6420 :           : stateless_validator_(validator) {}
      92             : 
      93             :       auto creatorAccountId(
      94             :           const interface::types::AccountIdType &account_id) const {
      95             :         return transform<CreatorAccountId>([&](auto &tx) {
      96        5627 :           tx.mutable_payload()
      97        5627 :               ->mutable_reduced_payload()
      98        5627 :               ->set_creator_account_id(account_id);
      99        5627 :         });
     100             :       }
     101             : 
     102             :       auto batchMeta(interface::types::BatchType type,
     103             :                      std::vector<interface::types::HashType> hashes) const {
     104             :         return transform<0>([&](auto &tx) {
     105        2190 :           tx.mutable_payload()->mutable_batch()->set_type(
     106             :               static_cast<
     107             :                   iroha::protocol::Transaction::Payload::BatchMeta::BatchType>(
     108        2190 :                   type));
     109        4781 :           for (const auto &hash : hashes) {
     110        2591 :             tx.mutable_payload()->mutable_batch()->add_reduced_hashes(
     111        2591 :                 crypto::toBinaryString(hash));
     112             :           }
     113        2190 :         });
     114             :       }
     115             : 
     116             :       auto createdTime(interface::types::TimestampType created_time) const {
     117             :         return transform<CreatedTime>([&](auto &tx) {
     118        5421 :           tx.mutable_payload()->mutable_reduced_payload()->set_created_time(
     119        5421 :               created_time);
     120        5421 :         });
     121             :       }
     122             : 
     123             :       auto quorum(interface::types::QuorumType quorum) const {
     124             :         return transform<Quorum>([&](auto &tx) {
     125        5427 :           tx.mutable_payload()->mutable_reduced_payload()->set_quorum(quorum);
     126        5427 :         });
     127             :       }
     128             : 
     129             :       auto addAssetQuantity(const interface::types::AssetIdType &asset_id,
     130             :                             const std::string &amount) const {
     131             :         return addCommand([&](auto proto_command) {
     132         144 :           auto command = proto_command->mutable_add_asset_quantity();
     133         144 :           command->set_asset_id(asset_id);
     134         144 :           command->set_amount(amount);
     135         144 :         });
     136             :       }
     137             : 
     138             :       auto addPeer(const interface::types::AddressType &address,
     139             :                    const interface::types::PubkeyType &peer_key) const {
     140             :         return addCommand([&](auto proto_command) {
     141         261 :           auto command = proto_command->mutable_add_peer();
     142         261 :           auto peer = command->mutable_peer();
     143         261 :           peer->set_address(address);
     144         261 :           peer->set_peer_key(crypto::toBinaryString(peer_key));
     145         261 :         });
     146             :       }
     147             : 
     148             :       auto addSignatory(const interface::types::AccountIdType &account_id,
     149             :                         const interface::types::PubkeyType &public_key) const {
     150             :         return addCommand([&](auto proto_command) {
     151         115 :           auto command = proto_command->mutable_add_signatory();
     152         115 :           command->set_account_id(account_id);
     153         115 :           command->set_public_key(crypto::toBinaryString(public_key));
     154         115 :         });
     155             :       }
     156             : 
     157             :       auto removeSignatory(
     158             :           const interface::types::AccountIdType &account_id,
     159             :           const interface::types::PubkeyType &public_key) const {
     160             :         return addCommand([&](auto proto_command) {
     161          21 :           auto command = proto_command->mutable_remove_signatory();
     162          21 :           command->set_account_id(account_id);
     163          21 :           command->set_public_key(crypto::toBinaryString(public_key));
     164          21 :         });
     165             :       }
     166             : 
     167             :       auto appendRole(const interface::types::AccountIdType &account_id,
     168             :                       const interface::types::RoleIdType &role_name) const {
     169             :         return addCommand([&](auto proto_command) {
     170         670 :           auto command = proto_command->mutable_append_role();
     171         670 :           command->set_account_id(account_id);
     172         670 :           command->set_role_name(role_name);
     173         670 :         });
     174             :       }
     175             : 
     176             :       auto createAsset(const interface::types::AssetNameType &asset_name,
     177             :                        const interface::types::DomainIdType &domain_id,
     178             :                        interface::types::PrecisionType precision) const {
     179             :         return addCommand([&](auto proto_command) {
     180         440 :           auto command = proto_command->mutable_create_asset();
     181         440 :           command->set_asset_name(asset_name);
     182         440 :           command->set_domain_id(domain_id);
     183         440 :           command->set_precision(precision);
     184         440 :         });
     185             :       }
     186             : 
     187             :       auto createAccount(
     188             :           const interface::types::AccountNameType &account_name,
     189             :           const interface::types::DomainIdType &domain_id,
     190             :           const interface::types::PubkeyType &main_pubkey) const {
     191             :         return addCommand([&](auto proto_command) {
     192         872 :           auto command = proto_command->mutable_create_account();
     193         872 :           command->set_account_name(account_name);
     194         872 :           command->set_domain_id(domain_id);
     195         872 :           command->set_public_key(crypto::toBinaryString(main_pubkey));
     196         872 :         });
     197             :       }
     198             : 
     199             :       auto createDomain(
     200             :           const interface::types::DomainIdType &domain_id,
     201             :           const interface::types::RoleIdType &default_role) const {
     202             :         return addCommand([&](auto proto_command) {
     203         509 :           auto command = proto_command->mutable_create_domain();
     204         509 :           command->set_domain_id(domain_id);
     205         509 :           command->set_default_role(default_role);
     206         509 :         });
     207             :       }
     208             : 
     209             :       auto createRole(const interface::types::RoleIdType &role_name,
     210             :                       const interface::RolePermissionSet &permissions) const {
     211             :         return addCommand([&](auto proto_command) {
     212        1076 :           auto command = proto_command->mutable_create_role();
     213        1076 :           command->set_role_name(role_name);
     214       47344 :           for (size_t i = 0; i < permissions.size(); ++i) {
     215       46268 :             auto perm = static_cast<interface::permissions::Role>(i);
     216       46268 :             if (permissions.test(perm)) {
     217       13266 :               command->add_permissions(permissions::toTransport(perm));
     218       13266 :             }
     219       46268 :           }
     220        1076 :         });
     221             :       }
     222             : 
     223             :       auto detachRole(const interface::types::AccountIdType &account_id,
     224             :                       const interface::types::RoleIdType &role_name) const {
     225             :         return addCommand([&](auto proto_command) {
     226         572 :           auto command = proto_command->mutable_detach_role();
     227         572 :           command->set_account_id(account_id);
     228         572 :           command->set_role_name(role_name);
     229         572 :         });
     230             :       }
     231             : 
     232             :       auto grantPermission(const interface::types::AccountIdType &account_id,
     233             :                            interface::permissions::Grantable permission) const {
     234             :         return addCommand([&](auto proto_command) {
     235          35 :           auto command = proto_command->mutable_grant_permission();
     236          35 :           command->set_account_id(account_id);
     237          35 :           command->set_permission(permissions::toTransport(permission));
     238          35 :         });
     239             :       }
     240             : 
     241             :       auto revokePermission(
     242             :           const interface::types::AccountIdType &account_id,
     243             :           interface::permissions::Grantable permission) const {
     244             :         return addCommand([&](auto proto_command) {
     245          11 :           auto command = proto_command->mutable_revoke_permission();
     246          11 :           command->set_account_id(account_id);
     247          11 :           command->set_permission(permissions::toTransport(permission));
     248          11 :         });
     249             :       }
     250             : 
     251             :       auto setAccountDetail(
     252             :           const interface::types::AccountIdType &account_id,
     253             :           const interface::types::AccountDetailKeyType &key,
     254             :           const interface::types::AccountDetailValueType &value) const {
     255             :         return addCommand([&](auto proto_command) {
     256          94 :           auto command = proto_command->mutable_set_account_detail();
     257          94 :           command->set_account_id(account_id);
     258          94 :           command->set_key(key);
     259          94 :           command->set_value(value);
     260          94 :         });
     261             :       }
     262             : 
     263             :       auto setAccountQuorum(const interface::types::AddressType &account_id,
     264             :                             interface::types::QuorumType quorum) const {
     265             :         return addCommand([&](auto proto_command) {
     266        4322 :           auto command = proto_command->mutable_set_account_quorum();
     267        4322 :           command->set_account_id(account_id);
     268        4322 :           command->set_quorum(quorum);
     269        4322 :         });
     270             :       }
     271             : 
     272             :       auto subtractAssetQuantity(const interface::types::AssetIdType &asset_id,
     273             :                                  const std::string &amount) const {
     274             :         return addCommand([&](auto proto_command) {
     275          11 :           auto command = proto_command->mutable_subtract_asset_quantity();
     276          11 :           command->set_asset_id(asset_id);
     277          11 :           command->set_amount(amount);
     278          11 :         });
     279             :       }
     280             : 
     281             :       auto transferAsset(const interface::types::AccountIdType &src_account_id,
     282             :                          const interface::types::AccountIdType &dest_account_id,
     283             :                          const interface::types::AssetIdType &asset_id,
     284             :                          const interface::types::DescriptionType &description,
     285             :                          const std::string &amount) const {
     286             :         return addCommand([&](auto proto_command) {
     287         105 :           auto command = proto_command->mutable_transfer_asset();
     288         105 :           command->set_src_account_id(src_account_id);
     289         105 :           command->set_dest_account_id(dest_account_id);
     290         105 :           command->set_asset_id(asset_id);
     291         105 :           command->set_description(description);
     292         105 :           command->set_amount(amount);
     293         105 :         });
     294             :       }
     295             : 
     296             :       auto build() const {
     297             :         static_assert(S == (1 << TOTAL) - 1, "Required fields are not set");
     298        6516 :         auto result = Transaction(iroha::protocol::Transaction(transaction_));
     299        6516 :         auto answer = stateless_validator_.validate(result);
     300        6518 :         if (answer.hasErrors()) {
     301           1 :           throw std::invalid_argument(answer.reason());
     302             :         }
     303        6517 :         return BT(std::move(result));
     304        6517 :       }
     305             : 
     306             :       static const int total = RequiredFields::TOTAL;
     307             : 
     308             :      private:
     309             :       ProtoTx transaction_;
     310             :       SV stateless_validator_;
     311             :     };
     312             : 
     313             :   }  // namespace proto
     314             : }  // namespace shared_model
     315             : 
     316             : #endif  // IROHA_PROTO_TRANSACTION_BUILDER_TEMPLATE_HPP

Generated by: LCOV version 1.13