LCOV - code coverage report
Current view: top level - src/kernel - bitcoinkernel_wrapper.h (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 92.7 % 480 445
Test Date: 2026-10-11 07:59:32 Functions: 93.8 % 240 225
Branches: 48.9 % 2312 1131

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2024-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #ifndef BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
       6                 :             : #define BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
       7                 :             : 
       8                 :             : #include <kernel/bitcoinkernel.h>
       9                 :             : 
      10                 :             : #include <array>
      11                 :             : #include <chrono>
      12                 :             : #include <exception>
      13                 :             : #include <functional>
      14                 :             : #include <memory>
      15                 :             : #include <optional>
      16                 :             : #include <span>
      17                 :             : #include <stdexcept>
      18                 :             : #include <string>
      19                 :             : #include <string_view>
      20                 :             : #include <type_traits>
      21                 :             : #include <utility>
      22                 :             : #include <vector>
      23                 :             : 
      24                 :             : namespace btck {
      25                 :             : 
      26                 :             : enum class LogCategory : btck_LogCategory {
      27                 :             :     NONE = btck_LogCategory_NONE,
      28                 :             :     BENCH = btck_LogCategory_BENCH,
      29                 :             :     BLOCKSTORAGE = btck_LogCategory_BLOCKSTORAGE,
      30                 :             :     COINDB = btck_LogCategory_COINDB,
      31                 :             :     LEVELDB = btck_LogCategory_LEVELDB,
      32                 :             :     MEMPOOL = btck_LogCategory_MEMPOOL,
      33                 :             :     PRUNE = btck_LogCategory_PRUNE,
      34                 :             :     RAND = btck_LogCategory_RAND,
      35                 :             :     REINDEX = btck_LogCategory_REINDEX,
      36                 :             :     VALIDATION = btck_LogCategory_VALIDATION,
      37                 :             :     KERNEL = btck_LogCategory_KERNEL,
      38                 :             :     TXPACKAGES = btck_LogCategory_TXPACKAGES,
      39                 :             :     LOCK = btck_LogCategory_LOCK,
      40                 :             : };
      41                 :             : 
      42                 :             : enum class LogLevel : btck_LogLevel {
      43                 :             :     TRACE_LEVEL = btck_LogLevel_TRACE,
      44                 :             :     DEBUG_LEVEL = btck_LogLevel_DEBUG,
      45                 :             :     INFO_LEVEL = btck_LogLevel_INFO,
      46                 :             :     WARNING_LEVEL = btck_LogLevel_WARNING,
      47                 :             :     ERROR_LEVEL = btck_LogLevel_ERROR,
      48                 :             : };
      49                 :             : 
      50                 :         109 : constexpr std::string_view Name(LogLevel level) noexcept
      51                 :             : {
      52   [ -  -  +  -  :         109 :     switch (level) {
                   +  - ]
      53                 :           0 :     case LogLevel::TRACE_LEVEL: return "trace";
      54                 :           0 :     case LogLevel::DEBUG_LEVEL: return "debug";
      55                 :         103 :     case LogLevel::INFO_LEVEL: return "info";
      56                 :           0 :     case LogLevel::WARNING_LEVEL: return "warning";
      57                 :           6 :     case LogLevel::ERROR_LEVEL: return "error";
      58                 :             :     } // no default case, so the compiler can warn about missing cases
      59                 :           0 :     return "unknown";
      60                 :             : }
      61                 :             : 
      62                 :         109 : constexpr std::string_view Name(LogCategory category) noexcept
      63                 :             : {
      64   [ +  -  -  -  :         109 :     switch (category) {
          -  -  -  -  -  
             -  -  -  -  
                      - ]
      65                 :         109 :     case LogCategory::NONE: return "none";
      66                 :           0 :     case LogCategory::BENCH: return "bench";
      67                 :           0 :     case LogCategory::BLOCKSTORAGE: return "blockstorage";
      68                 :           0 :     case LogCategory::COINDB: return "coindb";
      69                 :           0 :     case LogCategory::LEVELDB: return "leveldb";
      70                 :           0 :     case LogCategory::MEMPOOL: return "mempool";
      71                 :           0 :     case LogCategory::PRUNE: return "prune";
      72                 :           0 :     case LogCategory::RAND: return "rand";
      73                 :           0 :     case LogCategory::REINDEX: return "reindex";
      74                 :           0 :     case LogCategory::TXPACKAGES: return "txpackages";
      75                 :           0 :     case LogCategory::VALIDATION: return "validation";
      76                 :           0 :     case LogCategory::KERNEL: return "kernel";
      77                 :           0 :     case LogCategory::LOCK: return "lock";
      78                 :             :     } // no default case, so the compiler can warn about missing cases
      79                 :           0 :     return "unknown";
      80                 :             : }
      81                 :             : 
      82                 :             : enum class ChainType : btck_ChainType {
      83                 :             :     MAINNET = btck_ChainType_MAINNET,
      84                 :             :     TESTNET = btck_ChainType_TESTNET,
      85                 :             :     TESTNET_4 = btck_ChainType_TESTNET_4,
      86                 :             :     SIGNET = btck_ChainType_SIGNET,
      87                 :             :     REGTEST = btck_ChainType_REGTEST
      88                 :             : };
      89                 :             : 
      90                 :             : enum class SynchronizationState : btck_SynchronizationState {
      91                 :             :     INIT_REINDEX = btck_SynchronizationState_INIT_REINDEX,
      92                 :             :     INIT_DOWNLOAD = btck_SynchronizationState_INIT_DOWNLOAD,
      93                 :             :     POST_INIT = btck_SynchronizationState_POST_INIT
      94                 :             : };
      95                 :             : 
      96                 :             : enum class Warning : btck_Warning {
      97                 :             :     UNKNOWN_NEW_RULES_ACTIVATED = btck_Warning_UNKNOWN_NEW_RULES_ACTIVATED,
      98                 :             :     LARGE_WORK_INVALID_CHAIN = btck_Warning_LARGE_WORK_INVALID_CHAIN
      99                 :             : };
     100                 :             : 
     101                 :             : enum class ValidationMode : btck_ValidationMode {
     102                 :             :     VALID = btck_ValidationMode_VALID,
     103                 :             :     INVALID = btck_ValidationMode_INVALID,
     104                 :             :     INTERNAL_ERROR = btck_ValidationMode_INTERNAL_ERROR
     105                 :             : };
     106                 :             : 
     107                 :             : enum class BlockValidationResult : btck_BlockValidationResult {
     108                 :             :     UNSET = btck_BlockValidationResult_UNSET,
     109                 :             :     CONSENSUS = btck_BlockValidationResult_CONSENSUS,
     110                 :             :     CACHED_INVALID = btck_BlockValidationResult_CACHED_INVALID,
     111                 :             :     INVALID_HEADER = btck_BlockValidationResult_INVALID_HEADER,
     112                 :             :     MUTATED = btck_BlockValidationResult_MUTATED,
     113                 :             :     MISSING_PREV = btck_BlockValidationResult_MISSING_PREV,
     114                 :             :     INVALID_PREV = btck_BlockValidationResult_INVALID_PREV,
     115                 :             :     TIME_FUTURE = btck_BlockValidationResult_TIME_FUTURE,
     116                 :             :     HEADER_LOW_WORK = btck_BlockValidationResult_HEADER_LOW_WORK
     117                 :             : };
     118                 :             : 
     119                 :             : enum class TxValidationResult : btck_TxValidationResult {
     120                 :             :     UNSET               = btck_TxValidationResult_UNSET,
     121                 :             :     CONSENSUS           = btck_TxValidationResult_CONSENSUS,
     122                 :             :     INPUTS_NOT_STANDARD = btck_TxValidationResult_INPUTS_NOT_STANDARD,
     123                 :             :     NOT_STANDARD        = btck_TxValidationResult_NOT_STANDARD,
     124                 :             :     MISSING_INPUTS      = btck_TxValidationResult_MISSING_INPUTS,
     125                 :             :     PREMATURE_SPEND     = btck_TxValidationResult_PREMATURE_SPEND,
     126                 :             :     WITNESS_MUTATED     = btck_TxValidationResult_WITNESS_MUTATED,
     127                 :             :     WITNESS_STRIPPED    = btck_TxValidationResult_WITNESS_STRIPPED,
     128                 :             :     CONFLICT            = btck_TxValidationResult_CONFLICT,
     129                 :             :     MEMPOOL_POLICY      = btck_TxValidationResult_MEMPOOL_POLICY,
     130                 :             :     NO_MEMPOOL          = btck_TxValidationResult_NO_MEMPOOL,
     131                 :             :     RECONSIDERABLE      = btck_TxValidationResult_RECONSIDERABLE,
     132                 :             :     UNKNOWN             = btck_TxValidationResult_UNKNOWN
     133                 :             : };
     134                 :             : 
     135                 :             : enum class ScriptVerifyStatus : btck_ScriptVerifyStatus {
     136                 :             :     OK = btck_ScriptVerifyStatus_OK,
     137                 :             :     ERROR_INVALID_FLAGS_COMBINATION = btck_ScriptVerifyStatus_ERROR_INVALID_FLAGS_COMBINATION,
     138                 :             :     ERROR_SPENT_OUTPUTS_REQUIRED = btck_ScriptVerifyStatus_ERROR_SPENT_OUTPUTS_REQUIRED,
     139                 :             : };
     140                 :             : 
     141                 :             : enum class ScriptVerificationFlags : btck_ScriptVerificationFlags {
     142                 :             :     NONE = btck_ScriptVerificationFlags_NONE,
     143                 :             :     P2SH = btck_ScriptVerificationFlags_P2SH,
     144                 :             :     DERSIG = btck_ScriptVerificationFlags_DERSIG,
     145                 :             :     NULLDUMMY = btck_ScriptVerificationFlags_NULLDUMMY,
     146                 :             :     CHECKLOCKTIMEVERIFY = btck_ScriptVerificationFlags_CHECKLOCKTIMEVERIFY,
     147                 :             :     CHECKSEQUENCEVERIFY = btck_ScriptVerificationFlags_CHECKSEQUENCEVERIFY,
     148                 :             :     WITNESS = btck_ScriptVerificationFlags_WITNESS,
     149                 :             :     TAPROOT = btck_ScriptVerificationFlags_TAPROOT,
     150                 :             :     ALL = btck_ScriptVerificationFlags_ALL
     151                 :             : };
     152                 :             : 
     153                 :             : enum class BlockCheckFlags : btck_BlockCheckFlags {
     154                 :             :     BASE = btck_BlockCheckFlags_BASE,
     155                 :             :     POW = btck_BlockCheckFlags_POW,
     156                 :             :     MERKLE = btck_BlockCheckFlags_MERKLE,
     157                 :             :     ALL = btck_BlockCheckFlags_ALL
     158                 :             : };
     159                 :             : 
     160                 :             : template <typename T>
     161                 :             : struct is_bitmask_enum : std::false_type {
     162                 :             : };
     163                 :             : 
     164                 :             : template <>
     165                 :             : struct is_bitmask_enum<ScriptVerificationFlags> : std::true_type {
     166                 :             : };
     167                 :             : 
     168                 :             : template <>
     169                 :             : struct is_bitmask_enum<BlockCheckFlags> : std::true_type {
     170                 :             : };
     171                 :             : 
     172                 :             : template <typename T>
     173                 :             : concept BitmaskEnum = is_bitmask_enum<T>::value;
     174                 :             : 
     175                 :             : template <BitmaskEnum T>
     176                 :             : constexpr T operator|(T lhs, T rhs)
     177                 :             : {
     178                 :             :     return static_cast<T>(
     179                 :             :         static_cast<std::underlying_type_t<T>>(lhs) | static_cast<std::underlying_type_t<T>>(rhs));
     180                 :             : }
     181                 :             : 
     182                 :             : template <BitmaskEnum T>
     183                 :             : constexpr T operator&(T lhs, T rhs)
     184                 :             : {
     185                 :             :     return static_cast<T>(
     186                 :             :         static_cast<std::underlying_type_t<T>>(lhs) & static_cast<std::underlying_type_t<T>>(rhs));
     187                 :             : }
     188                 :             : 
     189                 :             : template <BitmaskEnum T>
     190                 :             : constexpr T operator^(T lhs, T rhs)
     191                 :             : {
     192                 :             :     return static_cast<T>(
     193                 :             :         static_cast<std::underlying_type_t<T>>(lhs) ^ static_cast<std::underlying_type_t<T>>(rhs));
     194                 :             : }
     195                 :             : 
     196                 :             : template <BitmaskEnum T>
     197                 :             : constexpr T operator~(T value)
     198                 :             : {
     199                 :             :     return static_cast<T>(~static_cast<std::underlying_type_t<T>>(value));
     200                 :             : }
     201                 :             : 
     202                 :             : template <BitmaskEnum T>
     203                 :             : constexpr T& operator|=(T& lhs, T rhs)
     204                 :             : {
     205                 :             :     return lhs = lhs | rhs;
     206                 :             : }
     207                 :             : 
     208                 :             : template <BitmaskEnum T>
     209                 :             : constexpr T& operator&=(T& lhs, T rhs)
     210                 :             : {
     211                 :             :     return lhs = lhs & rhs;
     212                 :             : }
     213                 :             : 
     214                 :             : template <BitmaskEnum T>
     215                 :             : constexpr T& operator^=(T& lhs, T rhs)
     216                 :             : {
     217                 :             :     return lhs = lhs ^ rhs;
     218                 :             : }
     219                 :             : 
     220                 :             : template <typename T>
     221                 :       36081 : T check(T ptr)
     222                 :             : {
     223         [ +  + ]:       36081 :     if (ptr == nullptr) {
     224         [ +  - ]:          11 :         throw std::runtime_error("failed to instantiate btck object");
     225                 :             :     }
     226                 :       36070 :     return ptr;
     227                 :             : }
     228                 :             : 
     229                 :             : template <typename Collection, typename ValueType, auto GetFunc>
     230                 :             : class Iterator
     231                 :             : {
     232                 :             : public:
     233                 :             :     using iterator_category = std::random_access_iterator_tag;
     234                 :             :     using iterator_concept = std::random_access_iterator_tag;
     235                 :             :     using difference_type = std::ptrdiff_t;
     236                 :             :     using value_type = ValueType;
     237                 :             : 
     238                 :             : private:
     239                 :             :     const Collection* m_collection;
     240                 :             :     size_t m_idx;
     241                 :             : 
     242                 :             : public:
     243                 :             :     Iterator() = default;
     244                 :             :     Iterator(const Collection* ptr) : m_collection{ptr}, m_idx{0} {}
     245                 :       15139 :     Iterator(const Collection* ptr, size_t idx) : m_collection{ptr}, m_idx{idx} {}
     246                 :             : 
     247                 :             :     // This is just a view, so return a copy.
     248                 :       32278 :     auto operator*() const { return std::invoke(GetFunc, *m_collection, m_idx); }
     249                 :             : 
     250                 :       15801 :     auto& operator++() { m_idx++; return *this; }
     251                 :           6 :     auto operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
     252                 :             : 
     253                 :         221 :     auto& operator--() { m_idx--; return *this; }
     254                 :           6 :     auto operator--(int) { auto temp = *this; --m_idx; return temp; }
     255                 :             : 
     256                 :           6 :     auto& operator+=(difference_type n) { m_idx += n; return *this; }
     257                 :           6 :     auto& operator-=(difference_type n) { m_idx -= n; return *this; }
     258                 :             : 
     259   [ +  -  +  -  :           6 :     auto operator+(difference_type n) const { return Iterator(m_collection, m_idx + n); }
          +  -  +  -  +  
                -  +  - ]
     260                 :             :     auto operator-(difference_type n) const { return Iterator(m_collection, m_idx - n); }
     261                 :             : 
     262   [ +  -  +  -  :           7 :     auto operator-(const Iterator& other) const { return static_cast<difference_type>(m_idx) - static_cast<difference_type>(other.m_idx); }
          +  -  +  -  +  
                -  +  - ]
     263                 :             : 
     264                 :           6 :     ValueType operator[](difference_type n) const { return *(*this + n); }
     265                 :             : 
     266   [ +  -  +  -  :          24 :     auto operator<=>(const Iterator& other) const { return m_idx <=> other.m_idx; }
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     267                 :             : 
     268   [ +  -  +  -  :       23288 :     bool operator==(const Iterator& other) const { return m_collection == other.m_collection && m_idx == other.m_idx; }
          +  -  +  -  +  
          -  -  +  +  +  
          +  -  +  +  +  
          -  +  -  +  -  
          -  +  +  +  +  
          -  +  +  +  -  
          +  -  +  -  -  
          +  +  +  +  -  
          +  +  +  -  +  
          -  +  -  -  +  
          +  +  +  -  +  
          +  +  -  +  -  
          +  -  -  +  +  
          +  +  -  +  +  
          +  -  +  -  +  
          -  -  +  +  +  
          +  -  +  +  +  
          -  +  +  +  -  
          +  +  +  -  +  
          +  +  -  +  +  
          +  -  +  +  +  
          -  +  +  +  -  
          +  +  +  -  +  
          +  +  -  +  +  
          +  -  +  +  +  
          -  +  -  +  -  
          +  +  +  -  +  
                      + ]
     269                 :             : 
     270                 :             : private:
     271   [ +  -  +  -  :           6 :     friend Iterator operator+(difference_type n, const Iterator& it) { return it + n; }
          +  -  +  -  +  
                -  +  - ]
     272                 :             : };
     273                 :             : 
     274                 :             : template <typename Container, typename SizeFunc, typename GetFunc>
     275                 :             : concept IndexedContainer = requires(const Container& c, SizeFunc size_func, GetFunc get_func, std::size_t i) {
     276                 :             :     { std::invoke(size_func, c) } -> std::convertible_to<std::size_t>;
     277                 :             :     { std::invoke(get_func, c, i) }; // Return type is deduced
     278                 :             : };
     279                 :             : 
     280                 :             : template <typename Container, auto SizeFunc, auto GetFunc>
     281                 :             :     requires IndexedContainer<Container, decltype(SizeFunc), decltype(GetFunc)>
     282                 :             : class Range
     283                 :             : {
     284                 :             : public:
     285                 :             :     using value_type = std::invoke_result_t<decltype(GetFunc), const Container&, size_t>;
     286                 :             :     using difference_type = std::ptrdiff_t;
     287                 :             :     using iterator = Iterator<Container, value_type, GetFunc>;
     288                 :             :     using const_iterator = iterator;
     289                 :             : 
     290                 :             : private:
     291                 :             :     const Container* m_container;
     292                 :             : 
     293                 :             : public:
     294                 :        7270 :     explicit Range(const Container& container) : m_container(&container)
     295                 :             :     {
     296                 :             :         static_assert(std::ranges::random_access_range<Range>);
     297                 :             :     }
     298                 :             : 
     299   [ +  -  +  -  :         534 :     iterator begin() const { return iterator(m_container, 0); }
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     300                 :        7313 :     iterator end() const { return iterator(m_container, size()); }
     301                 :             : 
     302   [ +  -  +  -  :           6 :     const_iterator cbegin() const { return begin(); }
          +  -  +  -  +  
                -  +  - ]
     303   [ +  -  +  -  :           6 :     const_iterator cend() const { return end(); }
          +  -  +  -  +  
                -  +  - ]
     304                 :             : 
     305                 :       15160 :     size_t size() const { return std::invoke(SizeFunc, *m_container); }
     306                 :             : 
     307   [ +  -  +  -  :           7 :     bool empty() const { return size() == 0; }
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     308                 :             : 
     309                 :         510 :     value_type operator[](size_t index) const { return std::invoke(GetFunc, *m_container, index); }
     310                 :             : 
     311                 :           6 :     value_type at(size_t index) const
     312                 :             :     {
     313         [ +  - ]:           6 :         if (index >= size()) {
     314         [ +  - ]:           6 :             throw std::out_of_range("Index out of range");
     315                 :             :         }
     316                 :           0 :         return (*this)[index];
     317                 :             :     }
     318                 :             : 
     319                 :           7 :     value_type front() const { return (*this)[0]; }
     320                 :           9 :     value_type back() const { return (*this)[size() - 1]; }
     321                 :             : };
     322                 :             : 
     323                 :             : #define MAKE_RANGE_METHOD(method_name, ContainerType, SizeFunc, GetFunc, container_expr) \
     324                 :             :     auto method_name() const & { \
     325                 :             :         return Range<ContainerType, SizeFunc, GetFunc>{container_expr}; \
     326                 :             :     } \
     327                 :             :     auto method_name() const && = delete;
     328                 :             : 
     329                 :             : template <typename T>
     330                 :         606 : std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, btck_WriteBytes, void*))
     331                 :             : {
     332                 :         606 :     std::vector<std::byte> bytes;
     333         [ -  - ]:           0 :     struct UserData {
     334                 :             :         std::vector<std::byte>* bytes;
     335                 :             :         std::exception_ptr exception;
     336                 :             :     };
     337         [ +  - ]:         606 :     UserData user_data = UserData{.bytes = &bytes, .exception = nullptr};
     338                 :             : 
     339                 :        1998 :     constexpr auto const write = +[](const void* buffer, size_t len, void* user_data) -> int {
     340                 :        1392 :         auto& data = *reinterpret_cast<UserData*>(user_data);
     341                 :        1392 :         auto& bytes = *data.bytes;
     342                 :             :         try {
     343                 :        1392 :             auto const* first = static_cast<const std::byte*>(buffer);
     344   [ +  -  +  -  :        1392 :             auto const* last = first + len;
          +  -  +  -  +  
                      - ]
     345   [ +  -  +  -  :        1392 :             bytes.insert(bytes.end(), first, last);
          +  -  +  -  +  
                      - ]
     346                 :             :             return 0;
     347                 :           0 :         } catch (...) {
     348   [ -  -  -  -  :           0 :             data.exception = std::current_exception();
          -  -  -  -  -  
                      - ]
     349                 :             :             return -1;
     350                 :             :         }
     351                 :             :     };
     352                 :             : 
     353   [ +  -  -  + ]:         606 :     if (to_bytes(object, write, &user_data) != 0) {
     354                 :           0 :         std::rethrow_exception(user_data.exception);
     355                 :             :     }
     356         [ -  + ]:         606 :     return bytes;
     357                 :         606 : }
     358                 :             : 
     359                 :             : template <typename CType>
     360                 :             : class View
     361                 :             : {
     362                 :             : protected:
     363                 :             :     const CType* m_ptr;
     364                 :             : 
     365                 :             : public:
     366                 :       52980 :     explicit View(const CType* ptr) : m_ptr{check(ptr)} {}
     367                 :             : 
     368   [ +  -  +  -  :         233 :     const CType* get() const { return m_ptr; }
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     369                 :             : };
     370                 :             : 
     371                 :             : template <typename CType, CType* (*CopyFunc)(const CType*), void (*DestroyFunc)(CType*)>
     372                 :             : class Handle
     373                 :             : {
     374                 :             : protected:
     375                 :             :     CType* m_ptr;
     376                 :             : 
     377                 :             : public:
     378                 :       18859 :     explicit Handle(CType* ptr) : m_ptr{check(ptr)} {}
     379                 :             : 
     380                 :             :     // Copy constructors
     381                 :         100 :     Handle(const Handle& other)
     382                 :         100 :         : m_ptr{check(CopyFunc(other.m_ptr))} {}
     383                 :          20 :     Handle& operator=(const Handle& other)
     384                 :             :     {
     385         [ +  - ]:          20 :         if (this != &other) {
     386                 :          20 :             Handle temp(other);
     387                 :          20 :             std::swap(m_ptr, temp.m_ptr);
     388                 :          20 :         }
     389                 :          20 :         return *this;
     390                 :             :     }
     391                 :             : 
     392                 :             :     // Move constructors
     393                 :          96 :     Handle(Handle&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
     394                 :          20 :     Handle& operator=(Handle&& other) noexcept
     395                 :             :     {
     396                 :             :         if (this != &other) {
     397                 :          20 :             DestroyFunc(m_ptr);
     398   [ +  -  +  -  :          20 :             m_ptr = std::exchange(other.m_ptr, nullptr);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     399                 :             :         }
     400                 :             :         return *this;
     401                 :             :     }
     402                 :             : 
     403                 :             :     template <typename ViewType>
     404                 :             :         requires std::derived_from<ViewType, View<CType>>
     405                 :         726 :     Handle(const ViewType& view)
     406                 :         726 :         : Handle{CopyFunc(view.get())}
     407                 :             :     {
     408                 :         726 :     }
     409                 :             : 
     410                 :          92 :     ~Handle() { DestroyFunc(m_ptr); }
     411                 :             : 
     412   [ +  -  +  -  :         177 :     CType* get() { return m_ptr; }
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     413   [ +  -  +  - ]:          26 :     const CType* get() const { return m_ptr; }
     414                 :             : };
     415                 :             : 
     416                 :             : template <typename CType, void (*DestroyFunc)(CType*)>
     417                 :         104 : class UniqueHandle
     418                 :             : {
     419                 :             : protected:
     420                 :             :     struct Deleter {
     421                 :          54 :         void operator()(CType* ptr) const noexcept
     422                 :             :         {
     423                 :             :             if (ptr) DestroyFunc(ptr);
     424                 :          54 :         }
     425                 :             :     };
     426                 :             :     std::unique_ptr<CType, Deleter> m_ptr;
     427                 :             : 
     428                 :             : public:
     429                 :         112 :     explicit UniqueHandle(CType* ptr) : m_ptr{check(ptr)} {}
     430                 :             : 
     431   [ +  -  +  -  :           4 :     CType* get() { return m_ptr.get(); }
                   +  - ]
     432                 :        7399 :     const CType* get() const { return m_ptr.get(); }
     433                 :             : };
     434                 :             : 
     435                 :             : class PrecomputedTransactionData;
     436                 :             : class Transaction;
     437                 :             : class TransactionOutput;
     438                 :             : class BlockValidationState;
     439                 :             : 
     440                 :             : template <typename Derived>
     441                 :             : class ScriptPubkeyApi
     442                 :             : {
     443                 :             : private:
     444                 :         632 :     auto impl() const
     445                 :             :     {
     446                 :         635 :         return static_cast<const Derived*>(this)->get();
     447                 :             :     }
     448                 :             : 
     449                 :             :     friend Derived;
     450                 :             :     ScriptPubkeyApi() = default;
     451                 :             : 
     452                 :             : public:
     453                 :             :     bool Verify(int64_t amount,
     454                 :             :                 const Transaction& tx_to,
     455                 :             :                 const PrecomputedTransactionData* precomputed_txdata,
     456                 :             :                 unsigned int input_index,
     457                 :             :                 ScriptVerificationFlags flags,
     458                 :             :                 ScriptVerifyStatus& status) const;
     459                 :             : 
     460                 :         555 :     std::vector<std::byte> ToBytes() const
     461                 :             :     {
     462   [ +  -  +  -  :         553 :         return write_bytes(impl(), btck_script_pubkey_to_bytes);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     463                 :             :     }
     464                 :             : };
     465                 :             : 
     466                 :             : class ScriptPubkeyView : public View<btck_ScriptPubkey>, public ScriptPubkeyApi<ScriptPubkeyView>
     467                 :             : {
     468                 :             : public:
     469                 :        1170 :     explicit ScriptPubkeyView(const btck_ScriptPubkey* ptr) : View{ptr} {}
     470                 :             : };
     471                 :             : 
     472   [ +  -  +  -  :          25 : class ScriptPubkey : public Handle<btck_ScriptPubkey, btck_script_pubkey_copy, btck_script_pubkey_destroy>, public ScriptPubkeyApi<ScriptPubkey>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     473                 :             : {
     474                 :             : public:
     475                 :          11 :     explicit ScriptPubkey(std::span<const std::byte> raw)
     476                 :          11 :         : Handle{btck_script_pubkey_create(raw.data(), raw.size())} {}
     477                 :             : 
     478                 :           2 :     ScriptPubkey(const ScriptPubkeyView& view)
     479   [ +  -  +  - ]:           2 :         : Handle(view) {}
     480                 :             : };
     481                 :             : 
     482                 :             : template <typename Derived>
     483                 :             : class TransactionOutputApi
     484                 :             : {
     485                 :             : private:
     486                 :         973 :     auto impl() const
     487                 :             :     {
     488                 :         973 :         return static_cast<const Derived*>(this)->get();
     489                 :             :     }
     490                 :             : 
     491                 :             :     friend Derived;
     492                 :             :     TransactionOutputApi() = default;
     493                 :             : 
     494                 :             : public:
     495                 :         388 :     int64_t Amount() const
     496                 :             :     {
     497   [ +  -  +  -  :         386 :         return btck_transaction_output_get_amount(impl());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     498                 :             :     }
     499                 :             : 
     500                 :         585 :     ScriptPubkeyView GetScriptPubkey() const
     501                 :             :     {
     502                 :         585 :         return ScriptPubkeyView{btck_transaction_output_get_script_pubkey(impl())};
     503                 :             :     }
     504                 :             : };
     505                 :             : 
     506                 :             : class TransactionOutputView : public View<btck_TransactionOutput>, public TransactionOutputApi<TransactionOutputView>
     507                 :             : {
     508                 :             : public:
     509                 :        1206 :     explicit TransactionOutputView(const btck_TransactionOutput* ptr) : View{ptr} {}
     510                 :             : };
     511                 :             : 
     512   [ +  -  +  -  :          79 : class TransactionOutput : public Handle<btck_TransactionOutput, btck_transaction_output_copy, btck_transaction_output_destroy>, public TransactionOutputApi<TransactionOutput>
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     513                 :             : {
     514                 :             : public:
     515                 :           5 :     explicit TransactionOutput(const ScriptPubkey& script_pubkey, int64_t amount)
     516                 :           5 :         : Handle{btck_transaction_output_create(script_pubkey.get(), amount)} {}
     517                 :             : 
     518                 :          61 :     TransactionOutput(const TransactionOutputView& view)
     519   [ +  -  +  -  :          61 :         : Handle(view) {}
                   +  - ]
     520                 :             : };
     521                 :             : 
     522                 :             : template <typename Derived>
     523                 :             : class TxidApi
     524                 :             : {
     525                 :             : private:
     526                 :        7664 :     auto impl() const
     527                 :             :     {
     528                 :        7666 :         return static_cast<const Derived*>(this)->get();
     529                 :             :     }
     530                 :             : 
     531                 :             :     friend Derived;
     532                 :             :     TxidApi() = default;
     533                 :             : 
     534                 :             : public:
     535                 :        7575 :     bool operator==(const TxidApi& other) const
     536                 :             :     {
     537   [ +  -  +  -  :        7575 :         return btck_txid_equals(impl(), other.impl()) != 0;
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     538                 :             :     }
     539                 :             : 
     540                 :          62 :     bool operator!=(const TxidApi& other) const
     541                 :             :     {
     542   [ +  -  +  -  :          62 :         return btck_txid_equals(impl(), other.impl()) == 0;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     543                 :             :     }
     544                 :             : 
     545   [ +  -  +  -  :          27 :     std::array<std::byte, 32> ToBytes() const
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     546                 :             :     {
     547                 :             :         std::array<std::byte, 32> hash;
     548   [ +  -  +  -  :          27 :         btck_txid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     549                 :          25 :         return hash;
     550                 :             :     }
     551                 :             : };
     552                 :             : 
     553                 :             : class TxidView : public View<btck_Txid>, public TxidApi<TxidView>
     554                 :             : {
     555                 :             : public:
     556                 :       15646 :     explicit TxidView(const btck_Txid* ptr) : View{ptr} {}
     557                 :             : };
     558                 :             : 
     559   [ +  -  +  -  :          22 : class Txid : public Handle<btck_Txid, btck_txid_copy, btck_txid_destroy>, public TxidApi<Txid>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     560                 :             : {
     561                 :             : public:
     562                 :           5 :     Txid(const TxidView& view)
     563   [ +  -  +  -  :           5 :         : Handle(view) {}
          +  -  +  -  +  
                      - ]
     564                 :             : };
     565                 :             : 
     566                 :             : template <typename Derived>
     567                 :             : class WtxidApi
     568                 :             : {
     569                 :             : private:
     570                 :          18 :     auto impl() const
     571                 :             :     {
     572                 :          19 :         return static_cast<const Derived*>(this)->get();
     573                 :             :     }
     574                 :             : 
     575                 :             :     friend Derived;
     576                 :             :     WtxidApi() = default;
     577                 :             : 
     578                 :             : public:
     579                 :           2 :     bool operator==(const WtxidApi& other) const
     580                 :             :     {
     581   [ +  -  +  -  :           2 :         return btck_wtxid_equals(impl(), other.impl()) != 0;
             +  -  +  - ]
     582                 :             :     }
     583                 :             : 
     584                 :           2 :     bool operator!=(const WtxidApi& other) const
     585                 :             :     {
     586   [ +  -  +  -  :           2 :         return btck_wtxid_equals(impl(), other.impl()) == 0;
             +  -  +  - ]
     587                 :             :     }
     588                 :             : 
     589   [ +  -  +  -  :          14 :     std::array<std::byte, 32> ToBytes() const
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     590                 :             :     {
     591                 :             :         std::array<std::byte, 32> hash;
     592   [ +  -  +  -  :          14 :         btck_wtxid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     593                 :          13 :         return hash;
     594                 :             :     }
     595                 :             : };
     596                 :             : 
     597                 :             : class WtxidView : public View<btck_Wtxid>, public WtxidApi<WtxidView>
     598                 :             : {
     599                 :             : public:
     600                 :          20 :     explicit WtxidView(const btck_Wtxid* ptr) : View{ptr} {}
     601                 :             : };
     602                 :             : 
     603   [ +  -  +  -  :          12 : class Wtxid : public Handle<btck_Wtxid, btck_wtxid_copy, btck_wtxid_destroy>, public WtxidApi<Wtxid>
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     604                 :             : {
     605                 :             : public:
     606                 :           3 :     Wtxid(const WtxidView& view)
     607   [ +  -  +  -  :           3 :         : Handle(view) {}
                   +  - ]
     608                 :             : };
     609                 :             : 
     610                 :             : template <typename Derived>
     611                 :             : class OutPointApi
     612                 :             : {
     613                 :             : private:
     614                 :         502 :     auto impl() const
     615                 :             :     {
     616                 :         502 :         return static_cast<const Derived*>(this)->get();
     617                 :             :     }
     618                 :             : 
     619                 :             :     friend Derived;
     620                 :             :     OutPointApi() = default;
     621                 :             : 
     622                 :             : public:
     623                 :         325 :     uint32_t index() const
     624                 :             :     {
     625   [ +  -  +  - ]:         325 :         return btck_transaction_out_point_get_index(impl());
     626                 :             :     }
     627                 :             : 
     628                 :         177 :     TxidView Txid() const
     629                 :             :     {
     630                 :         177 :         return TxidView{btck_transaction_out_point_get_txid(impl())};
     631                 :             :     }
     632                 :             : };
     633                 :             : 
     634                 :             : class OutPointView : public View<btck_TransactionOutPoint>, public OutPointApi<OutPointView>
     635                 :             : {
     636                 :             : public:
     637                 :         536 :     explicit OutPointView(const btck_TransactionOutPoint* ptr) : View{ptr} {}
     638                 :             : };
     639                 :             : 
     640   [ +  -  +  -  :          10 : class OutPoint : public Handle<btck_TransactionOutPoint, btck_transaction_out_point_copy, btck_transaction_out_point_destroy>, public OutPointApi<OutPoint>
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     641                 :             : {
     642                 :             : public:
     643                 :           2 :     OutPoint(const OutPointView& view)
     644   [ +  -  +  - ]:           2 :         : Handle(view) {}
     645                 :             : };
     646                 :             : 
     647                 :             : template <typename Derived>
     648                 :             : class WitnessStackApi
     649                 :             : {
     650                 :             : private:
     651                 :          21 :     auto impl() const
     652                 :             :     {
     653                 :          21 :         return static_cast<const Derived*>(this)->get();
     654                 :             :     }
     655                 :             : 
     656                 :             :     friend Derived;
     657                 :             :     WitnessStackApi() = default;
     658                 :             : 
     659                 :             : public:
     660                 :           9 :     size_t CountItems() const
     661                 :             :     {
     662   [ +  -  +  - ]:           9 :         return btck_witness_stack_count_items(impl());
     663                 :             :     }
     664                 :             : 
     665                 :          12 :     std::vector<std::byte> GetItem(size_t index) const
     666                 :             :     {
     667                 :             :         struct Item { const btck_WitnessStack* stack; size_t index; };
     668                 :          12 :         Item item{impl(), index};
     669                 :             :         return write_bytes(&item, +[](const Item* c, btck_WriteBytes w, void* ud) {
     670                 :             :             return btck_witness_stack_get_item_at(c->stack, c->index, w, ud);
     671   [ +  -  +  -  :          12 :         });
          +  -  +  -  +  
                      - ]
     672                 :             :     }
     673                 :             : 
     674   [ +  -  +  - ]:          13 :     MAKE_RANGE_METHOD(Items, Derived, &WitnessStackApi<Derived>::CountItems, &WitnessStackApi<Derived>::GetItem, *static_cast<const Derived*>(this))
     675                 :             : };
     676                 :             : 
     677                 :             : class WitnessStackView : public View<btck_WitnessStack>, public WitnessStackApi<WitnessStackView>
     678                 :             : {
     679                 :             : public:
     680                 :           4 :     explicit WitnessStackView(const btck_WitnessStack* ptr) : View{ptr} {}
     681                 :             : };
     682                 :             : 
     683   [ +  -  +  -  :          10 : class WitnessStack : public Handle<btck_WitnessStack, btck_witness_stack_copy, btck_witness_stack_destroy>, public WitnessStackApi<WitnessStack>
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     684                 :             : {
     685                 :             : public:
     686                 :           2 :     WitnessStack(const WitnessStackView& view)
     687   [ +  -  +  - ]:           1 :         : Handle(view) {}
     688                 :             : };
     689                 :             : 
     690                 :             : template <typename Derived>
     691                 :             : class TransactionInputApi
     692                 :             : {
     693                 :             : private:
     694                 :         274 :     auto impl() const
     695                 :             :     {
     696                 :         274 :         return static_cast<const Derived*>(this)->get();
     697                 :             :     }
     698                 :             : 
     699                 :             :     friend Derived;
     700                 :             :     TransactionInputApi() = default;
     701                 :             : 
     702                 :             : public:
     703                 :         268 :     OutPointView OutPoint() const
     704                 :             :     {
     705                 :         268 :         return OutPointView{btck_transaction_input_get_out_point(impl())};
     706                 :             :     }
     707                 :             : 
     708                 :           1 :     uint32_t GetSequence() const
     709                 :             :     {
     710         [ +  - ]:           1 :         return btck_transaction_input_get_sequence(impl());
     711                 :             :     }
     712                 :             : 
     713                 :           2 :     WitnessStackView GetWitnessStack() const
     714                 :             :     {
     715                 :           2 :         return WitnessStackView{btck_transaction_input_get_witness_stack(impl())};
     716                 :             :     }
     717                 :             : 
     718                 :           3 :     std::vector<std::byte> GetScriptSig() const
     719                 :             :     {
     720   [ +  -  +  -  :           3 :         return write_bytes(impl(), btck_transaction_input_get_script_sig);
                   +  - ]
     721                 :             :     }
     722                 :             : };
     723                 :             : 
     724                 :             : class TransactionInputView : public View<btck_TransactionInput>, public TransactionInputApi<TransactionInputView>
     725                 :             : {
     726                 :             : public:
     727                 :         564 :     explicit TransactionInputView(const btck_TransactionInput* ptr) : View{ptr} {}
     728                 :             : };
     729                 :             : 
     730   [ +  -  +  -  :          75 : class TransactionInput : public Handle<btck_TransactionInput, btck_transaction_input_copy, btck_transaction_input_destroy>, public TransactionInputApi<TransactionInput>
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     731                 :             : {
     732                 :             : public:
     733                 :          61 :     TransactionInput(const TransactionInputView& view)
     734   [ +  -  +  -  :          61 :         : Handle(view) {}
                   +  - ]
     735                 :             : };
     736                 :             : 
     737                 :             : template <typename Derived>
     738                 :             : class TransactionApi
     739                 :             : {
     740                 :             : private:
     741                 :        9129 :     auto impl() const
     742                 :             :     {
     743                 :        9130 :         return static_cast<const Derived*>(this)->get();
     744                 :             :     }
     745                 :             : 
     746                 :             : public:
     747                 :         287 :     size_t CountOutputs() const
     748                 :             :     {
     749   [ +  -  +  -  :         287 :         return btck_transaction_count_outputs(impl());
          +  -  +  -  +  
                      - ]
     750                 :             :     }
     751                 :             : 
     752                 :         284 :     size_t CountInputs() const
     753                 :             :     {
     754   [ +  -  +  -  :         284 :         return btck_transaction_count_inputs(impl());
          +  -  +  -  +  
                      - ]
     755                 :             :     }
     756                 :             : 
     757                 :         601 :     TransactionOutputView GetOutput(size_t index) const
     758                 :             :     {
     759                 :         601 :         return TransactionOutputView{btck_transaction_get_output_at(impl(), index)};
     760                 :             :     }
     761                 :             : 
     762                 :         282 :     TransactionInputView GetInput(size_t index) const
     763                 :             :     {
     764                 :         282 :         return TransactionInputView{btck_transaction_get_input_at(impl(), index)};
     765                 :             :     }
     766                 :             : 
     767                 :           3 :     uint32_t GetVersion() const
     768                 :             :     {
     769   [ +  -  +  - ]:           3 :         return btck_transaction_get_version(impl());
     770                 :             :     }
     771                 :             : 
     772                 :           1 :     uint32_t GetLocktime() const
     773                 :             :     {
     774         [ +  - ]:           1 :         return btck_transaction_get_locktime(impl());
     775                 :             :     }
     776                 :             : 
     777                 :           2 :     bool HasWitness() const
     778                 :             :     {
     779   [ +  -  +  -  :           2 :         return btck_transaction_has_witness(impl()) != 0;
                   +  - ]
     780                 :             :     }
     781                 :             : 
     782                 :        7646 :     TxidView Txid() const
     783                 :             :     {
     784                 :        7646 :         return TxidView{btck_transaction_get_txid(impl())};
     785                 :             :     }
     786                 :             : 
     787                 :          10 :     WtxidView Wtxid() const
     788                 :             :     {
     789                 :          10 :         return WtxidView{btck_transaction_get_wtxid(impl())};
     790                 :             :     }
     791                 :             : 
     792   [ +  -  +  -  :        1083 :     MAKE_RANGE_METHOD(Outputs, Derived, &TransactionApi<Derived>::CountOutputs, &TransactionApi<Derived>::GetOutput, *static_cast<const Derived*>(this))
             +  -  +  - ]
     793                 :             : 
     794   [ +  -  +  - ]:         818 :     MAKE_RANGE_METHOD(Inputs, Derived, &TransactionApi<Derived>::CountInputs, &TransactionApi<Derived>::GetInput, *static_cast<const Derived*>(this))
     795                 :             : 
     796                 :          14 :     std::vector<std::byte> ToBytes() const
     797                 :             :     {
     798   [ +  -  +  -  :          13 :         return write_bytes(impl(), btck_transaction_to_bytes);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     799                 :             :     }
     800                 :             : };
     801                 :             : 
     802                 :             : class TransactionView : public View<btck_Transaction>, public TransactionApi<TransactionView>
     803                 :             : {
     804                 :             : public:
     805                 :       16102 :     explicit TransactionView(const btck_Transaction* ptr) : View{ptr} {}
     806                 :             : };
     807                 :             : 
     808   [ +  -  +  -  :         471 : class Transaction : public Handle<btck_Transaction, btck_transaction_copy, btck_transaction_destroy>, public TransactionApi<Transaction>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
             -  -  -  +  
                      - ]
     809                 :             : {
     810                 :             : public:
     811                 :          31 :     explicit Transaction(std::span<const std::byte> raw_transaction)
     812                 :          31 :         : Handle{btck_transaction_create(raw_transaction.data(), raw_transaction.size())} {}
     813                 :             : 
     814                 :         379 :     Transaction(const TransactionView& view)
     815   [ +  -  +  -  :         379 :         : Handle{view} {}
             +  -  +  - ]
     816                 :             : };
     817                 :             : 
     818   [ +  -  +  -  :         273 : class PrecomputedTransactionData : public Handle<btck_PrecomputedTransactionData, btck_precomputed_transaction_data_copy, btck_precomputed_transaction_data_destroy>
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     819                 :             : {
     820                 :             : public:
     821                 :         266 :     explicit PrecomputedTransactionData(const Transaction& tx_to, std::span<const TransactionOutput> spent_outputs)
     822                 :         266 :         : Handle{btck_precomputed_transaction_data_create(
     823                 :             :             tx_to.get(),
     824                 :             :             reinterpret_cast<const btck_TransactionOutput**>(
     825                 :         266 :                 const_cast<TransactionOutput*>(spent_outputs.data())),
     826                 :         266 :             spent_outputs.size())} {}
     827                 :             : };
     828                 :             : 
     829                 :             : template <typename Derived>
     830                 :          80 : bool ScriptPubkeyApi<Derived>::Verify(int64_t amount,
     831                 :             :                                       const Transaction& tx_to,
     832                 :             :                                       const PrecomputedTransactionData* precomputed_txdata,
     833                 :             :                                       unsigned int input_index,
     834                 :             :                                       ScriptVerificationFlags flags,
     835                 :             :                                       ScriptVerifyStatus& status) const
     836                 :             : {
     837         [ +  + ]:         154 :     auto result = btck_script_pubkey_verify(
     838                 :             :         impl(),
     839                 :             :         amount,
     840                 :             :         tx_to.get(),
     841                 :          74 :         precomputed_txdata ? precomputed_txdata->get() : nullptr,
     842                 :             :         input_index,
     843                 :             :         static_cast<btck_ScriptVerificationFlags>(flags),
     844                 :             :         reinterpret_cast<btck_ScriptVerifyStatus*>(&status));
     845                 :          80 :     return result == 1;
     846                 :             : }
     847                 :             : 
     848                 :             : template <typename Derived>
     849                 :             : class BlockHashApi
     850                 :             : {
     851                 :             : private:
     852                 :         224 :     auto impl() const
     853                 :             :     {
     854                 :         226 :         return static_cast<const Derived*>(this)->get();
     855                 :             :     }
     856                 :             : 
     857                 :             : public:
     858                 :         207 :     bool operator==(const Derived& other) const
     859                 :             :     {
     860   [ +  -  +  -  :         207 :         return btck_block_hash_equals(impl(), other.get()) != 0;
             +  -  +  - ]
     861                 :             :     }
     862                 :             : 
     863                 :           1 :     bool operator!=(const Derived& other) const
     864                 :             :     {
     865   [ +  -  +  - ]:           1 :         return btck_block_hash_equals(impl(), other.get()) == 0;
     866                 :             :     }
     867                 :             : 
     868   [ +  -  +  -  :          17 :     std::array<std::byte, 32> ToBytes() const
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     869                 :             :     {
     870                 :             :         std::array<std::byte, 32> hash;
     871   [ +  -  +  -  :          17 :         btck_block_hash_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     872                 :          16 :         return hash;
     873                 :             :     }
     874                 :             : };
     875                 :             : 
     876                 :             : class BlockHashView : public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
     877                 :             : {
     878                 :             : public:
     879                 :         416 :     explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {}
     880                 :             : };
     881                 :             : 
     882   [ +  -  +  -  :         426 : class BlockHash : public Handle<btck_BlockHash, btck_block_hash_copy, btck_block_hash_destroy>, public BlockHashApi<BlockHash>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     883                 :             : {
     884                 :             : public:
     885                 :           2 :     explicit BlockHash(const std::array<std::byte, 32>& hash)
     886                 :           2 :         : Handle{btck_block_hash_create(reinterpret_cast<const unsigned char*>(hash.data()))} {}
     887                 :             : 
     888                 :         416 :     explicit BlockHash(btck_BlockHash* hash)
     889                 :         832 :         : Handle{hash} {}
     890                 :             : 
     891                 :         207 :     BlockHash(const BlockHashView& view)
     892   [ +  -  +  - ]:         207 :         : Handle{view} {}
     893                 :             : };
     894                 :             : 
     895                 :             : template <typename Derived>
     896                 :             : class BlockHeaderApi
     897                 :             : {
     898                 :             : private:
     899                 :         446 :     auto impl() const
     900                 :             :     {
     901                 :         446 :         return static_cast<const Derived*>(this)->get();
     902                 :             :     }
     903                 :             : 
     904                 :             :     friend Derived;
     905                 :             :     BlockHeaderApi() = default;
     906                 :             : 
     907                 :             : public:
     908                 :         415 :     BlockHash Hash() const
     909                 :             :     {
     910                 :         415 :         return BlockHash{btck_block_header_get_hash(impl())};
     911                 :             :     }
     912                 :             : 
     913                 :           1 :     BlockHashView PrevHash() const
     914                 :             :     {
     915                 :           1 :         return BlockHashView{btck_block_header_get_prev_hash(impl())};
     916                 :             :     }
     917                 :             : 
     918   [ +  -  +  - ]:           2 :     std::array<std::byte, 32> MerkleRoot() const
     919                 :             :     {
     920                 :             :         std::array<std::byte, 32> merkle_root;
     921   [ +  -  +  - ]:           2 :         btck_block_header_get_merkle_root(impl(), reinterpret_cast<unsigned char*>(merkle_root.data()));
     922                 :           2 :         return merkle_root;
     923                 :             :     }
     924                 :             : 
     925                 :           4 :     uint32_t Timestamp() const
     926                 :             :     {
     927   [ +  -  +  -  :           4 :         return btck_block_header_get_timestamp(impl());
             +  -  +  - ]
     928                 :             :     }
     929                 :             : 
     930                 :           3 :     uint32_t Bits() const
     931                 :             :     {
     932   [ +  -  +  -  :           3 :         return btck_block_header_get_bits(impl());
                   +  - ]
     933                 :             :     }
     934                 :             : 
     935                 :           3 :     int32_t Version() const
     936                 :             :     {
     937   [ +  -  +  -  :           3 :         return btck_block_header_get_version(impl());
                   +  - ]
     938                 :             :     }
     939                 :             : 
     940                 :           3 :     uint32_t Nonce() const
     941                 :             :     {
     942   [ +  -  +  -  :           3 :         return btck_block_header_get_nonce(impl());
                   +  - ]
     943                 :             :     }
     944                 :             : 
     945                 :          15 :     std::array<std::byte, 80> ToBytes() const
     946                 :             :     {
     947                 :             :         std::array<std::byte, 80> header;
     948                 :          15 :         int res{btck_block_header_to_bytes(impl(), reinterpret_cast<unsigned char*>(header.data()))};
     949         [ -  + ]:          15 :         if (res != 0) {
     950         [ #  # ]:           0 :             throw std::runtime_error("Failed to serialize block header");
     951                 :             :         }
     952                 :          15 :         return header;
     953                 :             :     }
     954                 :             : };
     955                 :             : 
     956                 :             : class BlockHeaderView : public View<btck_BlockHeader>, public BlockHeaderApi<BlockHeaderView>
     957                 :             : {
     958                 :             : public:
     959                 :             :     explicit BlockHeaderView(const btck_BlockHeader* ptr) : View{ptr} {}
     960                 :             : };
     961                 :             : 
     962   [ +  -  +  -  :         425 : class BlockHeader : public Handle<btck_BlockHeader, btck_block_header_copy, btck_block_header_destroy>, public BlockHeaderApi<BlockHeader>
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     963                 :             : {
     964                 :             : public:
     965                 :           4 :     explicit BlockHeader(std::span<const std::byte> raw_header)
     966                 :           4 :         : Handle{btck_block_header_create(reinterpret_cast<const unsigned char*>(raw_header.data()), raw_header.size())} {}
     967                 :             : 
     968                 :             :     BlockHeader(const BlockHeaderView& view)
     969                 :             :         : Handle{view} {}
     970                 :             : 
     971                 :         415 :     BlockHeader(btck_BlockHeader* header)
     972                 :         830 :         : Handle{header} {}
     973                 :             : };
     974                 :             : 
     975                 :             : class ConsensusParamsView : public View<btck_ConsensusParams>
     976                 :             : {
     977                 :             : public:
     978                 :           2 :     explicit ConsensusParamsView(const btck_ConsensusParams* ptr) : View{ptr} {}
     979                 :             : };
     980                 :             : 
     981   [ +  -  +  -  :        7323 : class Block : public Handle<btck_Block, btck_block_copy, btck_block_destroy>
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
                -  -  - ]
     982                 :             : {
     983                 :             : public:
     984                 :         635 :     Block(const std::span<const std::byte> raw_block)
     985                 :         635 :         : Handle{btck_block_create(raw_block.data(), raw_block.size())}
     986                 :             :     {
     987                 :         632 :     }
     988                 :             : 
     989                 :        6675 :     Block(btck_Block* block) : Handle{block} {}
     990                 :             : 
     991                 :        6688 :     size_t CountTransactions() const
     992                 :             :     {
     993   [ +  -  +  - ]:        6688 :         return btck_block_count_transactions(get());
     994                 :             :     }
     995                 :             : 
     996                 :        8051 :     TransactionView GetTransaction(size_t index) const
     997                 :             :     {
     998                 :        8051 :         return TransactionView{btck_block_get_transaction_at(get(), index)};
     999                 :             :     }
    1000                 :             : 
    1001                 :             :     bool Check(const ConsensusParamsView& consensus_params,
    1002                 :             :         BlockCheckFlags flags,
    1003                 :             :         BlockValidationState& state) const;
    1004                 :             : 
    1005   [ +  -  +  -  :       21407 :     MAKE_RANGE_METHOD(Transactions, Block, &Block::CountTransactions, &Block::GetTransaction, *this)
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
    1006                 :             : 
    1007                 :           1 :     BlockHash GetHash() const
    1008                 :             :     {
    1009                 :           1 :         return BlockHash{btck_block_get_hash(get())};
    1010                 :             :     }
    1011                 :             : 
    1012                 :         209 :     BlockHeader GetHeader() const
    1013                 :             :     {
    1014                 :         209 :         return BlockHeader{btck_block_get_header(get())};
    1015                 :             :     }
    1016                 :             : 
    1017                 :          22 :     std::vector<std::byte> ToBytes() const
    1018                 :             :     {
    1019   [ +  -  +  -  :          21 :         return write_bytes(get(), btck_block_to_bytes);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
    1020                 :             :     }
    1021                 :             : };
    1022                 :             : 
    1023                 :           3 : inline void logging_set_min_level(LogLevel level)
    1024                 :             : {
    1025   [ +  -  +  -  :           3 :     btck_logging_set_min_level(static_cast<btck_LogLevel>(level));
                   +  - ]
    1026                 :           3 : }
    1027                 :             : 
    1028                 :             : //! Non-owning view over a btck_LogEntry. The referenced entry is only valid for the duration of the
    1029                 :             : //! logging callback, so a LogEntry (and any string_view obtained from it) must not be stored or
    1030                 :             : //! used after the callback returns.
    1031                 :             : class LogEntry
    1032                 :             : {
    1033                 :             : private:
    1034                 :             :     const btck_LogEntry* m_entry;
    1035                 :             : 
    1036                 :             : public:
    1037                 :             :     explicit LogEntry(const btck_LogEntry& entry) : m_entry{&entry} {}
    1038                 :             : 
    1039                 :         115 :     std::string_view Message() const { return {m_entry->message, m_entry->message_len}; }
    1040                 :             :     std::string_view ThreadName() const { return {m_entry->thread_name, m_entry->thread_name_len}; }
    1041                 :         109 :     std::chrono::sys_time<std::chrono::nanoseconds> Timestamp() const
    1042                 :             :     {
    1043                 :         109 :         return std::chrono::sys_time<std::chrono::nanoseconds>{std::chrono::nanoseconds{m_entry->timestamp_ns}};
    1044                 :             :     }
    1045                 :             :     std::optional<std::chrono::sys_seconds> MockTime() const
    1046                 :             :     {
    1047                 :             :         if (m_entry->mocktime_s == 0) return std::nullopt;
    1048                 :             :         return std::chrono::sys_seconds{std::chrono::seconds{m_entry->mocktime_s}};
    1049                 :             :     }
    1050                 :             :     std::string_view FileName() const { return {m_entry->file_name, m_entry->file_name_len}; }
    1051                 :             :     std::string_view FunctionName() const { return {m_entry->function_name, m_entry->function_name_len}; }
    1052                 :             :     uint32_t Line() const { return m_entry->line; }
    1053                 :         109 :     LogLevel Level() const { return static_cast<LogLevel>(m_entry->level); }
    1054                 :         109 :     LogCategory Category() const { return static_cast<LogCategory>(m_entry->category); }
    1055                 :             : };
    1056                 :             : 
    1057                 :             : template <typename T>
    1058                 :             : concept Log = requires(T a, const LogEntry& entry) {
    1059                 :             :     { a.LogMessage(entry) } -> std::same_as<void>;
    1060                 :             : };
    1061                 :             : 
    1062                 :             : template <Log T>
    1063   [ +  -  -  -  :           7 : class Logger : UniqueHandle<btck_LoggingConnection, btck_logging_connection_destroy>
          +  -  +  -  +  
          -  +  -  +  -  
             -  -  -  - ]
           [ #  #  #  #  
                   #  # ]
    1064                 :             : {
    1065                 :             : public:
    1066                 :           4 :     Logger(std::unique_ptr<T> log)
    1067                 :             :         : UniqueHandle{btck_logging_connection_create(
    1068                 :             :               +[](void* user_data, const btck_LogEntry* entry) { static_cast<T*>(user_data)->LogMessage(LogEntry{*entry}); },
    1069                 :           4 :               log.release(),
    1070         [ +  - ]:           7 :               +[](void* user_data) { delete static_cast<T*>(user_data); })}
    1071                 :             :     {
    1072                 :           4 :     }
    1073                 :             : };
    1074                 :             : 
    1075                 :             : class BlockTreeEntry : public View<btck_BlockTreeEntry>
    1076                 :             : {
    1077                 :             : public:
    1078                 :        8361 :     BlockTreeEntry(const btck_BlockTreeEntry* entry)
    1079                 :         641 :         : View{entry}
    1080                 :             :     {
    1081                 :             :     }
    1082                 :             : 
    1083                 :          10 :     bool operator==(const BlockTreeEntry& other) const
    1084                 :             :     {
    1085   [ +  -  +  -  :          10 :         return btck_block_tree_entry_equals(get(), other.get()) != 0;
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
    1086                 :             :     }
    1087                 :             : 
    1088                 :           6 :     std::optional<BlockTreeEntry> GetPrevious() const
    1089                 :             :     {
    1090                 :           6 :         auto entry{btck_block_tree_entry_get_previous(get())};
    1091         [ +  + ]:           6 :         if (!entry) return std::nullopt;
    1092                 :           4 :         return entry;
    1093                 :             :     }
    1094                 :             : 
    1095                 :         211 :     int32_t GetHeight() const
    1096                 :             :     {
    1097   [ +  -  +  -  :         211 :         return btck_block_tree_entry_get_height(get());
          +  -  +  -  +  
                      - ]
    1098                 :             :     }
    1099                 :             : 
    1100                 :         207 :     BlockHashView GetHash() const
    1101                 :             :     {
    1102                 :         207 :         return BlockHashView{btck_block_tree_entry_get_block_hash(get())};
    1103                 :             :     }
    1104                 :             : 
    1105                 :         206 :     BlockHeader GetHeader() const
    1106                 :             :     {
    1107                 :         206 :         return BlockHeader{btck_block_tree_entry_get_block_header(get())};
    1108                 :             :     }
    1109                 :             : 
    1110                 :           3 :     BlockTreeEntry GetAncestor(int32_t height) const
    1111                 :             :     {
    1112                 :           3 :         return BlockTreeEntry{btck_block_tree_entry_get_ancestor(get(), height)};
    1113                 :             :     }
    1114                 :             : 
    1115                 :             : };
    1116                 :             : 
    1117                 :           9 : class KernelNotifications
    1118                 :             : {
    1119                 :             : public:
    1120                 :           0 :     virtual ~KernelNotifications() = default;
    1121                 :             : 
    1122                 :         428 :     virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress) {}
    1123                 :             : 
    1124                 :           0 :     virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
    1125                 :             : 
    1126                 :          13 :     virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible) {}
    1127                 :             : 
    1128                 :           0 :     virtual void WarningSetHandler(Warning warning, std::string_view message) {}
    1129                 :             : 
    1130                 :         428 :     virtual void WarningUnsetHandler(Warning warning) {}
    1131                 :             : 
    1132                 :           0 :     virtual void FlushErrorHandler(std::string_view error) {}
    1133                 :             : 
    1134                 :           0 :     virtual void FatalErrorHandler(std::string_view error) {}
    1135                 :             : };
    1136                 :             : 
    1137                 :             : template <typename Derived>
    1138                 :             : class BlockValidationStateApi
    1139                 :             : {
    1140                 :             : private:
    1141                 :         429 :     auto impl() const
    1142                 :             :     {
    1143                 :         430 :         return static_cast<const Derived*>(this)->get();
    1144                 :             :     }
    1145                 :             : 
    1146                 :             :     friend Derived;
    1147                 :             :     BlockValidationStateApi() = default;
    1148                 :             : 
    1149                 :             : public:
    1150                 :         218 :     ValidationMode GetValidationMode() const
    1151                 :             :     {
    1152   [ +  -  +  -  :         218 :         return static_cast<ValidationMode>(btck_block_validation_state_get_validation_mode(impl()));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
    1153                 :             :     }
    1154                 :             : 
    1155                 :         212 :     BlockValidationResult GetBlockValidationResult() const
    1156                 :             :     {
    1157   [ +  -  +  -  :         212 :         return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(impl()));
          +  -  +  -  +  
                -  +  - ]
    1158                 :             :     }
    1159                 :             : };
    1160                 :             : 
    1161                 :             : class BlockValidationStateView : public View<btck_BlockValidationState>, public BlockValidationStateApi<BlockValidationStateView>
    1162                 :             : {
    1163                 :             : public:
    1164                 :           3 :     explicit BlockValidationStateView(const btck_BlockValidationState* ptr) : View{ptr} {}
    1165                 :             : };
    1166                 :             : 
    1167                 :         208 : class BlockValidationState : public Handle<btck_BlockValidationState, btck_block_validation_state_copy, btck_block_validation_state_destroy>, public BlockValidationStateApi<BlockValidationState>
    1168                 :             : {
    1169                 :             : public:
    1170                 :           1 :     explicit BlockValidationState() : Handle{btck_block_validation_state_create()} {}
    1171                 :             : 
    1172                 :             :     explicit BlockValidationState(const BlockValidationStateView& view) : Handle{view} {}
    1173                 :             : 
    1174                 :         416 :     explicit BlockValidationState(btck_BlockValidationState* state) : Handle{state} {}
    1175                 :             : };
    1176                 :             : 
    1177                 :           7 : inline bool Block::Check(const ConsensusParamsView& consensus_params,
    1178                 :             :     BlockCheckFlags flags,
    1179                 :             :     BlockValidationState& state) const
    1180                 :             : {
    1181   [ +  -  +  -  :           7 :     return btck_block_check(get(), consensus_params.get(), static_cast<btck_BlockCheckFlags>(flags), state.get()) == 1;
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
    1182                 :             : }
    1183                 :             : 
    1184   [ +  -  -  -  :          22 : class TxValidationState : public UniqueHandle<btck_TxValidationState, btck_tx_validation_state_destroy>
          +  -  -  -  +  
                -  -  - ]
    1185                 :             : {
    1186                 :             : public:
    1187                 :             :     using UniqueHandle::UniqueHandle; // inherit ctor
    1188                 :          11 :     explicit TxValidationState() : UniqueHandle{btck_tx_validation_state_create()} {}
    1189                 :             : 
    1190                 :          12 :     ValidationMode GetValidationMode() const
    1191                 :             :     {
    1192   [ +  -  +  -  :          12 :         return static_cast<ValidationMode>(btck_tx_validation_state_get_validation_mode(get()));
             +  -  +  - ]
    1193                 :             :     }
    1194                 :             : 
    1195                 :          12 :     TxValidationResult GetTxValidationResult() const
    1196                 :             :     {
    1197   [ +  -  +  -  :          12 :         return static_cast<TxValidationResult>(btck_tx_validation_state_get_tx_validation_result(get()));
             +  -  +  - ]
    1198                 :             :     }
    1199                 :             : };
    1200                 :             : 
    1201                 :          10 : inline bool CheckTransaction(const Transaction& tx, TxValidationState& state)
    1202                 :             : {
    1203   [ +  -  +  -  :          10 :     return btck_transaction_check(tx.get(), state.get()) == 1;
                   +  - ]
    1204                 :             : }
    1205                 :             : 
    1206                 :           1 : class ValidationInterface
    1207                 :             : {
    1208                 :             : public:
    1209                 :           0 :     virtual ~ValidationInterface() = default;
    1210                 :             : 
    1211                 :           0 :     virtual void BlockChecked(Block block, BlockValidationStateView state) {}
    1212                 :             : 
    1213                 :           0 :     virtual void PowValidBlock(BlockTreeEntry entry, Block block) {}
    1214                 :             : 
    1215                 :           0 :     virtual void BlockConnected(Block block, BlockTreeEntry entry) {}
    1216                 :             : 
    1217                 :           0 :     virtual void BlockDisconnected(Block block, BlockTreeEntry entry) {}
    1218                 :             : };
    1219                 :             : 
    1220   [ +  -  +  -  :          28 : class ChainParams : public Handle<btck_ChainParameters, btck_chain_parameters_copy, btck_chain_parameters_destroy>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
           [ #  #  #  # ]
    1221                 :             : {
    1222                 :             : public:
    1223                 :          12 :     explicit ChainParams(ChainType chain_type)
    1224                 :          12 :         : Handle{btck_chain_parameters_create(static_cast<btck_ChainType>(chain_type))} {}
    1225                 :             : 
    1226                 :           1 :     explicit ChainParams(std::span<const std::byte> signet_challenge)
    1227                 :           1 :         : Handle{btck_chain_parameters_create_signet(signet_challenge.data(), signet_challenge.size())} {}
    1228                 :             : 
    1229                 :           1 :     ConsensusParamsView GetConsensusParams() const
    1230                 :             :     {
    1231                 :           1 :         return ConsensusParamsView{btck_chain_parameters_get_consensus_params(get())};
    1232                 :             :     }
    1233                 :             : };
    1234                 :             : 
    1235   [ +  -  +  -  :          26 : class ContextOptions : public UniqueHandle<btck_ContextOptions, btck_context_options_destroy>
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  -  
           - ][ #  #  #  
          #  #  #  #  #  
                   #  # ]
    1236                 :             : {
    1237                 :             : public:
    1238                 :          15 :     ContextOptions() : UniqueHandle{btck_context_options_create()} {}
    1239                 :             : 
    1240                 :           9 :     void SetChainParams(ChainParams& chain_params)
    1241                 :             :     {
    1242   [ +  -  +  - ]:           9 :         btck_context_options_set_chainparams(get(), chain_params.get());
                 [ #  # ]
    1243                 :           9 :     }
    1244                 :             : 
    1245                 :             :     template <typename T>
    1246                 :           9 :     void SetNotifications(std::shared_ptr<T> notifications)
    1247                 :             :     {
    1248                 :             :         static_assert(std::is_base_of_v<KernelNotifications, T>);
    1249         [ +  - ]:           9 :         auto heap_notifications = std::make_unique<std::shared_ptr<T>>(std::move(notifications));
    1250                 :             :         using user_type = std::shared_ptr<T>*;
    1251                 :           9 :         btck_context_options_set_notifications(
    1252                 :             :             get(),
    1253                 :             :             btck_NotificationInterfaceCallbacks{
    1254         [ +  - ]:           9 :                 .user_data = heap_notifications.release(),
    1255         [ +  - ]:          18 :                 .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
    1256                 :         428 :                 .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); },
    1257                 :             :                 .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); },
    1258                 :             :                 .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); },
    1259                 :             :                 .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}); },
    1260                 :             :                 .warning_unset = +[](void* user_data, btck_Warning warning) { (*static_cast<user_type>(user_data))->WarningUnsetHandler(static_cast<Warning>(warning)); },
    1261                 :             :                 .flush_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FlushErrorHandler({error, error_len}); },
    1262                 :             :                 .fatal_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FatalErrorHandler({error, error_len}); },
    1263                 :             :             });
    1264                 :           9 :     }
    1265                 :             : 
    1266                 :             :     template <typename T>
    1267                 :           1 :     void SetValidationInterface(std::shared_ptr<T> validation_interface)
    1268                 :             :     {
    1269                 :             :         static_assert(std::is_base_of_v<ValidationInterface, T>);
    1270         [ +  - ]:           1 :         auto heap_vi = std::make_unique<std::shared_ptr<T>>(std::move(validation_interface));
    1271                 :             :         using user_type = std::shared_ptr<T>*;
    1272                 :           1 :         btck_context_options_set_validation_interface(
    1273                 :             :             get(),
    1274                 :             :             btck_ValidationInterfaceCallbacks{
    1275         [ +  - ]:           1 :                 .user_data = heap_vi.release(),
    1276         [ +  - ]:           2 :                 .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
    1277         [ +  - ]:           6 :                 .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); },
    1278   [ #  #  #  # ]:           0 :                 .pow_valid_block = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->PowValidBlock(BlockTreeEntry{entry}, Block{block}); },
    1279         [ +  - ]:           4 :                 .block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },
    1280         [ #  # ]:           0 :                 .block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },
    1281                 :             :             });
    1282                 :           1 :     }
    1283                 :             : };
    1284                 :             : 
    1285   [ +  -  +  -  :          22 : class Context : public Handle<btck_Context, btck_context_copy, btck_context_destroy>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
    1286                 :             : {
    1287                 :             : public:
    1288                 :          11 :     Context(ContextOptions& opts)
    1289                 :          11 :         : Handle{btck_context_create(opts.get())} {}
    1290                 :             : 
    1291                 :           4 :     Context()
    1292   [ +  -  +  -  :           8 :         : Handle{btck_context_create(ContextOptions{}.get())} {}
                   +  - ]
    1293                 :             : 
    1294                 :           1 :     bool interrupt()
    1295                 :             :     {
    1296   [ +  -  +  - ]:           1 :         return btck_context_interrupt(get()) == 0;
    1297                 :             :     }
    1298                 :             : };
    1299                 :             : 
    1300   [ +  -  -  -  :          24 : class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
           - ][ #  #  #  
                #  #  # ]
    1301                 :             : {
    1302                 :             : public:
    1303                 :          16 :     ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)
    1304                 :          16 :         : UniqueHandle{btck_chainstate_manager_options_create(
    1305                 :          16 :               context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}
    1306                 :             :     {
    1307                 :          12 :     }
    1308                 :             : 
    1309                 :           1 :     void SetWorkerThreads(int worker_threads)
    1310                 :             :     {
    1311         [ +  - ]:           1 :         btck_chainstate_manager_options_set_worker_threads_num(get(), worker_threads);
    1312                 :           1 :     }
    1313                 :             : 
    1314                 :           2 :     bool SetDatabaseCacheBytes(uint64_t database_cache_bytes)
    1315                 :             :     {
    1316   [ +  -  +  -  :           2 :         return btck_chainstate_manager_options_set_database_cache_bytes(get(), database_cache_bytes) == 0;
                   +  - ]
    1317                 :             :     }
    1318                 :             : 
    1319                 :           6 :     bool SetWipeDbs(bool wipe_block_tree, bool wipe_chainstate)
    1320                 :             :     {
    1321   [ +  -  +  -  :           6 :         return btck_chainstate_manager_options_set_wipe_dbs(get(), wipe_block_tree, wipe_chainstate) == 0;
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
    1322                 :             :     }
    1323                 :             : 
    1324                 :           3 :     void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)
    1325                 :             :     {
    1326         [ +  - ]:           3 :         btck_chainstate_manager_options_update_block_tree_db_in_memory(get(), block_tree_db_in_memory);
    1327                 :           3 :     }
    1328                 :             : 
    1329                 :           3 :     void UpdateChainstateDbInMemory(bool chainstate_db_in_memory)
    1330                 :             :     {
    1331         [ +  - ]:           3 :         btck_chainstate_manager_options_update_chainstate_db_in_memory(get(), chainstate_db_in_memory);
    1332                 :           3 :     }
    1333                 :             : };
    1334                 :             : 
    1335                 :             : class ChainView : public View<btck_Chain>
    1336                 :             : {
    1337                 :             : public:
    1338                 :         538 :     explicit ChainView(const btck_Chain* ptr) : View{ptr} {}
    1339                 :             : 
    1340                 :           1 :     int32_t Height() const
    1341                 :             :     {
    1342         [ +  - ]:           1 :         return btck_chain_get_height(get());
    1343                 :             :     }
    1344                 :             : 
    1345                 :         291 :     int32_t CountEntries() const
    1346                 :             :     {
    1347   [ +  -  +  -  :         291 :         return btck_chain_get_height(get()) + 1;
             +  -  +  - ]
    1348                 :             :     }
    1349                 :             : 
    1350                 :        7512 :     BlockTreeEntry GetByHeight(int32_t height) const
    1351                 :             :     {
    1352                 :        7512 :         auto index{btck_chain_get_by_height(get(), height)};
    1353   [ +  +  +  - ]:        7512 :         if (!index) throw std::runtime_error("No entry in the chain at the provided height");
    1354                 :        7511 :         return index;
    1355                 :             :     }
    1356                 :             : 
    1357                 :         207 :     bool Contains(BlockTreeEntry& entry) const
    1358                 :             :     {
    1359   [ +  -  +  -  :         207 :         return btck_chain_contains(get(), entry.get());
                   +  - ]
    1360                 :             :     }
    1361                 :             : 
    1362   [ +  -  +  -  :        7859 :     MAKE_RANGE_METHOD(Entries, ChainView, &ChainView::CountEntries, &ChainView::GetByHeight, *this)
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
    1363                 :             : };
    1364                 :             : 
    1365                 :             : template <typename Derived>
    1366                 :             : class CoinApi
    1367                 :             : {
    1368                 :             : private:
    1369                 :           4 :     auto impl() const
    1370                 :             :     {
    1371                 :           4 :         return static_cast<const Derived*>(this)->get();
    1372                 :             :     }
    1373                 :             : 
    1374                 :             :     friend Derived;
    1375                 :             :     CoinApi() = default;
    1376                 :             : 
    1377                 :             : public:
    1378         [ +  - ]:           1 :     uint32_t GetConfirmationHeight() const { return btck_coin_confirmation_height(impl()); }
    1379                 :             : 
    1380         [ +  - ]:           1 :     bool IsCoinbase() const { return btck_coin_is_coinbase(impl()) == 1; }
    1381                 :             : 
    1382                 :           2 :     TransactionOutputView GetOutput() const
    1383                 :             :     {
    1384                 :           2 :         return TransactionOutputView{btck_coin_get_output(impl())};
    1385                 :             :     }
    1386                 :             : };
    1387                 :             : 
    1388                 :             : class CoinView : public View<btck_Coin>, public CoinApi<CoinView>
    1389                 :             : {
    1390                 :             : public:
    1391                 :          24 :     explicit CoinView(const btck_Coin* ptr) : View{ptr} {}
    1392                 :             : };
    1393                 :             : 
    1394   [ +  -  +  -  :          10 : class Coin : public Handle<btck_Coin, btck_coin_copy, btck_coin_destroy>, public CoinApi<Coin>
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
    1395                 :             : {
    1396                 :             : public:
    1397                 :             :     Coin(btck_Coin* coin) : Handle{coin} {}
    1398                 :             : 
    1399   [ +  -  +  - ]:           2 :     Coin(const CoinView& view) : Handle{view} {}
    1400                 :             : };
    1401                 :             : 
    1402                 :             : template <typename Derived>
    1403                 :             : class TransactionSpentOutputsApi
    1404                 :             : {
    1405                 :             : private:
    1406                 :          34 :     auto impl() const
    1407                 :             :     {
    1408                 :          34 :         return static_cast<const Derived*>(this)->get();
    1409                 :             :     }
    1410                 :             : 
    1411                 :             :     friend Derived;
    1412                 :             :     TransactionSpentOutputsApi() = default;
    1413                 :             : 
    1414                 :             : public:
    1415                 :          22 :     size_t Count() const
    1416                 :             :     {
    1417   [ +  -  +  -  :          22 :         return btck_transaction_spent_outputs_count(impl());
                   +  - ]
    1418                 :             :     }
    1419                 :             : 
    1420                 :          12 :     CoinView GetCoin(size_t index) const
    1421                 :             :     {
    1422                 :          12 :         return CoinView{btck_transaction_spent_outputs_get_coin_at(impl(), index)};
    1423                 :             :     }
    1424                 :             : 
    1425   [ +  -  +  - ]:          31 :     MAKE_RANGE_METHOD(Coins, Derived, &TransactionSpentOutputsApi<Derived>::Count, &TransactionSpentOutputsApi<Derived>::GetCoin, *static_cast<const Derived*>(this))
    1426                 :             : };
    1427                 :             : 
    1428                 :             : class TransactionSpentOutputsView : public View<btck_TransactionSpentOutputs>, public TransactionSpentOutputsApi<TransactionSpentOutputsView>
    1429                 :             : {
    1430                 :             : public:
    1431                 :          24 :     explicit TransactionSpentOutputsView(const btck_TransactionSpentOutputs* ptr) : View{ptr} {}
    1432                 :             : };
    1433                 :             : 
    1434   [ +  -  +  -  :          10 : class TransactionSpentOutputs : public Handle<btck_TransactionSpentOutputs, btck_transaction_spent_outputs_copy, btck_transaction_spent_outputs_destroy>,
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
    1435                 :             :                                 public TransactionSpentOutputsApi<TransactionSpentOutputs>
    1436                 :             : {
    1437                 :             : public:
    1438                 :             :     TransactionSpentOutputs(btck_TransactionSpentOutputs* transaction_spent_outputs) : Handle{transaction_spent_outputs} {}
    1439                 :             : 
    1440   [ +  -  +  - ]:           2 :     TransactionSpentOutputs(const TransactionSpentOutputsView& view) : Handle{view} {}
    1441                 :             : };
    1442                 :             : 
    1443   [ +  -  +  -  :          12 : class BlockSpentOutputs : public Handle<btck_BlockSpentOutputs, btck_block_spent_outputs_copy, btck_block_spent_outputs_destroy>
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
                -  +  - ]
    1444                 :             : {
    1445                 :             : public:
    1446                 :           5 :     BlockSpentOutputs(btck_BlockSpentOutputs* block_spent_outputs)
    1447                 :           9 :         : Handle{block_spent_outputs}
    1448                 :             :     {
    1449                 :             :     }
    1450                 :             : 
    1451                 :          25 :     size_t Count() const
    1452                 :             :     {
    1453   [ +  -  +  -  :          25 :         return btck_block_spent_outputs_count(get());
          +  -  +  -  +  
                -  +  - ]
    1454                 :             :     }
    1455                 :             : 
    1456                 :          12 :     TransactionSpentOutputsView GetTxSpentOutputs(size_t tx_undo_index) const
    1457                 :             :     {
    1458                 :          12 :         return TransactionSpentOutputsView{btck_block_spent_outputs_get_transaction_spent_outputs_at(get(), tx_undo_index)};
    1459                 :             :     }
    1460                 :             : 
    1461   [ +  -  +  - ]:          31 :     MAKE_RANGE_METHOD(TxsSpentOutputs, BlockSpentOutputs, &BlockSpentOutputs::Count, &BlockSpentOutputs::GetTxSpentOutputs, *this)
    1462                 :             : };
    1463                 :             : 
    1464   [ +  -  +  -  :          24 : class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
          +  -  +  -  +  
             -  +  -  +  
              - ][ #  # ]
    1465                 :             : {
    1466                 :             : public:
    1467                 :          12 :     ChainMan(const Context& context, const ChainstateManagerOptions& chainman_opts)
    1468                 :          12 :         : UniqueHandle{btck_chainstate_manager_create(chainman_opts.get())}
    1469                 :             :     {
    1470                 :          12 :     }
    1471                 :             : 
    1472                 :           2 :     bool ImportBlocks(const std::span<const std::string> paths)
    1473                 :             :     {
    1474                 :           2 :         std::vector<const char*> c_paths;
    1475                 :           2 :         std::vector<size_t> c_paths_lens;
    1476         [ +  - ]:           2 :         c_paths.reserve(paths.size());
    1477         [ +  - ]:           2 :         c_paths_lens.reserve(paths.size());
    1478         [ +  + ]:           3 :         for (const auto& path : paths) {
    1479         [ +  - ]:           1 :             c_paths.push_back(path.c_str());
    1480   [ -  +  +  - ]:           1 :             c_paths_lens.push_back(path.length());
    1481                 :             :         }
    1482                 :             : 
    1483   [ -  +  +  - ]:           2 :         return btck_chainstate_manager_import_blocks(get(), c_paths.data(), c_paths_lens.data(), c_paths.size()) == 0;
    1484                 :           2 :     }
    1485                 :             : 
    1486                 :         418 :     bool ProcessBlock(const Block& block, bool* new_block)
    1487                 :             :     {
    1488                 :         418 :         int _new_block;
    1489                 :         418 :         int res = btck_chainstate_manager_process_block(get(), block.get(), &_new_block);
    1490         [ +  - ]:         418 :         if (new_block) *new_block = _new_block == 1;
    1491                 :         418 :         return res == 0;
    1492                 :             :     }
    1493                 :             : 
    1494                 :         208 :     BlockValidationState ProcessBlockHeader(const BlockHeader& header)
    1495                 :             :     {
    1496                 :         208 :         auto state = btck_chainstate_manager_process_block_header(get(), header.get());
    1497                 :         208 :         return BlockValidationState{state};
    1498                 :             :     }
    1499                 :             : 
    1500                 :         269 :     ChainView GetChain() const
    1501                 :             :     {
    1502                 :         269 :         return ChainView{btck_chainstate_manager_get_active_chain(get())};
    1503                 :             :     }
    1504                 :             : 
    1505                 :         207 :     std::optional<BlockTreeEntry> GetBlockTreeEntry(const BlockHash& block_hash) const
    1506                 :             :     {
    1507                 :         207 :         auto entry{btck_chainstate_manager_get_block_tree_entry_by_hash(get(), block_hash.get())};
    1508         [ -  + ]:         207 :         if (!entry) return std::nullopt;
    1509                 :         207 :         return entry;
    1510                 :             :     }
    1511                 :             : 
    1512                 :         206 :     BlockTreeEntry GetBestEntry() const
    1513                 :             :     {
    1514                 :         206 :         return btck_chainstate_manager_get_best_entry(get());
    1515                 :             :     }
    1516                 :             : 
    1517                 :        6676 :     std::optional<Block> ReadBlock(const BlockTreeEntry& entry) const
    1518                 :             :     {
    1519                 :        6676 :         auto block{btck_block_read(get(), entry.get())};
    1520         [ +  + ]:        6676 :         if (!block) return std::nullopt;
    1521                 :        6675 :         return block;
    1522                 :             :     }
    1523                 :             : 
    1524                 :           5 :     BlockSpentOutputs ReadBlockSpentOutputs(const BlockTreeEntry& entry) const
    1525                 :             :     {
    1526                 :           5 :         return btck_block_spent_outputs_read(get(), entry.get());
    1527                 :             :     }
    1528                 :             : };
    1529                 :             : 
    1530                 :           5 : inline void set_mock_time(std::chrono::seconds timestamp)
    1531                 :             : {
    1532         [ +  + ]:           5 :     if (btck_set_mock_time(timestamp.count()) != 0) {
    1533         [ +  - ]:           2 :         throw std::runtime_error("timestamp out of range");
    1534                 :             :     }
    1535                 :           3 : }
    1536                 :             : 
    1537                 :             : } // namespace btck
    1538                 :             : 
    1539                 :             : #endif // BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
        

Generated by: LCOV version 2.0-1