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_COMMON_OBJECTS_FACTORY_HPP
7 : #define IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP
8 :
9 : #include <regex>
10 :
11 : #include "backend/protobuf/common_objects/account.hpp"
12 : #include "backend/protobuf/common_objects/account_asset.hpp"
13 : #include "backend/protobuf/common_objects/asset.hpp"
14 : #include "backend/protobuf/common_objects/domain.hpp"
15 : #include "backend/protobuf/common_objects/peer.hpp"
16 : #include "backend/protobuf/common_objects/signature.hpp"
17 : #include "common/result.hpp"
18 : #include "interfaces/common_objects/common_objects_factory.hpp"
19 : #include "primitive.pb.h"
20 : #include "validators/answer.hpp"
21 :
22 : namespace shared_model {
23 : namespace proto {
24 : /**
25 : * ProtoCommonObjectsFactory constructs protobuf-based objects.
26 : * It performs stateless validation with provided validator
27 : * @tparam Validator
28 : */
29 : template <typename Validator>
30 : class ProtoCommonObjectsFactory : public interface::CommonObjectsFactory {
31 : public:
32 : FactoryResult<std::unique_ptr<interface::Peer>> createPeer(
33 : const interface::types::AddressType &address,
34 : const interface::types::PubkeyType &public_key) override {
35 4156 : iroha::protocol::Peer peer;
36 4156 : peer.set_address(address);
37 4156 : peer.set_peer_key(crypto::toBinaryString(public_key));
38 4156 : auto proto_peer = std::make_unique<Peer>(std::move(peer));
39 :
40 : auto errors =
41 : validate(*proto_peer, [this](const auto &peer, auto &reasons) {
42 4156 : validator_.validatePeer(reasons, peer);
43 4156 : });
44 :
45 4156 : if (errors) {
46 1 : return iroha::expected::makeError(errors.reason());
47 : }
48 :
49 4155 : return iroha::expected::makeValue<std::unique_ptr<interface::Peer>>(
50 4155 : std::move(proto_peer));
51 4156 : }
52 :
53 : FactoryResult<std::unique_ptr<interface::Account>> createAccount(
54 : const interface::types::AccountIdType &account_id,
55 : const interface::types::DomainIdType &domain_id,
56 : interface::types::QuorumType quorum,
57 : const interface::types::JsonType &jsonData) override {
58 18 : iroha::protocol::Account account;
59 18 : account.set_account_id(account_id);
60 18 : account.set_domain_id(domain_id);
61 18 : account.set_quorum(quorum);
62 18 : account.set_json_data(jsonData);
63 :
64 18 : auto proto_account = std::make_unique<Account>(std::move(account));
65 :
66 18 : auto errors = validate(
67 : *proto_account, [this](const auto &account, auto &reasons) {
68 18 : validator_.validateAccountId(reasons, account.accountId());
69 18 : validator_.validateDomainId(reasons, account.domainId());
70 18 : validator_.validateQuorum(reasons, account.quorum());
71 18 : });
72 :
73 18 : if (errors) {
74 1 : return iroha::expected::makeError(errors.reason());
75 : }
76 :
77 17 : return iroha::expected::makeValue<std::unique_ptr<interface::Account>>(
78 17 : std::move(proto_account));
79 18 : }
80 :
81 : FactoryResult<std::unique_ptr<interface::AccountAsset>>
82 : createAccountAsset(const interface::types::AccountIdType &account_id,
83 : const interface::types::AssetIdType &asset_id,
84 : const interface::Amount &balance) override {
85 35 : iroha::protocol::AccountAsset asset;
86 35 : asset.set_account_id(account_id);
87 35 : asset.set_asset_id(asset_id);
88 35 : asset.set_balance(balance.toStringRepr());
89 :
90 35 : auto proto_asset = std::make_unique<AccountAsset>(std::move(asset));
91 :
92 : auto errors =
93 : validate(*proto_asset, [this](const auto &asset, auto &reasons) {
94 35 : validator_.validateAccountId(reasons, asset.accountId());
95 35 : validator_.validateAssetId(reasons, asset.assetId());
96 35 : });
97 :
98 35 : if (errors) {
99 1 : return iroha::expected::makeError(errors.reason());
100 : }
101 :
102 34 : return iroha::expected::makeValue<
103 34 : std::unique_ptr<interface::AccountAsset>>(std::move(proto_asset));
104 35 : }
105 :
106 : FactoryResult<std::unique_ptr<interface::Asset>> createAsset(
107 : const interface::types::AssetIdType &asset_id,
108 : const interface::types::DomainIdType &domain_id,
109 : interface::types::PrecisionType precision) override {
110 3 : iroha::protocol::Asset asset;
111 3 : asset.set_asset_id(asset_id);
112 3 : asset.set_domain_id(domain_id);
113 3 : asset.set_precision(precision);
114 :
115 3 : auto proto_asset = std::make_unique<Asset>(std::move(asset));
116 :
117 : auto errors =
118 : validate(*proto_asset, [this](const auto &asset, auto &reasons) {
119 3 : validator_.validateAssetId(reasons, asset.assetId());
120 3 : validator_.validateDomainId(reasons, asset.domainId());
121 3 : });
122 :
123 3 : if (errors) {
124 1 : return iroha::expected::makeError(errors.reason());
125 : }
126 :
127 2 : return iroha::expected::makeValue<std::unique_ptr<interface::Asset>>(
128 2 : std::move(proto_asset));
129 3 : }
130 :
131 : FactoryResult<std::unique_ptr<interface::Domain>> createDomain(
132 : const interface::types::DomainIdType &domain_id,
133 : const interface::types::RoleIdType &default_role) override {
134 5 : iroha::protocol::Domain domain;
135 5 : domain.set_domain_id(domain_id);
136 5 : domain.set_default_role(default_role);
137 :
138 5 : auto proto_domain = std::make_unique<Domain>(std::move(domain));
139 :
140 : auto errors =
141 : validate(*proto_domain, [this](const auto &domain, auto &reason) {
142 5 : validator_.validateDomainId(reason, domain.domainId());
143 5 : validator_.validateRoleId(reason, domain.defaultRole());
144 5 : });
145 :
146 5 : if (errors) {
147 1 : return iroha::expected::makeError(errors.reason());
148 : }
149 :
150 4 : return iroha::expected::makeValue<std::unique_ptr<interface::Domain>>(
151 4 : std::move(proto_domain));
152 5 : }
153 :
154 : FactoryResult<std::unique_ptr<interface::Signature>> createSignature(
155 : const interface::types::PubkeyType &key,
156 : const interface::Signature::SignedType &signed_data) override {
157 3571 : iroha::protocol::Signature signature;
158 3571 : signature.set_public_key(crypto::toBinaryString(key));
159 3572 : signature.set_signature(crypto::toBinaryString(signed_data));
160 :
161 : auto proto_singature =
162 3571 : std::make_unique<Signature>(std::move(signature));
163 :
164 3569 : auto errors = validate(
165 : *proto_singature, [this](const auto &signature, auto &reason) {
166 3572 : validator_.validatePubkey(reason, signature.publicKey());
167 3572 : });
168 :
169 3572 : if (errors) {
170 1 : return iroha::expected::makeError(errors.reason());
171 : }
172 :
173 3571 : return iroha::expected::makeValue<
174 3570 : std::unique_ptr<interface::Signature>>(std::move(proto_singature));
175 3572 : }
176 :
177 : private:
178 : /**
179 : * Perform validation of a given object
180 : * @param o - object to be validated
181 : * @param f - function which populates reason parameter with errors.
182 : * second parameter (reasons) must be passed by non-const reference
183 : * @return validation result
184 : */
185 : template <typename T, typename ValidationFunc>
186 : validation::Answer validate(const T &o, ValidationFunc &&f) const {
187 4190 : shared_model::validation::Answer errors;
188 4190 : validation::ReasonsGroupType reasons;
189 4190 : f(o, reasons);
190 4190 : if (not reasons.second.empty()) {
191 1 : errors.addReason(std::move(reasons));
192 1 : }
193 4190 : return errors;
194 4190 : }
195 :
196 : Validator validator_;
197 : };
198 : } // namespace proto
199 : } // namespace shared_model
200 :
201 : #endif // IROHA_PROTO_COMMON_OBJECTS_FACTORY_HPP
|