LCOV - code coverage report
Current view: top level - irohad/validation/impl - chain_validator_impl.cpp (source / functions) Hit Total Coverage
Test: cleared_cor.info Lines: 40 46 87.0 %
Date: 2019-03-07 14:46:43 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       6             : #include "validation/impl/chain_validator_impl.hpp"
       7             : 
       8             : #include "ametsuchi/mutable_storage.hpp"
       9             : #include "ametsuchi/peer_query.hpp"
      10             : #include "consensus/yac/supermajority_checker.hpp"
      11             : #include "cryptography/public_key.hpp"
      12             : #include "interfaces/common_objects/peer.hpp"
      13             : #include "interfaces/iroha_internal/block.hpp"
      14             : #include "logger/logger.hpp"
      15             : #include "validation/utils.hpp"
      16             : 
      17             : namespace iroha {
      18             :   namespace validation {
      19             :     ChainValidatorImpl::ChainValidatorImpl(
      20             :         std::shared_ptr<consensus::yac::SupermajorityChecker>
      21             :             supermajority_checker,
      22             :         logger::LoggerPtr log)
      23         254 :         : supermajority_checker_(supermajority_checker),
      24         254 :           log_(std::move(log)) {}
      25             : 
      26             :     bool ChainValidatorImpl::validateAndApply(
      27             :         rxcpp::observable<std::shared_ptr<shared_model::interface::Block>>
      28             :             blocks,
      29             :         ametsuchi::MutableStorage &storage) const {
      30           7 :       log_->info("validate chain...");
      31             : 
      32           7 :       return storage.apply(
      33           7 :           blocks,
      34             :           [this](const auto &block, auto &queries, const auto &top_hash) {
      35           9 :             return this->validateBlock(block, queries, top_hash);
      36             :           });
      37           0 :     }
      38             : 
      39             :     bool ChainValidatorImpl::validatePreviousHash(
      40             :         const shared_model::interface::Block &block,
      41             :         const shared_model::interface::types::HashType &top_hash) const {
      42           9 :       auto same_prev_hash = block.prevHash() == top_hash;
      43             : 
      44           9 :       if (not same_prev_hash) {
      45           2 :         log_->info(
      46           2 :             "Previous hash {} of block does not match top block hash {} "
      47             :             "in storage",
      48           2 :             block.prevHash().hex(),
      49           2 :             top_hash.hex());
      50           2 :       }
      51             : 
      52           9 :       return same_prev_hash;
      53           0 :     }
      54             : 
      55             :     bool ChainValidatorImpl::validatePeerSupermajority(
      56             :         const shared_model::interface::Block &block,
      57             :         const std::vector<std::shared_ptr<shared_model::interface::Peer>>
      58             :             &peers) const {
      59           7 :       const auto &signatures = block.signatures();
      60           7 :       auto has_supermajority = supermajority_checker_->hasSupermajority(
      61           7 :                                    boost::size(signatures), peers.size())
      62           7 :           and peersSubset(signatures, peers);
      63             : 
      64           7 :       if (not has_supermajority) {
      65           2 :         log_->info(
      66           2 :             "Block does not contain signatures of supermajority of "
      67             :             "peers. Block signatures public keys: [{}], ledger peers "
      68             :             "public keys: [{}]",
      69           2 :             std::accumulate(std::next(std::begin(signatures)),
      70           2 :                             std::end(signatures),
      71           2 :                             signatures.front().publicKey().hex(),
      72             :                             [](auto acc, auto &sig) {
      73           1 :                               return acc + ", " + sig.publicKey().hex();
      74           0 :                             }),
      75           2 :             std::accumulate(std::next(std::begin(peers)),
      76           2 :                             std::end(peers),
      77           2 :                             peers.front()->pubkey().hex(),
      78             :                             [](auto acc, auto &peer) {
      79           3 :                               return acc + ", " + peer->pubkey().hex();
      80           0 :                             }));
      81           2 :       }
      82             : 
      83           7 :       return has_supermajority;
      84           7 :     }
      85             : 
      86             :     bool ChainValidatorImpl::validateBlock(
      87             :         const shared_model::interface::Block &block,
      88             :         ametsuchi::PeerQuery &queries,
      89             :         const shared_model::interface::types::HashType &top_hash) const {
      90           9 :       log_->info("validate block: height {}, hash {}",
      91           9 :                  block.height(),
      92           9 :                  block.hash().hex());
      93             : 
      94           9 :       auto peers = queries.getLedgerPeers();
      95           9 :       if (not peers) {
      96           0 :         log_->info("Cannot retrieve peers from storage");
      97           0 :         return false;
      98             :       }
      99             : 
     100           9 :       return validatePreviousHash(block, top_hash)
     101           9 :           and validatePeerSupermajority(block, *peers);
     102           9 :     }
     103             : 
     104             :   }  // namespace validation
     105             : }  // namespace iroha

Generated by: LCOV version 1.13