Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #ifndef IROHA_UNSIGNED_PROTO_HPP
7 : #define IROHA_UNSIGNED_PROTO_HPP
8 :
9 : #include "backend/protobuf/common_objects/signature.hpp"
10 : #include "backend/protobuf/transaction.hpp"
11 : #include "cryptography/crypto_provider/crypto_signer.hpp"
12 : #include "cryptography/keypair.hpp"
13 : #include "interfaces/common_objects/types.hpp"
14 :
15 : namespace shared_model {
16 : namespace proto {
17 : /**
18 : * Class for holding built but still unsigned objects
19 : * @tparam T - type of object received from builder
20 : *
21 : * NOTE: finish() moves internal object, so calling methods after
22 : * finish() throws an exception
23 : */
24 : template <typename T>
25 : class [[deprecated]] UnsignedWrapper {
26 : public:
27 : using ModelType = T;
28 :
29 : /**
30 : * Constructs new unsigned object instance
31 : * @param o - object received from builder
32 : */
33 : explicit UnsignedWrapper(const T &o) : object_(o) {}
34 :
35 : explicit UnsignedWrapper(T &&o) : object_(std::move(o)) {}
36 :
37 : UnsignedWrapper(UnsignedWrapper<T> &&w)
38 : : object_(std::move(w.object_)),
39 : object_finalized_(w.object_finalized_) {
40 : w.object_finalized_ = true;
41 : }
42 :
43 : UnsignedWrapper<T> &operator=(UnsignedWrapper<T> &&w) {
44 : object_ = std::move(w.object_);
45 : object_finalized_ = w.object_finalized_;
46 : w.object_finalized_ = true;
47 :
48 : return *this;
49 : }
50 :
51 : UnsignedWrapper(const UnsignedWrapper<T> &o) = default;
52 : UnsignedWrapper<T> &operator=(const UnsignedWrapper<T> &w) = default;
53 :
54 : /**
55 : * Add signature and retrieve signed result
56 : * @param signature - signature to add
57 : * @return signed object
58 : */
59 : UnsignedWrapper &signAndAddSignature(const crypto::Keypair &keypair) {
60 1489 : auto signedBlob = shared_model::crypto::CryptoSigner<>::sign(
61 1489 : shared_model::crypto::Blob(object_.payload()), keypair);
62 1489 : if (object_finalized_) {
63 0 : throw std::runtime_error("object has already been finalized");
64 : }
65 1489 : object_.addSignature(signedBlob, keypair.publicKey());
66 : // TODO: 05.12.2017 luckychess think about false case
67 : return *this;
68 1489 : }
69 :
70 : /**
71 : * Finishes object building
72 : * @return built signed object
73 : */
74 : T finish() {
75 1471 : if (boost::size(object_.signatures()) == 0) {
76 0 : throw std::invalid_argument("Cannot get object without signatures");
77 : }
78 1471 : if (object_finalized_) {
79 0 : throw std::runtime_error("object has already been finalized");
80 : }
81 :
82 1471 : object_finalized_ = true;
83 1471 : return std::move(object_);
84 0 : }
85 :
86 : interface::types::HashType hash() {
87 1 : return object_.hash();
88 : }
89 :
90 : template <typename U = T>
91 : std::enable_if_t<
92 : std::is_base_of<shared_model::interface::Transaction, U>::value,
93 : interface::types::HashType>
94 : reducedHash() const {
95 27 : return object_.reducedHash();
96 : }
97 :
98 : private:
99 : T object_;
100 1499 : bool object_finalized_{false};
101 : };
102 : } // namespace proto
103 : } // namespace shared_model
104 :
105 : #endif // IROHA_UNSIGNED_PROTO_HPP
|