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.hpp"
7 :
8 : #include <boost/range/adaptor/transformed.hpp>
9 : #include "backend/protobuf/batch_meta.hpp"
10 : #include "backend/protobuf/commands/proto_command.hpp"
11 : #include "backend/protobuf/common_objects/signature.hpp"
12 : #include "backend/protobuf/util.hpp"
13 : #include "utils/reference_holder.hpp"
14 :
15 : namespace shared_model {
16 : namespace proto {
17 :
18 : struct Transaction::Impl {
19 : explicit Impl(TransportType &&ref) : proto_{std::move(ref)} {}
20 :
21 : explicit Impl(const TransportType &ref) : proto_{ref} {}
22 :
23 : detail::ReferenceHolder<TransportType> proto_;
24 :
25 13071 : iroha::protocol::Transaction::Payload &payload_{
26 13074 : *proto_->mutable_payload()};
27 :
28 13071 : iroha::protocol::Transaction::Payload::ReducedPayload &reduced_payload_{
29 13078 : *proto_->mutable_payload()->mutable_reduced_payload()};
30 :
31 : interface::types::BlobType blob_{[this] { return makeBlob(*proto_); }()};
32 :
33 12654 : interface::types::BlobType payload_blob_{
34 : [this] { return makeBlob(payload_); }()};
35 :
36 12729 : interface::types::BlobType reduced_payload_blob_{
37 : [this] { return makeBlob(reduced_payload_); }()};
38 :
39 12680 : interface::types::HashType reduced_hash_{
40 12680 : shared_model::crypto::Sha3_256::makeHash(reduced_payload_blob_)};
41 :
42 : std::vector<proto::Command> commands_{[this] {
43 21307 : return std::vector<proto::Command>(reduced_payload_.commands().begin(),
44 21307 : reduced_payload_.commands().end());
45 : }()};
46 :
47 13011 : boost::optional<std::shared_ptr<interface::BatchMeta>> meta_{
48 : [this]() -> boost::optional<std::shared_ptr<interface::BatchMeta>> {
49 21304 : if (payload_.has_batch()) {
50 6479 : std::shared_ptr<interface::BatchMeta> b =
51 6479 : std::make_shared<proto::BatchMeta>(payload_.batch());
52 6479 : return b;
53 6482 : }
54 14822 : return boost::none;
55 21298 : }()};
56 :
57 : SignatureSetType<proto::Signature> signatures_{[this] {
58 21250 : auto signatures = proto_->signatures()
59 : | boost::adaptors::transformed([](const auto &x) {
60 14049 : return proto::Signature(x);
61 : });
62 21304 : return SignatureSetType<proto::Signature>(signatures.begin(),
63 21290 : signatures.end());
64 21304 : }()};
65 : };
66 :
67 : Transaction::Transaction(const TransportType &transaction) {
68 13079 : impl_ = std::make_unique<Transaction::Impl>(transaction);
69 13079 : }
70 :
71 : Transaction::Transaction(TransportType &&transaction) {
72 8229 : impl_ = std::make_unique<Transaction::Impl>(std::move(transaction));
73 8230 : }
74 :
75 : // TODO [IR-1866] Akvinikym 13.11.18: remove the copy ctor and fix fallen
76 : // tests
77 : Transaction::Transaction(const Transaction &transaction)
78 638 : : Transaction(*transaction.impl_->proto_) {}
79 :
80 : Transaction::Transaction(Transaction &&transaction) noexcept = default;
81 :
82 : Transaction::~Transaction() = default;
83 :
84 : const interface::types::AccountIdType &Transaction::creatorAccountId()
85 : const {
86 8776 : return impl_->reduced_payload_.creator_account_id();
87 : }
88 :
89 : Transaction::CommandsType Transaction::commands() const {
90 12413 : return impl_->commands_;
91 : }
92 :
93 : const interface::types::BlobType &Transaction::blob() const {
94 0 : return impl_->blob_;
95 : }
96 :
97 : const interface::types::BlobType &Transaction::payload() const {
98 10449 : return impl_->payload_blob_;
99 : }
100 :
101 : const interface::types::BlobType &Transaction::reducedPayload() const {
102 0 : return impl_->reduced_payload_blob_;
103 : }
104 :
105 : interface::types::SignatureRangeType Transaction::signatures() const {
106 14267 : return impl_->signatures_;
107 : }
108 :
109 : const interface::types::HashType &Transaction::reducedHash() const {
110 5406 : return impl_->reduced_hash_;
111 : }
112 :
113 : bool Transaction::addSignature(const crypto::Signed &signed_blob,
114 : const crypto::PublicKey &public_key) {
115 : // if already has such signature
116 3369 : if (std::find_if(impl_->signatures_.begin(),
117 3369 : impl_->signatures_.end(),
118 : [&public_key](const auto &signature) {
119 88 : return signature.publicKey() == public_key;
120 : })
121 3369 : != impl_->signatures_.end()) {
122 15 : return false;
123 : }
124 :
125 3352 : auto sig = impl_->proto_->add_signatures();
126 3355 : sig->set_signature(crypto::toBinaryString(signed_blob));
127 3355 : sig->set_public_key(crypto::toBinaryString(public_key));
128 :
129 : impl_->signatures_ = [this] {
130 3352 : auto signatures = impl_->proto_->signatures()
131 : | boost::adaptors::transformed([](const auto &x) {
132 3420 : return proto::Signature(x);
133 : });
134 3355 : return SignatureSetType<proto::Signature>(signatures.begin(),
135 3354 : signatures.end());
136 3355 : }();
137 :
138 3355 : return true;
139 3369 : }
140 :
141 : const Transaction::TransportType &Transaction::getTransport() const {
142 6342 : return *impl_->proto_;
143 : }
144 :
145 : interface::types::TimestampType Transaction::createdTime() const {
146 4791 : return impl_->reduced_payload_.created_time();
147 : }
148 :
149 : interface::types::QuorumType Transaction::quorum() const {
150 5564 : return impl_->reduced_payload_.quorum();
151 : }
152 :
153 : boost::optional<std::shared_ptr<interface::BatchMeta>>
154 : Transaction::batchMeta() const {
155 10720 : return impl_->meta_;
156 : }
157 :
158 : Transaction::ModelType *Transaction::clone() const {
159 2240 : return new Transaction(*impl_->proto_);
160 0 : }
161 :
162 : } // namespace proto
163 : } // namespace shared_model
|