LCOV - code coverage report
Current view: top level - irohad/network/impl - block_loader_service.cpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 36 42 85.7 %
Date: 2018-12-05 17:11:35 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
       3             :  * http://soramitsu.co.jp
       4             :  *
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include "network/impl/block_loader_service.hpp"
      19             : #include "backend/protobuf/block.hpp"
      20             : #include "common/bind.hpp"
      21             : 
      22             : using namespace iroha;
      23             : using namespace iroha::ametsuchi;
      24             : using namespace iroha::network;
      25             : 
      26             : BlockLoaderService::BlockLoaderService(
      27             :     std::shared_ptr<BlockQueryFactory> block_query_factory,
      28             :     std::shared_ptr<iroha::consensus::ConsensusResultCache>
      29             :         consensus_result_cache)
      30         252 :     : block_query_factory_(std::move(block_query_factory)),
      31         252 :       consensus_result_cache_(std::move(consensus_result_cache)),
      32         252 :       log_(logger::log("BlockLoaderService")) {}
      33             : 
      34             : grpc::Status BlockLoaderService::retrieveBlocks(
      35             :     ::grpc::ServerContext *context,
      36             :     const proto::BlocksRequest *request,
      37             :     ::grpc::ServerWriter<::iroha::protocol::Block> *writer) {
      38           3 :   auto blocks = block_query_factory_->createBlockQuery() |
      39             :       [height = request->height()](const auto &block_query) {
      40           3 :         return block_query->getBlocksFrom(height);
      41             :       };
      42             :   std::for_each(blocks.begin(), blocks.end(), [&writer](const auto &block) {
      43           3 :     writer->Write(std::dynamic_pointer_cast<shared_model::proto::Block>(block)
      44           3 :                       ->getTransport());
      45           3 :   });
      46           3 :   return grpc::Status::OK;
      47           3 : }
      48             : 
      49             : grpc::Status BlockLoaderService::retrieveBlock(
      50             :     ::grpc::ServerContext *context,
      51             :     const proto::BlockRequest *request,
      52             :     protocol::Block *response) {
      53           4 :   const auto hash = shared_model::crypto::Hash(request->hash());
      54           4 :   if (hash.size() == 0) {
      55           0 :     log_->error("Bad hash in request");
      56           0 :     return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
      57           0 :                         "Bad hash provided");
      58             :   }
      59             : 
      60             :   // try to fetch block from the consensus cache
      61           4 :   auto block = consensus_result_cache_->get();
      62           4 :   if (block) {
      63           2 :     if (block->hash() == hash) {
      64           1 :       *response = std::static_pointer_cast<shared_model::proto::Block>(block)
      65           1 :                       ->getTransport();
      66           1 :       return grpc::Status::OK;
      67             :     } else {
      68           1 :       log_->info(
      69             :           "Requested to retrieve a block, but cache contains another block: "
      70             :           "requested {}, in cache {}",
      71           1 :           hash.hex(),
      72           1 :           block->hash().hex());
      73             :     }
      74           1 :   } else {
      75           2 :     log_->info(
      76             :         "Tried to retrieve a block from an empty cache: requested block hash "
      77             :         "{}",
      78           2 :         hash.hex());
      79             :   }
      80             : 
      81             :   // cache missed: notify and try to fetch the block from block storage itself
      82             :   auto blocks = block_query_factory_->createBlockQuery() |
      83             :       // TODO [IR-1757] Akvinikym 12.10.18: use block height to get one block
      84             :       // instead of the whole chain
      85             :       [](const auto &block_query) {
      86           3 :         return boost::make_optional(block_query->getBlocksFrom(1));
      87           0 :       };
      88           3 :   if (not blocks) {
      89           0 :     log_->error("Could not create block query to retrieve block from storage");
      90           0 :     return grpc::Status(grpc::StatusCode::INTERNAL, "internal error happened");
      91             :   }
      92             : 
      93           3 :   auto found_block = std::find_if(
      94             :       std::begin(*blocks), std::end(*blocks), [&hash](const auto &block) {
      95           2 :         return block->hash() == hash;
      96             :       });
      97           3 :   if (found_block == std::end(*blocks)) {
      98           1 :     log_->error("Could not retrieve a block from block storage: requested {}",
      99           1 :                 hash.hex());
     100           1 :     return grpc::Status(grpc::StatusCode::NOT_FOUND, "Block not found");
     101             :   }
     102             : 
     103           2 :   *response = std::static_pointer_cast<shared_model::proto::Block>(*found_block)
     104           2 :                   ->getTransport();
     105           2 :   return grpc::Status::OK;
     106           4 : }

Generated by: LCOV version 1.13