LCOV - code coverage report
Current view: top level - irohad/validation/impl - stateful_validator_impl.cpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 43 44 97.7 %
Date: 2018-12-05 17:11:35 Functions: 18 18 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/stateful_validator_impl.hpp"
       7             : 
       8             : #include <string>
       9             : 
      10             : #include <boost/algorithm/cxx11/all_of.hpp>
      11             : #include <boost/format.hpp>
      12             : #include <boost/range/adaptor/filtered.hpp>
      13             : #include <boost/range/adaptor/indexed.hpp>
      14             : #include <boost/range/adaptor/transformed.hpp>
      15             : #include "common/result.hpp"
      16             : #include "interfaces/iroha_internal/batch_meta.hpp"
      17             : #include "validation/utils.hpp"
      18             : 
      19             : namespace iroha {
      20             :   namespace validation {
      21             : 
      22             :     /**
      23             :      * Complements initial transaction check with command-by-command check
      24             :      * @param temporary_wsv to apply commands on
      25             :      * @param transactions_errors_log to write errors to
      26             :      * @param tx to be checked
      27             :      * @return empty result, if check is successful, command error otherwise
      28             :      */
      29             :     static bool checkTransactions(
      30             :         ametsuchi::TemporaryWsv &temporary_wsv,
      31             :         validation::TransactionsErrors &transactions_errors_log,
      32             :         const shared_model::interface::Transaction &tx) {
      33         733 :       return temporary_wsv.apply(tx).match(
      34             :           [](expected::Value<void> &) { return true; },
      35             :           [&tx, &transactions_errors_log](
      36             :               expected::Error<validation::CommandError> &error) {
      37          58 :             transactions_errors_log.emplace(tx.hash(), std::move(error.error));
      38          58 :             return false;
      39             :           });
      40           0 :     };
      41             : 
      42             :     /**
      43             :      * Validate all transactions supplied; includes special rules, such as batch
      44             :      * validation etc
      45             :      * @param txs to be validated
      46             :      * @param temporary_wsv to apply transactions on
      47             :      * @param transactions_errors_log to write errors to
      48             :      * @param log to write errors to console
      49             :      * @param batch_parser to parse batches from transaction range
      50             :      * @return range of transactions, which passed stateful validation
      51             :      */
      52             :     static auto validateTransactions(
      53             :         const shared_model::interface::types::TransactionsCollectionType &txs,
      54             :         ametsuchi::TemporaryWsv &temporary_wsv,
      55             :         validation::TransactionsErrors &transactions_errors_log,
      56             :         const logger::Logger &log,
      57             :         const shared_model::interface::TransactionBatchParser &batch_parser) {
      58         711 :       std::vector<bool> validation_results;
      59         711 :       validation_results.reserve(boost::size(txs));
      60             : 
      61        1437 :       for (auto batch : batch_parser.parseBatches(txs)) {
      62             :         auto validation = [&](auto &tx) {
      63         733 :           return checkTransactions(temporary_wsv, transactions_errors_log, tx);
      64             :         };
      65         726 :         if (batch.front().batchMeta()
      66         726 :             and batch.front().batchMeta()->get()->type()
      67           7 :                 == shared_model::interface::types::BatchType::ATOMIC) {
      68             :           // check all batch's transactions for validness
      69           4 :           auto savepoint = temporary_wsv.createSavepoint(
      70           4 :               "batch_" + batch.front().hash().hex());
      71           4 :           bool validation_result = false;
      72             : 
      73           4 :           if (boost::algorithm::all_of(batch, validation)) {
      74             :             // batch is successful; release savepoint
      75           2 :             validation_result = true;
      76           2 :             savepoint->release();
      77           2 :           }
      78             : 
      79           4 :           validation_results.insert(
      80           4 :               validation_results.end(), boost::size(batch), validation_result);
      81           4 :         } else {
      82             :           for (const auto &tx : batch) {
      83         726 :             validation_results.push_back(validation(tx));
      84             :           }
      85             :         }
      86         726 :       }
      87             : 
      88         711 :       return txs | boost::adaptors::indexed()
      89         711 :           | boost::adaptors::filtered(
      90             :                  [validation_results =
      91         711 :                       std::move(validation_results)](const auto &el) {
      92             :                    return validation_results.at(el.index());
      93             :                  })
      94         711 :           | boost::adaptors::transformed(
      95             :                  [](const auto &el) -> decltype(auto) { return el.value(); });
      96         711 :     }
      97             : 
      98             :     StatefulValidatorImpl::StatefulValidatorImpl(
      99             :         std::unique_ptr<shared_model::interface::UnsafeProposalFactory> factory,
     100             :         std::shared_ptr<shared_model::interface::TransactionBatchParser>
     101             :             batch_parser)
     102             :         : factory_(std::move(factory)),
     103         248 :           batch_parser_(std::move(batch_parser)),
     104         248 :           log_(logger::log("SFV")) {}
     105             : 
     106             :     std::unique_ptr<validation::VerifiedProposalAndErrors>
     107             :     StatefulValidatorImpl::validate(
     108             :         const shared_model::interface::Proposal &proposal,
     109             :         ametsuchi::TemporaryWsv &temporaryWsv) {
     110         711 :       log_->info("transactions in proposal: {}",
     111         711 :                  proposal.transactions().size());
     112             : 
     113         711 :       auto validation_result = std::make_unique<VerifiedProposalAndErrors>();
     114             :       auto valid_txs =
     115         711 :           validateTransactions(proposal.transactions(),
     116         711 :                                temporaryWsv,
     117         711 :                                validation_result->rejected_transactions,
     118         711 :                                log_,
     119         711 :                                *batch_parser_);
     120             : 
     121             :       // Since proposal came from ordering gate it was already validated.
     122             :       // All transactions has been validated as well
     123             :       // This allows for unsafe construction of proposal
     124         711 :       validation_result->verified_proposal = factory_->unsafeCreateProposal(
     125         711 :           proposal.height(), proposal.createdTime(), valid_txs);
     126             : 
     127         711 :       log_->info("transactions in verified proposal: {}",
     128         711 :                  validation_result->verified_proposal->transactions().size());
     129         711 :       return validation_result;
     130         711 :     }
     131             :   }  // namespace validation
     132             : }  // namespace iroha

Generated by: LCOV version 1.13