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(const TransportType &ref) : proto_{ref} {}
20 :
21 : explicit Impl(TransportType &&ref) : proto_{std::move(ref)} {}
22 :
23 : explicit Impl(TransportType &ref) : proto_{ref} {}
24 :
25 : detail::ReferenceHolder<TransportType> proto_;
26 :
27 10896 : iroha::protocol::Transaction::Payload &payload_{
28 10896 : *proto_->mutable_payload()};
29 :
30 10896 : iroha::protocol::Transaction::Payload::ReducedPayload &reduced_payload_{
31 10896 : *proto_->mutable_payload()->mutable_reduced_payload()};
32 :
33 : interface::types::BlobType blob_{[this] { return makeBlob(*proto_); }()};
34 :
35 10892 : interface::types::BlobType payload_blob_{
36 : [this] { return makeBlob(payload_); }()};
37 :
38 10895 : interface::types::BlobType reduced_payload_blob_{
39 : [this] { return makeBlob(reduced_payload_); }()};
40 :
41 10891 : interface::types::HashType reduced_hash_{
42 10891 : shared_model::crypto::Sha3_256::makeHash(reduced_payload_blob_)};
43 :
44 10896 : std::vector<proto::Command> commands_{
45 10896 : reduced_payload_.mutable_commands()->begin(),
46 10896 : reduced_payload_.mutable_commands()->end()};
47 :
48 10896 : boost::optional<std::shared_ptr<interface::BatchMeta>> meta_{
49 : [this]() -> boost::optional<std::shared_ptr<interface::BatchMeta>> {
50 21302 : if (payload_.has_batch()) {
51 484 : std::shared_ptr<interface::BatchMeta> b =
52 484 : std::make_shared<proto::BatchMeta>(*payload_.mutable_batch());
53 484 : return b;
54 484 : }
55 20784 : return boost::none;
56 21362 : }()};
57 :
58 : SignatureSetType<proto::Signature> signatures_{[this] {
59 21078 : auto signatures = *proto_->mutable_signatures()
60 21078 : | boost::adaptors::transformed(
61 : [](auto &x) { return proto::Signature(x); });
62 21269 : return SignatureSetType<proto::Signature>(signatures.begin(),
63 21203 : signatures.end());
64 21269 : }()};
65 : }; // namespace proto
66 :
67 : Transaction::Transaction(const TransportType &transaction) {
68 1028 : impl_ = std::make_unique<Transaction::Impl>(transaction);
69 1028 : }
70 :
71 : Transaction::Transaction(TransportType &&transaction) {
72 9469 : impl_ = std::make_unique<Transaction::Impl>(std::move(transaction));
73 9469 : }
74 :
75 : Transaction::Transaction(TransportType &transaction) {
76 10896 : impl_ = std::make_unique<Transaction::Impl>(transaction);
77 10896 : }
78 :
79 : // TODO [IR-1866] Akvinikym 13.11.18: remove the copy ctor and fix fallen
80 : // tests
81 : Transaction::Transaction(const Transaction &transaction)
82 644 : : Transaction(
83 644 : static_cast<const TransportType &>(*transaction.impl_->proto_)) {}
84 :
85 : Transaction::Transaction(Transaction &&transaction) noexcept = default;
86 :
87 : Transaction::~Transaction() = default;
88 :
89 : const interface::types::AccountIdType &Transaction::creatorAccountId()
90 : const {
91 13016 : return impl_->reduced_payload_.creator_account_id();
92 : }
93 :
94 : Transaction::CommandsType Transaction::commands() const {
95 22083 : return impl_->commands_;
96 : }
97 :
98 : const interface::types::BlobType &Transaction::blob() const {
99 0 : return impl_->blob_;
100 : }
101 :
102 : const interface::types::BlobType &Transaction::payload() const {
103 19005 : return impl_->payload_blob_;
104 : }
105 :
106 : const interface::types::BlobType &Transaction::reducedPayload() const {
107 0 : return impl_->reduced_payload_blob_;
108 : }
109 :
110 : interface::types::SignatureRangeType Transaction::signatures() const {
111 25173 : return impl_->signatures_;
112 : }
113 :
114 : const interface::types::HashType &Transaction::reducedHash() const {
115 4739 : return impl_->reduced_hash_;
116 : }
117 :
118 : bool Transaction::addSignature(const crypto::Signed &signed_blob,
119 : const crypto::PublicKey &public_key) {
120 : // if already has such signature
121 1342 : if (std::find_if(impl_->signatures_.begin(),
122 1342 : impl_->signatures_.end(),
123 : [&public_key](const auto &signature) {
124 97 : return signature.publicKey() == public_key;
125 : })
126 1342 : != impl_->signatures_.end()) {
127 16 : return false;
128 : }
129 :
130 1326 : auto sig = impl_->proto_->add_signatures();
131 1326 : sig->set_signature(signed_blob.hex());
132 1326 : sig->set_public_key(public_key.hex());
133 :
134 : impl_->signatures_ = [this] {
135 1326 : auto signatures = *impl_->proto_->mutable_signatures()
136 1326 : | boost::adaptors::transformed(
137 : [](auto &x) { return proto::Signature(x); });
138 1326 : return SignatureSetType<proto::Signature>(signatures.begin(),
139 1326 : signatures.end());
140 1326 : }();
141 :
142 1326 : return true;
143 1342 : }
144 :
145 : const Transaction::TransportType &Transaction::getTransport() const {
146 8378 : return *impl_->proto_;
147 : }
148 :
149 : interface::types::TimestampType Transaction::createdTime() const {
150 9722 : return impl_->reduced_payload_.created_time();
151 : }
152 :
153 : interface::types::QuorumType Transaction::quorum() const {
154 10528 : return impl_->reduced_payload_.quorum();
155 : }
156 :
157 : boost::optional<std::shared_ptr<interface::BatchMeta>>
158 : Transaction::batchMeta() const {
159 24118 : return impl_->meta_;
160 : }
161 :
162 : Transaction::ModelType *Transaction::clone() const {
163 205 : return new Transaction(TransportType(*impl_->proto_));
164 0 : }
165 :
166 : } // namespace proto
167 : } // namespace shared_model
|