LCOV - code coverage report
Current view: top level - irohad/network/impl - block_loader_service.cpp (source / functions) Hit Total Coverage
Test: cleared_cor.info Lines: 45 51 88.2 %
Date: 2019-03-07 14:46:43 Functions: 8 8 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 "network/impl/block_loader_service.hpp"
       7             : 
       8             : #include "backend/protobuf/block.hpp"
       9             : #include "common/bind.hpp"
      10             : #include "logger/logger.hpp"
      11             : 
      12             : using namespace iroha;
      13             : using namespace iroha::ametsuchi;
      14             : using namespace iroha::network;
      15             : 
      16             : BlockLoaderService::BlockLoaderService(
      17             :     std::shared_ptr<BlockQueryFactory> block_query_factory,
      18             :     std::shared_ptr<iroha::consensus::ConsensusResultCache>
      19             :         consensus_result_cache,
      20             :     logger::LoggerPtr log)
      21         254 :     : block_query_factory_(std::move(block_query_factory)),
      22         254 :       consensus_result_cache_(std::move(consensus_result_cache)),
      23         254 :       log_(std::move(log)) {}
      24             : 
      25             : grpc::Status BlockLoaderService::retrieveBlocks(
      26             :     ::grpc::ServerContext *context,
      27             :     const proto::BlocksRequest *request,
      28             :     ::grpc::ServerWriter<::iroha::protocol::Block> *writer) {
      29           3 :   auto blocks = block_query_factory_->createBlockQuery() |
      30             :       [height = request->height()](const auto &block_query) {
      31           3 :         return block_query->getBlocksFrom(height);
      32             :       };
      33             :   std::for_each(blocks.begin(), blocks.end(), [&writer](const auto &block) {
      34           3 :     protocol::Block proto_block;
      35           3 :     *proto_block.mutable_block_v1() =
      36           3 :         std::dynamic_pointer_cast<shared_model::proto::Block>(block)
      37           3 :             ->getTransport();
      38             : 
      39           3 :     writer->Write(proto_block);
      40           3 :   });
      41           3 :   return grpc::Status::OK;
      42           3 : }
      43             : 
      44             : grpc::Status BlockLoaderService::retrieveBlock(
      45             :     ::grpc::ServerContext *context,
      46             :     const proto::BlockRequest *request,
      47             :     protocol::Block *response) {
      48           4 :   const auto hash = shared_model::crypto::Hash(request->hash());
      49           4 :   if (hash.size() == 0) {
      50           0 :     log_->error("Bad hash in request");
      51           0 :     return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
      52           0 :                         "Bad hash provided");
      53             :   }
      54             : 
      55             :   // try to fetch block from the consensus cache
      56           4 :   auto block = consensus_result_cache_->get();
      57           4 :   if (block) {
      58           2 :     if (block->hash() == hash) {
      59             :       auto block_v1 =
      60           1 :           std::static_pointer_cast<shared_model::proto::Block>(block)
      61           1 :               ->getTransport();
      62           1 :       *response->mutable_block_v1() = block_v1;
      63           1 :       return grpc::Status::OK;
      64           1 :     } else {
      65           1 :       log_->info(
      66           1 :           "Requested to retrieve a block, but cache contains another block: "
      67             :           "requested {}, in cache {}",
      68           1 :           hash.hex(),
      69           1 :           block->hash().hex());
      70             :     }
      71           1 :   } else {
      72           2 :     log_->info(
      73           2 :         "Tried to retrieve a block from an empty cache: requested block hash "
      74             :         "{}",
      75           2 :         hash.hex());
      76             :   }
      77             : 
      78             :   // cache missed: notify and try to fetch the block from block storage itself
      79           3 :   auto blocks = block_query_factory_->createBlockQuery() |
      80             :       // TODO [IR-1757] Akvinikym 12.10.18: use block height to get one block
      81             :       // instead of the whole chain
      82             :       [](const auto &block_query) {
      83           3 :         return boost::make_optional(block_query->getBlocksFrom(1));
      84           0 :       };
      85           3 :   if (not blocks) {
      86           0 :     log_->error("Could not create block query to retrieve block from storage");
      87           0 :     return grpc::Status(grpc::StatusCode::INTERNAL, "internal error happened");
      88             :   }
      89             : 
      90           3 :   auto found_block = std::find_if(
      91             :       std::begin(*blocks), std::end(*blocks), [&hash](const auto &block) {
      92           2 :         return block->hash() == hash;
      93             :       });
      94           3 :   if (found_block == std::end(*blocks)) {
      95           1 :     log_->error("Could not retrieve a block from block storage: requested {}",
      96           1 :                 hash.hex());
      97           1 :     return grpc::Status(grpc::StatusCode::NOT_FOUND, "Block not found");
      98             :   }
      99             : 
     100             :   auto block_v1 =
     101           2 :       std::static_pointer_cast<shared_model::proto::Block>(*found_block)
     102           2 :           ->getTransport();
     103           2 :   *response->mutable_block_v1() = block_v1;
     104           2 :   return grpc::Status::OK;
     105           4 : }

Generated by: LCOV version 1.13