diff --git a/test/fuzzing/CMakeLists.txt b/test/fuzzing/CMakeLists.txt index 4cc98b1ee0..b2e839f43f 100644 --- a/test/fuzzing/CMakeLists.txt +++ b/test/fuzzing/CMakeLists.txt @@ -37,11 +37,27 @@ target_link_libraries(find_fuzzing add_executable(ordering_gate_fuzz ordering_gate_fuzz.cpp) target_link_libraries(ordering_gate_fuzz - rxcpp gtest::gtest gmock::gmock on_demand_ordering_gate shared_model_default_builders - shared_model_stateless_validation protobuf-mutator -) + ) + +add_executable(send_batches_fuzz send_batches_fuzz.cpp) +target_link_libraries(send_batches_fuzz + gtest::gtest + gmock::gmock + on_demand_ordering_service + on_demand_ordering_service_transport_grpc + protobuf-mutator + ) + +add_executable(request_proposal_fuzz request_proposal_fuzz.cpp) +target_link_libraries(request_proposal_fuzz + gtest::gtest + gmock::gmock + on_demand_ordering_service + on_demand_ordering_service_transport_grpc + protobuf-mutator + ) diff --git a/test/fuzzing/ordering_gate_fuzz.cpp b/test/fuzzing/ordering_gate_fuzz.cpp index 070ee33c12..cdec677d93 100644 --- a/test/fuzzing/ordering_gate_fuzz.cpp +++ b/test/fuzzing/ordering_gate_fuzz.cpp @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#include "ordering/impl/on_demand_ordering_gate.hpp" +#include +#include "backend/protobuf/proto_block_factory.hpp" #include "module/irohad/ordering/ordering_mocks.hpp" #include "module/shared_model/interface_mocks.hpp" -#include "backend/protobuf/proto_block_factory.hpp" +#include "ordering/impl/on_demand_ordering_gate.hpp" #include "validators/default_validator.hpp" using namespace iroha::ordering; @@ -16,31 +16,31 @@ using namespace testing; struct OrderingGateFixture { std::shared_ptr block_factory_; - std::shared_ptr ordering_service_; - std::shared_ptr network_client_; + std::shared_ptr> ordering_service_; + std::shared_ptr> network_client_; rxcpp::subjects::subject rounds_; - MockUnsafeProposalFactory *proposal_factory_; + NiceMock *proposal_factory_; std::shared_ptr ordering_gate_; iroha::consensus::Round initial_round_ = {2, 1}; - OrderingGateFixture() : - block_factory_(std::make_shared(std::make_unique< - shared_model::validation::DefaultUnsignedBlockValidator>())), - ordering_service_(std::make_shared()), - network_client_(std::make_shared()) { - - auto proposal_factory = std::make_unique(); + OrderingGateFixture() + : block_factory_(std::make_shared( + std::make_unique< + shared_model::validation::DefaultUnsignedBlockValidator>())), + ordering_service_( + std::make_shared>()), + network_client_( + std::make_shared>()) { + auto proposal_factory = + std::make_unique>(); proposal_factory_ = proposal_factory.get(); - ordering_gate_ = std::make_shared(ordering_service_, network_client_, - rounds_.get_observable(), - std::move(proposal_factory), - initial_round_); - - // to suppress "uninteresting" gmock warnings - EXPECT_CALL(*ordering_service_, onCollaborationOutcome(_)).Times(AtLeast(0)); - EXPECT_CALL(*network_client_, onRequestProposal(_)).Times(AtLeast(0)); - EXPECT_CALL(*proposal_factory_, unsafeCreateProposal(_, _, _)).Times(AtLeast(0)); + ordering_gate_ = + std::make_shared(ordering_service_, + network_client_, + rounds_.get_observable(), + std::move(proposal_factory), + initial_round_); } }; @@ -52,10 +52,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { iroha::protocol::Block block; if (protobuf_mutator::libfuzzer::LoadProtoInput(true, data, size, &block)) { - auto iroha_block = ordering_gate_fixture.block_factory_->createBlock(std::move(block)); - if (auto result = boost::get>>( - &iroha_block)) { - ordering_gate_fixture.rounds_.get_subscriber().on_next(std::move(result->value)); + auto iroha_block = + ordering_gate_fixture.block_factory_->createBlock(std::move(block)); + if (auto result = boost::get>>(&iroha_block)) { + ordering_gate_fixture.rounds_.get_subscriber().on_next( + std::move(result->value)); } } diff --git a/test/fuzzing/ordering_service_fixture.hpp b/test/fuzzing/ordering_service_fixture.hpp new file mode 100644 index 0000000000..32a98e45c0 --- /dev/null +++ b/test/fuzzing/ordering_service_fixture.hpp @@ -0,0 +1,63 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IROHA_ORDERING_SERVICE_FIXTURE_HPP +#define IROHA_ORDERING_SERVICE_FIXTURE_HPP + +#include + +#include +#include + +#include "backend/protobuf/proto_transport_factory.hpp" +#include "backend/protobuf/transaction.hpp" +#include "interfaces/iroha_internal/transaction_batch_factory_impl.hpp" +#include "interfaces/iroha_internal/transaction_batch_impl.hpp" +#include "interfaces/iroha_internal/transaction_batch_parser_impl.hpp" +#include "module/shared_model/interface/mock_transaction_batch_factory.hpp" +#include "module/shared_model/interface_mocks.hpp" +#include "module/shared_model/validators/validators.hpp" +#include "ordering/impl/on_demand_ordering_service_impl.hpp" +#include "ordering/impl/on_demand_os_server_grpc.hpp" + +using namespace testing; +using namespace iroha::ordering; +using namespace iroha::ordering::transport; + +namespace fuzzing { + struct OrderingServiceFixture { + std::shared_ptr + transaction_factory_; + std::shared_ptr + batch_parser_; + std::shared_ptr> + transaction_batch_factory_; + NiceMock> *transaction_validator_; + + OrderingServiceFixture() { + // fuzzing target is intended to run many times (~millions) so any + // additional output slows it down significantly + spdlog::set_level(spdlog::level::err); + + auto transaction_validator = + std::make_unique>>(); + transaction_validator_ = transaction_validator.get(); + transaction_factory_ = + std::make_shared>( + std::move(transaction_validator)); + + batch_parser_ = std::make_shared< + shared_model::interface::TransactionBatchParserImpl>(); + transaction_batch_factory_ = + std::make_shared>(); + } + }; +} // namespace fuzzing + +#endif // IROHA_ORDERING_SERVICE_FIXTURE_HPP diff --git a/test/fuzzing/request_proposal_fuzz.cpp b/test/fuzzing/request_proposal_fuzz.cpp new file mode 100644 index 0000000000..c4d9593ac1 --- /dev/null +++ b/test/fuzzing/request_proposal_fuzz.cpp @@ -0,0 +1,36 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ordering_service_fixture.hpp" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { + static fuzzing::OrderingServiceFixture fixture; + + if (size < 1) { + return 0; + } + + std::shared_ptr ordering_service_; + std::shared_ptr server_; + + auto proposal_factory = std::make_unique(); + ordering_service_ = std::make_shared( + data[0], std::move(proposal_factory)); + server_ = std::make_shared( + ordering_service_, + fixture.transaction_factory_, + fixture.batch_parser_, + fixture.transaction_batch_factory_); + + proto::ProposalRequest request; + if (protobuf_mutator::libfuzzer::LoadProtoInput( + true, data + 1, size - 1, &request)) { + grpc::ServerContext context; + proto::ProposalResponse response; + server_->RequestProposal(&context, &request, &response); + } + + return 0; +} diff --git a/test/fuzzing/send_batches_fuzz.cpp b/test/fuzzing/send_batches_fuzz.cpp new file mode 100644 index 0000000000..94a3aa81d8 --- /dev/null +++ b/test/fuzzing/send_batches_fuzz.cpp @@ -0,0 +1,36 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ordering_service_fixture.hpp" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, std::size_t size) { + static fuzzing::OrderingServiceFixture fixture; + + if (size < 1) { + return 0; + } + + std::shared_ptr ordering_service_; + std::shared_ptr server_; + + auto proposal_factory = std::make_unique(); + ordering_service_ = std::make_shared( + data[0], std::move(proposal_factory)); + server_ = std::make_shared( + ordering_service_, + fixture.transaction_factory_, + fixture.batch_parser_, + fixture.transaction_batch_factory_); + + proto::BatchesRequest request; + if (protobuf_mutator::libfuzzer::LoadProtoInput( + true, data + 1, size - 1, &request)) { + grpc::ServerContext context; + google::protobuf::Empty response; + server_->SendBatches(&context, &request, &response); + } + + return 0; +}