Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include "model/converters/json_command_factory.hpp"
7 :
8 : #include <regex>
9 :
10 : #include "model/commands/add_asset_quantity.hpp"
11 : #include "model/commands/add_peer.hpp"
12 : #include "model/commands/add_signatory.hpp"
13 : #include "model/commands/append_role.hpp"
14 : #include "model/commands/create_account.hpp"
15 : #include "model/commands/create_asset.hpp"
16 : #include "model/commands/create_domain.hpp"
17 : #include "model/commands/create_role.hpp"
18 : #include "model/commands/detach_role.hpp"
19 : #include "model/commands/grant_permission.hpp"
20 : #include "model/commands/remove_signatory.hpp"
21 : #include "model/commands/revoke_permission.hpp"
22 : #include "model/commands/set_account_detail.hpp"
23 : #include "model/commands/set_quorum.hpp"
24 : #include "model/commands/subtract_asset_quantity.hpp"
25 : #include "model/commands/transfer_asset.hpp"
26 :
27 : using namespace rapidjson;
28 :
29 : namespace iroha {
30 : namespace model {
31 : namespace converters {
32 : template <>
33 : struct Convert<Peer> {
34 : template <typename T>
35 : boost::optional<Peer> operator()(T &&x) const {
36 3 : auto des = makeFieldDeserializer(std::forward<T>(x));
37 3 : auto address = des.String("address");
38 3 : auto pubkey = des.String("peer_key");
39 :
40 3 : if (not address or not pubkey) {
41 0 : return boost::none;
42 : }
43 :
44 3 : return boost::make_optional(Peer(
45 3 : address.value(),
46 3 : iroha::hexstringToArray<iroha::pubkey_t::size()>(pubkey.value())
47 3 : .value()));
48 3 : }
49 : };
50 :
51 : JsonCommandFactory::JsonCommandFactory() {
52 24 : serializers_ = {
53 24 : {typeid(AddAssetQuantity),
54 24 : &JsonCommandFactory::serializeAddAssetQuantity},
55 24 : {typeid(SubtractAssetQuantity),
56 24 : &JsonCommandFactory::serializeSubtractAssetQuantity},
57 24 : {typeid(AddPeer), &JsonCommandFactory::serializeAddPeer},
58 24 : {typeid(AddSignatory), &JsonCommandFactory::serializeAddSignatory},
59 24 : {typeid(CreateAccount),
60 24 : &JsonCommandFactory::serializeCreateAccount},
61 24 : {typeid(CreateAsset), &JsonCommandFactory::serializeCreateAsset},
62 24 : {typeid(CreateDomain), &JsonCommandFactory::serializeCreateDomain},
63 24 : {typeid(SetAccountDetail),
64 24 : &JsonCommandFactory::serializeSetAccountDetail},
65 24 : {typeid(RemoveSignatory),
66 24 : &JsonCommandFactory::serializeRemoveSignatory},
67 24 : {typeid(SetQuorum), &JsonCommandFactory::serializeSetQuorum},
68 24 : {typeid(TransferAsset),
69 24 : &JsonCommandFactory::serializeTransferAsset},
70 24 : {typeid(AppendRole), &JsonCommandFactory::serializeAppendRole},
71 24 : {typeid(CreateRole), &JsonCommandFactory::serializeCreateRole},
72 24 : {typeid(DetachRole), &JsonCommandFactory::serializeDetachRole},
73 24 : {typeid(GrantPermission),
74 24 : &JsonCommandFactory::serializeGrantPermission},
75 24 : {typeid(RevokePermission),
76 24 : &JsonCommandFactory::serializeRevokePermission}};
77 :
78 384 : deserializers_ = {
79 24 : {"AddAssetQuantity",
80 24 : &JsonCommandFactory::deserializeAddAssetQuantity},
81 24 : {"SubtractAssetQuantity",
82 24 : &JsonCommandFactory::deserializeSubtractAssetQuantity},
83 24 : {"AddPeer", &JsonCommandFactory::deserializeAddPeer},
84 24 : {"AddSignatory", &JsonCommandFactory::deserializeAddSignatory},
85 24 : {"CreateAccount", &JsonCommandFactory::deserializeCreateAccount},
86 24 : {"CreateAsset", &JsonCommandFactory::deserializeCreateAsset},
87 24 : {"CreateDomain", &JsonCommandFactory::deserializeCreateDomain},
88 24 : {"SetAccountDetail",
89 24 : &JsonCommandFactory::deserializeSetAccountDetail},
90 24 : {"RemoveSignatory",
91 24 : &JsonCommandFactory::deserializeRemoveSignatory},
92 24 : {"SetQuorum", &JsonCommandFactory::deserializeSetQuorum},
93 24 : {"TransferAsset", &JsonCommandFactory::deserializeTransferAsset},
94 24 : {"AppendRole", &JsonCommandFactory::deserializeAppendRole},
95 24 : {"DetachRole", &JsonCommandFactory::deserializeDetachRole},
96 24 : {"CreateRole", &JsonCommandFactory::deserializeCreateRole},
97 24 : {"GrantPermission",
98 24 : &JsonCommandFactory::deserializeGrantPermission},
99 24 : {"RevokePermission",
100 24 : &JsonCommandFactory::deserializeRevokePermission}};
101 24 : }
102 :
103 : // AddAssetQuantity
104 : Document JsonCommandFactory::serializeAddAssetQuantity(
105 : std::shared_ptr<Command> command) {
106 4 : auto add_asset_quantity =
107 4 : static_cast<AddAssetQuantity *>(command.get());
108 :
109 4 : Document document;
110 4 : auto &allocator = document.GetAllocator();
111 :
112 4 : document.SetObject();
113 4 : document.AddMember("command_type", "AddAssetQuantity", allocator);
114 4 : document.AddMember("asset_id", add_asset_quantity->asset_id, allocator);
115 4 : document.AddMember("amount", add_asset_quantity->amount, allocator);
116 :
117 4 : return document;
118 4 : }
119 :
120 : optional_ptr<Command> JsonCommandFactory::deserializeAddAssetQuantity(
121 : const Value &document) {
122 4 : auto des = makeFieldDeserializer(document);
123 4 : return make_optional_ptr<AddAssetQuantity>()
124 4 : | des.String(&AddAssetQuantity::asset_id, "asset_id")
125 4 : | des.String(&AddAssetQuantity::amount, "amount") | toCommand;
126 0 : }
127 :
128 : // AddPeer
129 : Document JsonCommandFactory::serializeAddPeer(
130 : std::shared_ptr<Command> command) {
131 3 : auto add_peer = static_cast<AddPeer *>(command.get());
132 3 : Document document;
133 3 : auto &allocator = document.GetAllocator();
134 :
135 3 : document.SetObject();
136 3 : document.AddMember("command_type", "AddPeer", allocator);
137 :
138 3 : Value peer;
139 3 : peer.SetObject();
140 3 : peer.AddMember("address", add_peer->peer.address, allocator);
141 3 : peer.AddMember(
142 3 : "peer_key", add_peer->peer.pubkey.to_hexstring(), allocator);
143 :
144 3 : document.AddMember("peer", peer, allocator);
145 :
146 3 : return document;
147 3 : }
148 :
149 : optional_ptr<Command> JsonCommandFactory::deserializeAddPeer(
150 : const Value &document) {
151 3 : auto des = makeFieldDeserializer(document);
152 3 : return make_optional_ptr<AddPeer>() | des.Object(&AddPeer::peer, "peer")
153 3 : | toCommand;
154 0 : }
155 :
156 : // AddSignatory
157 : Document JsonCommandFactory::serializeAddSignatory(
158 : std::shared_ptr<Command> command) {
159 4 : auto add_signatory = static_cast<AddSignatory *>(command.get());
160 :
161 4 : Document document;
162 4 : auto &allocator = document.GetAllocator();
163 :
164 4 : document.SetObject();
165 4 : document.AddMember("command_type", "AddSignatory", allocator);
166 4 : document.AddMember("account_id", add_signatory->account_id, allocator);
167 4 : document.AddMember(
168 4 : "pubkey", add_signatory->pubkey.to_hexstring(), allocator);
169 :
170 4 : return document;
171 4 : }
172 :
173 : optional_ptr<Command> JsonCommandFactory::deserializeAddSignatory(
174 : const Value &document) {
175 4 : auto des = makeFieldDeserializer(document);
176 4 : return make_optional_ptr<AddSignatory>()
177 4 : | des.String(&AddSignatory::account_id, "account_id")
178 4 : | des.String(&AddSignatory::pubkey, "pubkey") | toCommand;
179 0 : }
180 :
181 : // CreateAccount
182 : Document JsonCommandFactory::serializeCreateAccount(
183 : std::shared_ptr<Command> command) {
184 3 : auto create_account = static_cast<CreateAccount *>(command.get());
185 :
186 3 : Document document;
187 3 : auto &allocator = document.GetAllocator();
188 :
189 3 : document.SetObject();
190 3 : document.AddMember("command_type", "CreateAccount", allocator);
191 3 : document.AddMember(
192 3 : "account_name", create_account->account_name, allocator);
193 3 : document.AddMember("domain_id", create_account->domain_id, allocator);
194 3 : document.AddMember(
195 3 : "pubkey", create_account->pubkey.to_hexstring(), allocator);
196 3 : return document;
197 3 : }
198 :
199 : optional_ptr<Command> JsonCommandFactory::deserializeCreateAccount(
200 : const Value &document) {
201 3 : auto des = makeFieldDeserializer(document);
202 3 : return make_optional_ptr<CreateAccount>()
203 3 : | des.String(&CreateAccount::account_name, "account_name")
204 3 : | des.String(&CreateAccount::domain_id, "domain_id")
205 3 : | des.String(&CreateAccount::pubkey, "pubkey") | toCommand;
206 0 : }
207 :
208 : // Set Account Detail
209 : rapidjson::Document JsonCommandFactory::serializeSetAccountDetail(
210 : std::shared_ptr<Command> command) {
211 2 : auto set_account_detail =
212 2 : static_cast<SetAccountDetail *>(command.get());
213 :
214 2 : Document document;
215 2 : auto &allocator = document.GetAllocator();
216 :
217 2 : document.SetObject();
218 2 : document.AddMember("command_type", "SetAccountDetail", allocator);
219 2 : document.AddMember(
220 2 : "account_id", set_account_detail->account_id, allocator);
221 2 : document.AddMember("key", set_account_detail->key, allocator);
222 2 : document.AddMember("value", set_account_detail->value, allocator);
223 :
224 2 : return document;
225 2 : }
226 :
227 : optional_ptr<Command> JsonCommandFactory::deserializeSetAccountDetail(
228 : const rapidjson::Value &document) {
229 2 : auto des = makeFieldDeserializer(document);
230 2 : return make_optional_ptr<SetAccountDetail>()
231 2 : | des.String(&SetAccountDetail::account_id, "account_id")
232 2 : | des.String(&SetAccountDetail::key, "key")
233 2 : | des.String(&SetAccountDetail::value, "value") | toCommand;
234 0 : }
235 :
236 : // CreateAsset
237 : Document JsonCommandFactory::serializeCreateAsset(
238 : std::shared_ptr<Command> command) {
239 3 : auto create_asset = static_cast<CreateAsset *>(command.get());
240 :
241 3 : Document document;
242 3 : auto &allocator = document.GetAllocator();
243 :
244 3 : document.SetObject();
245 3 : document.AddMember("command_type", "CreateAsset", allocator);
246 3 : document.AddMember("asset_name", create_asset->asset_name, allocator);
247 3 : document.AddMember("domain_id", create_asset->domain_id, allocator);
248 3 : document.AddMember("precision", create_asset->precision, allocator);
249 :
250 3 : return document;
251 3 : }
252 :
253 : optional_ptr<Command> JsonCommandFactory::deserializeCreateAsset(
254 : const Value &document) {
255 4 : auto des = makeFieldDeserializer(document);
256 4 : return make_optional_ptr<CreateAsset>()
257 4 : | des.String(&CreateAsset::asset_name, "asset_name")
258 4 : | des.String(&CreateAsset::domain_id, "domain_id")
259 4 : | des.Uint(&CreateAsset::precision, "precision") | toCommand;
260 0 : }
261 :
262 : // CreateDomain
263 : Document JsonCommandFactory::serializeCreateDomain(
264 : std::shared_ptr<Command> command) {
265 3 : auto create_domain = static_cast<CreateDomain *>(command.get());
266 :
267 3 : Document document;
268 3 : auto &allocator = document.GetAllocator();
269 :
270 3 : document.SetObject();
271 3 : document.AddMember("command_type", "CreateDomain", allocator);
272 3 : document.AddMember("domain_id", create_domain->domain_id, allocator);
273 3 : document.AddMember(
274 3 : "user_default_role", create_domain->user_default_role, allocator);
275 :
276 3 : return document;
277 3 : }
278 :
279 : optional_ptr<Command> JsonCommandFactory::deserializeCreateDomain(
280 : const Value &document) {
281 3 : auto des = makeFieldDeserializer(document);
282 3 : return make_optional_ptr<CreateDomain>()
283 3 : | des.String(&CreateDomain::domain_id, "domain_id")
284 3 : | des.String(&CreateDomain::user_default_role, "user_default_role")
285 3 : | toCommand;
286 0 : }
287 :
288 : // RemoveSignatory
289 : Document JsonCommandFactory::serializeRemoveSignatory(
290 : std::shared_ptr<Command> command) {
291 3 : auto remove_signatory = static_cast<RemoveSignatory *>(command.get());
292 :
293 3 : Document document;
294 3 : auto &allocator = document.GetAllocator();
295 :
296 3 : document.SetObject();
297 3 : document.AddMember("command_type", "RemoveSignatory", allocator);
298 3 : document.AddMember(
299 3 : "account_id", remove_signatory->account_id, allocator);
300 3 : document.AddMember(
301 3 : "pubkey", remove_signatory->pubkey.to_hexstring(), allocator);
302 :
303 3 : return document;
304 3 : }
305 :
306 : optional_ptr<Command> JsonCommandFactory::deserializeRemoveSignatory(
307 : const Value &document) {
308 3 : auto des = makeFieldDeserializer(document);
309 3 : return make_optional_ptr<RemoveSignatory>()
310 3 : | des.String(&RemoveSignatory::account_id, "account_id")
311 3 : | des.String(&RemoveSignatory::pubkey, "pubkey") | toCommand;
312 0 : }
313 :
314 : // SetAccountQuorum
315 : Document JsonCommandFactory::serializeSetQuorum(
316 : std::shared_ptr<Command> command) {
317 3 : auto set_quorum = static_cast<SetQuorum *>(command.get());
318 :
319 3 : Document document;
320 3 : auto &allocator = document.GetAllocator();
321 :
322 3 : document.SetObject();
323 3 : document.AddMember("command_type", "SetQuorum", allocator);
324 3 : document.AddMember("account_id", set_quorum->account_id, allocator);
325 3 : document.AddMember("new_quorum", set_quorum->new_quorum, allocator);
326 :
327 3 : return document;
328 3 : }
329 :
330 : optional_ptr<Command> JsonCommandFactory::deserializeSetQuorum(
331 : const Value &document) {
332 3 : auto des = makeFieldDeserializer(document);
333 3 : return make_optional_ptr<SetQuorum>()
334 3 : | des.String(&SetQuorum::account_id, "account_id")
335 3 : | des.Uint(&SetQuorum::new_quorum, "new_quorum") | toCommand;
336 0 : }
337 :
338 : // TransferAsset
339 : Document JsonCommandFactory::serializeTransferAsset(
340 : std::shared_ptr<Command> command) {
341 3 : auto transfer_asset = static_cast<TransferAsset *>(command.get());
342 :
343 3 : Document document;
344 3 : auto &allocator = document.GetAllocator();
345 :
346 3 : document.SetObject();
347 3 : document.AddMember("command_type", "TransferAsset", allocator);
348 3 : document.AddMember(
349 3 : "src_account_id", transfer_asset->src_account_id, allocator);
350 3 : document.AddMember(
351 3 : "dest_account_id", transfer_asset->dest_account_id, allocator);
352 3 : document.AddMember("asset_id", transfer_asset->asset_id, allocator);
353 3 : document.AddMember(
354 3 : "description", transfer_asset->description, allocator);
355 3 : document.AddMember("amount", transfer_asset->amount, allocator);
356 :
357 3 : return document;
358 3 : }
359 :
360 : optional_ptr<Command> JsonCommandFactory::deserializeTransferAsset(
361 : const Value &document) {
362 3 : auto des = makeFieldDeserializer(document);
363 3 : return make_optional_ptr<TransferAsset>()
364 3 : | des.String(&TransferAsset::src_account_id, "src_account_id")
365 3 : | des.String(&TransferAsset::dest_account_id, "dest_account_id")
366 3 : | des.String(&TransferAsset::asset_id, "asset_id")
367 3 : | des.String(&TransferAsset::description, "description")
368 3 : | des.String(&TransferAsset::amount, "amount") | toCommand;
369 0 : }
370 :
371 : rapidjson::Document JsonCommandFactory::serializeAppendRole(
372 : std::shared_ptr<Command> command) {
373 2 : auto cmd = static_cast<AppendRole *>(command.get());
374 :
375 2 : Document document;
376 2 : auto &allocator = document.GetAllocator();
377 :
378 2 : document.SetObject();
379 2 : document.AddMember("command_type", "AppendRole", allocator);
380 2 : document.AddMember("account_id", cmd->account_id, allocator);
381 2 : document.AddMember("role_name", cmd->role_name, allocator);
382 2 : return document;
383 2 : }
384 :
385 : optional_ptr<Command> JsonCommandFactory::deserializeAppendRole(
386 : const rapidjson::Value &document) {
387 2 : auto des = makeFieldDeserializer(document);
388 2 : return make_optional_ptr<AppendRole>()
389 2 : | des.String(&AppendRole::account_id, "account_id")
390 2 : | des.String(&AppendRole::role_name, "role_name") | toCommand;
391 0 : }
392 :
393 : rapidjson::Document JsonCommandFactory::serializeDetachRole(
394 : std::shared_ptr<Command> command) {
395 3 : auto cmd = static_cast<DetachRole *>(command.get());
396 :
397 3 : Document document;
398 3 : auto &allocator = document.GetAllocator();
399 :
400 3 : document.SetObject();
401 3 : document.AddMember("command_type", "DetachRole", allocator);
402 3 : document.AddMember("account_id", cmd->account_id, allocator);
403 3 : document.AddMember("role_name", cmd->role_name, allocator);
404 3 : return document;
405 3 : }
406 :
407 : optional_ptr<Command> JsonCommandFactory::deserializeDetachRole(
408 : const rapidjson::Value &document) {
409 3 : auto des = makeFieldDeserializer(document);
410 3 : return make_optional_ptr<DetachRole>()
411 3 : | des.String(&DetachRole::account_id, "account_id")
412 3 : | des.String(&DetachRole::role_name, "role_name") | toCommand;
413 0 : }
414 :
415 : rapidjson::Document JsonCommandFactory::serializeCreateRole(
416 : std::shared_ptr<Command> command) {
417 2 : auto cmd = static_cast<CreateRole *>(command.get());
418 :
419 2 : Document document;
420 2 : auto &allocator = document.GetAllocator();
421 :
422 2 : document.SetObject();
423 2 : document.AddMember("command_type", "CreateRole", allocator);
424 2 : document.AddMember("role_name", cmd->role_name, allocator);
425 2 : Value perms;
426 2 : perms.SetArray();
427 8 : for (auto perm : cmd->permissions) {
428 6 : Value perm_value;
429 6 : perm_value.Set(perm, allocator);
430 6 : perms.PushBack(perm_value, allocator);
431 6 : }
432 2 : document.AddMember("permissions", perms, allocator);
433 2 : return document;
434 2 : }
435 :
436 : optional_ptr<Command> JsonCommandFactory::deserializeCreateRole(
437 : const rapidjson::Value &document) {
438 2 : if (document.HasMember("role_name") and document["role_name"].IsString()
439 2 : and document.HasMember("permissions")
440 2 : and document["permissions"].IsArray()) {
441 2 : std::set<std::string> perms;
442 8 : for (auto &v : document["permissions"].GetArray()) {
443 6 : if (not v.IsString()) {
444 0 : return boost::none;
445 : }
446 6 : perms.insert(v.GetString());
447 : }
448 2 : auto role_name = document["role_name"].GetString();
449 2 : return make_optional_ptr<CreateRole>(role_name, perms) | toCommand;
450 2 : }
451 0 : return boost::none;
452 2 : }
453 :
454 : rapidjson::Document JsonCommandFactory::serializeGrantPermission(
455 : std::shared_ptr<Command> command) {
456 2 : auto cmd = static_cast<GrantPermission *>(command.get());
457 :
458 2 : Document document;
459 2 : auto &allocator = document.GetAllocator();
460 2 : document.SetObject();
461 2 : document.AddMember("command_type", "GrantPermission", allocator);
462 2 : document.AddMember("account_id", cmd->account_id, allocator);
463 2 : document.AddMember("permission_name", cmd->permission_name, allocator);
464 2 : return document;
465 2 : }
466 :
467 : optional_ptr<Command> JsonCommandFactory::deserializeGrantPermission(
468 : const rapidjson::Value &document) {
469 2 : auto des = makeFieldDeserializer(document);
470 2 : return make_optional_ptr<GrantPermission>()
471 2 : | des.String(&GrantPermission::account_id, "account_id")
472 2 : | des.String(&GrantPermission::permission_name, "permission_name")
473 2 : | toCommand;
474 0 : }
475 :
476 : rapidjson::Document JsonCommandFactory::serializeRevokePermission(
477 : std::shared_ptr<Command> command) {
478 2 : auto cmd = static_cast<RevokePermission *>(command.get());
479 :
480 2 : Document document;
481 2 : auto &allocator = document.GetAllocator();
482 2 : document.SetObject();
483 2 : document.AddMember("command_type", "RevokePermission", allocator);
484 2 : document.AddMember("account_id", cmd->account_id, allocator);
485 2 : document.AddMember("permission_name", cmd->permission_name, allocator);
486 2 : return document;
487 2 : }
488 :
489 : optional_ptr<Command> JsonCommandFactory::deserializeRevokePermission(
490 : const rapidjson::Value &document) {
491 2 : auto des = makeFieldDeserializer(document);
492 2 : return make_optional_ptr<RevokePermission>()
493 2 : | des.String(&RevokePermission::account_id, "account_id")
494 2 : | des.String(&RevokePermission::permission_name, "permission_name")
495 2 : | toCommand;
496 0 : }
497 :
498 : // SubtractAssetQuantity
499 : Document JsonCommandFactory::serializeSubtractAssetQuantity(
500 : std::shared_ptr<Command> command) {
501 3 : auto subtract_asset_quantity =
502 3 : static_cast<SubtractAssetQuantity *>(command.get());
503 :
504 3 : Document document;
505 3 : auto &allocator = document.GetAllocator();
506 :
507 3 : document.SetObject();
508 3 : document.AddMember("command_type", "SubtractAssetQuantity", allocator);
509 3 : document.AddMember(
510 3 : "asset_id", subtract_asset_quantity->asset_id, allocator);
511 3 : document.AddMember(
512 3 : "amount", subtract_asset_quantity->amount, allocator);
513 :
514 3 : return document;
515 3 : }
516 :
517 : optional_ptr<Command>
518 : JsonCommandFactory::deserializeSubtractAssetQuantity(
519 : const Value &document) {
520 3 : auto des = makeFieldDeserializer(document);
521 3 : return make_optional_ptr<SubtractAssetQuantity>()
522 3 : | des.String(&SubtractAssetQuantity::asset_id, "asset_id")
523 3 : | des.String(&SubtractAssetQuantity::amount, "amount") | toCommand;
524 0 : }
525 :
526 : // Abstract
527 : Document JsonCommandFactory::serializeAbstractCommand(
528 : std::shared_ptr<Command> command) {
529 29 : return makeMethodInvoke(*this,
530 29 : command)(serializers_.at(typeid(*command)));
531 : }
532 :
533 : optional_ptr<model::Command>
534 : JsonCommandFactory::deserializeAbstractCommand(const Value &document) {
535 31 : return makeFieldDeserializer(document).String("command_type")
536 31 : | makeOptionalGet(deserializers_)
537 31 : | makeMethodInvoke(*this, document);
538 0 : }
539 : } // namespace converters
540 : } // namespace model
541 : } // namespace iroha
|