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.
1001return BlockTreeEntry{btck_block_tree_entry_get_ancestor(get(), height)};1002}1004};1006class KernelNotifications1007{1008public:1009virtual ~KernelNotifications() = default;1011virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress) {}1013virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}1015virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible) {}1017virtual void WarningSetHandler(Warning warning, std::string_view message) {}1019virtual void WarningUnsetHandler(Warning warning) {}1021virtual void FlushErrorHandler(std::string_view error) {}1023virtual void FatalErrorHandler(std::string_view error) {}1024};1026template <typename Derived>1027class BlockValidationStateApi1028{1029private:1030auto impl() const1031{1032return static_cast<const Derived*>(this)->get();1033}1035friend Derived;1036BlockValidationStateApi() = default;1038public:1039ValidationMode GetValidationMode() const1040{1041return static_cast<ValidationMode>(btck_block_validation_state_get_validation_mode(impl()));1042}1044BlockValidationResult GetBlockValidationResult() const1045{1046return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(impl()));1047}1048};1050class BlockValidationStateView : public View<btck_BlockValidationState>, public BlockValidationStateApi<BlockValidationStateView>1051{1052public:1053explicit BlockValidationStateView(const btck_BlockValidationState* ptr) : View{ptr} {}1054};1056class BlockValidationState : public Handle<btck_BlockValidationState, btck_block_validation_state_copy, btck_block_validation_state_destroy>, public BlockValidationStateApi<BlockValidationState>1057{1058public:1059explicit BlockValidationState() : Handle{btck_block_validation_state_create()} {}1061explicit BlockValidationState(const BlockValidationStateView& view) : Handle{view} {}1063explicit BlockValidationState(btck_BlockValidationState* state) : Handle{state} {}1064};1066inline bool Block::Check(const ConsensusParamsView& consensus_params,1067BlockCheckFlags flags,1068BlockValidationState& state) const1069{1070return btck_block_check(get(), consensus_params.get(), static_cast<btck_BlockCheckFlags>(flags), state.get()) == 1;1071}1073class TxValidationState : public UniqueHandle<btck_TxValidationState, btck_tx_validation_state_destroy>1074{1075public:1076using UniqueHandle::UniqueHandle; // inherit ctor1077explicit TxValidationState() : UniqueHandle{btck_tx_validation_state_create()} {}1079ValidationMode GetValidationMode() const1080{1081return static_cast<ValidationMode>(btck_tx_validation_state_get_validation_mode(get()));1082}1084TxValidationResult GetTxValidationResult() const1085{1086return static_cast<TxValidationResult>(btck_tx_validation_state_get_tx_validation_result(get()));1087}1088};1090inline bool CheckTransaction(const Transaction& tx, TxValidationState& state)1091{1092return btck_transaction_check(tx.get(), state.get()) == 1;1093}1095class ValidationInterface1096{1097public:1098virtual ~ValidationInterface() = default;1100virtual void BlockChecked(Block block, BlockValidationStateView state) {}1102virtual void PowValidBlock(BlockTreeEntry entry, Block block) {}1104virtual void BlockConnected(Block block, BlockTreeEntry entry) {}1106virtual void BlockDisconnected(Block block, BlockTreeEntry entry) {}1107};1109class ChainParams : public Handle<btck_ChainParameters, btck_chain_parameters_copy, btck_chain_parameters_destroy>1110{1111public:1112explicit ChainParams(ChainType chain_type)1113: Handle{btck_chain_parameters_create(static_cast<btck_ChainType>(chain_type))} {}1115explicit ChainParams(std::span<const std::byte> signet_challenge)1116: Handle{btck_chain_parameters_create_signet(signet_challenge.data(), signet_challenge.size())} {}1118ConsensusParamsView GetConsensusParams() const1119{1120return ConsensusParamsView{btck_chain_parameters_get_consensus_params(get())};1121}1122};1124class ContextOptions : public UniqueHandle<btck_ContextOptions, btck_context_options_destroy>1125{1126public:1127ContextOptions() : UniqueHandle{btck_context_options_create()} {}1129void SetChainParams(ChainParams& chain_params)1130{1131btck_context_options_set_chainparams(get(), chain_params.get());1132}1134template <typename T>1135void SetNotifications(std::shared_ptr<T> notifications)1136{1137static_assert(std::is_base_of_v<KernelNotifications, T>);1138auto heap_notifications = std::make_unique<std::shared_ptr<T>>(std::move(notifications));1139using user_type = std::shared_ptr<T>*;1140btck_context_options_set_notifications(1141get(),1142btck_NotificationInterfaceCallbacks{1143.user_data = heap_notifications.release(),1144.user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },1145.block_tip = +[](void* user_data, btck_SynchronizationState state, const btck_BlockTreeEntry* entry, double verification_progress) { (*static_cast<user_type>(user_data))->BlockTipHandler(static_cast<SynchronizationState>(state), BlockTreeEntry{entry}, verification_progress); },1146.header_tip = +[](void* user_data, btck_SynchronizationState state, int64_t height, int64_t timestamp, int presync) { (*static_cast<user_type>(user_data))->HeaderTipHandler(static_cast<SynchronizationState>(state), height, timestamp, presync == 1); },1147.progress = +[](void* user_data, const char* title, size_t title_len, int progress_percent, int resume_possible) { (*static_cast<user_type>(user_data))->ProgressHandler({title, title_len}, progress_percent, resume_possible == 1); },1148.warning_set = +[](void* user_data, btck_Warning warning, const char* message, size_t message_len) { (*static_cast<user_type>(user_data))->WarningSetHandler(static_cast<Warning>(warning), {message, message_len}); },1149.warning_unset = +[](void* user_data, btck_Warning warning) { (*static_cast<user_type>(user_data))->WarningUnsetHandler(static_cast<Warning>(warning)); },1150.flush_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FlushErrorHandler({error, error_len}); },1151.fatal_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FatalErrorHandler({error, error_len}); },1152});1153}1155template <typename T>1156void SetValidationInterface(std::shared_ptr<T> validation_interface)1157{1158static_assert(std::is_base_of_v<ValidationInterface, T>);1159auto heap_vi = std::make_unique<std::shared_ptr<T>>(std::move(validation_interface));1160using user_type = std::shared_ptr<T>*;1161btck_context_options_set_validation_interface(1162get(),1163btck_ValidationInterfaceCallbacks{1164.user_data = heap_vi.release(),1165.user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },1166.block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); },1167.pow_valid_block = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->PowValidBlock(BlockTreeEntry{entry}, Block{block}); },1168.block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },1169.block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },1170});1171}1172};1174class Context : public Handle<btck_Context, btck_context_copy, btck_context_destroy>1175{1176public:1177Context(ContextOptions& opts)1178: Handle{btck_context_create(opts.get())} {}1180Context()1181: Handle{btck_context_create(ContextOptions{}.get())} {}1183bool interrupt()1184{1185return btck_context_interrupt(get()) == 0;1186}1187};1189class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>1190{1191public:1192ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)1193: UniqueHandle{btck_chainstate_manager_options_create(1194context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}1195{1196}1198void SetWorkerThreads(int worker_threads)1199{1200btck_chainstate_manager_options_set_worker_threads_num(get(), worker_threads);1201}1203bool SetDatabaseCacheBytes(uint64_t database_cache_bytes)1204{1205return btck_chainstate_manager_options_set_database_cache_bytes(get(), database_cache_bytes) == 0;1206}1208bool SetWipeDbs(bool wipe_block_tree, bool wipe_chainstate)1209{1210return btck_chainstate_manager_options_set_wipe_dbs(get(), wipe_block_tree, wipe_chainstate) == 0;1211}1213void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)1214{1215btck_chainstate_manager_options_update_block_tree_db_in_memory(get(), block_tree_db_in_memory);1216}1218void UpdateChainstateDbInMemory(bool chainstate_db_in_memory)1219{1220btck_chainstate_manager_options_update_chainstate_db_in_memory(get(), chainstate_db_in_memory);1221}1222};1224class ChainView : public View<btck_Chain>1225{1226public:1227explicit ChainView(const btck_Chain* ptr) : View{ptr} {}1229int32_t Height() const1230{1231return btck_chain_get_height(get());1232}1234int32_t CountEntries() const1235{1236return btck_chain_get_height(get()) + 1;1237}1239BlockTreeEntry GetByHeight(int32_t height) const1240{1241auto index{btck_chain_get_by_height(get(), height)};1242if (!index) throw std::runtime_error("No entry in the chain at the provided height");1243return index;1244}1246bool Contains(BlockTreeEntry& entry) const1247{1248return btck_chain_contains(get(), entry.get());1249}