Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include "backend/protobuf/transaction_responses/proto_tx_response.hpp"
7 :
8 : #include <limits>
9 :
10 : #include "backend/protobuf/transaction_responses/proto_concrete_tx_response.hpp"
11 : #include "common/visitor.hpp"
12 : #include "cryptography/hash.hpp"
13 : #include "utils/reference_holder.hpp"
14 : #include "utils/variant_deserializer.hpp"
15 :
16 : namespace {
17 : /// Variant type, that contains all concrete tx responses in the system
18 : using ProtoResponseVariantType =
19 : boost::variant<shared_model::proto::StatelessFailedTxResponse,
20 : shared_model::proto::StatelessValidTxResponse,
21 : shared_model::proto::StatefulFailedTxResponse,
22 : shared_model::proto::StatefulValidTxResponse,
23 : shared_model::proto::RejectedTxResponse,
24 : shared_model::proto::CommittedTxResponse,
25 : shared_model::proto::MstExpiredResponse,
26 : shared_model::proto::NotReceivedTxResponse,
27 : shared_model::proto::MstPendingResponse,
28 : shared_model::proto::EnoughSignaturesCollectedResponse>;
29 :
30 : /// Type with list of types in ResponseVariantType
31 : using ProtoResponseListType = ProtoResponseVariantType::types;
32 :
33 : constexpr int kMaxPriority = std::numeric_limits<int>::max();
34 : } // namespace
35 :
36 : namespace shared_model {
37 : namespace proto {
38 :
39 : struct TransactionResponse::Impl {
40 : explicit Impl(TransportType &&ref) : proto_{std::move(ref)} {}
41 : explicit Impl(const TransportType &ref) : proto_{ref} {}
42 :
43 : detail::ReferenceHolder<TransportType> proto_;
44 :
45 : const ProtoResponseVariantType variant_{[this] {
46 4846 : auto &&ar = *proto_;
47 :
48 4846 : unsigned which = ar.GetDescriptor()
49 4846 : ->FindFieldByName("tx_status")
50 4846 : ->enum_type()
51 4846 : ->FindValueByNumber(ar.tx_status())
52 4846 : ->index();
53 4846 : constexpr unsigned last =
54 : boost::mpl::size<ProtoResponseListType>::type::value - 1;
55 :
56 4846 : return shared_model::detail::variant_impl<ProtoResponseListType>::
57 : template load<ProtoResponseVariantType>(
58 4846 : std::forward<decltype(ar)>(ar), which > last ? last : which);
59 0 : }()};
60 :
61 3803 : const ResponseVariantType ivariant_{variant_};
62 :
63 : // stub hash
64 3803 : const crypto::Hash hash_{proto_->tx_hash()};
65 : };
66 :
67 : TransactionResponse::TransactionResponse(const TransactionResponse &r)
68 19 : : TransactionResponse(*r.impl_->proto_) {}
69 : TransactionResponse::TransactionResponse(TransactionResponse &&r) noexcept =
70 : default;
71 :
72 : TransactionResponse::TransactionResponse(const TransportType &ref) {
73 1043 : impl_ = std::make_unique<Impl>(ref);
74 1043 : }
75 : TransactionResponse::TransactionResponse(TransportType &&ref) {
76 3803 : impl_ = std::make_unique<Impl>(std::move(ref));
77 3803 : }
78 :
79 : TransactionResponse::~TransactionResponse() = default;
80 :
81 : const interface::types::HashType &TransactionResponse::transactionHash()
82 : const {
83 47467 : return impl_->hash_;
84 : }
85 :
86 : const TransactionResponse::ResponseVariantType &TransactionResponse::get()
87 : const {
88 41702 : return impl_->ivariant_;
89 : }
90 :
91 : const TransactionResponse::StatelessErrorOrFailedCommandNameType &
92 : TransactionResponse::statelessErrorOrCommandName() const {
93 41457 : return impl_->proto_->err_or_cmd_name();
94 : }
95 :
96 : TransactionResponse::FailedCommandIndexType
97 : TransactionResponse::failedCommandIndex() const {
98 40752 : return impl_->proto_->failed_cmd_index();
99 : }
100 :
101 : TransactionResponse::ErrorCodeType TransactionResponse::errorCode() const {
102 40752 : return impl_->proto_->error_code();
103 : }
104 :
105 : int TransactionResponse::priority() const noexcept {
106 7092 : return iroha::visit_in_place(
107 7092 : impl_->variant_,
108 : // not received can be changed to any response
109 : [](const NotReceivedTxResponse &) { return 0; },
110 : // following types are sequential in pipeline
111 : [](const StatelessValidTxResponse &) { return 1; },
112 : [](const MstPendingResponse &) { return 2; },
113 : [](const EnoughSignaturesCollectedResponse &) { return 3; },
114 : [](const StatefulValidTxResponse &) { return 4; },
115 : // following types are local on this peer and can be substituted by
116 : // final ones, if consensus decides so
117 : [](const StatelessFailedTxResponse &) { return 5; },
118 : [](const StatefulFailedTxResponse &) { return 5; },
119 : [](const MstExpiredResponse &) { return 5; },
120 : // following types are the final ones
121 : [](const CommittedTxResponse &) { return kMaxPriority; },
122 : [](const RejectedTxResponse &) { return kMaxPriority; });
123 : }
124 :
125 : const TransactionResponse::TransportType &
126 : TransactionResponse::getTransport() const {
127 824 : return *impl_->proto_;
128 : }
129 :
130 : TransactionResponse *TransactionResponse::clone() const {
131 14 : return new TransactionResponse(*impl_->proto_);
132 0 : }
133 : }; // namespace proto
134 : } // namespace shared_model
|