LCOV - code coverage report
Current view: top level - shared_model/interfaces/base - signable.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 16 19 84.2 %
Date: 2018-12-05 17:11:35 Functions: 26 47 55.3 %

          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_SIGNABLE_HPP
       7             : #define IROHA_SIGNABLE_HPP
       8             : 
       9             : #include "interfaces/base/model_primitive.hpp"
      10             : 
      11             : #include <boost/functional/hash.hpp>
      12             : #include <boost/optional.hpp>
      13             : #include <unordered_set>
      14             : #include "cryptography/default_hash_provider.hpp"
      15             : #include "interfaces/common_objects/range_types.hpp"
      16             : #include "interfaces/common_objects/signature.hpp"
      17             : #include "interfaces/common_objects/types.hpp"
      18             : #include "utils/string_builder.hpp"
      19             : 
      20             : namespace shared_model {
      21             : 
      22             :   namespace crypto {
      23             :     class Signed;
      24             :     class PublicKey;
      25             :   }  // namespace crypto
      26             : 
      27             :   namespace interface {
      28             : 
      29             :     /**
      30             :      * Interface provides signatures and adds them to model object
      31             :      * @tparam Model - your model
      32             :      */
      33             :     template <typename Model,
      34             :               typename HashProvider = shared_model::crypto::Sha3_256>
      35             :     class Signable : public ModelPrimitive<Model> {
      36             :      public:
      37             :       /**
      38             :        * @return attached signatures
      39             :        */
      40             :       virtual types::SignatureRangeType signatures() const = 0;
      41             : 
      42             :       /**
      43             :        * Attach signature to object
      44             :        * @param signature - signature object for insertion
      45             :        * @return true, if signature was added
      46             :        */
      47             :       virtual bool addSignature(const crypto::Signed &signed_blob,
      48             :                                 const crypto::PublicKey &public_key) = 0;
      49             : 
      50             :       /**
      51             :        * @return time of creation
      52             :        */
      53             :       virtual types::TimestampType createdTime() const = 0;
      54             : 
      55             :       /**
      56             :        * @return object payload (everything except signatures)
      57             :        */
      58             :       virtual const types::BlobType &payload() const = 0;
      59             : 
      60             :       /**
      61             :        * @return blob representation of object include signatures
      62             :        */
      63             :       virtual const types::BlobType &blob() const = 0;
      64             : 
      65             :       /**
      66             :        * Provides comparison based on equality of objects and signatures.
      67             :        * @param rhs - another model object
      68             :        * @return true, if objects totally equal
      69             :        */
      70             :       bool operator==(const Model &rhs) const override {
      71          82 :         return equalsByValue(rhs)
      72             :             // is_permutation consumes ~O(N^2)
      73          82 :             and std::is_permutation(signatures().begin(),
      74          64 :                                     signatures().end(),
      75          64 :                                     rhs.signatures().begin());
      76           0 :       }
      77             : 
      78             :       /**
      79             :        * Provides comaprison based on equality objects only
      80             :        * @param rhs - another model object
      81             :        * @return true, if hashes of objects are equal
      82             :        */
      83             :       bool equalsByValue(const Model &rhs) const {
      84          87 :         return this->hash() == rhs.hash();
      85             :       }
      86             : 
      87             :       virtual const types::HashType &hash() const {
      88       13330 :         if (hash_ == boost::none) {
      89        6199 :           hash_.emplace(HashProvider::makeHash(payload()));
      90        6199 :         }
      91       13329 :         return *hash_;
      92           0 :       }
      93             : 
      94             :       // ------------------------| Primitive override |-------------------------
      95             : 
      96             :       std::string toString() const override {
      97         150 :         return detail::PrettyStringBuilder()
      98         149 :             .init("Signable")
      99         150 :             .append("created_time", std::to_string(createdTime()))
     100         149 :             .appendAll(signatures(),
     101             :                        [](auto &signature) { return signature.toString(); })
     102         150 :             .finalize();
     103           0 :       }
     104             : 
     105             :      protected:
     106             :       /**
     107             :        * Type of set of signatures
     108             :        *
     109             :        * Note: we can't use const SignatureType due to unordered_set
     110             :        * limitations: it requires to have write access for elements for some
     111             :        * internal operations.
     112             :        */
     113             : 
     114             :      protected:
     115             :       class SignatureSetTypeOps {
     116             :        public:
     117             :         /**
     118             :          * @param sig is item to find hash from
     119             :          * @return calculated hash of public key
     120             :          */
     121             :         template <typename T>
     122             :         size_t operator()(const T &sig) const {
     123       22750 :           return std::hash<std::string>{}(sig.publicKey().hex());
     124             :         }
     125             : 
     126             :         /**
     127             :          * Function for set elements uniqueness by public key
     128             :          * @param lhs
     129             :          * @param rhs
     130             :          * @return true, if public keys are the same
     131             :          */
     132             :         template <typename T>
     133             :         bool operator()(const T &lhs, const T &rhs) const {
     134          89 :           return lhs.publicKey() == rhs.publicKey();
     135             :         }
     136             :       };
     137             : 
     138             :       template <typename T>
     139             :       using SignatureSetType =
     140             :           std::unordered_set<T, SignatureSetTypeOps, SignatureSetTypeOps>;
     141             : 
     142             :      private:
     143             :       mutable boost::optional<types::HashType> hash_;
     144             :     };
     145             : 
     146             :   }  // namespace interface
     147             : }  // namespace shared_model
     148             : 
     149             : #endif  // IROHA_SIGNABLE_HPP

Generated by: LCOV version 1.13