mirror of
https://github.com/wownero/wownero.git
synced 2026-10-17 15:41:44 +02:00
Merge pull request #10820
0a47ee2 tests: harden RPC fuzz harness setup (selsta)
ACKs: thomasbuilds, jpk68
This commit is contained in:
@@ -120,9 +120,11 @@ namespace cryptonote
|
||||
core_rpc_server::core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool restricted
|
||||
)
|
||||
: m_core(cr)
|
||||
, m_p2p(p2p)
|
||||
, m_restricted(restricted)
|
||||
, disable_rpc_ban(false)
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -73,6 +73,7 @@ namespace cryptonote
|
||||
core_rpc_server(
|
||||
core& cr
|
||||
, nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& p2p
|
||||
, bool restricted = false
|
||||
);
|
||||
~core_rpc_server();
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ These are the main fuzzing entry points, containing `LLVMFuzzerTestOneInput`, wh
|
||||
|
||||
## `initialisation.cpp` / `initialisation.h`
|
||||
|
||||
This set of source files provides initialisation helper functions to configure the `core_rpc_server` class with dummy protocols, P2P, payment modules, and other components. It also includes functions to generate fake random blocks, miners, and transactions for use in fuzzing.
|
||||
This set of source files provides initialisation helper functions to configure the `core_rpc_server` class with dummy protocols, P2P, and other components. It also includes functions to generate fake random blocks, miners, and transactions for use in fuzzing.
|
||||
|
||||
## `rpc_endpoints.cpp` / `rpc_endpoints.h` / `zmq_endpoints.cpp` / `zmq_endpoints.h`
|
||||
|
||||
These source files handle the creation of the necessary request and response objects and the invocation of specific endpoint functions. These simulate real RPC requests / ZMQ requests for the purpose of fuzzing. There are three categories of RPC endpoint functions and only one for ZMQ endpoint functions:
|
||||
|
||||
* **Safe**: Considered stable and unlikely to fail.
|
||||
* **Risky**: More prone to failure and early exits, especially if no valid blockchain is generated or no payment modules are configured.
|
||||
* **Risky**: More prone to failure and early exits, especially if no valid blockchain is generated.
|
||||
* **Priority**: Most critical RPC endpoint functions that will at least run once per iteration.
|
||||
|
||||
# Building the Fuzzing Harnesses
|
||||
@@ -24,7 +24,7 @@ These source files handle the creation of the necessary request and response obj
|
||||
The same `fuzz_rpc.cpp` is compiled into two versions of the fuzzer, one with the `SAFE` macro defined and one without. Meanwhile, `fuzz_zmq` is compiled into a single version.
|
||||
|
||||
* With `SAFE` defined: Only safe endpoint functions are fuzzed.
|
||||
* Without `SAFE`: Both safe and risky functions are included in the fuzzing process, and payment modules are configured.
|
||||
* Without `SAFE`: Both safe and risky functions are included in the fuzzing process.
|
||||
|
||||
# Fuzzing Harness Flow
|
||||
|
||||
@@ -35,8 +35,7 @@ Random data is used to generate selectors that choose an RPC endpoint function /
|
||||
|
||||
## `initialise_rpc_core` / `initialise_rpc_server`
|
||||
|
||||
At the start of each fuzzing iteration, a `core_rpc_server` object is created and initialised with dummy protocols, P2P, payment modules, and more.
|
||||
If the `SAFE` macro is not defined, the payment module will also be initialised.
|
||||
At the start of each fuzzing iteration, a `core_rpc_server` object is created and initialised with dummy protocols and P2P. The fuzz input selects whether the server runs in restricted or unrestricted RPC mode.
|
||||
This step is skipped for `fuzz_zmq`.
|
||||
|
||||
## `generate_random_blocks`
|
||||
|
||||
@@ -57,8 +57,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
|
||||
// Initialise core and core_rpc_server
|
||||
auto core_env = initialise_rpc_core();
|
||||
if (!core_env) {
|
||||
return 0;
|
||||
}
|
||||
auto& dummy_core = core_env->core;
|
||||
auto rpc_handler = initialise_rpc_server(*dummy_core, provider, !is_safe_mode);
|
||||
auto rpc_handler = initialise_rpc_server(*dummy_core, provider.ConsumeBool());
|
||||
|
||||
// Generate random blocks/miners/transactions and push to the core blockchains
|
||||
if (!generate_random_blocks(*dummy_core, provider)) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "serialization/binary_utils.h"
|
||||
#include "serialization/variant.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -51,21 +52,29 @@ std::unique_ptr<CoreEnv> initialise_rpc_core() {
|
||||
cryptonote::core::init_options(desc);
|
||||
boost::program_options::variables_map vm;
|
||||
|
||||
// Add command line argument to configure the rpc core object to use regression testing mode (FAKECHAIN)
|
||||
// Enabling FAKECHAIN mode allows skipping validation logic of the authors signature and transactions ID
|
||||
// on valid blocks and transactions while keeping other logic
|
||||
std::vector<const char*> argv = {"fuzz", "--regtest"};
|
||||
// Add command line arguments to configure the rpc core object to use regression testing mode (FAKECHAIN)
|
||||
// and a throwaway data directory. Enabling FAKECHAIN mode allows skipping validation logic of the authors
|
||||
// signature and transactions ID on valid blocks and transactions while keeping other logic.
|
||||
const boost::filesystem::path data_dir = boost::filesystem::temp_directory_path() / "monero-fuzz-rpc";
|
||||
std::vector<std::string> args = {"fuzz", "--regtest", "--offline", "--data-dir", data_dir.string()};
|
||||
std::vector<const char*> argv;
|
||||
argv.reserve(args.size());
|
||||
for (const auto& arg : args) {
|
||||
argv.push_back(arg.c_str());
|
||||
}
|
||||
boost::program_options::store(boost::program_options::parse_command_line(argv.size(), argv.data(), desc), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
// Initialise the dummy core with all the above settings
|
||||
env->core->init(vm);
|
||||
if (!env->core->init(vm)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
// Build the core_rpc_server handler object with the configured dummy core object
|
||||
std::unique_ptr<RpcServerBundle> initialise_rpc_server(cryptonote::core& dummy_core, FuzzedDataProvider& provider, bool need_payment) {
|
||||
std::unique_ptr<RpcServerBundle> initialise_rpc_server(cryptonote::core& dummy_core, bool restricted) {
|
||||
// Create rpc server bundle object
|
||||
auto bundle = std::make_unique<RpcServerBundle>();
|
||||
|
||||
@@ -73,7 +82,7 @@ std::unique_ptr<RpcServerBundle> initialise_rpc_server(cryptonote::core& dummy_c
|
||||
bundle->proto_handler = std::make_unique<cryptonote::t_cryptonote_protocol_handler<cryptonote::core>>(dummy_core, nullptr, true);
|
||||
bundle->proto_handler->set_no_sync(false);
|
||||
bundle->dummy_p2p = std::make_unique<nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core>>>(*bundle->proto_handler);
|
||||
bundle->rpc = std::make_unique<cryptonote::core_rpc_server>(dummy_core, *bundle->dummy_p2p);
|
||||
bundle->rpc = std::make_unique<cryptonote::core_rpc_server>(dummy_core, *bundle->dummy_p2p, restricted);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Define templates for dummy protocol object
|
||||
template class nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core>>;
|
||||
|
||||
struct DummyProtocol : public cryptonote::i_cryptonote_protocol {
|
||||
struct DummyProtocol final : public cryptonote::i_cryptonote_protocol {
|
||||
public:
|
||||
bool is_synchronized() const;
|
||||
bool relay_transactions(cryptonote::NOTIFY_NEW_TRANSACTIONS::request&, const boost::uuids::uuid&, epee::net_utils::zone, cryptonote::relay_method);
|
||||
@@ -25,7 +25,7 @@ struct CoreEnv {
|
||||
};
|
||||
|
||||
std::unique_ptr<CoreEnv> initialise_rpc_core();
|
||||
std::unique_ptr<RpcServerBundle> initialise_rpc_server(cryptonote::core&, FuzzedDataProvider&, bool);
|
||||
std::unique_ptr<RpcServerBundle> initialise_rpc_server(cryptonote::core&, bool);
|
||||
bool generate_random_blocks(cryptonote::core&, FuzzedDataProvider&);
|
||||
|
||||
extern std::vector<crypto::hash> cached_tx_hashes;
|
||||
|
||||
Reference in New Issue
Block a user