hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
block_validator.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_BLOCK_VALIDATOR_HPP
7 #define IROHA_BLOCK_VALIDATOR_HPP
8 
9 #include <unordered_map>
10 
11 #include <fmt/core.h>
12 #include <boost/range/adaptor/indexed.hpp>
13 #include "datetime/time.hpp"
20 
21 namespace shared_model {
22  namespace validation {
23 
27  template <typename FieldValidator, typename TransactionsCollectionValidator>
28  class BlockValidator : public AbstractValidator<interface::Block> {
29  public:
30  BlockValidator(std::shared_ptr<ValidatorsConfig> config)
31  : transactions_collection_validator_(
33  field_validator_(FieldValidator{config}) {}
34 
40  boost::optional<ValidationError> validate(
41  const interface::Block &block) const override {
42  ValidationErrorCreator error_creator;
43 
44  error_creator |= field_validator_.validateHeight(block.height());
45  error_creator |= field_validator_.validateHash(block.prevHash());
46  error_creator |= transactions_collection_validator_.validate(
47  block.transactions(), block.createdTime());
48 
49  std::unordered_map<shared_model::crypto::Hash,
50  size_t,
52  rejected_hashes;
53  for (const auto &hash : block.rejected_transactions_hashes()
54  | boost::adaptors::indexed(1)) {
55  ValidationErrorCreator hash_error_creator;
56  auto emplace_result =
57  rejected_hashes.emplace(hash.value(), hash.index());
58  if (not emplace_result.second) {
59  hash_error_creator.addReason(fmt::format(
60  "Duplicates hash #{}", emplace_result.first->second));
61  }
62  hash_error_creator |= field_validator_.validateHash(hash.value());
63  error_creator |=
64  std::move(hash_error_creator)
66  return fmt::format("Rejected transaction hash #{} {}",
67  hash.index(),
68  hash.value().hex());
69  });
70  }
71 
72  for (const auto &tx :
73  block.transactions() | boost::adaptors::indexed(1)) {
74  auto it = rejected_hashes.find(tx.value().hash());
75  if (it != rejected_hashes.end()) {
76  error_creator.addReason(
77  fmt::format("Hash '{}' of transaction #{} has already "
78  "appeared in rejected hashes (#{}).",
79  tx.value().hash().hex(),
80  tx.index(),
81  it->second));
82  }
83  }
84 
85  return std::move(error_creator).getValidationError("Block");
86  }
87 
88  private:
89  TransactionsCollectionValidator transactions_collection_validator_;
90  FieldValidator field_validator_;
91  };
92 
93  } // namespace validation
94 } // namespace shared_model
95 
96 #endif // IROHA_BLOCK_VALIDATOR_HPP
virtual interface::types::HashCollectionType rejected_transactions_hashes() const =0
Definition: hash.hpp:18
Definition: block_validator.hpp:28
boost::optional< ValidationError > validate(const interface::Block &block) const override
Definition: block_validator.hpp:40
Definition: abstract_validator.hpp:17
boost::optional< ValidationError > getValidationError(const ReasonName &name) &&
Definition: validation_error_helpers.cpp:15
Definition: block.hpp:16
boost::optional< ValidationError > validateHeight(const interface::types::HeightType &height) const
Definition: field_validator.cpp:361
virtual types::TimestampType createdTime() const =0
virtual types::TransactionsCollectionType transactions() const =0
ValidationErrorCreator & addReason(ReasonType reason)
Add a reason to error.
Definition: validation_error_helpers.cpp:23
boost::optional< ValidationError > getValidationErrorWithGeneratedName(NameProvider &&name_provider) &&
Definition: validation_error_helpers.hpp:31
hash256_t hash(const T &pb)
Definition: pb_common.hpp:43
BlockValidator(std::shared_ptr< ValidatorsConfig > config)
Definition: block_validator.hpp:30
Definition: field_validator.hpp:40
Helper class for ValidationError creation.
Definition: validation_error_helpers.hpp:16
virtual const types::HashType & prevHash() const =0
Definition: command_executor.hpp:12
Definition: hash.hpp:23
Definition: transactions_collection_validator.hpp:24
boost::optional< ValidationError > validateHash(const crypto::Hash &hash) const
Definition: field_validator.cpp:371
boost::optional< ValidationError > validate(const interface::types::TransactionsForwardCollectionType &transactions) const
Definition: transactions_collection_validator.cpp:96
virtual types::HeightType height() const =0