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 : 17443 : T check(T ptr)
169 : : {
170 [ + + ]: 17443 : if (ptr == nullptr) {
171 [ + - ]: 14 : throw std::runtime_error("failed to instantiate btck object");
172 : : }
173 : 17429 : 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 : 524 : std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, btck_WriteBytes, void*))
279 : : {
280 : 524 : std::vector<std::byte> bytes;
281 [ - - ]: 0 : struct UserData {
282 : : std::vector<std::byte>* bytes;
283 : : std::exception_ptr exception;
284 : : };
285 [ + - ]: 524 : UserData user_data = UserData{.bytes = &bytes, .exception = nullptr};
286 : :
287 : 1801 : constexpr auto const write = +[](const void* buffer, size_t len, void* user_data) -> int {
288 : 1277 : auto& data = *reinterpret_cast<UserData*>(user_data);
289 : 1277 : auto& bytes = *data.bytes;
290 : : try {
291 : 1277 : auto const* first = static_cast<const std::byte*>(buffer);
292 [ + - + - : 1277 : auto const* last = first + len;
+ - ]
293 [ + - + - : 1277 : 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 [ + - - + ]: 524 : if (to_bytes(object, write, &user_data) != 0) {
302 : 0 : std::rethrow_exception(user_data.exception);
303 : : }
304 [ - + ]: 524 : return bytes;
305 : 524 : }
306 : :
307 : : template <typename CType>
308 : : class View
309 : : {
310 : : protected:
311 : : const CType* m_ptr;
312 : :
313 : : public:
314 : 23910 : 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 : 10678 : 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 : 16 : DestroyFunc(m_ptr);
345 [ + - + - : 16 : m_ptr = std::exchange(other.m_ptr, nullptr);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
346 : : return *this;
347 : : }
348 : :
349 : : template <typename ViewType>
350 : : requires std::derived_from<ViewType, View<CType>>
351 : 558 : Handle(const ViewType& view)
352 : 558 : : Handle{CopyFunc(view.get())}
353 : : {
354 : 558 : }
355 : :
356 : 74 : ~Handle() { DestroyFunc(m_ptr); }
357 : :
358 [ + - + - : 127 : CType* get() { return m_ptr; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
359 : 20 : const CType* get() const { return m_ptr; }
360 : : };
361 : :
362 : : template <typename CType, void (*DestroyFunc)(CType*)>
363 : 111 : class UniqueHandle
364 : : {
365 : : protected:
366 : : struct Deleter {
367 : 60 : void operator()(CType* ptr) const noexcept
368 : : {
369 : : if (ptr) DestroyFunc(ptr);
370 : 60 : }
371 : : };
372 : : std::unique_ptr<CType, Deleter> m_ptr;
373 : :
374 : : public:
375 : 124 : explicit UniqueHandle(CType* ptr) : m_ptr{check(ptr)} {}
376 : :
377 [ + - ]: 30 : CType* get() { return m_ptr.get(); }
378 : 3459 : const CType* get() const { return m_ptr.get(); }
379 : : };
380 : :
381 : : class PrecomputedTransactionData;
382 : : class Transaction;
383 : : class TransactionOutput;
384 : : class BlockValidationState;
385 : :
386 : : template <typename Derived>
387 : : class ScriptPubkeyApi
388 : : {
389 : : private:
390 : 536 : auto impl() const
391 : : {
392 : 539 : return static_cast<const Derived*>(this)->get();
393 : : }
394 : :
395 : : friend Derived;
396 : : ScriptPubkeyApi() = default;
397 : :
398 : : public:
399 : : bool Verify(int64_t amount,
400 : : const Transaction& tx_to,
401 : : const PrecomputedTransactionData* precomputed_txdata,
402 : : unsigned int input_index,
403 : : ScriptVerificationFlags flags,
404 : : ScriptVerifyStatus& status) const;
405 : :
406 : 492 : std::vector<std::byte> ToBytes() const
407 : : {
408 [ + - + - : 490 : return write_bytes(impl(), btck_script_pubkey_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
409 : : }
410 : : };
411 : :
412 : : class ScriptPubkeyView : public View<btck_ScriptPubkey>, public ScriptPubkeyApi<ScriptPubkeyView>
413 : : {
414 : : public:
415 : 986 : explicit ScriptPubkeyView(const btck_ScriptPubkey* ptr) : View{ptr} {}
416 : : };
417 : :
418 [ + - + - : 23 : class ScriptPubkey : public Handle<btck_ScriptPubkey, btck_script_pubkey_copy, btck_script_pubkey_destroy>, public ScriptPubkeyApi<ScriptPubkey>
+ - + - +
- + - + -
+ - + - ]
419 : : {
420 : : public:
421 : 11 : explicit ScriptPubkey(std::span<const std::byte> raw)
422 : 11 : : Handle{btck_script_pubkey_create(raw.data(), raw.size())} {}
423 : :
424 : 2 : ScriptPubkey(const ScriptPubkeyView& view)
425 [ + - + - ]: 2 : : Handle(view) {}
426 : : };
427 : :
428 : : template <typename Derived>
429 : : class TransactionOutputApi
430 : : {
431 : : private:
432 : 790 : auto impl() const
433 : : {
434 : 790 : return static_cast<const Derived*>(this)->get();
435 : : }
436 : :
437 : : friend Derived;
438 : : TransactionOutputApi() = default;
439 : :
440 : : public:
441 : 297 : int64_t Amount() const
442 : : {
443 [ + - + - : 295 : return btck_transaction_output_get_amount(impl());
+ - + - +
- + - + -
+ - + - +
- + - ]
444 : : }
445 : :
446 : 493 : ScriptPubkeyView GetScriptPubkey() const
447 : : {
448 : 493 : return ScriptPubkeyView{btck_transaction_output_get_script_pubkey(impl())};
449 : : }
450 : : };
451 : :
452 : : class TransactionOutputView : public View<btck_TransactionOutput>, public TransactionOutputApi<TransactionOutputView>
453 : : {
454 : : public:
455 : 1024 : explicit TransactionOutputView(const btck_TransactionOutput* ptr) : View{ptr} {}
456 : : };
457 : :
458 [ + - + - : 40 : class TransactionOutput : public Handle<btck_TransactionOutput, btck_transaction_output_copy, btck_transaction_output_destroy>, public TransactionOutputApi<TransactionOutput>
+ - + - +
- + - ]
459 : : {
460 : : public:
461 : 5 : explicit TransactionOutput(const ScriptPubkey& script_pubkey, int64_t amount)
462 : 5 : : Handle{btck_transaction_output_create(script_pubkey.get(), amount)} {}
463 : :
464 : 28 : TransactionOutput(const TransactionOutputView& view)
465 [ + - + - : 28 : : Handle(view) {}
+ - ]
466 : : };
467 : :
468 : : template <typename Derived>
469 : : class TxidApi
470 : : {
471 : : private:
472 : 2509 : auto impl() const
473 : : {
474 : 2510 : return static_cast<const Derived*>(this)->get();
475 : : }
476 : :
477 : : friend Derived;
478 : : TxidApi() = default;
479 : :
480 : : public:
481 : 2472 : bool operator==(const TxidApi& other) const
482 : : {
483 [ + - + - : 2472 : return btck_txid_equals(impl(), other.impl()) != 0;
+ - + - +
- ]
484 : : }
485 : :
486 : 27 : bool operator!=(const TxidApi& other) const
487 : : {
488 [ + - + - : 27 : return btck_txid_equals(impl(), other.impl()) == 0;
+ - + - ]
489 : : }
490 : :
491 [ + - + - : 10 : std::array<std::byte, 32> ToBytes() const
+ - + - +
- + - + -
+ - + - ]
492 : : {
493 : : std::array<std::byte, 32> hash;
494 [ + - + - : 10 : btck_txid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
+ - + - +
- + - + -
+ - + - ]
495 : 9 : return hash;
496 : : }
497 : : };
498 : :
499 : : class TxidView : public View<btck_Txid>, public TxidApi<TxidView>
500 : : {
501 : : public:
502 : 5156 : explicit TxidView(const btck_Txid* ptr) : View{ptr} {}
503 : : };
504 : :
505 [ + - + - : 9 : class Txid : public Handle<btck_Txid, btck_txid_copy, btck_txid_destroy>, public TxidApi<Txid>
+ - + - +
- + - +
- ]
506 : : {
507 : : public:
508 : 2 : Txid(const TxidView& view)
509 [ + - + - ]: 2 : : Handle(view) {}
510 : : };
511 : :
512 : : template <typename Derived>
513 : : class OutPointApi
514 : : {
515 : : private:
516 : 337 : auto impl() const
517 : : {
518 : 337 : return static_cast<const Derived*>(this)->get();
519 : : }
520 : :
521 : : friend Derived;
522 : : OutPointApi() = default;
523 : :
524 : : public:
525 : 259 : uint32_t index() const
526 : : {
527 [ + - + - ]: 259 : return btck_transaction_out_point_get_index(impl());
528 : : }
529 : :
530 : 78 : TxidView Txid() const
531 : : {
532 : 78 : return TxidView{btck_transaction_out_point_get_txid(impl())};
533 : : }
534 : : };
535 : :
536 : : class OutPointView : public View<btck_TransactionOutPoint>, public OutPointApi<OutPointView>
537 : : {
538 : : public:
539 : 470 : explicit OutPointView(const btck_TransactionOutPoint* ptr) : View{ptr} {}
540 : : };
541 : :
542 [ + - + - : 8 : class OutPoint : public Handle<btck_TransactionOutPoint, btck_transaction_out_point_copy, btck_transaction_out_point_destroy>, public OutPointApi<OutPoint>
+ - + - +
- + - ]
543 : : {
544 : : public:
545 : 2 : OutPoint(const OutPointView& view)
546 [ + - + - ]: 2 : : Handle(view) {}
547 : : };
548 : :
549 : : template <typename Derived>
550 : : class TransactionInputApi
551 : : {
552 : : private:
553 : 236 : auto impl() const
554 : : {
555 : 236 : return static_cast<const Derived*>(this)->get();
556 : : }
557 : :
558 : : friend Derived;
559 : : TransactionInputApi() = default;
560 : :
561 : : public:
562 : 235 : OutPointView OutPoint() const
563 : : {
564 : 235 : return OutPointView{btck_transaction_input_get_out_point(impl())};
565 : : }
566 : :
567 : 1 : uint32_t GetSequence() const
568 : : {
569 [ + - ]: 1 : return btck_transaction_input_get_sequence(impl());
570 : : }
571 : : };
572 : :
573 : : class TransactionInputView : public View<btck_TransactionInput>, public TransactionInputApi<TransactionInputView>
574 : : {
575 : : public:
576 : 496 : explicit TransactionInputView(const btck_TransactionInput* ptr) : View{ptr} {}
577 : : };
578 : :
579 [ + - + - : 36 : class TransactionInput : public Handle<btck_TransactionInput, btck_transaction_input_copy, btck_transaction_input_destroy>, public TransactionInputApi<TransactionInput>
+ - + - +
- + - +
- ]
580 : : {
581 : : public:
582 : 28 : TransactionInput(const TransactionInputView& view)
583 [ + - + - : 28 : : Handle(view) {}
+ - ]
584 : : };
585 : :
586 : : template <typename Derived>
587 : : class TransactionApi
588 : : {
589 : : private:
590 : 3784 : auto impl() const
591 : : {
592 : 3785 : return static_cast<const Derived*>(this)->get();
593 : : }
594 : :
595 : : public:
596 : 259 : size_t CountOutputs() const
597 : : {
598 [ + - + - : 259 : return btck_transaction_count_outputs(impl());
+ - + - +
- ]
599 : : }
600 : :
601 : 256 : size_t CountInputs() const
602 : : {
603 [ + - + - : 256 : return btck_transaction_count_inputs(impl());
+ - + - +
- ]
604 : : }
605 : :
606 : 509 : TransactionOutputView GetOutput(size_t index) const
607 : : {
608 : 509 : return TransactionOutputView{btck_transaction_get_output_at(impl(), index)};
609 : : }
610 : :
611 : 248 : TransactionInputView GetInput(size_t index) const
612 : : {
613 : 248 : return TransactionInputView{btck_transaction_get_input_at(impl(), index)};
614 : : }
615 : :
616 : 1 : uint32_t GetLocktime() const
617 : : {
618 [ + - ]: 1 : return btck_transaction_get_locktime(impl());
619 : : }
620 : :
621 : 2500 : TxidView Txid() const
622 : : {
623 : 2500 : return TxidView{btck_transaction_get_txid(impl())};
624 : : }
625 : :
626 [ + - + - : 968 : MAKE_RANGE_METHOD(Outputs, Derived, &TransactionApi<Derived>::CountOutputs, &TransactionApi<Derived>::GetOutput, *static_cast<const Derived*>(this))
+ - + - ]
627 : :
628 [ + - + - ]: 729 : MAKE_RANGE_METHOD(Inputs, Derived, &TransactionApi<Derived>::CountInputs, &TransactionApi<Derived>::GetInput, *static_cast<const Derived*>(this))
629 : :
630 : 12 : std::vector<std::byte> ToBytes() const
631 : : {
632 [ + - + - : 11 : return write_bytes(impl(), btck_transaction_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - ]
633 : : }
634 : : };
635 : :
636 : : class TransactionView : public View<btck_Transaction>, public TransactionApi<TransactionView>
637 : : {
638 : : public:
639 : 5852 : explicit TransactionView(const btck_Transaction* ptr) : View{ptr} {}
640 : : };
641 : :
642 [ + - + - : 328 : class Transaction : public Handle<btck_Transaction, btck_transaction_copy, btck_transaction_destroy>, public TransactionApi<Transaction>
+ - + - +
- + - + -
- - - - -
- + - ]
643 : : {
644 : : public:
645 : 14 : explicit Transaction(std::span<const std::byte> raw_transaction)
646 : 14 : : Handle{btck_transaction_create(raw_transaction.data(), raw_transaction.size())} {}
647 : :
648 : 285 : Transaction(const TransactionView& view)
649 [ + - + - : 285 : : Handle{view} {}
+ - + - ]
650 : : };
651 : :
652 [ + - + - : 244 : class PrecomputedTransactionData : public Handle<btck_PrecomputedTransactionData, btck_precomputed_transaction_data_copy, btck_precomputed_transaction_data_destroy>
+ - + - +
- + - ]
653 : : {
654 : : public:
655 : 238 : explicit PrecomputedTransactionData(const Transaction& tx_to, std::span<const TransactionOutput> spent_outputs)
656 : 238 : : Handle{btck_precomputed_transaction_data_create(
657 : : tx_to.get(),
658 : : reinterpret_cast<const btck_TransactionOutput**>(
659 : 238 : const_cast<TransactionOutput*>(spent_outputs.data())),
660 : 238 : spent_outputs.size())} {}
661 : : };
662 : :
663 : : template <typename Derived>
664 : 47 : bool ScriptPubkeyApi<Derived>::Verify(int64_t amount,
665 : : const Transaction& tx_to,
666 : : const PrecomputedTransactionData* precomputed_txdata,
667 : : unsigned int input_index,
668 : : ScriptVerificationFlags flags,
669 : : ScriptVerifyStatus& status) const
670 : : {
671 [ + + ]: 88 : auto result = btck_script_pubkey_verify(
672 : : impl(),
673 : : amount,
674 : : tx_to.get(),
675 : 41 : precomputed_txdata ? precomputed_txdata->get() : nullptr,
676 : : input_index,
677 : : static_cast<btck_ScriptVerificationFlags>(flags),
678 : : reinterpret_cast<btck_ScriptVerifyStatus*>(&status));
679 : 47 : return result == 1;
680 : : }
681 : :
682 : : template <typename Derived>
683 : : class BlockHashApi
684 : : {
685 : : private:
686 : 222 : auto impl() const
687 : : {
688 : 224 : return static_cast<const Derived*>(this)->get();
689 : : }
690 : :
691 : : public:
692 : 207 : bool operator==(const Derived& other) const
693 : : {
694 [ + - + - : 207 : return btck_block_hash_equals(impl(), other.get()) != 0;
+ - + - ]
695 : : }
696 : :
697 : 1 : bool operator!=(const Derived& other) const
698 : : {
699 [ + - + - ]: 1 : return btck_block_hash_equals(impl(), other.get()) == 0;
700 : : }
701 : :
702 [ + - + - : 15 : std::array<std::byte, 32> ToBytes() const
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
703 : : {
704 : : std::array<std::byte, 32> hash;
705 [ + - + - : 15 : btck_block_hash_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
706 : 14 : return hash;
707 : : }
708 : : };
709 : :
710 : : class BlockHashView : public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
711 : : {
712 : : public:
713 : 416 : explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {}
714 : : };
715 : :
716 [ + - + - : 425 : class BlockHash : public Handle<btck_BlockHash, btck_block_hash_copy, btck_block_hash_destroy>, public BlockHashApi<BlockHash>
+ - + - +
- + - + -
+ - + - +
- ]
717 : : {
718 : : public:
719 : 2 : explicit BlockHash(const std::array<std::byte, 32>& hash)
720 : 2 : : Handle{btck_block_hash_create(reinterpret_cast<const unsigned char*>(hash.data()))} {}
721 : :
722 : 416 : explicit BlockHash(btck_BlockHash* hash)
723 : 832 : : Handle{hash} {}
724 : :
725 : 207 : BlockHash(const BlockHashView& view)
726 [ + - + - ]: 207 : : Handle{view} {}
727 : : };
728 : :
729 : : template <typename Derived>
730 : : class BlockHeaderApi
731 : : {
732 : : private:
733 : 428 : auto impl() const
734 : : {
735 : 428 : return static_cast<const Derived*>(this)->get();
736 : : }
737 : :
738 : : friend Derived;
739 : : BlockHeaderApi() = default;
740 : :
741 : : public:
742 : 415 : BlockHash Hash() const
743 : : {
744 : 415 : return BlockHash{btck_block_header_get_hash(impl())};
745 : : }
746 : :
747 : 1 : BlockHashView PrevHash() const
748 : : {
749 : 1 : return BlockHashView{btck_block_header_get_prev_hash(impl())};
750 : : }
751 : :
752 : 3 : uint32_t Timestamp() const
753 : : {
754 [ + - + - : 3 : return btck_block_header_get_timestamp(impl());
+ - ]
755 : : }
756 : :
757 : 3 : uint32_t Bits() const
758 : : {
759 [ + - + - : 3 : return btck_block_header_get_bits(impl());
+ - ]
760 : : }
761 : :
762 : 3 : int32_t Version() const
763 : : {
764 [ + - + - : 3 : return btck_block_header_get_version(impl());
+ - ]
765 : : }
766 : :
767 : 3 : uint32_t Nonce() const
768 : : {
769 [ + - + - : 3 : return btck_block_header_get_nonce(impl());
+ - ]
770 : : }
771 : : };
772 : :
773 : : class BlockHeaderView : public View<btck_BlockHeader>, public BlockHeaderApi<BlockHeaderView>
774 : : {
775 : : public:
776 : : explicit BlockHeaderView(const btck_BlockHeader* ptr) : View{ptr} {}
777 : : };
778 : :
779 [ + - + - : 423 : class BlockHeader : public Handle<btck_BlockHeader, btck_block_header_copy, btck_block_header_destroy>, public BlockHeaderApi<BlockHeader>
+ - + - +
- + - +
- ]
780 : : {
781 : : public:
782 : 5 : explicit BlockHeader(std::span<const std::byte> raw_header)
783 : 5 : : Handle{btck_block_header_create(reinterpret_cast<const unsigned char*>(raw_header.data()), raw_header.size())} {}
784 : :
785 : : BlockHeader(const BlockHeaderView& view)
786 : : : Handle{view} {}
787 : :
788 : 414 : BlockHeader(btck_BlockHeader* header)
789 : 828 : : Handle{header} {}
790 : : };
791 : :
792 : : class ConsensusParamsView : public View<btck_ConsensusParams>
793 : : {
794 : : public:
795 : 2 : explicit ConsensusParamsView(const btck_ConsensusParams* ptr) : View{ptr} {}
796 : : };
797 : :
798 [ + - + - : 3441 : class Block : public Handle<btck_Block, btck_block_copy, btck_block_destroy>
+ - + - -
- + - + -
+ - - - -
- ]
799 : : {
800 : : public:
801 : 638 : Block(const std::span<const std::byte> raw_block)
802 : 638 : : Handle{btck_block_create(raw_block.data(), raw_block.size())}
803 : : {
804 : 634 : }
805 : :
806 : 2788 : Block(btck_Block* block) : Handle{block} {}
807 : :
808 : 2801 : size_t CountTransactions() const
809 : : {
810 [ + - + - ]: 2801 : return btck_block_count_transactions(get());
811 : : }
812 : :
813 : 2926 : TransactionView GetTransaction(size_t index) const
814 : : {
815 : 2926 : return TransactionView{btck_block_get_transaction_at(get(), index)};
816 : : }
817 : :
818 : : bool Check(const ConsensusParamsView& consensus_params,
819 : : BlockCheckFlags flags,
820 : : BlockValidationState& state) const;
821 : :
822 [ + - + - : 8508 : MAKE_RANGE_METHOD(Transactions, Block, &Block::CountTransactions, &Block::GetTransaction, *this)
+ - + - +
- + - + -
+ - ]
823 : :
824 : 1 : BlockHash GetHash() const
825 : : {
826 : 1 : return BlockHash{btck_block_get_hash(get())};
827 : : }
828 : :
829 : 208 : BlockHeader GetHeader() const
830 : : {
831 : 208 : return BlockHeader{btck_block_get_header(get())};
832 : : }
833 : :
834 : 20 : std::vector<std::byte> ToBytes() const
835 : : {
836 [ + - + - : 19 : return write_bytes(get(), btck_block_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
837 : : }
838 : : };
839 : :
840 : : inline void logging_disable()
841 : : {
842 : : btck_logging_disable();
843 : : }
844 : :
845 : 6 : inline void logging_set_options(const btck_LoggingOptions& logging_options)
846 : : {
847 [ + - ]: 6 : btck_logging_set_options(logging_options);
848 : 5 : }
849 : :
850 : 2 : inline void logging_set_level_category(LogCategory category, LogLevel level)
851 : : {
852 : 2 : btck_logging_set_level_category(static_cast<btck_LogCategory>(category), static_cast<btck_LogLevel>(level));
853 : : }
854 : :
855 : 2 : inline void logging_enable_category(LogCategory category)
856 : : {
857 : 2 : btck_logging_enable_category(static_cast<btck_LogCategory>(category));
858 : : }
859 : :
860 : 2 : inline void logging_disable_category(LogCategory category)
861 : : {
862 : 2 : btck_logging_disable_category(static_cast<btck_LogCategory>(category));
863 : : }
864 : :
865 : : template <typename T>
866 : : concept Log = requires(T a, std::string_view message) {
867 : : { a.LogMessage(message) } -> std::same_as<void>;
868 : : };
869 : :
870 : : template <Log T>
871 [ + - - - : 17 : class Logger : UniqueHandle<btck_LoggingConnection, btck_logging_connection_destroy>
+ - + - +
- - - ][ #
# # # #
# ]
872 : : {
873 : : public:
874 : 9 : Logger(std::unique_ptr<T> log)
875 : : : UniqueHandle{btck_logging_connection_create(
876 : : +[](void* user_data, const char* message, size_t message_len) { static_cast<T*>(user_data)->LogMessage({message, message_len}); },
877 : 9 : log.release(),
878 : 9 : +[](void* user_data) { delete static_cast<T*>(user_data); })}
879 : : {
880 : 9 : }
881 : : };
882 : :
883 : : class BlockTreeEntry : public View<btck_BlockTreeEntry>
884 : : {
885 : : public:
886 : 4479 : BlockTreeEntry(const btck_BlockTreeEntry* entry)
887 : 649 : : View{entry}
888 : : {
889 : : }
890 : :
891 : 7 : bool operator==(const BlockTreeEntry& other) const
892 : : {
893 [ + - + - : 7 : return btck_block_tree_entry_equals(get(), other.get()) != 0;
+ - + - +
- + - + -
+ - + - +
- + - ]
894 : : }
895 : :
896 : 6 : std::optional<BlockTreeEntry> GetPrevious() const
897 : : {
898 : 6 : auto entry{btck_block_tree_entry_get_previous(get())};
899 [ + + ]: 6 : if (!entry) return std::nullopt;
900 : 4 : return entry;
901 : : }
902 : :
903 : 211 : int32_t GetHeight() const
904 : : {
905 [ + - + - : 211 : return btck_block_tree_entry_get_height(get());
+ - + - +
- ]
906 : : }
907 : :
908 : 207 : BlockHashView GetHash() const
909 : : {
910 : 207 : return BlockHashView{btck_block_tree_entry_get_block_hash(get())};
911 : : }
912 : :
913 : 206 : BlockHeader GetHeader() const
914 : : {
915 : 206 : return BlockHeader{btck_block_tree_entry_get_block_header(get())};
916 : : }
917 : : };
918 : :
919 : 13 : class KernelNotifications
920 : : {
921 : : public:
922 : 0 : virtual ~KernelNotifications() = default;
923 : :
924 : 427 : virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress) {}
925 : :
926 : 3 : virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
927 : :
928 : 13 : virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible) {}
929 : :
930 : 0 : virtual void WarningSetHandler(Warning warning, std::string_view message) {}
931 : :
932 : 0 : virtual void WarningUnsetHandler(Warning warning) {}
933 : :
934 : 0 : virtual void FlushErrorHandler(std::string_view error) {}
935 : :
936 : 0 : virtual void FatalErrorHandler(std::string_view error) {}
937 : : };
938 : :
939 : : template <typename Derived>
940 : : class BlockValidationStateApi
941 : : {
942 : : private:
943 : 427 : auto impl() const
944 : : {
945 : 428 : return static_cast<const Derived*>(this)->get();
946 : : }
947 : :
948 : : friend Derived;
949 : : BlockValidationStateApi() = default;
950 : :
951 : : public:
952 : 218 : ValidationMode GetValidationMode() const
953 : : {
954 [ + - + - : 218 : return static_cast<ValidationMode>(btck_block_validation_state_get_validation_mode(impl()));
+ - + - +
- + - + -
+ - ]
955 : : }
956 : :
957 : 210 : BlockValidationResult GetBlockValidationResult() const
958 : : {
959 [ + - + - : 210 : return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(impl()));
+ - + - ]
960 : : }
961 : : };
962 : :
963 : : class BlockValidationStateView : public View<btck_BlockValidationState>, public BlockValidationStateApi<BlockValidationStateView>
964 : : {
965 : : public:
966 : 5 : explicit BlockValidationStateView(const btck_BlockValidationState* ptr) : View{ptr} {}
967 : : };
968 : :
969 : 207 : class BlockValidationState : public Handle<btck_BlockValidationState, btck_block_validation_state_copy, btck_block_validation_state_destroy>, public BlockValidationStateApi<BlockValidationState>
970 : : {
971 : : public:
972 : 207 : explicit BlockValidationState() : Handle{btck_block_validation_state_create()} {}
973 : :
974 : : BlockValidationState(const BlockValidationStateView& view) : Handle{view} {}
975 : : };
976 : :
977 : 7 : inline bool Block::Check(const ConsensusParamsView& consensus_params,
978 : : BlockCheckFlags flags,
979 : : BlockValidationState& state) const
980 : : {
981 [ + - + - : 7 : return btck_block_check(get(), consensus_params.get(), static_cast<btck_BlockCheckFlags>(flags), state.get()) == 1;
+ - + - +
- + - + -
+ - + - +
- + - ]
982 : : }
983 : :
984 : 6 : class ValidationInterface
985 : : {
986 : : public:
987 : 0 : virtual ~ValidationInterface() = default;
988 : :
989 : 0 : virtual void BlockChecked(Block block, BlockValidationStateView state) {}
990 : :
991 : 0 : virtual void PowValidBlock(BlockTreeEntry entry, Block block) {}
992 : :
993 : 2 : virtual void BlockConnected(Block block, BlockTreeEntry entry) {}
994 : :
995 : 0 : virtual void BlockDisconnected(Block block, BlockTreeEntry entry) {}
996 : : };
997 : :
998 [ + - + - : 22 : class ChainParams : public Handle<btck_ChainParameters, btck_chain_parameters_copy, btck_chain_parameters_destroy>
+ - + - +
- + - + -
+ - + - ]
[ # # # # ]
999 : : {
1000 : : public:
1001 : 15 : ChainParams(ChainType chain_type)
1002 : 15 : : Handle{btck_chain_parameters_create(static_cast<btck_ChainType>(chain_type))} {}
1003 : :
1004 : 1 : ConsensusParamsView GetConsensusParams() const
1005 : : {
1006 : 1 : return ConsensusParamsView{btck_chain_parameters_get_consensus_params(get())};
1007 : : }
1008 : : };
1009 : :
1010 [ + - + - : 34 : class ContextOptions : public UniqueHandle<btck_ContextOptions, btck_context_options_destroy>
- - + - -
- + - + -
- - - - -
- ][ # # #
# # # # #
# # ]
1011 : : {
1012 : : public:
1013 : 19 : ContextOptions() : UniqueHandle{btck_context_options_create()} {}
1014 : :
1015 : 13 : void SetChainParams(ChainParams& chain_params)
1016 : : {
1017 [ + - + - ]: 13 : btck_context_options_set_chainparams(get(), chain_params.get());
[ # # ]
1018 : 13 : }
1019 : :
1020 : : template <typename T>
1021 : 13 : void SetNotifications(std::shared_ptr<T> notifications)
1022 : : {
1023 : : static_assert(std::is_base_of_v<KernelNotifications, T>);
1024 [ + - ]: 13 : auto heap_notifications = std::make_unique<std::shared_ptr<T>>(std::move(notifications));
1025 : : using user_type = std::shared_ptr<T>*;
1026 : 13 : btck_context_options_set_notifications(
1027 : : get(),
1028 : : btck_NotificationInterfaceCallbacks{
1029 [ + - ]: 13 : .user_data = heap_notifications.release(),
1030 [ + - ]: 26 : .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
1031 : 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); },
1032 : : .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); },
1033 : : .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); },
1034 : : .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}); },
1035 : : .warning_unset = +[](void* user_data, btck_Warning warning) { (*static_cast<user_type>(user_data))->WarningUnsetHandler(static_cast<Warning>(warning)); },
1036 : : .flush_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FlushErrorHandler({error, error_len}); },
1037 : : .fatal_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FatalErrorHandler({error, error_len}); },
1038 : : });
1039 : 13 : }
1040 : :
1041 : : template <typename T>
1042 : 6 : void SetValidationInterface(std::shared_ptr<T> validation_interface)
1043 : : {
1044 : : static_assert(std::is_base_of_v<ValidationInterface, T>);
1045 [ + - ]: 6 : auto heap_vi = std::make_unique<std::shared_ptr<T>>(std::move(validation_interface));
1046 : : using user_type = std::shared_ptr<T>*;
1047 : 6 : btck_context_options_set_validation_interface(
1048 : : get(),
1049 : : btck_ValidationInterfaceCallbacks{
1050 [ + - ]: 6 : .user_data = heap_vi.release(),
1051 [ + - ]: 12 : .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
1052 [ + - ]: 10 : .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); },
1053 [ # # # # ]: 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}); },
1054 [ + - ]: 8 : .block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },
1055 [ # # ]: 0 : .block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },
1056 : : });
1057 : 6 : }
1058 : : };
1059 : :
1060 [ + - + - : 25 : class Context : public Handle<btck_Context, btck_context_copy, btck_context_destroy>
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
1061 : : {
1062 : : public:
1063 : 15 : Context(ContextOptions& opts)
1064 : 15 : : Handle{btck_context_create(opts.get())} {}
1065 : :
1066 : 4 : Context()
1067 [ + - + - : 8 : : Handle{btck_context_create(ContextOptions{}.get())} {}
+ - ]
1068 : :
1069 : 1 : bool interrupt()
1070 : : {
1071 [ + - + - ]: 1 : return btck_context_interrupt(get()) == 0;
1072 : : }
1073 : : };
1074 : :
1075 [ + - - - : 32 : class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>
+ - + - -
- - - + -
- - - - -
- ][ # # #
# # # ]
1076 : : {
1077 : : public:
1078 : 20 : ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)
1079 : 20 : : UniqueHandle{btck_chainstate_manager_options_create(
1080 : 20 : context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}
1081 : : {
1082 : 16 : }
1083 : :
1084 : 6 : void SetWorkerThreads(int worker_threads)
1085 : : {
1086 [ + - ]: 6 : btck_chainstate_manager_options_set_worker_threads_num(get(), worker_threads);
1087 : 6 : }
1088 : :
1089 : 6 : bool SetWipeDbs(bool wipe_block_tree, bool wipe_chainstate)
1090 : : {
1091 [ + - + - : 6 : return btck_chainstate_manager_options_set_wipe_dbs(get(), wipe_block_tree, wipe_chainstate) == 0;
+ - + - +
- + - + -
+ - + - ]
1092 : : }
1093 : :
1094 : 2 : void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)
1095 : : {
1096 [ + - ]: 2 : btck_chainstate_manager_options_update_block_tree_db_in_memory(get(), block_tree_db_in_memory);
1097 : 2 : }
1098 : :
1099 : 2 : void UpdateChainstateDbInMemory(bool chainstate_db_in_memory)
1100 : : {
1101 [ + - ]: 2 : btck_chainstate_manager_options_update_chainstate_db_in_memory(get(), chainstate_db_in_memory);
1102 : 2 : }
1103 : : };
1104 : :
1105 : : class ChainView : public View<btck_Chain>
1106 : : {
1107 : : public:
1108 : 472 : explicit ChainView(const btck_Chain* ptr) : View{ptr} {}
1109 : :
1110 : 1 : int32_t Height() const
1111 : : {
1112 [ + - ]: 1 : return btck_chain_get_height(get());
1113 : : }
1114 : :
1115 : 258 : int CountEntries() const
1116 : : {
1117 [ + - + - : 258 : return btck_chain_get_height(get()) + 1;
+ - + - ]
1118 : : }
1119 : :
1120 : 3625 : BlockTreeEntry GetByHeight(int height) const
1121 : : {
1122 : 3625 : auto index{btck_chain_get_by_height(get(), height)};
1123 [ + + + - ]: 3625 : if (!index) throw std::runtime_error("No entry in the chain at the provided height");
1124 : 3624 : return index;
1125 : : }
1126 : :
1127 : 207 : bool Contains(BlockTreeEntry& entry) const
1128 : : {
1129 [ + - + - : 207 : return btck_chain_contains(get(), entry.get());
+ - ]
1130 : : }
1131 : :
1132 [ + - + - : 3906 : MAKE_RANGE_METHOD(Entries, ChainView, &ChainView::CountEntries, &ChainView::GetByHeight, *this)
+ - + - +
- + - + -
+ - ]
1133 : : };
1134 : :
1135 : : template <typename Derived>
1136 : : class CoinApi
1137 : : {
1138 : : private:
1139 : 5 : auto impl() const
1140 : : {
1141 : 5 : return static_cast<const Derived*>(this)->get();
1142 : : }
1143 : :
1144 : : friend Derived;
1145 : : CoinApi() = default;
1146 : :
1147 : : public:
1148 [ + - ]: 1 : uint32_t GetConfirmationHeight() const { return btck_coin_confirmation_height(impl()); }
1149 : :
1150 [ + - ]: 1 : bool IsCoinbase() const { return btck_coin_is_coinbase(impl()) == 1; }
1151 : :
1152 : 3 : TransactionOutputView GetOutput() const
1153 : : {
1154 : 3 : return TransactionOutputView{btck_coin_get_output(impl())};
1155 : : }
1156 : : };
1157 : :
1158 : : class CoinView : public View<btck_Coin>, public CoinApi<CoinView>
1159 : : {
1160 : : public:
1161 : 32 : explicit CoinView(const btck_Coin* ptr) : View{ptr} {}
1162 : : };
1163 : :
1164 [ + - + - : 9 : class Coin : public Handle<btck_Coin, btck_coin_copy, btck_coin_destroy>, public CoinApi<Coin>
+ - + - +
- + - +
- ]
1165 : : {
1166 : : public:
1167 : : Coin(btck_Coin* coin) : Handle{coin} {}
1168 : :
1169 [ + - + - ]: 2 : Coin(const CoinView& view) : Handle{view} {}
1170 : : };
1171 : :
1172 : : template <typename Derived>
1173 : : class TransactionSpentOutputsApi
1174 : : {
1175 : : private:
1176 : 39 : auto impl() const
1177 : : {
1178 : 39 : return static_cast<const Derived*>(this)->get();
1179 : : }
1180 : :
1181 : : friend Derived;
1182 : : TransactionSpentOutputsApi() = default;
1183 : :
1184 : : public:
1185 : 22 : size_t Count() const
1186 : : {
1187 [ + - + - : 23 : return btck_transaction_spent_outputs_count(impl());
+ - ]
1188 : : }
1189 : :
1190 : 16 : CoinView GetCoin(size_t index) const
1191 : : {
1192 : 16 : return CoinView{btck_transaction_spent_outputs_get_coin_at(impl(), index)};
1193 : : }
1194 : :
1195 [ + - + - ]: 36 : MAKE_RANGE_METHOD(Coins, Derived, &TransactionSpentOutputsApi<Derived>::Count, &TransactionSpentOutputsApi<Derived>::GetCoin, *static_cast<const Derived*>(this))
1196 : : };
1197 : :
1198 : : class TransactionSpentOutputsView : public View<btck_TransactionSpentOutputs>, public TransactionSpentOutputsApi<TransactionSpentOutputsView>
1199 : : {
1200 : : public:
1201 : 36 : explicit TransactionSpentOutputsView(const btck_TransactionSpentOutputs* ptr) : View{ptr} {}
1202 : : };
1203 : :
1204 [ + - + - : 9 : class TransactionSpentOutputs : public Handle<btck_TransactionSpentOutputs, btck_transaction_spent_outputs_copy, btck_transaction_spent_outputs_destroy>,
+ - + - +
- + - +
- ]
1205 : : public TransactionSpentOutputsApi<TransactionSpentOutputs>
1206 : : {
1207 : : public:
1208 : : TransactionSpentOutputs(btck_TransactionSpentOutputs* transaction_spent_outputs) : Handle{transaction_spent_outputs} {}
1209 : :
1210 [ + - + - ]: 2 : TransactionSpentOutputs(const TransactionSpentOutputsView& view) : Handle{view} {}
1211 : : };
1212 : :
1213 [ + - + - : 11 : class BlockSpentOutputs : public Handle<btck_BlockSpentOutputs, btck_block_spent_outputs_copy, btck_block_spent_outputs_destroy>
+ - + - +
- + - + -
- - + - +
- ]
1214 : : {
1215 : : public:
1216 : 5 : BlockSpentOutputs(btck_BlockSpentOutputs* block_spent_outputs)
1217 : 9 : : Handle{block_spent_outputs}
1218 : : {
1219 : : }
1220 : :
1221 : 27 : size_t Count() const
1222 : : {
1223 [ + - + - : 27 : return btck_block_spent_outputs_count(get());
+ - + - +
- + - ]
1224 : : }
1225 : :
1226 : 18 : TransactionSpentOutputsView GetTxSpentOutputs(size_t tx_undo_index) const
1227 : : {
1228 : 18 : return TransactionSpentOutputsView{btck_block_spent_outputs_get_transaction_spent_outputs_at(get(), tx_undo_index)};
1229 : : }
1230 : :
1231 [ + - + - ]: 39 : MAKE_RANGE_METHOD(TxsSpentOutputs, BlockSpentOutputs, &BlockSpentOutputs::Count, &BlockSpentOutputs::GetTxSpentOutputs, *this)
1232 : : };
1233 : :
1234 [ + - + - : 32 : class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
+ - + - +
- + - +
- ][ # # ]
1235 : : {
1236 : : public:
1237 : 16 : ChainMan(const Context& context, const ChainstateManagerOptions& chainman_opts)
1238 : 16 : : UniqueHandle{btck_chainstate_manager_create(chainman_opts.get())}
1239 : : {
1240 : 16 : }
1241 : :
1242 : 2 : bool ImportBlocks(const std::span<const std::string> paths)
1243 : : {
1244 : 2 : std::vector<const char*> c_paths;
1245 : 2 : std::vector<size_t> c_paths_lens;
1246 [ + - ]: 2 : c_paths.reserve(paths.size());
1247 [ + - ]: 2 : c_paths_lens.reserve(paths.size());
1248 [ + + ]: 3 : for (const auto& path : paths) {
1249 [ + - ]: 1 : c_paths.push_back(path.c_str());
1250 [ - + + - ]: 1 : c_paths_lens.push_back(path.length());
1251 : : }
1252 : :
1253 [ - + + - ]: 2 : return btck_chainstate_manager_import_blocks(get(), c_paths.data(), c_paths_lens.data(), c_paths.size()) == 0;
1254 : 2 : }
1255 : :
1256 : 421 : bool ProcessBlock(const Block& block, bool* new_block)
1257 : : {
1258 : 421 : int _new_block;
1259 : 421 : int res = btck_chainstate_manager_process_block(get(), block.get(), &_new_block);
1260 [ + - ]: 421 : if (new_block) *new_block = _new_block == 1;
1261 : 421 : return res == 0;
1262 : : }
1263 : :
1264 : 206 : bool ProcessBlockHeader(const BlockHeader& header, BlockValidationState& state)
1265 : : {
1266 [ + - + - ]: 206 : return btck_chainstate_manager_process_block_header(get(), header.get(), state.get()) == 0;
1267 : : }
1268 : :
1269 : 236 : ChainView GetChain() const
1270 : : {
1271 : 236 : return ChainView{btck_chainstate_manager_get_active_chain(get())};
1272 : : }
1273 : :
1274 : 207 : std::optional<BlockTreeEntry> GetBlockTreeEntry(const BlockHash& block_hash) const
1275 : : {
1276 : 207 : auto entry{btck_chainstate_manager_get_block_tree_entry_by_hash(get(), block_hash.get())};
1277 [ - + ]: 207 : if (!entry) return std::nullopt;
1278 : 207 : return entry;
1279 : : }
1280 : :
1281 : 206 : BlockTreeEntry GetBestEntry() const
1282 : : {
1283 : 206 : return btck_chainstate_manager_get_best_entry(get());
1284 : : }
1285 : :
1286 : 2789 : std::optional<Block> ReadBlock(const BlockTreeEntry& entry) const
1287 : : {
1288 : 2789 : auto block{btck_block_read(get(), entry.get())};
1289 [ + + ]: 2789 : if (!block) return std::nullopt;
1290 : 2788 : return block;
1291 : : }
1292 : :
1293 : 5 : BlockSpentOutputs ReadBlockSpentOutputs(const BlockTreeEntry& entry) const
1294 : : {
1295 : 5 : return btck_block_spent_outputs_read(get(), entry.get());
1296 : : }
1297 : : };
1298 : :
1299 : : } // namespace btck
1300 : :
1301 : : #endif // BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
|