Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Commit

Permalink
Proto Validation for Block (#1905)
Browse files Browse the repository at this point in the history
* Proto Validator is added

Signed-off-by: Akvinikym <anarant12@gmail.com>

* Review issues

Signed-off-by: Akvinikym <anarant12@gmail.com>

* Review issues 2

Signed-off-by: Akvinikym <anarant12@gmail.com>
  • Loading branch information
Akvinikym authored and kamilsa committed Dec 11, 2018
1 parent 43b8fce commit f3668f1
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 19 deletions.
4 changes: 3 additions & 1 deletion irohad/main/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "torii/impl/status_bus_impl.hpp"
#include "validators/default_validator.hpp"
#include "validators/field_validator.hpp"
#include "validators/protobuf/proto_block_validator.hpp"
#include "validators/protobuf/proto_query_validator.hpp"
#include "validators/protobuf/proto_transaction_validator.hpp"

Expand Down Expand Up @@ -293,7 +294,8 @@ void Irohad::initSimulator() {
// are validated in the ordering gate, where they are received from the
// ordering service.
std::make_unique<
shared_model::validation::DefaultUnsignedBlockValidator>());
shared_model::validation::DefaultUnsignedBlockValidator>(),
std::make_unique<shared_model::validation::ProtoBlockValidator>());
simulator = std::make_shared<Simulator>(ordering_gate,
stateful_validator,
storage,
Expand Down
5 changes: 3 additions & 2 deletions irohad/main/impl/block_loader_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "main/impl/block_loader_init.hpp"
#include "validators/default_validator.hpp"
#include "validators/protobuf/proto_block_validator.hpp"

using namespace iroha;
using namespace iroha::ametsuchi;
Expand All @@ -20,8 +21,8 @@ auto BlockLoaderInit::createService(
auto BlockLoaderInit::createLoader(
std::shared_ptr<PeerQueryFactory> peer_query_factory) {
shared_model::proto::ProtoBlockFactory factory(
std::make_unique<
shared_model::validation::DefaultSignedBlockValidator>());
std::make_unique<shared_model::validation::DefaultSignedBlockValidator>(),
std::make_unique<shared_model::validation::ProtoBlockValidator>());
return std::make_shared<BlockLoaderImpl>(std::move(peer_query_factory),
std::move(factory));
}
Expand Down
17 changes: 12 additions & 5 deletions shared_model/backend/protobuf/impl/proto_block_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ using namespace shared_model::proto;

ProtoBlockFactory::ProtoBlockFactory(
std::unique_ptr<shared_model::validation::AbstractValidator<
shared_model::interface::Block>> validator)
: validator_(std::move(validator)){};
shared_model::interface::Block>> interface_validator,
std::unique_ptr<
shared_model::validation::AbstractValidator<iroha::protocol::Block>>
proto_validator)
: interface_validator_{std::move(interface_validator)},
proto_validator_{std::move(proto_validator)} {}

