Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include "interfaces/iroha_internal/transaction_sequence_factory.hpp"
7 :
8 : #include <unordered_map>
9 :
10 : #include "interfaces/iroha_internal/batch_meta.hpp"
11 : #include "interfaces/iroha_internal/transaction_batch_factory_impl.hpp"
12 : #include "interfaces/iroha_internal/transaction_batch_helpers.hpp"
13 : #include "interfaces/iroha_internal/transaction_batch_impl.hpp"
14 : #include "interfaces/transaction.hpp"
15 : #include "validators/answer.hpp"
16 :
17 : namespace shared_model {
18 : namespace interface {
19 : const std::unique_ptr<TransactionBatchFactory> batch_factory =
20 5 : std::make_unique<TransactionBatchFactoryImpl>();
21 :
22 : template <typename TransactionValidator, typename FieldValidator>
23 : iroha::expected::Result<TransactionSequence, std::string>
24 : TransactionSequenceFactory::createTransactionSequence(
25 : const types::SharedTxsCollectionType &transactions,
26 : const validation::TransactionsCollectionValidator<TransactionValidator>
27 : &validator,
28 : const FieldValidator &field_validator) {
29 : std::unordered_map<interface::types::HashType,
30 : std::vector<std::shared_ptr<Transaction>>,
31 : interface::types::HashType::Hasher>
32 10 : extracted_batches;
33 :
34 10 : const auto &transaction_validator = validator.getTransactionValidator();
35 :
36 10 : types::BatchesCollectionType batches;
37 : auto insert_batch =
38 : [&batches](iroha::expected::Value<std::unique_ptr<TransactionBatch>>
39 13 : &value) { batches.push_back(std::move(value.value)); };
40 :
41 10 : validation::Answer result;
42 10 : if (transactions.empty()) {
43 1 : result.addReason(std::make_pair(
44 : "Transaction collection error",
45 1 : std::vector<std::string>{"sequence can not be empty"}));
46 1 : }
47 66 : for (const auto &tx : transactions) {
48 : // perform stateless validation checks
49 56 : validation::ReasonsGroupType reason;
50 56 : reason.first = "Transaction: ";
51 : // check signatures validness
52 56 : if (not boost::empty(tx->signatures())) {
53 23 : field_validator.validateSignatures(
54 23 : reason, tx->signatures(), tx->payload());
55 23 : if (not reason.second.empty()) {
56 0 : result.addReason(std::move(reason));
57 0 : continue;
58 : }
59 23 : }
60 : // check transaction validness
61 56 : auto tx_errors = transaction_validator.validate(*tx);
62 56 : if (tx_errors) {
63 3 : reason.second.emplace_back(tx_errors.reason());
64 3 : result.addReason(std::move(reason));
65 3 : continue;
66 : }
67 :
68 : // if transaction is valid, try to form batch out of it
69 53 : if (auto meta = tx->batchMeta()) {
70 48 : auto hashes = meta.get()->reducedHashes();
71 : auto batch_hash =
72 48 : TransactionBatchHelpers::calculateReducedBatchHash(hashes);
73 48 : extracted_batches[batch_hash].push_back(tx);
74 48 : } else {
75 10 : batch_factory->createTransactionBatch(tx).match(
76 : insert_batch, [&tx, &result](const auto &err) {
77 0 : result.addReason(std::make_pair(
78 0 : std::string("Error in transaction with reduced hash: ")
79 0 : + tx->reducedHash().hex(),
80 0 : std::vector<std::string>{err.error}));
81 0 : });
82 : }
83 109 : }
84 :
85 22 : for (const auto &it : extracted_batches) {
86 12 : batch_factory->createTransactionBatch(it.second).match(
87 : insert_batch, [&it, &result](const auto &err) {
88 4 : result.addReason(std::make_pair(
89 4 : it.first.toString(), std::vector<std::string>{err.error}));
90 4 : });
91 : }
92 :
93 10 : if (result.hasErrors()) {
94 4 : return iroha::expected::makeError(result.reason());
95 : }
96 :
97 6 : return iroha::expected::makeValue(TransactionSequence(batches));
98 10 : }
99 :
100 : template iroha::expected::Result<TransactionSequence, std::string>
101 : TransactionSequenceFactory::createTransactionSequence(
102 : const types::SharedTxsCollectionType &transactions,
103 : const validation::DefaultUnsignedTransactionsValidator &validator,
104 : const validation::FieldValidator &field_validator);
105 :
106 : template iroha::expected::Result<TransactionSequence, std::string>
107 : TransactionSequenceFactory::createTransactionSequence(
108 : const types::SharedTxsCollectionType &transactions,
109 : const validation::DefaultSignedTransactionsValidator &validator,
110 : const validation::FieldValidator &field_validator);
111 : } // namespace interface
112 : } // namespace shared_model
|