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 : : template <typename T>
101 : : struct is_bitmask_enum : std::false_type {
102 : : };
103 : :
104 : : template <>
105 : : struct is_bitmask_enum<ScriptVerificationFlags> : std::true_type {
106 : : };
107 : :
108 : : template <typename T>
109 : : concept BitmaskEnum = is_bitmask_enum<T>::value;
110 : :
111 : : template <BitmaskEnum T>
112 : : constexpr T operator|(T lhs, T rhs)
113 : : {
114 : : return static_cast<T>(
115 : : static_cast<std::underlying_type_t<T>>(lhs) | static_cast<std::underlying_type_t<T>>(rhs));
116 : : }
117 : :
118 : : template <BitmaskEnum T>
119 : : constexpr T operator&(T lhs, T rhs)
120 : : {
121 : : return static_cast<T>(
122 : : static_cast<std::underlying_type_t<T>>(lhs) & static_cast<std::underlying_type_t<T>>(rhs));
123 : : }
124 : :
125 : : template <BitmaskEnum T>
126 : : constexpr T operator^(T lhs, T rhs)
127 : : {
128 : : return static_cast<T>(
129 : : static_cast<std::underlying_type_t<T>>(lhs) ^ static_cast<std::underlying_type_t<T>>(rhs));
130 : : }
131 : :
132 : : template <BitmaskEnum T>
133 : : constexpr T operator~(T value)
134 : : {
135 : : return static_cast<T>(~static_cast<std::underlying_type_t<T>>(value));
136 : : }
137 : :
138 : : template <BitmaskEnum T>
139 : : constexpr T& operator|=(T& lhs, T rhs)
140 : : {
141 : : return lhs = lhs | rhs;
142 : : }
143 : :
144 : : template <BitmaskEnum T>
145 : : constexpr T& operator&=(T& lhs, T rhs)
146 : : {
147 : : return lhs = lhs & rhs;
148 : : }
149 : :
150 : : template <BitmaskEnum T>
151 : : constexpr T& operator^=(T& lhs, T rhs)
152 : : {
153 : : return lhs = lhs ^ rhs;
154 : : }
155 : :
156 : : template <typename T>
157 : 15108 : T check(T ptr)
158 : : {
159 [ + + ]: 15108 : if (ptr == nullptr) {
160 [ + - ]: 10 : throw std::runtime_error("failed to instantiate btck object");
161 : : }
162 : 15098 : return ptr;
163 : : }
164 : :
165 : : template <typename Collection, typename ValueType>
166 : : class Iterator
167 : : {
168 : : public:
169 : : using iterator_category = std::random_access_iterator_tag;
170 : : using iterator_concept = std::random_access_iterator_tag;
171 : : using difference_type = std::ptrdiff_t;
172 : : using value_type = ValueType;
173 : :
174 : : private:
175 : : const Collection* m_collection;
176 : : size_t m_idx;
177 : :
178 : : public:
179 : : Iterator() = default;
180 : : Iterator(const Collection* ptr) : m_collection{ptr}, m_idx{0} {}
181 : 7184 : Iterator(const Collection* ptr, size_t idx) : m_collection{ptr}, m_idx{idx} {}
182 : :
183 : : // This is just a view, so return a copy.
184 [ + - + - : 6819 : auto operator*() const { return (*m_collection)[m_idx]; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
185 : : auto operator->() const { return (*m_collection)[m_idx]; }
186 : :
187 : 6769 : auto& operator++() { m_idx++; return *this; }
188 : 6 : auto operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
189 : :
190 : 224 : auto& operator--() { m_idx--; return *this; }
191 : 6 : auto operator--(int) { auto temp = *this; --m_idx; return temp; }
192 : :
193 : 6 : auto& operator+=(difference_type n) { m_idx += n; return *this; }
194 : 6 : auto& operator-=(difference_type n) { m_idx -= n; return *this; }
195 : :
196 [ + - + - : 6 : auto operator+(difference_type n) const { return Iterator(m_collection, m_idx + n); }
+ - + - +
- + - ]
197 : : auto operator-(difference_type n) const { return Iterator(m_collection, m_idx - n); }
198 : :
199 [ + - + - : 6 : auto operator-(const Iterator& other) const { return static_cast<difference_type>(m_idx) - static_cast<difference_type>(other.m_idx); }
+ - + - +
- + - ]
200 : :
201 : 6 : ValueType operator[](difference_type n) const { return (*m_collection)[m_idx + n]; }
202 : :
203 [ + - + - : 24 : auto operator<=>(const Iterator& other) const { return m_idx <=> other.m_idx; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ]
204 : :
205 [ + - + - : 10283 : bool operator==(const Iterator& other) const { return m_collection == other.m_collection && m_idx == other.m_idx; }
+ - + - +
- - + + +
+ - + + +
- + - + -
- + + + +
- + + + -
+ - + - -
+ + + + -
+ + + - +
- + - - +
+ + + - +
+ + - + -
+ - - + +
+ + - + +
+ - + - +
- - + + +
+ - + + +
- + + + -
+ + + - +
+ + - + +
+ - + + +
- + + + -
+ + + - +
+ + - + +
+ - + + +
- + - + -
+ + + - +
+ ]
206 : :
207 : : private:
208 [ + - + - : 6 : friend Iterator operator+(difference_type n, const Iterator& it) { return it + n; }
+ - + - +
- + - ]
209 : : };
210 : :
211 : : template <typename Container, typename SizeFunc, typename GetFunc>
212 : : concept IndexedContainer = requires(const Container& c, SizeFunc size_func, GetFunc get_func, std::size_t i) {
213 : : { std::invoke(size_func, c) } -> std::convertible_to<std::size_t>;
214 : : { std::invoke(get_func, c, i) }; // Return type is deduced
215 : : };
216 : :
217 : : template <typename Container, auto SizeFunc, auto GetFunc>
218 : : requires IndexedContainer<Container, decltype(SizeFunc), decltype(GetFunc)>
219 : : class Range
220 : : {
221 : : public:
222 : : using value_type = std::invoke_result_t<decltype(GetFunc), const Container&, size_t>;
223 : : using difference_type = std::ptrdiff_t;
224 : : using iterator = Iterator<Range, value_type>;
225 : : using const_iterator = iterator;
226 : :
227 : : private:
228 : : const Container* m_container;
229 : :
230 : : public:
231 : 3290 : explicit Range(const Container& container) : m_container(&container)
232 : : {
233 : : static_assert(std::ranges::random_access_range<Range>);
234 : : }
235 : :
236 [ + - + - : 539 : iterator begin() const { return iterator(this, 0); }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ]
237 : 3337 : iterator end() const { return iterator(this, size()); }
238 : :
239 [ + - + - : 6 : const_iterator cbegin() const { return begin(); }
+ - + - +
- + - ]
240 [ + - + - : 6 : const_iterator cend() const { return end(); }
+ - + - +
- + - ]
241 : :
242 : 7212 : size_t size() const { return std::invoke(SizeFunc, *m_container); }
243 : :
244 [ + - + - : 6 : bool empty() const { return size() == 0; }
+ - + - +
- + - ]
245 : :
246 : 14618 : value_type operator[](size_t index) const { return std::invoke(GetFunc, *m_container, index); }
247 : :
248 : 18 : value_type at(size_t index) const
249 : : {
250 [ + + ]: 18 : if (index >= size()) {
251 [ + - ]: 6 : throw std::out_of_range("Index out of range");
252 : : }
253 : 12 : return (*this)[index];
254 : : }
255 : :
256 : 7 : value_type front() const { return (*this)[0]; }
257 : 9 : value_type back() const { return (*this)[size() - 1]; }
258 : : };
259 : :
260 : : #define MAKE_RANGE_METHOD(method_name, ContainerType, SizeFunc, GetFunc, container_expr) \
261 : : auto method_name() const & { \
262 : : return Range<ContainerType, SizeFunc, GetFunc>{container_expr}; \
263 : : } \
264 : : auto method_name() const && = delete;
265 : :
266 : : template <typename T>
267 : 524 : std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, btck_WriteBytes, void*))
268 : : {
269 : 524 : std::vector<std::byte> bytes;
270 [ - - ]: 0 : struct UserData {
271 : : std::vector<std::byte>* bytes;
272 : : std::exception_ptr exception;
273 : : };
274 [ + - ]: 524 : UserData user_data = UserData{.bytes = &bytes, .exception = nullptr};
275 : :
276 : 1801 : constexpr auto const write = +[](const void* buffer, size_t len, void* user_data) -> int {
277 : 1277 : auto& data = *reinterpret_cast<UserData*>(user_data);
278 : 1277 : auto& bytes = *data.bytes;
279 : : try {
280 : 1277 : auto const* first = static_cast<const std::byte*>(buffer);
281 [ + - + - : 1277 : auto const* last = first + len;
+ - ]
282 [ + - + - : 1277 : bytes.insert(bytes.end(), first, last);
+ - ]
283 : : return 0;
284 : 0 : } catch (...) {
285 [ - - - - : 0 : data.exception = std::current_exception();
- - ]
286 : : return -1;
287 : : }
288 : : };
289 : :
290 [ + - - + ]: 524 : if (to_bytes(object, write, &user_data) != 0) {
291 : 0 : std::rethrow_exception(user_data.exception);
292 : : }
293 [ - + ]: 524 : return bytes;
294 : 524 : }
295 : :
296 : : template <typename CType>
297 : : class View
298 : : {
299 : : protected:
300 : : const CType* m_ptr;
301 : :
302 : : public:
303 : 22250 : explicit View(const CType* ptr) : m_ptr{check(ptr)} {}
304 : :
305 [ + - + - : 242 : const CType* get() const { return m_ptr; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
306 : : };
307 : :
308 : : template <typename CType, CType* (*CopyFunc)(const CType*), void (*DestroyFunc)(CType*)>
309 : : class Handle
310 : : {
311 : : protected:
312 : : CType* m_ptr;
313 : :
314 : : public:
315 : 7726 : explicit Handle(CType* ptr) : m_ptr{check(ptr)} {}
316 : :
317 : : // Copy constructors
318 : 75 : Handle(const Handle& other)
319 : 75 : : m_ptr{check(CopyFunc(other.m_ptr))} {}
320 : 15 : Handle& operator=(const Handle& other)
321 : : {
322 [ + - ]: 15 : if (this != &other) {
323 : 15 : Handle temp(other);
324 : 15 : std::swap(m_ptr, temp.m_ptr);
325 : 15 : }
326 : 15 : return *this;
327 : : }
328 : :
329 : : // Move constructors
330 : 48 : Handle(Handle&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
331 : 15 : Handle& operator=(Handle&& other) noexcept
332 : : {
333 : 15 : DestroyFunc(m_ptr);
334 [ + - + - : 15 : m_ptr = std::exchange(other.m_ptr, nullptr);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
335 : : return *this;
336 : : }
337 : :
338 : : template <typename ViewType>
339 : : requires std::derived_from<ViewType, View<CType>>
340 : 352 : Handle(const ViewType& view)
341 : 352 : : Handle{CopyFunc(view.get())}
342 : : {
343 : 352 : }
344 : :
345 : 44 : ~Handle() { DestroyFunc(m_ptr); }
346 : :
347 [ + - + - : 113 : CType* get() { return m_ptr; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ]
348 : 14 : const CType* get() const { return m_ptr; }
349 : : };
350 : :
351 : : template <typename CType, void (*DestroyFunc)(CType*)>
352 : 72 : class UniqueHandle
353 : : {
354 : : protected:
355 : : struct Deleter {
356 : 38 : void operator()(CType* ptr) const noexcept
357 : : {
358 : : if (ptr) DestroyFunc(ptr);
359 : 38 : }
360 : : };
361 : : std::unique_ptr<CType, Deleter> m_ptr;
362 : :
363 : : public:
364 : 80 : explicit UniqueHandle(CType* ptr) : m_ptr{check(ptr)} {}
365 : :
366 [ + - ]: 2 : CType* get() { return m_ptr.get(); }
367 : 2835 : const CType* get() const { return m_ptr.get(); }
368 : : };
369 : :
370 : : class PrecomputedTransactionData;
371 : : class Transaction;
372 : : class TransactionOutput;
373 : :
374 : : template <typename Derived>
375 : : class ScriptPubkeyApi
376 : : {
377 : : private:
378 : 536 : auto impl() const
379 : : {
380 : 539 : return static_cast<const Derived*>(this)->get();
381 : : }
382 : :
383 : : friend Derived;
384 : : ScriptPubkeyApi() = default;
385 : :
386 : : public:
387 : : bool Verify(int64_t amount,
388 : : const Transaction& tx_to,
389 : : const PrecomputedTransactionData* precomputed_txdata,
390 : : unsigned int input_index,
391 : : ScriptVerificationFlags flags,
392 : : ScriptVerifyStatus& status) const;
393 : :
394 : 492 : std::vector<std::byte> ToBytes() const
395 : : {
396 [ + - + - : 492 : return write_bytes(impl(), btck_script_pubkey_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
397 : : }
398 : : };
399 : :
400 : : class ScriptPubkeyView : public View<btck_ScriptPubkey>, public ScriptPubkeyApi<ScriptPubkeyView>
401 : : {
402 : : public:
403 : 986 : explicit ScriptPubkeyView(const btck_ScriptPubkey* ptr) : View{ptr} {}
404 : : };
405 : :
406 [ + - + - : 23 : class ScriptPubkey : public Handle<btck_ScriptPubkey, btck_script_pubkey_copy, btck_script_pubkey_destroy>, public ScriptPubkeyApi<ScriptPubkey>
+ - + - +
- + - + -
+ - + - ]
407 : : {
408 : : public:
409 : 11 : explicit ScriptPubkey(std::span<const std::byte> raw)
410 : 11 : : Handle{btck_script_pubkey_create(raw.data(), raw.size())} {}
411 : :
412 : 2 : ScriptPubkey(const ScriptPubkeyView& view)
413 [ + - + - ]: 2 : : Handle(view) {}
414 : : };
415 : :
416 : : template <typename Derived>
417 : : class TransactionOutputApi
418 : : {
419 : : private:
420 : 790 : auto impl() const
421 : : {
422 : 790 : return static_cast<const Derived*>(this)->get();
423 : : }
424 : :
425 : : friend Derived;
426 : : TransactionOutputApi() = default;
427 : :
428 : : public:
429 : 297 : int64_t Amount() const
430 : : {
431 [ + - + - : 295 : return btck_transaction_output_get_amount(impl());
+ - + - +
- + - + -
+ - + - +
- + - ]
432 : : }
433 : :
434 : 493 : ScriptPubkeyView GetScriptPubkey() const
435 : : {
436 : 493 : return ScriptPubkeyView{btck_transaction_output_get_script_pubkey(impl())};
437 : : }
438 : : };
439 : :
440 : : class TransactionOutputView : public View<btck_TransactionOutput>, public TransactionOutputApi<TransactionOutputView>
441 : : {
442 : : public:
443 : 1028 : explicit TransactionOutputView(const btck_TransactionOutput* ptr) : View{ptr} {}
444 : : };
445 : :
446 [ + - + - : 40 : class TransactionOutput : public Handle<btck_TransactionOutput, btck_transaction_output_copy, btck_transaction_output_destroy>, public TransactionOutputApi<TransactionOutput>
+ - + - +
- + - ]
447 : : {
448 : : public:
449 : 5 : explicit TransactionOutput(const ScriptPubkey& script_pubkey, int64_t amount)
450 : 5 : : Handle{btck_transaction_output_create(script_pubkey.get(), amount)} {}
451 : :
452 : 28 : TransactionOutput(const TransactionOutputView& view)
453 [ + - + - : 28 : : Handle(view) {}
+ - ]
454 : : };
455 : :
456 : : template <typename Derived>
457 : : class TxidApi
458 : : {
459 : : private:
460 : 2500 : auto impl() const
461 : : {
462 : 2500 : return static_cast<const Derived*>(this)->get();
463 : : }
464 : :
465 : : friend Derived;
466 : : TxidApi() = default;
467 : :
468 : : public:
469 : 2472 : bool operator==(const TxidApi& other) const
470 : : {
471 [ + - + - : 2472 : return btck_txid_equals(impl(), other.impl()) != 0;
+ - + - +
- ]
472 : : }
473 : :
474 : 27 : bool operator!=(const TxidApi& other) const
475 : : {
476 [ + - + - : 27 : return btck_txid_equals(impl(), other.impl()) == 0;
+ - + - ]
477 : : }
478 : :
479 [ + - ]: 1 : std::array<std::byte, 32> ToBytes() const
480 : : {
481 : : std::array<std::byte, 32> hash;
482 [ + - ]: 1 : btck_txid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
483 : 1 : return hash;
484 : : }
485 : : };
486 : :
487 : : class TxidView : public View<btck_Txid>, public TxidApi<TxidView>
488 : : {
489 : : public:
490 : 5156 : explicit TxidView(const btck_Txid* ptr) : View{ptr} {}
491 : : };
492 : :
493 [ + - + - : 9 : class Txid : public Handle<btck_Txid, btck_txid_copy, btck_txid_destroy>, public TxidApi<Txid>
+ - + - +
- + - +
- ]
494 : : {
495 : : public:
496 : 2 : Txid(const TxidView& view)
497 [ + - + - ]: 2 : : Handle(view) {}
498 : : };
499 : :
500 : : template <typename Derived>
501 : : class OutPointApi
502 : : {
503 : : private:
504 : 337 : auto impl() const
505 : : {
506 : 337 : return static_cast<const Derived*>(this)->get();
507 : : }
508 : :
509 : : friend Derived;
510 : : OutPointApi() = default;
511 : :
512 : : public:
513 : 259 : uint32_t index() const
514 : : {
515 [ + - + - ]: 259 : return btck_transaction_out_point_get_index(impl());
516 : : }
517 : :
518 : 78 : TxidView Txid() const
519 : : {
520 : 78 : return TxidView{btck_transaction_out_point_get_txid(impl())};
521 : : }
522 : : };
523 : :
524 : : class OutPointView : public View<btck_TransactionOutPoint>, public OutPointApi<OutPointView>
525 : : {
526 : : public:
527 : 470 : explicit OutPointView(const btck_TransactionOutPoint* ptr) : View{ptr} {}
528 : : };
529 : :
530 [ + - + - : 8 : class OutPoint : public Handle<btck_TransactionOutPoint, btck_transaction_out_point_copy, btck_transaction_out_point_destroy>, public OutPointApi<OutPoint>
+ - + - +
- + - ]
531 : : {
532 : : public:
533 : 2 : OutPoint(const OutPointView& view)
534 [ + - + - ]: 2 : : Handle(view) {}
535 : : };
536 : :
537 : : template <typename Derived>
538 : : class TransactionInputApi
539 : : {
540 : : private:
541 : 235 : auto impl() const
542 : : {
543 : 235 : return static_cast<const Derived*>(this)->get();
544 : : }
545 : :
546 : : friend Derived;
547 : : TransactionInputApi() = default;
548 : :
549 : : public:
550 : 235 : OutPointView OutPoint() const
551 : : {
552 : 235 : return OutPointView{btck_transaction_input_get_out_point(impl())};
553 : : }
554 : : };
555 : :
556 : : class TransactionInputView : public View<btck_TransactionInput>, public TransactionInputApi<TransactionInputView>
557 : : {
558 : : public:
559 : 498 : explicit TransactionInputView(const btck_TransactionInput* ptr) : View{ptr} {}
560 : : };
561 : :
562 [ + - + - : 36 : class TransactionInput : public Handle<btck_TransactionInput, btck_transaction_input_copy, btck_transaction_input_destroy>, public TransactionInputApi<TransactionInput>
+ - + - +
- + - +
- ]
563 : : {
564 : : public:
565 : 28 : TransactionInput(const TransactionInputView& view)
566 [ + - + - : 28 : : Handle(view) {}
+ - ]
567 : : };
568 : :
569 : : template <typename Derived>
570 : : class TransactionApi
571 : : {
572 : : private:
573 : 3788 : auto impl() const
574 : : {
575 : 3789 : return static_cast<const Derived*>(this)->get();
576 : : }
577 : :
578 : : public:
579 : 260 : size_t CountOutputs() const
580 : : {
581 [ + - + - : 260 : return btck_transaction_count_outputs(impl());
+ - + - +
- ]
582 : : }
583 : :
584 : 257 : size_t CountInputs() const
585 : : {
586 [ + - + - : 257 : return btck_transaction_count_inputs(impl());
+ - + - +
- ]
587 : : }
588 : :
589 : 511 : TransactionOutputView GetOutput(size_t index) const
590 : : {
591 : 511 : return TransactionOutputView{btck_transaction_get_output_at(impl(), index)};
592 : : }
593 : :
594 : 249 : TransactionInputView GetInput(size_t index) const
595 : : {
596 : 249 : return TransactionInputView{btck_transaction_get_input_at(impl(), index)};
597 : : }
598 : :
599 : 2500 : TxidView Txid() const
600 : : {
601 : 2500 : return TxidView{btck_transaction_get_txid(impl())};
602 : : }
603 : :
604 [ + - + - : 971 : MAKE_RANGE_METHOD(Outputs, Derived, &TransactionApi<Derived>::CountOutputs, &TransactionApi<Derived>::GetOutput, *static_cast<const Derived*>(this))
+ - + - ]
605 : :
606 [ + - + - ]: 732 : MAKE_RANGE_METHOD(Inputs, Derived, &TransactionApi<Derived>::CountInputs, &TransactionApi<Derived>::GetInput, *static_cast<const Derived*>(this))
607 : :
608 : 12 : std::vector<std::byte> ToBytes() const
609 : : {
610 [ + - + - : 12 : return write_bytes(impl(), btck_transaction_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - ]
611 : : }
612 : : };
613 : :
614 : : class TransactionView : public View<btck_Transaction>, public TransactionApi<TransactionView>
615 : : {
616 : : public:
617 : 5856 : explicit TransactionView(const btck_Transaction* ptr) : View{ptr} {}
618 : : };
619 : :
620 [ + - + - : 328 : class Transaction : public Handle<btck_Transaction, btck_transaction_copy, btck_transaction_destroy>, public TransactionApi<Transaction>
+ - + - +
- + - + -
- - - - -
- + - ]
621 : : {
622 : : public:
623 : 14 : explicit Transaction(std::span<const std::byte> raw_transaction)
624 : 14 : : Handle{btck_transaction_create(raw_transaction.data(), raw_transaction.size())} {}
625 : :
626 : 285 : Transaction(const TransactionView& view)
627 [ + - + - : 285 : : Handle{view} {}
+ - + - ]
628 : : };
629 : :
630 [ + - + - : 244 : class PrecomputedTransactionData : public Handle<btck_PrecomputedTransactionData, btck_precomputed_transaction_data_copy, btck_precomputed_transaction_data_destroy>
+ - + - +
- + - ]
631 : : {
632 : : public:
633 : 238 : explicit PrecomputedTransactionData(const Transaction& tx_to, std::span<const TransactionOutput> spent_outputs)
634 : 238 : : Handle{btck_precomputed_transaction_data_create(
635 : : tx_to.get(),
636 : : reinterpret_cast<const btck_TransactionOutput**>(
637 : 238 : const_cast<TransactionOutput*>(spent_outputs.data())),
638 : 238 : spent_outputs.size())} {}
639 : : };
640 : :
641 : : template <typename Derived>
642 : 47 : bool ScriptPubkeyApi<Derived>::Verify(int64_t amount,
643 : : const Transaction& tx_to,
644 : : const PrecomputedTransactionData* precomputed_txdata,
645 : : unsigned int input_index,
646 : : ScriptVerificationFlags flags,
647 : : ScriptVerifyStatus& status) const
648 : : {
649 [ + + ]: 88 : auto result = btck_script_pubkey_verify(
650 : : impl(),
651 : : amount,
652 : : tx_to.get(),
653 : 41 : precomputed_txdata ? precomputed_txdata->get() : nullptr,
654 : : input_index,
655 : : static_cast<btck_ScriptVerificationFlags>(flags),
656 : : reinterpret_cast<btck_ScriptVerifyStatus*>(&status));
657 : 47 : return result == 1;
658 : : }
659 : :
660 : : template <typename Derived>
661 : : class BlockHashApi
662 : : {
663 : : private:
664 : 3 : auto impl() const
665 : : {
666 : 4 : return static_cast<const Derived*>(this)->get();
667 : : }
668 : :
669 : : public:
670 : 1 : bool operator==(const Derived& other) const
671 : : {
672 [ + - + - ]: 1 : return btck_block_hash_equals(impl(), other.get()) != 0;
673 : : }
674 : :
675 : 1 : bool operator!=(const Derived& other) const
676 : : {
677 [ + - + - ]: 1 : return btck_block_hash_equals(impl(), other.get()) == 0;
678 : : }
679 : :
680 [ + - + - ]: 2 : std::array<std::byte, 32> ToBytes() const
681 : : {
682 : : std::array<std::byte, 32> hash;
683 [ + - + - ]: 2 : btck_block_hash_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
684 : 2 : return hash;
685 : : }
686 : : };
687 : :
688 : : class BlockHashView: public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
689 : : {
690 : : public:
691 : 2 : explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {}
692 : : };
693 : :
694 [ + - + - : 10 : class BlockHash : public Handle<btck_BlockHash, btck_block_hash_copy, btck_block_hash_destroy>, public BlockHashApi<BlockHash>
+ - + - +
- + - +
- ]
695 : : {
696 : : public:
697 : 2 : explicit BlockHash(const std::array<std::byte, 32>& hash)
698 : 2 : : Handle{btck_block_hash_create(reinterpret_cast<const unsigned char*>(hash.data()))} {}
699 : :
700 : 1 : explicit BlockHash(btck_BlockHash* hash)
701 : 2 : : Handle{hash} {}
702 : :
703 : 1 : BlockHash(const BlockHashView& view)
704 [ + - ]: 1 : : Handle{view} {}
705 : : };
706 : :
707 [ + - + - : 3225 : class Block : public Handle<btck_Block, btck_block_copy, btck_block_destroy>
+ - + - +
- + - + -
- - - - ]
708 : : {
709 : : public:
710 : 422 : Block(const std::span<const std::byte> raw_block)
711 : 422 : : Handle{btck_block_create(raw_block.data(), raw_block.size())}
712 : : {
713 : 420 : }
714 : :
715 : 2788 : Block(btck_Block* block) : Handle{block} {}
716 : :
717 : 2802 : size_t CountTransactions() const
718 : : {
719 [ + - + - ]: 2802 : return btck_block_count_transactions(get());
720 : : }
721 : :
722 : 2928 : TransactionView GetTransaction(size_t index) const
723 : : {
724 : 2928 : return TransactionView{btck_block_get_transaction_at(get(), index)};
725 : : }
726 : :
727 [ + - + - : 8511 : MAKE_RANGE_METHOD(Transactions, Block, &Block::CountTransactions, &Block::GetTransaction, *this)
+ - + - +
- + - + -
+ - ]
728 : :
729 : 1 : BlockHash GetHash() const
730 : : {
731 : 1 : return BlockHash{btck_block_get_hash(get())};
732 : : }
733 : :
734 : 20 : std::vector<std::byte> ToBytes() const
735 : : {
736 [ + - + - : 20 : return write_bytes(get(), btck_block_to_bytes);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
737 : : }
738 : : };
739 : :
740 : : inline void logging_disable()
741 : : {
742 : : btck_logging_disable();
743 : : }
744 : :
745 : 1 : inline void logging_set_options(const btck_LoggingOptions& logging_options)
746 : : {
747 [ # # ]: 1 : btck_logging_set_options(logging_options);
748 : 0 : }
749 : :
750 : 2 : inline void logging_set_level_category(LogCategory category, LogLevel level)
751 : : {
752 : 2 : btck_logging_set_level_category(static_cast<btck_LogCategory>(category), static_cast<btck_LogLevel>(level));
753 : : }
754 : :
755 : 2 : inline void logging_enable_category(LogCategory category)
756 : : {
757 : 2 : btck_logging_enable_category(static_cast<btck_LogCategory>(category));
758 : : }
759 : :
760 : 2 : inline void logging_disable_category(LogCategory category)
761 : : {
762 : 2 : btck_logging_disable_category(static_cast<btck_LogCategory>(category));
763 : : }
764 : :
765 : : template <typename T>
766 : : concept Log = requires(T a, std::string_view message) {
767 : : { a.LogMessage(message) } -> std::same_as<void>;
768 : : };
769 : :
770 : : template <Log T>
771 [ + - - - : 7 : class Logger : UniqueHandle<btck_LoggingConnection, btck_logging_connection_destroy>
+ - + - +
- - - ][ #
# # # # #
# # # # #
# ]
772 : : {
773 : : public:
774 : 4 : Logger(std::unique_ptr<T> log)
775 : : : UniqueHandle{btck_logging_connection_create(
776 : : +[](void* user_data, const char* message, size_t message_len) { static_cast<T*>(user_data)->LogMessage({message, message_len}); },
777 : 4 : log.release(),
778 : 4 : +[](void* user_data) { delete static_cast<T*>(user_data); })}
779 : : {
780 : 4 : }
781 : : };
782 : :
783 : : class BlockTreeEntry : public View<btck_BlockTreeEntry>
784 : : {
785 : : public:
786 : 4059 : BlockTreeEntry(const btck_BlockTreeEntry* entry)
787 : 433 : : View{entry}
788 : : {
789 : : }
790 : :
791 : 7 : bool operator==(const BlockTreeEntry& other) const
792 : : {
793 [ + - + - : 7 : return btck_block_tree_entry_equals(get(), other.get()) != 0;
+ - + - +
- + - + -
+ - + - +
- + - ]
794 : : }
795 : :
796 : 6 : std::optional<BlockTreeEntry> GetPrevious() const
797 : : {
798 : 6 : auto entry{btck_block_tree_entry_get_previous(get())};
799 [ + + ]: 6 : if (!entry) return std::nullopt;
800 : 4 : return entry;
801 : : }
802 : :
803 : 211 : int32_t GetHeight() const
804 : : {
805 [ + - + - : 211 : return btck_block_tree_entry_get_height(get());
+ - + - +
- ]
806 : : }
807 : :
808 : 1 : BlockHashView GetHash() const
809 : : {
810 : 1 : return BlockHashView{btck_block_tree_entry_get_block_hash(get())};
811 : : }
812 : : };
813 : :
814 : 8 : class KernelNotifications
815 : : {
816 : : public:
817 : 0 : virtual ~KernelNotifications() = default;
818 : :
819 : 426 : virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress) {}
820 : :
821 : 0 : virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
822 : :
823 : 11 : virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible) {}
824 : :
825 : 0 : virtual void WarningSetHandler(Warning warning, std::string_view message) {}
826 : :
827 : 0 : virtual void WarningUnsetHandler(Warning warning) {}
828 : :
829 : 0 : virtual void FlushErrorHandler(std::string_view error) {}
830 : :
831 : 0 : virtual void FatalErrorHandler(std::string_view error) {}
832 : : };
833 : :
834 : : class BlockValidationState
835 : : {
836 : : private:
837 : : const btck_BlockValidationState* m_state;
838 : :
839 : : public:
840 : 3 : BlockValidationState(const btck_BlockValidationState* state) : m_state{state} {}
841 : :
842 : : BlockValidationState(const BlockValidationState&) = delete;
843 : : BlockValidationState& operator=(const BlockValidationState&) = delete;
844 : : BlockValidationState(BlockValidationState&&) = delete;
845 : : BlockValidationState& operator=(BlockValidationState&&) = delete;
846 : :
847 : 3 : ValidationMode GetValidationMode() const
848 : : {
849 : 3 : return static_cast<ValidationMode>(btck_block_validation_state_get_validation_mode(m_state));
850 : : }
851 : :
852 : 1 : BlockValidationResult GetBlockValidationResult() const
853 : : {
854 : 1 : return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(m_state));
855 : : }
856 : : };
857 : :
858 : 1 : class ValidationInterface
859 : : {
860 : : public:
861 : 0 : virtual ~ValidationInterface() = default;
862 : :
863 : 0 : virtual void BlockChecked(Block block, const BlockValidationState state) {}
864 : :
865 : 0 : virtual void PowValidBlock(BlockTreeEntry entry, Block block) {}
866 : :
867 : 0 : virtual void BlockConnected(Block block, BlockTreeEntry entry) {}
868 : :
869 : 0 : virtual void BlockDisconnected(Block block, BlockTreeEntry entry) {}
870 : : };
871 : :
872 [ + - + - : 16 : class ChainParams : public Handle<btck_ChainParameters, btck_chain_parameters_copy, btck_chain_parameters_destroy>
+ - + - +
- + - + -
+ - + - ]
[ # # # #
# # # # #
# # # # #
# # # # ]
873 : : {
874 : : public:
875 : 9 : ChainParams(ChainType chain_type)
876 : 9 : : Handle{btck_chain_parameters_create(static_cast<btck_ChainType>(chain_type))} {}
877 : : };
878 : :
879 [ + - + - : 24 : class ContextOptions : public UniqueHandle<btck_ContextOptions, btck_context_options_destroy>
- - + - -
- + - + -
- - - - -
- ][ # # #
# # # # #
# # # # #
# # # # #
# # ]
880 : : {
881 : : public:
882 : 14 : ContextOptions() : UniqueHandle{btck_context_options_create()} {}
883 : :
884 : 8 : void SetChainParams(ChainParams& chain_params)
885 : : {
886 [ + - + - ]: 8 : btck_context_options_set_chainparams(get(), chain_params.get());
[ # # # # ]
887 : 8 : }
888 : :
889 : : template <typename T>
890 : 8 : void SetNotifications(std::shared_ptr<T> notifications)
891 : : {
892 : : static_assert(std::is_base_of_v<KernelNotifications, T>);
893 [ + - ]: 8 : auto heap_notifications = std::make_unique<std::shared_ptr<T>>(std::move(notifications));
894 : : using user_type = std::shared_ptr<T>*;
895 : 8 : btck_context_options_set_notifications(
896 : : get(),
897 : : btck_NotificationInterfaceCallbacks{
898 [ + - ]: 8 : .user_data = heap_notifications.release(),
899 [ + - ]: 16 : .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
900 : 426 : .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); },
901 : : .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); },
902 : : .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); },
903 : : .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}); },
904 : : .warning_unset = +[](void* user_data, btck_Warning warning) { (*static_cast<user_type>(user_data))->WarningUnsetHandler(static_cast<Warning>(warning)); },
905 : : .flush_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FlushErrorHandler({error, error_len}); },
906 : : .fatal_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FatalErrorHandler({error, error_len}); },
907 : : });
908 : 8 : }
909 : :
910 : : template <typename T>
911 : 1 : void SetValidationInterface(std::shared_ptr<T> validation_interface)
912 : : {
913 : : static_assert(std::is_base_of_v<ValidationInterface, T>);
914 [ + - ]: 1 : auto heap_vi = std::make_unique<std::shared_ptr<T>>(std::move(validation_interface));
915 : : using user_type = std::shared_ptr<T>*;
916 : 1 : btck_context_options_set_validation_interface(
917 : : get(),
918 : : btck_ValidationInterfaceCallbacks{
919 [ + - ]: 1 : .user_data = heap_vi.release(),
920 [ + - ]: 2 : .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
921 [ + - ]: 6 : .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationState{state}); },
922 [ # # # # ]: 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}); },
923 [ + - ]: 4 : .block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },
924 [ # # ]: 0 : .block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },
925 : : });
926 : 1 : }
927 : : };
928 : :
929 [ + - + - : 20 : class Context : public Handle<btck_Context, btck_context_copy, btck_context_destroy>
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
930 : : {
931 : : public:
932 : 10 : Context(ContextOptions& opts)
933 : 10 : : Handle{btck_context_create(opts.get())} {}
934 : :
935 : 4 : Context()
936 [ + - + - : 8 : : Handle{btck_context_create(ContextOptions{}.get())} {}
+ - ]
937 : :
938 : 1 : bool interrupt()
939 : : {
940 [ + - + - ]: 1 : return btck_context_interrupt(get()) == 0;
941 : : }
942 : : };
943 : :
944 [ + - - - : 20 : class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>
+ - + - -
- - - + -
- - - - -
- ][ # # #
# # # # #
# # # # #
# # # # #
# # ]
945 : : {
946 : : public:
947 : 14 : ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)
948 : 14 : : UniqueHandle{btck_chainstate_manager_options_create(
949 : 14 : context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}
950 : : {
951 : 10 : }
952 : :
953 : 1 : void SetWorkerThreads(int worker_threads)
954 : : {
955 [ + - ]: 1 : btck_chainstate_manager_options_set_worker_threads_num(get(), worker_threads);
956 : 1 : }
957 : :
958 : 6 : bool SetWipeDbs(bool wipe_block_tree, bool wipe_chainstate)
959 : : {
960 [ + - + - : 6 : return btck_chainstate_manager_options_set_wipe_dbs(get(), wipe_block_tree, wipe_chainstate) == 0;
+ - + - +
- + - + -
+ - + - ]
961 : : }
962 : :
963 : 2 : void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)
964 : : {
965 [ + - ]: 2 : btck_chainstate_manager_options_update_block_tree_db_in_memory(get(), block_tree_db_in_memory);
966 : 2 : }
967 : :
968 : 2 : void UpdateChainstateDbInMemory(bool chainstate_db_in_memory)
969 : : {
970 [ + - ]: 2 : btck_chainstate_manager_options_update_chainstate_db_in_memory(get(), chainstate_db_in_memory);
971 : 2 : }
972 : : };
973 : :
974 : : class ChainView : public View<btck_Chain>
975 : : {
976 : : public:
977 : 60 : explicit ChainView(const btck_Chain* ptr) : View{ptr} {}
978 : :
979 : 1 : int32_t Height() const
980 : : {
981 [ + - ]: 1 : return btck_chain_get_height(get());
982 : : }
983 : :
984 : 259 : int CountEntries() const
985 : : {
986 [ + - + - : 259 : return btck_chain_get_height(get()) + 1;
+ - + - ]
987 : : }
988 : :
989 : 3627 : BlockTreeEntry GetByHeight(int height) const
990 : : {
991 : 3627 : auto index{btck_chain_get_by_height(get(), height)};
992 [ + + + - ]: 3627 : if (!index) throw std::runtime_error("No entry in the chain at the provided height");
993 : 3626 : return index;
994 : : }
995 : :
996 : 1 : bool Contains(BlockTreeEntry& entry) const
997 : : {
998 [ + - + - ]: 1 : return btck_chain_contains(get(), entry.get());
999 : : }
1000 : :
1001 [ + - + - : 3909 : MAKE_RANGE_METHOD(Entries, ChainView, &ChainView::CountEntries, &ChainView::GetByHeight, *this)
+ - + - +
- + - + -
+ - ]
1002 : : };
1003 : :
1004 : : template <typename Derived>
1005 : : class CoinApi
1006 : : {
1007 : : private:
1008 : 5 : auto impl() const
1009 : : {
1010 : 5 : return static_cast<const Derived*>(this)->get();
1011 : : }
1012 : :
1013 : : friend Derived;
1014 : : CoinApi() = default;
1015 : :
1016 : : public:
1017 [ + - ]: 1 : uint32_t GetConfirmationHeight() const { return btck_coin_confirmation_height(impl()); }
1018 : :
1019 [ + - ]: 1 : bool IsCoinbase() const { return btck_coin_is_coinbase(impl()) == 1; }
1020 : :
1021 : 3 : TransactionOutputView GetOutput() const
1022 : : {
1023 : 3 : return TransactionOutputView{btck_coin_get_output(impl())};
1024 : : }
1025 : : };
1026 : :
1027 : : class CoinView : public View<btck_Coin>, public CoinApi<CoinView>
1028 : : {
1029 : : public:
1030 : 36 : explicit CoinView(const btck_Coin* ptr) : View{ptr} {}
1031 : : };
1032 : :
1033 [ + - + - : 9 : class Coin : public Handle<btck_Coin, btck_coin_copy, btck_coin_destroy>, public CoinApi<Coin>
+ - + - +
- + - +
- ]
1034 : : {
1035 : : public:
1036 : : Coin(btck_Coin* coin) : Handle{coin} {}
1037 : :
1038 [ + - + - ]: 2 : Coin(const CoinView& view) : Handle{view} {}
1039 : : };
1040 : :
1041 : : template <typename Derived>
1042 : : class TransactionSpentOutputsApi
1043 : : {
1044 : : private:
1045 : 42 : auto impl() const
1046 : : {
1047 : 42 : return static_cast<const Derived*>(this)->get();
1048 : : }
1049 : :
1050 : : friend Derived;
1051 : : TransactionSpentOutputsApi() = default;
1052 : :
1053 : : public:
1054 : 24 : size_t Count() const
1055 : : {
1056 [ + - + - : 24 : return btck_transaction_spent_outputs_count(impl());
+ - ]
1057 : : }
1058 : :
1059 : 18 : CoinView GetCoin(size_t index) const
1060 : : {
1061 : 18 : return CoinView{btck_transaction_spent_outputs_get_coin_at(impl(), index)};
1062 : : }
1063 : :
1064 [ + - + - ]: 39 : MAKE_RANGE_METHOD(Coins, Derived, &TransactionSpentOutputsApi<Derived>::Count, &TransactionSpentOutputsApi<Derived>::GetCoin, *static_cast<const Derived*>(this))
1065 : : };
1066 : :
1067 : : class TransactionSpentOutputsView : public View<btck_TransactionSpentOutputs>, public TransactionSpentOutputsApi<TransactionSpentOutputsView>
1068 : : {
1069 : : public:
1070 : 40 : explicit TransactionSpentOutputsView(const btck_TransactionSpentOutputs* ptr) : View{ptr} {}
1071 : : };
1072 : :
1073 [ + - + - : 9 : class TransactionSpentOutputs : public Handle<btck_TransactionSpentOutputs, btck_transaction_spent_outputs_copy, btck_transaction_spent_outputs_destroy>,
+ - + - +
- + - +
- ]
1074 : : public TransactionSpentOutputsApi<TransactionSpentOutputs>
1075 : : {
1076 : : public:
1077 : : TransactionSpentOutputs(btck_TransactionSpentOutputs* transaction_spent_outputs) : Handle{transaction_spent_outputs} {}
1078 : :
1079 [ + - + - ]: 2 : TransactionSpentOutputs(const TransactionSpentOutputsView& view) : Handle{view} {}
1080 : : };
1081 : :
1082 [ + - + - : 11 : class BlockSpentOutputs : public Handle<btck_BlockSpentOutputs, btck_block_spent_outputs_copy, btck_block_spent_outputs_destroy>
+ - + - +
- + - + -
- - + - +
- ]
1083 : : {
1084 : : public:
1085 : 5 : BlockSpentOutputs(btck_BlockSpentOutputs* block_spent_outputs)
1086 : 9 : : Handle{block_spent_outputs}
1087 : : {
1088 : : }
1089 : :
1090 : 28 : size_t Count() const
1091 : : {
1092 [ + - + - : 28 : return btck_block_spent_outputs_count(get());
+ - + - +
- + - ]
1093 : : }
1094 : :
1095 : 20 : TransactionSpentOutputsView GetTxSpentOutputs(size_t tx_undo_index) const
1096 : : {
1097 : 20 : return TransactionSpentOutputsView{btck_block_spent_outputs_get_transaction_spent_outputs_at(get(), tx_undo_index)};
1098 : : }
1099 : :
1100 [ + - + - ]: 42 : MAKE_RANGE_METHOD(TxsSpentOutputs, BlockSpentOutputs, &BlockSpentOutputs::Count, &BlockSpentOutputs::GetTxSpentOutputs, *this)
1101 : : };
1102 : :
1103 [ + - + - : 20 : class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
+ - + - +
- + - +
- ][ # # #
# # # # #
# # # # #
# ]
1104 : : {
1105 : : public:
1106 : 10 : ChainMan(const Context& context, const ChainstateManagerOptions& chainman_opts)
1107 : 10 : : UniqueHandle{btck_chainstate_manager_create(chainman_opts.get())}
1108 : : {
1109 : 10 : }
1110 : :
1111 : 2 : bool ImportBlocks(const std::span<const std::string> paths)
1112 : : {
1113 : 2 : std::vector<const char*> c_paths;
1114 : 2 : std::vector<size_t> c_paths_lens;
1115 [ + - ]: 2 : c_paths.reserve(paths.size());
1116 [ + - ]: 2 : c_paths_lens.reserve(paths.size());
1117 [ + + ]: 3 : for (const auto& path : paths) {
1118 [ + - ]: 1 : c_paths.push_back(path.c_str());
1119 [ - + + - ]: 1 : c_paths_lens.push_back(path.length());
1120 : : }
1121 : :
1122 [ - + ]: 4 : return btck_chainstate_manager_import_blocks(get(), c_paths.data(), c_paths_lens.data(), c_paths.size()) == 0;
1123 : 2 : }
1124 : :
1125 : 418 : bool ProcessBlock(const Block& block, bool* new_block)
1126 : : {
1127 : 418 : int _new_block;
1128 : 418 : int res = btck_chainstate_manager_process_block(get(), block.get(), &_new_block);
1129 [ + - ]: 418 : if (new_block) *new_block = _new_block == 1;
1130 : 418 : return res == 0;
1131 : : }
1132 : :
1133 : 30 : ChainView GetChain() const
1134 : : {
1135 : 30 : return ChainView{btck_chainstate_manager_get_active_chain(get())};
1136 : : }
1137 : :
1138 : 1 : std::optional<BlockTreeEntry> GetBlockTreeEntry(const BlockHash& block_hash) const
1139 : : {
1140 : 1 : auto entry{btck_chainstate_manager_get_block_tree_entry_by_hash(get(), block_hash.get())};
1141 [ - + ]: 1 : if (!entry) return std::nullopt;
1142 : 1 : return entry;
1143 : : }
1144 : :
1145 : 2789 : std::optional<Block> ReadBlock(const BlockTreeEntry& entry) const
1146 : : {
1147 : 2789 : auto block{btck_block_read(get(), entry.get())};
1148 [ + + ]: 2789 : if (!block) return std::nullopt;
1149 : 2788 : return block;
1150 : : }
1151 : :
1152 : 5 : BlockSpentOutputs ReadBlockSpentOutputs(const BlockTreeEntry& entry) const
1153 : : {
1154 : 5 : return btck_block_spent_outputs_read(get(), entry.get());
1155 : : }
1156 : : };
1157 : :
1158 : : } // namespace btck
1159 : :
1160 : : #endif // BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
|