LCOV - code coverage report
Current view: top level - irohad/main - irohad.cpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 0 80 0.0 %
Date: 2018-12-05 17:11:35 Functions: 0 32 0.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 <gflags/gflags.h>
      19             : #include <grpc++/grpc++.h>
      20             : #include <csignal>
      21             : #include <fstream>
      22             : #include <thread>
      23             : #include "common/result.hpp"
      24             : #include "crypto/keys_manager_impl.hpp"
      25           0 : #include "main/application.hpp"
      26             : #include "main/iroha_conf_loader.hpp"
      27             : #include "main/raw_block_loader.hpp"
      28             : 
      29             : static const std::string kListenIp = "0.0.0.0";
      30             : 
      31             : /**
      32             :  * Gflag validator.
      33             :  * Validator for the configuration file path input argument.
      34             :  * Path is considered to be valid if it is not empty.
      35             :  * @param flag_name - flag name. Must be 'config' in this case
      36             :  * @param path      - file name. Should be path to the config file
      37             :  * @return true if argument is valid
      38             :  */
      39             : bool validate_config(const char *flag_name, std::string const &path) {
      40           0 :   return not path.empty();
      41             : }
      42             : 
      43             : /**
      44             :  * Gflag validator.
      45             :  * Validator for the keypair files path input argument.
      46             :  * Path is considered to be valid if it is not empty.
      47             :  * @param flag_name - flag name. Must be 'keypair_name' in this case
      48             :  * @param path      - file name. Should be path to the keypair files
      49             :  * @return true if argument is valid
      50             :  */
      51             : bool validate_keypair_name(const char *flag_name, std::string const &path) {
      52           0 :   return not path.empty();
      53             : }
      54             : 
      55             : /**
      56             :  * Creating input argument for the configuration file location.
      57             :  */
      58             : DEFINE_string(config, "", "Specify iroha provisioning path.");
      59             : /**
      60             :  * Registering validator for the configuration file location.
      61             :  */
      62             : DEFINE_validator(config, &validate_config);
      63             : 
      64             : /**
      65             :  * Creating input argument for the genesis block file location.
      66             :  */
      67             : DEFINE_string(genesis_block, "", "Specify file with initial block");
      68             : 
      69             : /**
      70             :  * Creating input argument for the keypair files location.
      71             :  */
      72             : DEFINE_string(keypair_name, "", "Specify name of .pub and .priv files");
      73             : /**
      74             :  * Registering validator for the keypair files location.
      75             :  */
      76             : DEFINE_validator(keypair_name, &validate_keypair_name);
      77             : 
      78             : /**
      79             :  * Creating boolean flag for overwriting already existing block storage
      80             :  */
      81             : DEFINE_bool(overwrite_ledger, false, "Overwrite ledger data if existing");
      82             : 
      83             : static bool validateVerbosity(const char *flagname, int32_t val) {
      84           0 :   if (val >= 0 && val <= 6)
      85           0 :     return true;
      86             : 
      87           0 :   std::cout << "Invalid value for " << flagname << ": should be in range [0, 6]"
      88           0 :             << std::endl;
      89           0 :   return false;
      90           0 : }
      91             : 
      92             : /// Verbosity flag for spdlog configuration
      93             : DEFINE_int32(verbosity, spdlog::level::info, "Log verbosity");
      94             : DEFINE_validator(verbosity, validateVerbosity);
      95             : 
      96             : std::promise<void> exit_requested;
      97             : 
      98             : int main(int argc, char *argv[]) {
      99           0 :   spdlog::set_level(spdlog::level::level_enum(FLAGS_verbosity));
     100             : 
     101           0 :   auto log = logger::log("MAIN");
     102             :   log->info("start");
     103             : 
     104             :   // Check if validators are registered.
     105           0 :   if (not config_validator_registered
     106           0 :       or not keypair_name_validator_registered) {
     107             :     // Abort execution if not
     108           0 :     log->error("Flag validator is not registered");
     109           0 :     return EXIT_FAILURE;
     110             :   }
     111             : 
     112             :   namespace mbr = config_members;
     113             : 
     114             :   // Parsing command line arguments
     115           0 :   gflags::ParseCommandLineFlags(&argc, &argv, true);
     116           0 :   gflags::ShutDownCommandLineFlags();
     117             : 
     118             :   // Reading iroha configuration file
     119           0 :   auto config = parse_iroha_config(FLAGS_config);
     120           0 :   log->info("config initialized");
     121             : 
     122             :   // Reading public and private key files
     123           0 :   iroha::KeysManagerImpl keysManager(FLAGS_keypair_name);
     124           0 :   auto keypair = keysManager.loadKeys();
     125             :   // Check if both keys are read properly
     126           0 :   if (not keypair) {
     127             :     // Abort execution if not
     128           0 :     log->error("Failed to load keypair");
     129           0 :     return EXIT_FAILURE;
     130             :   }
     131             : 
     132             :   // Configuring iroha daemon
     133           0 :   Irohad irohad(config[mbr::BlockStorePath].GetString(),
     134           0 :                 config[mbr::PgOpt].GetString(),
     135             :                 kListenIp,  // TODO(mboldyrev) 17/10/2018: add a parameter in
     136             :                             // config file and/or command-line arguments?
     137           0 :                 config[mbr::ToriiPort].GetUint(),
     138           0 :                 config[mbr::InternalPort].GetUint(),
     139           0 :                 config[mbr::MaxProposalSize].GetUint(),
     140           0 :                 std::chrono::milliseconds(config[mbr::ProposalDelay].GetUint()),
     141           0 :                 std::chrono::milliseconds(config[mbr::VoteDelay].GetUint()),
     142           0 :                 *keypair,
     143           0 :                 boost::make_optional(config[mbr::MstSupport].GetBool(),
     144           0 :                                      iroha::GossipPropagationStrategyParams{}));
     145             : 
     146             :   // Check if iroha daemon storage was successfully initialized
     147           0 :   if (not irohad.storage) {
     148             :     // Abort execution if not
     149           0 :     log->error("Failed to initialize storage");
     150           0 :     return EXIT_FAILURE;
     151             :   }
     152             : 
     153             :   /*
     154             :    * The logic implemented below is reflected in the following truth table.
     155             :    *
     156             :   +------------+--------------+------------------+---------------+---------+
     157             :   | Blockstore | New genesis  | Overwrite ledger | Genesis block | Message |
     158             :   | presence   | block is set | flag is set      | that is used  |         |
     159             :   +------------+--------------+------------------+---------------+---------+
     160             :   | 0          | 1            | 0                | new           |         |
     161             :   | 0          | 1            | 1                | new           | warning |
     162             :   | 1          | 1            | 0                | old           | warning |
     163             :   | 1          | 1            | 1                | new           |         |
     164             :   | 0          | 0            | 0                | none          | error   |
     165             :   | 0          | 0            | 1                | none          | error   |
     166             :   | 1          | 0            | 0                | old           |         |
     167             :   | 1          | 0            | 1                | old           | warning |
     168             :   +------------+--------------+------------------+---------------+---------+
     169             :    */
     170             : 
     171             :   /// if there are any blocks in blockstore, then true
     172           0 :   bool blockstore = irohad.storage->getBlockQuery()->getTopBlockHeight() != 0;
     173             : 
     174             :   /// genesis block file is specified as launch parameter
     175           0 :   bool genesis = not FLAGS_genesis_block.empty();
     176             : 
     177             :   /// overwrite ledger flag was set as launch parameter
     178           0 :   bool overwrite = FLAGS_overwrite_ledger;
     179             : 
     180           0 :   if (genesis) {  // genesis block file is specified
     181           0 :     if (blockstore and not overwrite) {
     182           0 :       log->warn(
     183             :           "Passed genesis block will be ignored without --overwrite_ledger "
     184             :           "flag. Restoring existing state.");
     185           0 :     } else {
     186           0 :       iroha::main::BlockLoader loader;
     187           0 :       auto file = loader.loadFile(FLAGS_genesis_block);
     188           0 :       auto block = loader.parseBlock(file.value());
     189             : 
     190           0 :       if (not block) {
     191           0 :         log->error("Failed to parse genesis block.");
     192           0 :         return EXIT_FAILURE;
     193             :       }
     194             : 
     195           0 :       if (not blockstore and overwrite) {
     196           0 :         log->warn(
     197             :             "Blockstore is empty - there is nothing to overwrite. Inserting "
     198             :             "new genesis block.");
     199           0 :       }
     200             : 
     201             :       // clear previous storage if any
     202           0 :       irohad.dropStorage();
     203             :       // reset ordering service persistent counter
     204           0 :       irohad.resetOrderingService();
     205             : 
     206           0 :       irohad.storage->insertBlock(*block.value());
     207           0 :       log->info("Genesis block inserted, number of transactions: {}",
     208           0 :                 block.value()->transactions().size());
     209           0 :     }
     210           0 :   } else {  // genesis block file is not specified
     211           0 :     if (not blockstore) {
     212           0 :       log->error(
     213             :           "Cannot restore nor create new state. Blockstore is empty. No "
     214             :           "genesis block is provided. Please pecify new genesis block using "
     215             :           "--genesis_block parameter.");
     216           0 :       return EXIT_FAILURE;
     217             :     } else {
     218           0 :       if (overwrite) {
     219           0 :         log->warn(
     220             :             "No new genesis block is specified - blockstore cannot be "
     221             :             "overwritten. If you want overwrite ledger state, please "
     222             :             "specify new genesis block using --genesis_block parameter.");
     223           0 :       }
     224             :     }
     225             :   }
     226             : 
     227             :   // check if at least one block is available in the ledger
     228           0 :   auto blocks_exist = irohad.storage->getBlockQuery()->getTopBlock().match(
     229             :       [](const auto &) { return true; },
     230             :       [](iroha::expected::Error<std::string> &) { return false; });
     231             : 
     232           0 :   if (not blocks_exist) {  // may happen only in case of bug or zero disk space
     233           0 :     log->error(
     234             :         "You should have never seen this message. There are no blocks in the "
     235             :         "ledger.  Unable to start. Try to specify --genesis_block and "
     236             :         "--overwrite_ledger parameters at the same time.");
     237           0 :     return EXIT_FAILURE;
     238             :   }
     239             : 
     240             :   // init pipeline components
     241           0 :   irohad.init();
     242             : 
     243             :   auto handler = [](int s) { exit_requested.set_value(); };
     244           0 :   std::signal(SIGINT, handler);
     245           0 :   std::signal(SIGTERM, handler);
     246           0 :   std::signal(SIGQUIT, handler);
     247             : 
     248             :   // runs iroha
     249           0 :   log->info("Running iroha");
     250           0 :   irohad.run();
     251           0 :   exit_requested.get_future().wait();
     252             : 
     253             :   // We do not care about shutting down grpc servers
     254             :   // They do all necessary work in their destructors
     255           0 :   log->info("shutting down...");
     256             : 
     257           0 :   return 0;
     258           0 : }

Generated by: LCOV version 1.13