Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2026-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <primitives/transaction.h>6#include <capnp/capability.h>7#include <capnp/rpc.h>8#include <ipc/util.h>9#include <kj/memory.h>10#include <mp/proxy-io.h>11#include <mp/proxy.h>12#include <test/fuzz/FuzzedDataProvider.h>13#include <test/fuzz/fuzz.h>14#include <ipc/test/fuzz/ipc_fuzz.capnp.h>15#include <ipc/test/fuzz/ipc_fuzz.capnp.proxy.h>16#include <ipc/test/fuzz/ipc_fuzz.h>17#include <test/fuzz/util.h>18#include <test/util/setup_common.h>20#include <future>21#include <memory>22#include <stdexcept>23#include <thread>25namespace {26class IpcFuzzSetup27{28public:29IpcFuzzSetup()30{31std::promise<std::unique_ptr<mp::ProxyClient<test::fuzz::messages::IpcFuzzInterface>>> client_promise;32auto client_future{client_promise.get_future()};33m_loop_thread = std::thread([&client_promise] {34mp::EventLoop loop("ipc-fuzz", [](mp::LogMessage message) {35if (message.level == mp::Log::Raise) throw std::runtime_error(message.message);36});37auto pipe = loop.m_io_context.provider->newTwoWayPipe();39auto server_connection = std::make_unique<mp::Connection>(40loop,41kj::mv(pipe.ends[0]),42[&](mp::Connection& connection) {43auto server_proxy = kj::heap<mp::ProxyServer<test::fuzz::messages::IpcFuzzInterface>>(44std::make_shared<IpcFuzzImplementation>(), connection);45return capnp::Capability::Client(kj::mv(server_proxy));46});47server_connection->onDisconnect([&] { server_connection.reset(); });49auto client_connection = std::make_unique<mp::Connection>(loop, kj::mv(pipe.ends[1]));50auto client_proxy = std::make_unique<mp::ProxyClient<test::fuzz::messages::IpcFuzzInterface>>(51client_connection->m_rpc_system->bootstrap(mp::ServerVatId().vat_id)52.castAs<test::fuzz::messages::IpcFuzzInterface>(),53client_connection.get(),54/* destroy_connection= */ true);55(void)client_connection.release();57client_promise.set_value(std::move(client_proxy));58loop.loop();59});60m_client = client_future.get();61}63~IpcFuzzSetup()64{65m_client.reset();66if (m_loop_thread.joinable()) m_loop_thread.join();67}69std::unique_ptr<mp::ProxyClient<test::fuzz::messages::IpcFuzzInterface>> m_client;71private:72std::thread m_loop_thread;73};75static IpcFuzzSetup* g_ipc;77static void initialize_ipc()78{79static const auto testing_setup = MakeNoLogFileContext<>();80(void)testing_setup;82// Ensure the thread's ThreadContext is created before the IPC setup, so83// it is destroyed after it, since C++ destroys thread_local objects in84// reverse construction order.85mp::CurrentThread();87thread_local static IpcFuzzSetup ipc; // NOLINT(bitcoin-nontrivial-threadlocal)88g_ipc = &ipc;89}91FUZZ_TARGET(ipc, .init = initialize_ipc)92{93auto& ipc = *g_ipc;94FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());95LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 64) {96CallOneOf(97fuzzed_data_provider,98[&] {99static constexpr int MIN_ADD{-1'000'000};100static constexpr int MAX_ADD{1'000'000};101const int a = fuzzed_data_provider.ConsumeIntegralInRange<int>(MIN_ADD, MAX_ADD);102const int b = fuzzed_data_provider.ConsumeIntegralInRange<int>(MIN_ADD, MAX_ADD);103assert(ipc.m_client->add(a, b) == a + b);104},105[&] {106COutPoint outpoint{Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)),107fuzzed_data_provider.ConsumeIntegral<uint32_t>()};108COutPoint expected{outpoint.hash, outpoint.n ^ 0xFFFFFFFFu};109assert(ipc.m_client->passOutPoint(outpoint) == expected);110},111[&] {112std::vector<uint8_t> value = ConsumeRandomLengthByteVector<uint8_t>(fuzzed_data_provider, 512);113std::vector<uint8_t> expected{value.rbegin(), value.rend()};114assert(ipc.m_client->passVectorUint8(value) == expected);115},116[&] {117CScript script{ConsumeScript(fuzzed_data_provider)};118CScript expected{script};119expected << OP_NOP;120assert(ipc.m_client->passScript(script) == expected);121},122[&] {123UniValue value;124if (!value.read(fuzzed_data_provider.ConsumeRandomLengthString(512))) return;125assert(ipc.m_client->passUniValue(value).write() == value.write());126},127[&] {128const CMutableTransaction mutable_tx = ConsumeTransaction(fuzzed_data_provider, std::nullopt);129if (mutable_tx.vin.empty()) return;130const CTransactionRef tx = MakeTransactionRef(mutable_tx);131assert(ipc.m_client->passTransaction(tx)->Equals(*tx));132});133}134}135} // namespace
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.