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_POSTGRES_QUERY_EXECUTOR_HPP
7 : #define IROHA_POSTGRES_QUERY_EXECUTOR_HPP
8 :
9 : #include "ametsuchi/query_executor.hpp"
10 :
11 : #include "ametsuchi/impl/soci_utils.hpp"
12 : #include "ametsuchi/key_value_storage.hpp"
13 : #include "ametsuchi/storage.hpp"
14 : #include "interfaces/commands/add_asset_quantity.hpp"
15 : #include "interfaces/commands/add_peer.hpp"
16 : #include "interfaces/commands/add_signatory.hpp"
17 : #include "interfaces/commands/append_role.hpp"
18 : #include "interfaces/commands/create_account.hpp"
19 : #include "interfaces/commands/create_asset.hpp"
20 : #include "interfaces/commands/create_domain.hpp"
21 : #include "interfaces/commands/create_role.hpp"
22 : #include "interfaces/commands/detach_role.hpp"
23 : #include "interfaces/commands/grant_permission.hpp"
24 : #include "interfaces/commands/remove_signatory.hpp"
25 : #include "interfaces/commands/revoke_permission.hpp"
26 : #include "interfaces/commands/set_account_detail.hpp"
27 : #include "interfaces/commands/set_quorum.hpp"
28 : #include "interfaces/commands/subtract_asset_quantity.hpp"
29 : #include "interfaces/commands/transfer_asset.hpp"
30 : #include "interfaces/iroha_internal/block_json_converter.hpp"
31 : #include "interfaces/iroha_internal/query_response_factory.hpp"
32 : #include "interfaces/permission_to_string.hpp"
33 : #include "interfaces/queries/blocks_query.hpp"
34 : #include "interfaces/queries/query.hpp"
35 : #include "interfaces/query_responses/query_response.hpp"
36 : #include "logger/logger_fwd.hpp"
37 : #include "logger/logger_manager_fwd.hpp"
38 :
39 : namespace iroha {
40 : namespace ametsuchi {
41 :
42 : using QueryErrorType =
43 : shared_model::interface::QueryResponseFactory::ErrorQueryType;
44 :
45 : using ErrorQueryResponse = shared_model::interface::ErrorQueryResponse;
46 : using QueryErrorMessageType = ErrorQueryResponse::ErrorMessageType;
47 : using QueryErrorCodeType = ErrorQueryResponse::ErrorCodeType;
48 :
49 : class PostgresQueryExecutorVisitor
50 : : public boost::static_visitor<QueryExecutorResult> {
51 : public:
52 : PostgresQueryExecutorVisitor(
53 : soci::session &sql,
54 : KeyValueStorage &block_store,
55 : std::shared_ptr<PendingTransactionStorage> pending_txs_storage,
56 : std::shared_ptr<shared_model::interface::BlockJsonConverter>
57 : converter,
58 : std::shared_ptr<shared_model::interface::QueryResponseFactory>
59 : response_factory,
60 : std::shared_ptr<shared_model::interface::PermissionToString>
61 : perm_converter,
62 : logger::LoggerPtr log);
63 :
64 : void setCreatorId(
65 : const shared_model::interface::types::AccountIdType &creator_id);
66 :
67 : void setQueryHash(const shared_model::crypto::Hash &query_hash);
68 :
69 : /**
70 : * Check that account has a specific role permission
71 : * @param permission to be in that account
72 : * @param account_id of account to be checked
73 : * @return true, if account has that permission, false otherwise
74 : */
75 : bool hasAccountRolePermission(
76 : shared_model::interface::permissions::Role permission,
77 : const std::string &account_id) const;
78 :
79 : QueryExecutorResult operator()(
80 : const shared_model::interface::GetAccount &q);
81 :
82 : QueryExecutorResult operator()(
83 : const shared_model::interface::GetBlock &q);
84 :
85 : QueryExecutorResult operator()(
86 : const shared_model::interface::GetSignatories &q);
87 :
88 : QueryExecutorResult operator()(
89 : const shared_model::interface::GetAccountTransactions &q);
90 :
91 : QueryExecutorResult operator()(
92 : const shared_model::interface::GetTransactions &q);
93 :
94 : QueryExecutorResult operator()(
95 : const shared_model::interface::GetAccountAssetTransactions &q);
96 :
97 : QueryExecutorResult operator()(
98 : const shared_model::interface::GetAccountAssets &q);
99 :
100 : QueryExecutorResult operator()(
101 : const shared_model::interface::GetAccountDetail &q);
102 :
103 : QueryExecutorResult operator()(
104 : const shared_model::interface::GetRoles &q);
105 :
106 : QueryExecutorResult operator()(
107 : const shared_model::interface::GetRolePermissions &q);
108 :
109 : QueryExecutorResult operator()(
110 : const shared_model::interface::GetAssetInfo &q);
111 :
112 : QueryExecutorResult operator()(
113 : const shared_model::interface::GetPendingTransactions &q);
114 :
115 : private:
116 : /**
117 : * Get transactions from block using range from range_gen and filtered by
118 : * predicate pred
119 : */
120 : template <typename RangeGen, typename Pred>
121 : std::vector<std::unique_ptr<shared_model::interface::Transaction>>
122 : getTransactionsFromBlock(uint64_t block_id,
123 : RangeGen &&range_gen,
124 : Pred &&pred);
125 :
126 : /**
127 : * Execute query and return its response
128 : * @tparam QueryTuple - types of values, returned by the query
129 : * @tparam PermissionTuple - permissions, needed for the query
130 : * @tparam QueryExecutor - type of function, which executes the query
131 : * @tparam ResponseCreator - type of function, which creates response of
132 : * the query, successful or error one
133 : * @tparam PermissionsErrResponse - type of function, which creates error
134 : * response in case something wrong with permissions
135 : * @param query_executor - function, executing query
136 : * @param response_creator - function, creating query response
137 : * @param perms_err_response - function, creating error response
138 : * @return query response created as a result of query execution
139 : */
140 : template <typename QueryTuple,
141 : typename PermissionTuple,
142 : typename QueryExecutor,
143 : typename ResponseCreator,
144 : typename PermissionsErrResponse>
145 : QueryExecutorResult executeQuery(
146 : QueryExecutor &&query_executor,
147 : ResponseCreator &&response_creator,
148 : PermissionsErrResponse &&perms_err_response);
149 :
150 : /**
151 : * Create a query error response and log it
152 : * @param error_type - type of query error
153 : * @param error_body - stringified error of the query
154 : * @param error_code of the query
155 : * @return ptr to created error response
156 : */
157 : std::unique_ptr<shared_model::interface::QueryResponse>
158 : logAndReturnErrorResponse(iroha::ametsuchi::QueryErrorType error_type,
159 : QueryErrorMessageType error_body,
160 : QueryErrorCodeType error_code) const;
161 :
162 : /**
163 : * Execute query which returns list of transactions
164 : * uses pagination
165 : * @param query - query object
166 : * @param qry_checker - fallback checker of the query, needed if paging
167 : * hash is not specified and 0 transaction are returned as a query result
168 : * @param related_txs - SQL query which returns transaction relevant
169 : * to this query
170 : * @param applier - function which accepts SQL
171 : * and returns another function which executes that query
172 : * @param perms - permissions, necessary to execute the query
173 : * @return Result of a query execution
174 : */
175 : template <typename Query,
176 : typename QueryChecker,
177 : typename QueryApplier,
178 : typename... Permissions>
179 : QueryExecutorResult executeTransactionsQuery(
180 : const Query &query,
181 : QueryChecker &&qry_checker,
182 : const std::string &related_txs,
183 : QueryApplier applier,
184 : Permissions... perms);
185 :
186 : /**
187 : * Check if entry with such key exists in the database
188 : * @tparam ReturnValueType - type of the value to be returned in the
189 : * underlying query
190 : * @param table_name - name of the table to be checked
191 : * @param key_name - name of the table attribute, against which the search
192 : * is performed
193 : * @param value_name - name of the value, which is to be returned
194 : * from the search (attribute with such name is to exist)
195 : * @param value - actual value of the key attribute
196 : * @return true, if entry with such value of the key attribute exists,
197 : * false otherwise
198 : *
199 : * @throws if check query finishes with an exception
200 : */
201 : template <typename ReturnValueType>
202 : bool existsInDb(const std::string &table_name,
203 : const std::string &key_name,
204 : const std::string &value_name,
205 : const std::string &value) const;
206 :
207 : struct QueryFallbackCheckResult {
208 : QueryFallbackCheckResult() = default;
209 : QueryFallbackCheckResult(
210 : shared_model::interface::ErrorQueryResponse::ErrorCodeType
211 : error_code,
212 : shared_model::interface::ErrorQueryResponse::ErrorMessageType
213 : &&error_message)
214 3 : : contains_error{true},
215 3 : error_code{error_code},
216 3 : error_message{std::move(error_message)} {}
217 :
218 : explicit operator bool() const {
219 5 : return contains_error;
220 : }
221 2 : bool contains_error = false;
222 2 : shared_model::interface::ErrorQueryResponse::ErrorCodeType error_code =
223 : 0;
224 : shared_model::interface::ErrorQueryResponse::ErrorMessageType
225 2 : error_message = "";
226 : };
227 :
228 : soci::session &sql_;
229 : KeyValueStorage &block_store_;
230 : shared_model::interface::types::AccountIdType creator_id_;
231 : shared_model::interface::types::HashType query_hash_;
232 : std::shared_ptr<PendingTransactionStorage> pending_txs_storage_;
233 : std::shared_ptr<shared_model::interface::BlockJsonConverter> converter_;
234 : std::shared_ptr<shared_model::interface::QueryResponseFactory>
235 : query_response_factory_;
236 : std::shared_ptr<shared_model::interface::PermissionToString>
237 : perm_converter_;
238 : logger::LoggerPtr log_;
239 : };
240 :
241 : class PostgresQueryExecutor : public QueryExecutor {
242 : public:
243 : PostgresQueryExecutor(
244 : std::unique_ptr<soci::session> sql,
245 : KeyValueStorage &block_store,
246 : std::shared_ptr<PendingTransactionStorage> pending_txs_storage,
247 : std::shared_ptr<shared_model::interface::BlockJsonConverter>
248 : converter,
249 : std::shared_ptr<shared_model::interface::QueryResponseFactory>
250 : response_factory,
251 : std::shared_ptr<shared_model::interface::PermissionToString>
252 : perm_converter,
253 : logger::LoggerManagerTreePtr log_manager);
254 :
255 : QueryExecutorResult validateAndExecute(
256 : const shared_model::interface::Query &query,
257 : const bool validate_signatories) override;
258 :
259 : bool validate(const shared_model::interface::BlocksQuery &query,
260 : const bool validate_signatories) override;
261 :
262 : private:
263 : template <class Q>
264 : bool validateSignatures(const Q &query);
265 :
266 : std::unique_ptr<soci::session> sql_;
267 : KeyValueStorage &block_store_;
268 : std::shared_ptr<PendingTransactionStorage> pending_txs_storage_;
269 : PostgresQueryExecutorVisitor visitor_;
270 : std::shared_ptr<shared_model::interface::QueryResponseFactory>
271 : query_response_factory_;
272 : logger::LoggerPtr log_;
273 : };
274 :
275 : } // namespace ametsuchi
276 : } // namespace iroha
277 :
278 : #endif // IROHA_POSTGRES_QUERY_EXECUTOR_HPP
|