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