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