Inside Bitcoin
Opening the selected file…
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) 2022-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#define BITCOINKERNEL_BUILD7#include <kernel/bitcoinkernel.h>9#include <chain.h>10#include <coins.h>11#include <consensus/tx_check.h>12#include <consensus/validation.h>13#include <dbwrapper.h>14#include <kernel/caches.h>15#include <kernel/chainparams.h>16#include <kernel/checks.h>17#include <kernel/context.h>18#include <kernel/notifications_interface.h>19#include <kernel/warning.h>20#include <logging.h>21#include <node/blockstorage.h>22#include <node/chainstate.h>23#include <primitives/block.h>24#include <primitives/transaction.h>25#include <script/interpreter.h>26#include <script/script.h>27#include <script/verify_flags.h>28#include <serialize.h>29#include <streams.h>30#include <sync.h>31#include <uint256.h>32#include <undo.h>33#include <util/check.h>34#include <util/fs.h>35#include <util/result.h>36#include <util/signalinterrupt.h>37#include <util/task_runner.h>38#include <util/time.h>39#include <util/translation.h>40#include <validation.h>41#include <validationinterface.h>43#include <cstddef>44#include <cstring>45#include <exception>46#include <functional>47#include <limits>48#include <list>49#include <memory>50#include <optional>51#include <span>52#include <stdexcept>53#include <string>54#include <tuple>55#include <utility>56#include <vector>58namespace Consensus {59struct Params;60} // namespace Consensus62using kernel::ChainstateRole;63using util::ImmediateTaskRunner;65// Define G_TRANSLATION_FUN symbol in libbitcoinkernel library so users of the66// library aren't required to export this symbol67extern const TranslateFn G_TRANSLATION_FUN{nullptr};69static const kernel::Context btck_context_static{};71namespace {73bool is_valid_flag_combination(script_verify_flags flags)74{75if (flags & SCRIPT_VERIFY_CLEANSTACK && ~flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) return false;76if (flags & SCRIPT_VERIFY_WITNESS && ~flags & SCRIPT_VERIFY_P2SH) return false;77return true;78}80class WriterStream81{82private:83btck_WriteBytes m_writer;84void* m_user_data;86public:87WriterStream(btck_WriteBytes writer, void* user_data)88: m_writer{writer}, m_user_data{user_data} {}90//91// Stream subset92//93void write(std::span<const std::byte> src)94{95if (m_writer(src.data(), src.size(), m_user_data) != 0) {96throw std::runtime_error("Failed to write serialization data");97}98}100template <typename T>101WriterStream& operator<<(const T& obj)102{103::Serialize(*this, obj);104return *this;105}106};108template <typename C, typename CPP>109struct Handle {110static C* ref(CPP* cpp_type)111{112return reinterpret_cast<C*>(cpp_type);113}115static const C* ref(const CPP* cpp_type)116{117return reinterpret_cast<const C*>(cpp_type);118}120template <typename... Args>121static C* create(Args&&... args)122{123auto cpp_obj{std::make_unique<CPP>(std::forward<Args>(args)...)};124return ref(cpp_obj.release());125}127static C* copy(const C* ptr)128{129auto cpp_obj{std::make_unique<CPP>(get(ptr))};130return ref(cpp_obj.release());131}133static const CPP& get(const C* ptr)134{135return *reinterpret_cast<const CPP*>(ptr);136}138static CPP& get(C* ptr)139{140return *reinterpret_cast<CPP*>(ptr);141}143static void operator delete(void* ptr)144{145delete reinterpret_cast<CPP*>(ptr);146}147};149} // namespace151struct btck_BlockTreeEntry: Handle<btck_BlockTreeEntry, CBlockIndex> {};152struct btck_Block : Handle<btck_Block, std::shared_ptr<const CBlock>> {};153struct btck_BlockValidationState : Handle<btck_BlockValidationState, BlockValidationState> {};154struct btck_TxValidationState : Handle<btck_TxValidationState, TxValidationState> {};156namespace {158BCLog::Level get_bclog_level(btck_LogLevel level)159{160switch (level) {161case btck_LogLevel_INFO: {162return BCLog::Level::Info;163}164case btck_LogLevel_DEBUG: {165return BCLog::Level::Debug;166}167case btck_LogLevel_TRACE: {168return BCLog::Level::Trace;169}170}171assert(false);172}174BCLog::LogFlags get_bclog_flag(btck_LogCategory category)175{176switch (category) {177case btck_LogCategory_BENCH: {178return BCLog::LogFlags::BENCH;179}180case btck_LogCategory_BLOCKSTORAGE: {181return BCLog::LogFlags::BLOCKSTORAGE;182}183case btck_LogCategory_COINDB: {184return BCLog::LogFlags::COINDB;185}186case btck_LogCategory_LEVELDB: {187return BCLog::LogFlags::LEVELDB;188}189case btck_LogCategory_MEMPOOL: {190return BCLog::LogFlags::MEMPOOL;191}192case btck_LogCategory_PRUNE: {193return BCLog::LogFlags::PRUNE;194}195case btck_LogCategory_RAND: {196return BCLog::LogFlags::RAND;197}198case btck_LogCategory_REINDEX: {199return BCLog::LogFlags::REINDEX;200}201case btck_LogCategory_VALIDATION: {202return BCLog::LogFlags::VALIDATION;203}204case btck_LogCategory_KERNEL: {205return BCLog::LogFlags::KERNEL;206}207case btck_LogCategory_ALL: {208return BCLog::LogFlags::ALL;209}210}211assert(false);212}214btck_SynchronizationState cast_state(SynchronizationState state)215{216switch (state) {217case SynchronizationState::INIT_REINDEX:218return btck_SynchronizationState_INIT_REINDEX;219case SynchronizationState::INIT_DOWNLOAD:220return btck_SynchronizationState_INIT_DOWNLOAD;221case SynchronizationState::POST_INIT:222return btck_SynchronizationState_POST_INIT;223} // no default case, so the compiler can warn about missing cases224assert(false);225}227btck_Warning cast_btck_warning(kernel::Warning warning)228{229switch (warning) {230case kernel::Warning::UNKNOWN_NEW_RULES_ACTIVATED:231return btck_Warning_UNKNOWN_NEW_RULES_ACTIVATED;232case kernel::Warning::LARGE_WORK_INVALID_CHAIN:233return btck_Warning_LARGE_WORK_INVALID_CHAIN;234} // no default case, so the compiler can warn about missing cases235assert(false);236}238struct LoggingConnection {239std::unique_ptr<std::list<std::function<void(const std::string&)>>::iterator> m_connection;240void* m_user_data;241std::function<void(void* user_data)> m_deleter;243LoggingConnection(btck_LogCallback callback, void* user_data, btck_DestroyCallback user_data_destroy_callback)244{245LOCK(cs_main);247auto connection{LogInstance().PushBackCallback([callback, user_data](const std::string& str) { callback(user_data, str.c_str(), str.length()); })};249// Only start logging if we just added the connection.250if (LogInstance().NumConnections() == 1 && !LogInstance().StartLogging()) {