Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include "validators/transactions_collection/transactions_collection_validator.hpp"
7 :
8 : #include <algorithm>
9 :
10 : #include <boost/format.hpp>
11 : #include <boost/range/adaptor/indirected.hpp>
12 : #include "interfaces/common_objects/transaction_sequence_common.hpp"
13 : #include "interfaces/iroha_internal/transaction_batch_parser_impl.hpp"
14 : #include "validators/default_validator.hpp"
15 : #include "validators/field_validator.hpp"
16 : #include "validators/signable_validator.hpp"
17 : #include "validators/transaction_batch_validator.hpp"
18 : #include "validators/transaction_validator.hpp"
19 : #include "validators/transactions_collection/batch_order_validator.hpp"
20 :
21 : namespace shared_model {
22 : namespace validation {
23 :
24 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
25 : TransactionsCollectionValidator<TransactionValidator,
26 : CollectionCanBeEmpty>::
27 : TransactionsCollectionValidator(
28 : const TransactionValidator &transactions_validator)
29 759 : : transaction_validator_(transactions_validator) {}
30 :
31 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
32 : template <typename Validator>
33 : Answer TransactionsCollectionValidator<TransactionValidator,
34 : CollectionCanBeEmpty>::
35 : validateImpl(const interface::types::TransactionsForwardCollectionType
36 : &transactions,
37 : Validator &&validator) const {
38 1328 : Answer res;
39 1328 : ReasonsGroupType reason;
40 1328 : reason.first = "Transaction list";
41 :
42 1328 : auto tx_collection_empty = boost::empty(transactions);
43 1328 : if (tx_collection_empty and CollectionCanBeEmpty) {
44 1 : return res;
45 : }
46 1328 : if (tx_collection_empty) {
47 0 : reason.second.emplace_back("Transaction sequence can not be empty");
48 0 : res.addReason(std::move(reason));
49 0 : return res;
50 : }
51 :
52 2666 : for (const auto &tx : transactions) {
53 1338 : auto answer = std::forward<Validator>(validator)(tx);
54 1338 : if (answer.hasErrors()) {
55 : auto message =
56 2 : (boost::format("Tx %s : %s") % tx.hash().hex() % answer.reason())
57 2 : .str();
58 2 : reason.second.push_back(message);
59 2 : }
60 1338 : }
61 :
62 1328 : interface::TransactionBatchParserImpl batch_parser;
63 1328 : BatchValidator batch_validator;
64 :
65 1328 : auto batches = batch_parser.parseBatches(transactions);
66 2661 : for (auto &batch : batches) {
67 1333 : if (auto answer = batch_validator.validate(batch)) {
68 2 : reason.second.emplace_back(answer.reason());
69 2 : }
70 : }
71 :
72 1328 : if (not reason.second.empty()) {
73 3 : res.addReason(std::move(reason));
74 3 : }
75 1328 : return res;
76 1328 : }
77 :
78 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
79 : Answer TransactionsCollectionValidator<TransactionValidator,
80 : CollectionCanBeEmpty>::
81 : validate(const shared_model::interface::types::
82 : TransactionsForwardCollectionType &transactions) const {
83 : return validateImpl(transactions, [this](const auto &tx) {
84 0 : return transaction_validator_.validate(tx);
85 : });
86 : }
87 :
88 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
89 : Answer TransactionsCollectionValidator<TransactionValidator,
90 : CollectionCanBeEmpty>::
91 : validate(const shared_model::interface::types::SharedTxsCollectionType
92 : &transactions) const {
93 0 : return validate(transactions | boost::adaptors::indirected);
94 0 : }
95 :
96 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
97 : Answer TransactionsCollectionValidator<TransactionValidator,
98 : CollectionCanBeEmpty>::
99 : validate(const interface::types::TransactionsForwardCollectionType
100 : &transactions,
101 : interface::types::TimestampType current_timestamp) const {
102 1328 : return validateImpl(
103 : transactions, [this, current_timestamp](const auto &tx) {
104 1338 : return transaction_validator_.validate(tx, current_timestamp);
105 : });
106 : }
107 :
108 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
109 : Answer TransactionsCollectionValidator<TransactionValidator,
110 : CollectionCanBeEmpty>::
111 : validate(const interface::types::SharedTxsCollectionType &transactions,
112 : interface::types::TimestampType current_timestamp) const {
113 0 : return validate(transactions | boost::adaptors::indirected,
114 0 : current_timestamp);
115 0 : }
116 :
117 : template <typename TransactionValidator, bool CollectionCanBeEmpty>
118 : const TransactionValidator &TransactionsCollectionValidator<
119 : TransactionValidator,
120 : CollectionCanBeEmpty>::getTransactionValidator() const {
121 10 : return transaction_validator_;
122 : }
123 :
124 : template class TransactionsCollectionValidator<
125 : DefaultUnsignedTransactionValidator,
126 : true>;
127 :
128 : template class TransactionsCollectionValidator<
129 : DefaultUnsignedTransactionValidator,
130 : false>;
131 :
132 : template class TransactionsCollectionValidator<
133 : DefaultSignedTransactionValidator,
134 : true>;
135 :
136 : template class TransactionsCollectionValidator<
137 : DefaultSignedTransactionValidator,
138 : false>;
139 :
140 : } // namespace validation
141 : } // namespace shared_model
|