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