std::unique_ptr<shared_model::interface::Block>
ProtoBlockFactory::unsafeCreateBlock(
Expand Down Expand Up @@ -49,12 +53,15 @@ ProtoBlockFactory::unsafeCreateBlock(
iroha::expected::Result<std::unique_ptr<shared_model::interface::Block>,
std::string>
ProtoBlockFactory::createBlock(iroha::protocol::Block block) {
if (auto errors = proto_validator_->validate(block)) {
return iroha::expected::makeError(errors.reason());
}

std::unique_ptr<shared_model::interface::Block> proto_block =
std::make_unique<Block>(std::move(block.block_v1()));

auto errors = validator_->validate(*proto_block);
if (errors) {
if (auto errors = interface_validator_->validate(*proto_block)) {
return iroha::expected::makeError(errors.reason());
}

return iroha::expected::makeValue(std::move(proto_block));
}
13 changes: 9 additions & 4 deletions shared_model/backend/protobuf/proto_block_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ namespace shared_model {
*/
class ProtoBlockFactory : public interface::UnsafeBlockFactory {
public:
explicit ProtoBlockFactory(
ProtoBlockFactory(
std::unique_ptr<shared_model::validation::AbstractValidator<
shared_model::interface::Block>> validator);
shared_model::interface::Block>> interface_validator,
std::unique_ptr<shared_model::validation::AbstractValidator<
iroha::protocol::Block>> proto_validator);

std::unique_ptr<interface::Block> unsafeCreateBlock(
interface::types::HeightType height,
Expand All @@ -34,7 +36,7 @@ namespace shared_model {
* Create block variant
*
* @param block - proto block from which block variant is created
* @return BlockVariant with block.
* @return Pointer to block.
* Error if block is invalid
*/
iroha::expected::Result<std::unique_ptr<interface::Block>, std::string>
Expand All @@ -43,7 +45,10 @@ namespace shared_model {
private:
std::unique_ptr<shared_model::validation::AbstractValidator<
shared_model::interface::Block>>
validator_;
interface_validator_;
std::unique_ptr<
shared_model::validation::AbstractValidator<iroha::protocol::Block>>
proto_validator_;
};
} // namespace proto
} // namespace shared_model
Expand Down
1 change: 1 addition & 0 deletions shared_model/validators/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_library(shared_model_stateless_validation
field_validator.cpp
transactions_collection/transactions_collection_validator.cpp
transactions_collection/batch_order_validator.cpp
protobuf/proto_block_validator.cpp
)

target_link_libraries(shared_model_stateless_validation
Expand Down
27 changes: 27 additions & 0 deletions shared_model/validators/protobuf/proto_block_validator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "validators/protobuf/proto_block_validator.hpp"

namespace shared_model {
namespace validation {
Answer ProtoBlockValidator::validate(
const iroha::protocol::Block &block) const {
Answer answer;
std::string tx_reason_name = "Protobuf Block";
ReasonsGroupType reason{tx_reason_name, GroupedReasons()};

// make sure version one_of field of the Block is set
if (block.block_version_case()
== iroha::protocol::Block::BLOCK_VERSION_NOT_SET) {
reason.second.emplace_back("Block version is not set");
answer.addReason(std::move(reason));
return answer;
}

return answer;
}
} // namespace validation
} // namespace shared_model
22 changes: 22 additions & 0 deletions shared_model/validators/protobuf/proto_block_validator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef IROHA_PROTO_BLOCK_VALIDATOR_HPP
#define IROHA_PROTO_BLOCK_VALIDATOR_HPP

#include "block.pb.h"
#include "validators/abstract_validator.hpp"

namespace shared_model {
namespace validation {
class ProtoBlockValidator
: public AbstractValidator<iroha::protocol::Block> {
public:
Answer validate(const iroha::protocol::Block &block) const override;
};
} // namespace validation
} // namespace shared_model

#endif // IROHA_PROTO_BLOCK_VALIDATOR_HPP
4 changes: 3 additions & 1 deletion test/module/irohad/network/block_loader_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class BlockLoaderTest : public testing::Test {
validator = validator_ptr.get();
loader = std::make_shared<BlockLoaderImpl>(
peer_query_factory,
shared_model::proto::ProtoBlockFactory(std::move(validator_ptr)));
shared_model::proto::ProtoBlockFactory(
std::move(validator_ptr),
std::make_unique<MockValidator<iroha::protocol::Block>>()));
service =
std::make_shared<BlockLoaderService>(block_query_factory, block_cache);

Expand Down
4 changes: 3 additions & 1 deletion test/module/irohad/simulator/simulator_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ class SimulatorTest : public ::testing::Test {
std::shared_ptr<iroha::ametsuchi::BlockQuery>(query))));
block_factory = std::make_unique<shared_model::proto::ProtoBlockFactory>(
std::make_unique<shared_model::validation::MockValidator<
shared_model::interface::Block>>());
shared_model::interface::Block>>(),
std::make_unique<
shared_model::validation::MockValidator<iroha::protocol::Block>>());
}

void TearDown() override {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ using namespace shared_model;
class ProtoBlockFactoryTest : public ::testing::Test {
public:
std::unique_ptr<proto::ProtoBlockFactory> factory;
validation::MockValidator<interface::Block> *validator;

ProtoBlockFactoryTest() {
auto validator_ptr =
auto interface_validator =
std::make_unique<validation::MockValidator<interface::Block>>();
validator = validator_ptr.get();
factory =
std::make_unique<proto::ProtoBlockFactory>(std::move(validator_ptr));
auto proto_validator =
std::make_unique<validation::MockValidator<iroha::protocol::Block>>();
factory = std::make_unique<proto::ProtoBlockFactory>(
std::move(interface_validator), std::move(proto_validator));
}
};

Expand Down
8 changes: 8 additions & 0 deletions test/module/shared_model/validators/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,11 @@ target_link_libraries(proto_transaction_validator_test
shared_model_proto_backend
shared_model_stateless_validation
)

addtest(proto_block_validator_test
protobuf/proto_block_validator_test.cpp
)
target_link_libraries(proto_block_validator_test
shared_model_proto_backend
shared_model_stateless_validation
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#include "validators/protobuf/proto_block_validator.hpp"
#include <gmock/gmock-matchers.h>
#include "block.pb.h"
#include "module/shared_model/validators/validators_fixture.hpp"

using testing::HasSubstr;

class ProtoBlockValidatorTest : public ValidatorsTest {
public:
shared_model::validation::ProtoBlockValidator validator;
};

/**
* @given protocol block object with unset version field
* @when validating this object
* @then corresponding error is returned
*/
TEST_F(ProtoBlockValidatorTest, UnsetVersion) {
iroha::protocol::Block invalid_block;

auto answer = validator.validate(invalid_block);
ASSERT_TRUE(answer.hasErrors());
ASSERT_THAT(answer.reason(), HasSubstr("Block version is not set"));
}

/**
* @given valid protocol block object
* @when validating this object
* @then validation is successful
*/
TEST_F(ProtoBlockValidatorTest, ValidBlock) {
iroha::protocol::Block valid_block;

iroha::protocol::Block_v1 versioned_block;
*valid_block.mutable_block_v1() = versioned_block;

auto answer = validator.validate(valid_block);
ASSERT_FALSE(answer.hasErrors());
}

0 comments on commit f3668f1

Please sign in to comment.