Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
bitcoinkernel_wrapper.h
Go to the documentation of this file.
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
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
24namespace btck {
25
41
49
50constexpr std::string_view Name(LogLevel level) noexcept
51{
52 switch (level) {
53 case LogLevel::TRACE_LEVEL: return "trace";
54 case LogLevel::DEBUG_LEVEL: return "debug";
55 case LogLevel::INFO_LEVEL: return "info";
56 case LogLevel::WARNING_LEVEL: return "warning";
57 case LogLevel::ERROR_LEVEL: return "error";
58 } // no default case, so the compiler can warn about missing cases
59 return "unknown";
60}
61
62constexpr std::string_view Name(LogCategory category) noexcept
63{
64 switch (category) {
65 case LogCategory::NONE: return "none";
66 case LogCategory::BENCH: return "bench";
67 case LogCategory::BLOCKSTORAGE: return "blockstorage";
68 case LogCategory::COINDB: return "coindb";
69 case LogCategory::LEVELDB: return "leveldb";
70 case LogCategory::MEMPOOL: return "mempool";
71 case LogCategory::PRUNE: return "prune";
72 case LogCategory::RAND: return "rand";
73 case LogCategory::REINDEX: return "reindex";
74 case LogCategory::TXPACKAGES: return "txpackages";
75 case LogCategory::VALIDATION: return "validation";
76 case LogCategory::KERNEL: return "kernel";
77 case LogCategory::LOCK: return "lock";
78 } // no default case, so the compiler can warn about missing cases
79 return "unknown";
80}
81
89
95
100
106
118
134
140
152
159
160template <typename T>
161struct is_bitmask_enum : std::false_type {
162};
163
164template <>
165struct is_bitmask_enum<ScriptVerificationFlags> : std::true_type {
166};
167
168template <>
169struct is_bitmask_enum<BlockCheckFlags> : std::true_type {
170};
171
172template <typename T>
173concept BitmaskEnum = is_bitmask_enum<T>::value;
174
175template <BitmaskEnum T>
176constexpr 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
182template <BitmaskEnum T>
183constexpr 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
189template <BitmaskEnum T>
190constexpr 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
196template <BitmaskEnum T>
197constexpr T operator~(T value)
198{
199 return static_cast<T>(~static_cast<std::underlying_type_t<T>>(value));
200}
201
202template <BitmaskEnum T>
203constexpr T& operator|=(T& lhs, T rhs)
204{
205 return lhs = lhs | rhs;
206}
207
208template <BitmaskEnum T>
209constexpr T& operator&=(T& lhs, T rhs)
210{
211 return lhs = lhs & rhs;
212}
213
214template <BitmaskEnum T>
215constexpr T& operator^=(T& lhs, T rhs)
216{
217 return lhs = lhs ^ rhs;
218}
219
220template <typename T>
222{
223 if (ptr == nullptr) {
224 throw std::runtime_error("failed to instantiate btck object");
225 }
226 return ptr;
227}
228
229inline std::string_view ToStringView(btck_StringView view)
230{
231 return {view.data, view.len};
232}
233
234template <typename Collection, typename ValueType, auto GetFunc>
236{
237public:
238 using iterator_category = std::random_access_iterator_tag;
239 using iterator_concept = std::random_access_iterator_tag;
240 using difference_type = std::ptrdiff_t;
242
243private:
245 size_t m_idx;
246
247public:
248 Iterator() = default;
249 Iterator(const Collection* ptr) : m_collection{ptr}, m_idx{0} {}
250 Iterator(const Collection* ptr, size_t idx) : m_collection{ptr}, m_idx{idx} {}
251
252 // This is just a view, so return a copy.
253 auto operator*() const { return std::invoke(GetFunc, *m_collection, m_idx); }
254
255 auto& operator++() { m_idx++; return *this; }
256 auto operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
257
258 auto& operator--() { m_idx--; return *this; }
259 auto operator--(int) { auto temp = *this; --m_idx; return temp; }
260
261 auto& operator+=(difference_type n) { m_idx += n; return *this; }
262 auto& operator-=(difference_type n) { m_idx -= n; return *this; }
263
264 auto operator+(difference_type n) const { return Iterator(m_collection, m_idx + n); }
265 auto operator-(difference_type n) const { return Iterator(m_collection, m_idx - n); }
266
267 auto operator-(const Iterator& other) const { return static_cast<difference_type>(m_idx) - static_cast<difference_type>(other.m_idx); }
268
269 ValueType operator[](difference_type n) const { return *(*this + n); }
270
271 auto operator<=>(const Iterator& other) const { return m_idx <=> other.m_idx; }
272
273 bool operator==(const Iterator& other) const { return m_collection == other.m_collection && m_idx == other.m_idx; }
274
275private:
276 friend Iterator operator+(difference_type n, const Iterator& it) { return it + n; }
277};
278
279template <typename Container, typename SizeFunc, typename GetFunc>
280concept IndexedContainer = requires(const Container& c, SizeFunc size_func, GetFunc get_func, std::size_t i) {
281 { std::invoke(size_func, c) } -> std::convertible_to<std::size_t>;
282 { std::invoke(get_func, c, i) }; // Return type is deduced
283};
284
285template <typename Container, auto SizeFunc, auto GetFunc>
286 requires IndexedContainer<Container, decltype(SizeFunc), decltype(GetFunc)>
287class Range
288{
289public:
290 using value_type = std::invoke_result_t<decltype(GetFunc), const Container&, size_t>;
291 using difference_type = std::ptrdiff_t;
294
295private:
297
298public:
300 {
301 static_assert(std::ranges::random_access_range<Range>);
302 }
303
304 iterator begin() const { return iterator(m_container, 0); }
305 iterator end() const { return iterator(m_container, size()); }
306
307 const_iterator cbegin() const { return begin(); }
308 const_iterator cend() const { return end(); }
309
310 size_t size() const { return std::invoke(SizeFunc, *m_container); }
311
312 bool empty() const { return size() == 0; }
313
314 value_type operator[](size_t index) const { return std::invoke(GetFunc, *m_container, index); }
315
316 value_type at(size_t index) const
317 {
318 if (index >= size()) {
319 throw std::out_of_range("Index out of range");
320 }
321 return (*this)[index];
322 }
323
324 value_type front() const { return (*this)[0]; }
325 value_type back() const { return (*this)[size() - 1]; }
326};
327
328#define MAKE_RANGE_METHOD(method_name, ContainerType, SizeFunc, GetFunc, container_expr) \
329 auto method_name() const & { \
330 return Range<ContainerType, SizeFunc, GetFunc>{container_expr}; \
331 } \
332 auto method_name() const && = delete;
333
334template <typename T>
335std::vector<std::byte> write_bytes(const T* object, int (*to_bytes)(const T*, btck_WriteBytes, void*))
336{
337 std::vector<std::byte> bytes;
338 struct UserData {
339 std::vector<std::byte>* bytes;
340 std::exception_ptr exception;
341 };
342 UserData user_data = UserData{.bytes = &bytes, .exception = nullptr};
343
344 constexpr auto const write = +[](const void* buffer, size_t len, void* user_data) -> int {
345 auto& data = *reinterpret_cast<UserData*>(user_data);
346 auto& bytes = *data.bytes;
347 try {
348 auto const* first = static_cast<const std::byte*>(buffer);
349 auto const* last = first + len;
350 bytes.insert(bytes.end(), first, last);
351 return 0;
352 } catch (...) {
353 data.exception = std::current_exception();
354 return -1;
355 }
356 };
357
358 if (to_bytes(object, write, &user_data) != 0) {
359 std::rethrow_exception(user_data.exception);
360 }
361 return bytes;
362}
363
364template <typename CType>
365class View
366{
367protected:
368 const CType* m_ptr;
369
370public:
371 explicit View(const CType* ptr) : m_ptr{check(ptr)} {}
372
373 const CType* get() const { return m_ptr; }
374};
375
376template <typename CType, CType* (*CopyFunc)(const CType*), void (*DestroyFunc)(CType*)>
378{
379protected:
381
382public:
383 explicit Handle(CType* ptr) : m_ptr{check(ptr)} {}
384
385 // Copy constructors
386 Handle(const Handle& other)
387 : m_ptr{check(CopyFunc(other.m_ptr))} {}
388 Handle& operator=(const Handle& other)
389 {
390 if (this != &other) {
391 Handle temp(other);
392 std::swap(m_ptr, temp.m_ptr);
393 }
394 return *this;
395 }
396
397 // Move constructors
398 Handle(Handle&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
399 Handle& operator=(Handle&& other) noexcept
400 {
401 if (this != &other) {
403 m_ptr = std::exchange(other.m_ptr, nullptr);
404 }
405 return *this;
406 }
407
408 template <typename ViewType>
409 requires std::derived_from<ViewType, View<CType>>
411 : Handle{CopyFunc(view.get())}
412 {
413 }
414
416
417 CType* get() { return m_ptr; }
418 const CType* get() const { return m_ptr; }
419};
420
421template <typename CType, void (*DestroyFunc)(CType*)>
423{
424protected:
425 struct Deleter {
426 void operator()(CType* ptr) const noexcept
427 {
428 if (ptr) DestroyFunc(ptr);
429 }
430 };
431 std::unique_ptr<CType, Deleter> m_ptr;
432
433public:
434 explicit UniqueHandle(CType* ptr) : m_ptr{check(ptr)} {}
435
436 CType* get() { return m_ptr.get(); }
437 const CType* get() const { return m_ptr.get(); }
438};
439
441class Transaction;
442class TransactionOutput;
444
445template <typename Derived>
447{
448private:
449 auto impl() const
450 {
451 return static_cast<const Derived*>(this)->get();
452 }
453
454 friend Derived;
455 ScriptPubkeyApi() = default;
456
457public:
458 bool Verify(int64_t amount,
459 const Transaction& tx_to,
461 unsigned int input_index,
463 ScriptVerifyStatus& status) const;
464
465 std::vector<std::byte> ToBytes() const
466 {
468 }
469};
470
471class ScriptPubkeyView : public View<btck_ScriptPubkey>, public ScriptPubkeyApi<ScriptPubkeyView>
472{
473public:
474 explicit ScriptPubkeyView(const btck_ScriptPubkey* ptr) : View{ptr} {}
475};
476
477class ScriptPubkey : public Handle<btck_ScriptPubkey, btck_script_pubkey_copy, btck_script_pubkey_destroy>, public ScriptPubkeyApi<ScriptPubkey>
478{
479public:
480 explicit ScriptPubkey(std::span<const std::byte> raw)
482
485};
486
487template <typename Derived>
489{
490private:
491 auto impl() const
492 {
493 return static_cast<const Derived*>(this)->get();
494 }
495
496 friend Derived;
498
499public:
501 {
503 }
504
509};
510
511class TransactionOutputView : public View<btck_TransactionOutput>, public TransactionOutputApi<TransactionOutputView>
512{
513public:
514 explicit TransactionOutputView(const btck_TransactionOutput* ptr) : View{ptr} {}
515};
516
517class TransactionOutput : public Handle<btck_TransactionOutput, btck_transaction_output_copy, btck_transaction_output_destroy>, public TransactionOutputApi<TransactionOutput>
518{
519public:
520 explicit TransactionOutput(const ScriptPubkey& script_pubkey, int64_t amount)
521 : Handle{btck_transaction_output_create(script_pubkey.get(), amount)} {}
522
525};
526
527template <typename Derived>
529{
530private:
531 auto impl() const
532 {
533 return static_cast<const Derived*>(this)->get();
534 }
535
536 friend Derived;
537 TxidApi() = default;
538
539public:
540 bool operator==(const TxidApi& other) const
541 {
542 return btck_txid_equals(impl(), other.impl()) != 0;
543 }
544
545 bool operator!=(const TxidApi& other) const
546 {
547 return btck_txid_equals(impl(), other.impl()) == 0;
548 }
549
550 std::array<std::byte, 32> ToBytes() const
551 {
552 std::array<std::byte, 32> hash;
553 btck_txid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
554 return hash;
555 }
556};
557
558class TxidView : public View<btck_Txid>, public TxidApi<TxidView>
559{
560public:
561 explicit TxidView(const btck_Txid* ptr) : View{ptr} {}
562};
563
564class Txid : public Handle<btck_Txid, btck_txid_copy, btck_txid_destroy>, public TxidApi<Txid>
565{
566public:
568 : Handle(view) {}
569};
570
571template <typename Derived>
573{
574private:
575 auto impl() const
576 {
577 return static_cast<const Derived*>(this)->get();
578 }
579
580 friend Derived;
581 WtxidApi() = default;
582
583public:
584 bool operator==(const WtxidApi& other) const
585 {
586 return btck_wtxid_equals(impl(), other.impl()) != 0;
587 }
588
589 bool operator!=(const WtxidApi& other) const
590 {
591 return btck_wtxid_equals(impl(), other.impl()) == 0;
592 }
593
594 std::array<std::byte, 32> ToBytes() const
595 {
596 std::array<std::byte, 32> hash;
597 btck_wtxid_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
598 return hash;
599 }
600};
601
602class WtxidView : public View<btck_Wtxid>, public WtxidApi<WtxidView>
603{
604public:
605 explicit WtxidView(const btck_Wtxid* ptr) : View{ptr} {}
606};
607
608class Wtxid : public Handle<btck_Wtxid, btck_wtxid_copy, btck_wtxid_destroy>, public WtxidApi<Wtxid>
609{
610public:
612 : Handle(view) {}
613};
614
615template <typename Derived>
617{
618private:
619 auto impl() const
620 {
621 return static_cast<const Derived*>(this)->get();
622 }
623
624 friend Derived;
625 OutPointApi() = default;
626
627public:
629 {
631 }
632
634 {
636 }
637};
638
639class OutPointView : public View<btck_TransactionOutPoint>, public OutPointApi<OutPointView>
640{
641public:
642 explicit OutPointView(const btck_TransactionOutPoint* ptr) : View{ptr} {}
643};
644
645class OutPoint : public Handle<btck_TransactionOutPoint, btck_transaction_out_point_copy, btck_transaction_out_point_destroy>, public OutPointApi<OutPoint>
646{
647public:
650};
651
652template <typename Derived>
654{
655private:
656 auto impl() const
657 {
658 return static_cast<const Derived*>(this)->get();
659 }
660
661 friend Derived;
662 WitnessStackApi() = default;
663
664public:
665 size_t CountItems() const
666 {
668 }
669
670 std::vector<std::byte> GetItem(size_t index) const
671 {
672 struct Item { const btck_WitnessStack* stack; size_t index; };
673 Item item{impl(), index};
674 return write_bytes(&item, +[](const Item* c, btck_WriteBytes w, void* ud) {
675 return btck_witness_stack_get_item_at(c->stack, c->index, w, ud);
676 });
677 }
678
680};
681
682class WitnessStackView : public View<btck_WitnessStack>, public WitnessStackApi<WitnessStackView>
683{
684public:
685 explicit WitnessStackView(const btck_WitnessStack* ptr) : View{ptr} {}
686};
687
688class WitnessStack : public Handle<btck_WitnessStack, btck_witness_stack_copy, btck_witness_stack_destroy>, public WitnessStackApi<WitnessStack>
689{
690public:
693};
694
695template <typename Derived>
697{
698private:
699 auto impl() const
700 {
701 return static_cast<const Derived*>(this)->get();
702 }
703
704 friend Derived;
706
707public:
712
717
722
723 std::vector<std::byte> GetScriptSig() const
724 {
726 }
727};
728
729class TransactionInputView : public View<btck_TransactionInput>, public TransactionInputApi<TransactionInputView>
730{
731public:
732 explicit TransactionInputView(const btck_TransactionInput* ptr) : View{ptr} {}
733};
734
735class TransactionInput : public Handle<btck_TransactionInput, btck_transaction_input_copy, btck_transaction_input_destroy>, public TransactionInputApi<TransactionInput>
736{
737public:
740};
741
742template <typename Derived>
744{
745private:
746 auto impl() const
747 {
748 return static_cast<const Derived*>(this)->get();
749 }
750
751public:
752 size_t CountOutputs() const
753 {
755 }
756
757 size_t CountInputs() const
758 {
760 }
761
763 {
765 }
766
767 TransactionInputView GetInput(size_t index) const
768 {
770 }
771
773 {
775 }
776
778 {
780 }
781
782 bool HasWitness() const
783 {
784 return btck_transaction_has_witness(impl()) != 0;
785 }
786
788 {
790 }
791
793 {
795 }
796
798
800
801 std::vector<std::byte> ToBytes() const
802 {
804 }
805};
806
807class TransactionView : public View<btck_Transaction>, public TransactionApi<TransactionView>
808{
809public:
810 explicit TransactionView(const btck_Transaction* ptr) : View{ptr} {}
811};
812
813class Transaction : public Handle<btck_Transaction, btck_transaction_copy, btck_transaction_destroy>, public TransactionApi<Transaction>
814{
815public:
816 explicit Transaction(std::span<const std::byte> raw_transaction)
818
821};
822
823class PrecomputedTransactionData : public Handle<btck_PrecomputedTransactionData, btck_precomputed_transaction_data_copy, btck_precomputed_transaction_data_destroy>
824{
825public:
832};
833
834template <typename Derived>
836 const Transaction& tx_to,
838 unsigned int input_index,
840 ScriptVerifyStatus& status) const
841{
842 auto result = btck_script_pubkey_verify(
843 impl(),
844 amount,
845 tx_to.get(),
846 precomputed_txdata ? precomputed_txdata->get() : nullptr,
849 reinterpret_cast<btck_ScriptVerifyStatus*>(&status));
850 return result == 1;
851}
852
853template <typename Derived>
855{
856private:
857 auto impl() const
858 {
859 return static_cast<const Derived*>(this)->get();
860 }
861
862public:
863 bool operator==(const Derived& other) const
864 {
865 return btck_block_hash_equals(impl(), other.get()) != 0;
866 }
867
868 bool operator!=(const Derived& other) const
869 {
870 return btck_block_hash_equals(impl(), other.get()) == 0;
871 }
872
873 std::array<std::byte, 32> ToBytes() const
874 {
875 std::array<std::byte, 32> hash;
876 btck_block_hash_to_bytes(impl(), reinterpret_cast<unsigned char*>(hash.data()));
877 return hash;
878 }
879};
880
881class BlockHashView : public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
882{
883public:
884 explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {}
885};
886
887class BlockHash : public Handle<btck_BlockHash, btck_block_hash_copy, btck_block_hash_destroy>, public BlockHashApi<BlockHash>
888{
889public:
890 explicit BlockHash(const std::array<std::byte, 32>& hash)
892
893 explicit BlockHash(btck_BlockHash* hash)
894 : Handle{hash} {}
895
898};
899
900template <typename Derived>
902{
903private:
904 auto impl() const
905 {
906 return static_cast<const Derived*>(this)->get();
907 }
908
909 friend Derived;
910 BlockHeaderApi() = default;
911
912public:
914 {
916 }
917
922
923 std::array<std::byte, 32> MerkleRoot() const
924 {
925 std::array<std::byte, 32> merkle_root;
926 btck_block_header_get_merkle_root(impl(), reinterpret_cast<unsigned char*>(merkle_root.data()));
927 return merkle_root;
928 }
929
931 {
933 }
934
936 {
938 }
939
941 {
943 }
944
946 {
948 }
949
950 std::array<std::byte, 80> ToBytes() const
951 {
952 std::array<std::byte, 80> header;
953 int res{btck_block_header_to_bytes(impl(), reinterpret_cast<unsigned char*>(header.data()))};
954 if (res != 0) {
955 throw std::runtime_error("Failed to serialize block header");
956 }
957 return header;
958 }
959};
960
961class BlockHeaderView : public View<btck_BlockHeader>, public BlockHeaderApi<BlockHeaderView>
962{
963public:
964 explicit BlockHeaderView(const btck_BlockHeader* ptr) : View{ptr} {}
965};
966
967class BlockHeader : public Handle<btck_BlockHeader, btck_block_header_copy, btck_block_header_destroy>, public BlockHeaderApi<BlockHeader>
968{
969public:
970 explicit BlockHeader(std::span<const std::byte> raw_header)
972
975
977 : Handle{header} {}
978};
979
980class ConsensusParamsView : public View<btck_ConsensusParams>
981{
982public:
983 explicit ConsensusParamsView(const btck_ConsensusParams* ptr) : View{ptr} {}
984};
985
986class Block : public Handle<btck_Block, btck_block_copy, btck_block_destroy>
987{
988public:
989 Block(const std::span<const std::byte> raw_block)
991 {
992 }
993
994 Block(btck_Block* block) : Handle{block} {}
995
996 size_t CountTransactions() const
997 {
999 }
1000
1002 {
1004 }
1005
1008 BlockValidationState& state) const;
1009
1011
1013 {
1015 }
1016
1018 {
1020 }
1021
1022 std::vector<std::byte> ToBytes() const
1023 {
1025 }
1026};
1027
1029{
1030 btck_logging_set_min_level(static_cast<btck_LogLevel>(level));
1031}
1032
1036class LogEntry : public View<btck_LogEntry>
1037{
1038public:
1039 explicit LogEntry(const btck_LogEntry* entry) : View{entry} {}
1040
1041 std::string_view Message() const { return ToStringView(btck_log_entry_get_message(get())); }
1042 std::string_view ThreadName() const { return ToStringView(btck_log_entry_get_thread_name(get())); }
1043 std::chrono::sys_time<std::chrono::nanoseconds> Timestamp() const
1044 {
1045 return std::chrono::sys_time<std::chrono::nanoseconds>{std::chrono::nanoseconds{btck_log_entry_get_timestamp_ns(get())}};
1046 }
1047 std::optional<std::chrono::sys_seconds> MockTime() const
1048 {
1050 if (mocktime_s == 0) return std::nullopt;
1051 return std::chrono::sys_seconds{std::chrono::seconds{mocktime_s}};
1052 }
1053 std::string_view FileName() const { return ToStringView(btck_log_entry_get_file_name(get())); }
1054 std::string_view FunctionName() const { return ToStringView(btck_log_entry_get_function_name(get())); }
1056 LogLevel Level() const { return static_cast<LogLevel>(btck_log_entry_get_level(get())); }
1058};
1059
1060template <typename T>
1061concept Log = requires(T a, const LogEntry& entry) {
1062 { a.LogMessage(entry) } -> std::same_as<void>;
1063};
1064
1065template <Log T>
1066class Logger : UniqueHandle<btck_LoggingConnection, btck_logging_connection_destroy>
1067{
1068public:
1069 Logger(std::unique_ptr<T> log)
1071 +[](void* user_data, const btck_LogEntry* entry) { static_cast<T*>(user_data)->LogMessage(LogEntry{entry}); },
1072 log.release(),
1073 +[](void* user_data) { delete static_cast<T*>(user_data); })}
1074 {
1075 }
1076};
1077
1078class BlockTreeEntry : public View<btck_BlockTreeEntry>
1079{
1080public:
1082 : View{entry}
1083 {
1084 }
1085
1086 bool operator==(const BlockTreeEntry& other) const
1087 {
1088 return btck_block_tree_entry_equals(get(), other.get()) != 0;
1089 }
1090
1091 std::optional<BlockTreeEntry> GetPrevious() const
1092 {
1093 auto entry{btck_block_tree_entry_get_previous(get())};
1094 if (!entry) return std::nullopt;
1095 return entry;
1096 }
1097
1099 {
1101 }
1102
1107
1112
1114 {
1116 }
1117
1118};
1119
1121{
1122public:
1123 virtual ~KernelNotifications() = default;
1124
1125 virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress) {}
1126
1127 virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {}
1128
1129 virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible) {}
1130
1131 virtual void WarningSetHandler(Warning warning, std::string_view message) {}
1132
1134
1135 virtual void FlushErrorHandler(std::string_view error) {}
1136
1137 virtual void FatalErrorHandler(std::string_view error) {}
1138};
1139
1140template <typename Derived>
1142{
1143private:
1144 auto impl() const
1145 {
1146 return static_cast<const Derived*>(this)->get();
1147 }
1148
1149 friend Derived;
1151
1152public:
1157
1162};
1163
1164class BlockValidationStateView : public View<btck_BlockValidationState>, public BlockValidationStateApi<BlockValidationStateView>
1165{
1166public:
1168};
1169
1170class BlockValidationState : public Handle<btck_BlockValidationState, btck_block_validation_state_copy, btck_block_validation_state_destroy>, public BlockValidationStateApi<BlockValidationState>
1171{
1172public:
1174
1176
1178};
1179
1180inline bool Block::Check(const ConsensusParamsView& consensus_params,
1182 BlockValidationState& state) const
1183{
1184 return btck_block_check(get(), consensus_params.get(), static_cast<btck_BlockCheckFlags>(flags), state.get()) == 1;
1185}
1186
1187class TxValidationState : public UniqueHandle<btck_TxValidationState, btck_tx_validation_state_destroy>
1188{
1189public:
1190 using UniqueHandle::UniqueHandle; // inherit ctor
1192
1197
1202};
1203
1204inline bool CheckTransaction(const Transaction& tx, TxValidationState& state)
1205{
1206 return btck_transaction_check(tx.get(), state.get()) == 1;
1207}
1208
1210{
1211public:
1212 virtual ~ValidationInterface() = default;
1213
1214 virtual void BlockChecked(Block block, BlockValidationStateView state) {}
1215
1216 virtual void PowValidBlock(BlockTreeEntry entry, Block block) {}
1217
1218 virtual void BlockConnected(Block block, BlockTreeEntry entry) {}
1219
1220 virtual void BlockDisconnected(Block block, BlockTreeEntry entry) {}
1221};
1222
1223class ChainParams : public Handle<btck_ChainParameters, btck_chain_parameters_copy, btck_chain_parameters_destroy>
1224{
1225public:
1228
1229 explicit ChainParams(std::span<const std::byte> signet_challenge)
1230 : Handle{btck_chain_parameters_create_signet(signet_challenge.data(), signet_challenge.size())} {}
1231
1236};
1237
1238class ContextOptions : public UniqueHandle<btck_ContextOptions, btck_context_options_destroy>
1239{
1240public:
1242
1247
1248 template <typename T>
1249 void SetNotifications(std::shared_ptr<T> notifications)
1250 {
1251 static_assert(std::is_base_of_v<KernelNotifications, T>);
1252 auto heap_notifications = std::make_unique<std::shared_ptr<T>>(std::move(notifications));
1253 using user_type = std::shared_ptr<T>*;
1255 get(),
1257 .user_data = heap_notifications.release(),
1258 .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
1259 .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); },
1260 .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); },
1261 .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); },
1262 .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}); },
1263 .warning_unset = +[](void* user_data, btck_Warning warning) { (*static_cast<user_type>(user_data))->WarningUnsetHandler(static_cast<Warning>(warning)); },
1264 .flush_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FlushErrorHandler({error, error_len}); },
1265 .fatal_error = +[](void* user_data, const char* error, size_t error_len) { (*static_cast<user_type>(user_data))->FatalErrorHandler({error, error_len}); },
1266 });
1267 }
1268
1269 template <typename T>
1271 {
1272 static_assert(std::is_base_of_v<ValidationInterface, T>);
1273 auto heap_vi = std::make_unique<std::shared_ptr<T>>(std::move(validation_interface));
1274 using user_type = std::shared_ptr<T>*;
1276 get(),
1278 .user_data = heap_vi.release(),
1279 .user_data_destroy = +[](void* user_data) { delete static_cast<user_type>(user_data); },
1280 .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); },
1281 .pow_valid_block = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->PowValidBlock(BlockTreeEntry{entry}, Block{block}); },
1282 .block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },
1283 .block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },
1284 });
1285 }
1286};
1287
1288class Context : public Handle<btck_Context, btck_context_copy, btck_context_destroy>
1289{
1290public:
1292 : Handle{btck_context_create(opts.get())} {}
1293
1296
1298 {
1299 return btck_context_interrupt(get()) == 0;
1300 }
1301};
1302
1303class ChainstateManagerOptions : public UniqueHandle<btck_ChainstateManagerOptions, btck_chainstate_manager_options_destroy>
1304{
1305public:
1306 ChainstateManagerOptions(const Context& context, std::string_view data_dir, std::string_view blocks_dir)
1308 context.get(), data_dir.data(), data_dir.length(), blocks_dir.data(), blocks_dir.length())}
1309 {
1310 }
1311
1316
1321
1326
1327 void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)
1328 {
1330 }
1331
1336};
1337
1338class ChainView : public View<btck_Chain>
1339{
1340public:
1341 explicit ChainView(const btck_Chain* ptr) : View{ptr} {}
1342
1344 {
1345 return btck_chain_get_height(get());
1346 }
1347
1349 {
1350 return btck_chain_get_height(get()) + 1;
1351 }
1352
1354 {
1355 auto index{btck_chain_get_by_height(get(), height)};
1356 if (!index) throw std::runtime_error("No entry in the chain at the provided height");
1357 return index;
1358 }
1359
1360 bool Contains(BlockTreeEntry& entry) const
1361 {
1362 return btck_chain_contains(get(), entry.get());
1363 }
1364
1365 MAKE_RANGE_METHOD(Entries, ChainView, &ChainView::CountEntries, &ChainView::GetByHeight, *this)
1366};
1367
1368template <typename Derived>
1370{
1371private:
1372 auto impl() const
1373 {
1374 return static_cast<const Derived*>(this)->get();
1375 }
1376
1377 friend Derived;
1378 CoinApi() = default;
1379
1380public:
1382
1383 bool IsCoinbase() const { return btck_coin_is_coinbase(impl()) == 1; }
1384
1389};
1390
1391class CoinView : public View<btck_Coin>, public CoinApi<CoinView>
1392{
1393public:
1394 explicit CoinView(const btck_Coin* ptr) : View{ptr} {}
1395};
1396
1397class Coin : public Handle<btck_Coin, btck_coin_copy, btck_coin_destroy>, public CoinApi<Coin>
1398{
1399public:
1400 Coin(btck_Coin* coin) : Handle{coin} {}
1401
1403};
1404
1405template <typename Derived>
1407{
1408private:
1409 auto impl() const
1410 {
1411 return static_cast<const Derived*>(this)->get();
1412 }
1413
1414 friend Derived;
1416
1417public:
1418 size_t Count() const
1419 {
1421 }
1422
1423 CoinView GetCoin(size_t index) const
1424 {
1426 }
1427
1429};
1430
1431class TransactionSpentOutputsView : public View<btck_TransactionSpentOutputs>, public TransactionSpentOutputsApi<TransactionSpentOutputsView>
1432{
1433public:
1435};
1436
1437class TransactionSpentOutputs : public Handle<btck_TransactionSpentOutputs, btck_transaction_spent_outputs_copy, btck_transaction_spent_outputs_destroy>,
1438 public TransactionSpentOutputsApi<TransactionSpentOutputs>
1439{
1440public:
1442
1444};
1445
1446class BlockSpentOutputs : public Handle<btck_BlockSpentOutputs, btck_block_spent_outputs_copy, btck_block_spent_outputs_destroy>
1447{
1448public:
1453
1454 size_t Count() const
1455 {
1456 return btck_block_spent_outputs_count(get());
1457 }
1458
1463
1464 MAKE_RANGE_METHOD(TxsSpentOutputs, BlockSpentOutputs, &BlockSpentOutputs::Count, &BlockSpentOutputs::GetTxSpentOutputs, *this)
1465};
1466
1467class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
1468{
1469public:
1474
1475 bool ImportBlocks(const std::span<const std::string> paths)
1476 {
1477 std::vector<const char*> c_paths;
1478 std::vector<size_t> c_paths_lens;
1479 c_paths.reserve(paths.size());
1480 c_paths_lens.reserve(paths.size());
1481 for (const auto& path : paths) {
1482 c_paths.push_back(path.c_str());
1483 c_paths_lens.push_back(path.length());
1484 }
1485
1486 return btck_chainstate_manager_import_blocks(get(), c_paths.data(), c_paths_lens.data(), c_paths.size()) == 0;
1487 }
1488
1489 bool ProcessBlock(const Block& block, bool* new_block)
1490 {
1491 int _new_block;
1493 if (new_block) *new_block = _new_block == 1;
1494 return res == 0;
1495 }
1496
1498 {
1499 auto state = btck_chainstate_manager_process_block_header(get(), header.get());
1500 return BlockValidationState{state};
1501 }
1502
1504 {
1506 }
1507
1508 std::optional<BlockTreeEntry> GetBlockTreeEntry(const BlockHash& block_hash) const
1509 {
1510 auto entry{btck_chainstate_manager_get_block_tree_entry_by_hash(get(), block_hash.get())};
1511 if (!entry) return std::nullopt;
1512 return entry;
1513 }
1514
1516 {
1518 }
1519
1520 std::optional<Block> ReadBlock(const BlockTreeEntry& entry) const
1521 {
1522 auto block{btck_block_read(get(), entry.get())};
1523 if (!block) return std::nullopt;
1524 return block;
1525 }
1526
1528 {
1529 return btck_block_spent_outputs_read(get(), entry.get());
1530 }
1531};
1532
1533inline void set_mock_time(std::chrono::seconds timestamp)
1534{
1535 if (btck_set_mock_time(timestamp.count()) != 0) {
1536 throw std::runtime_error("timestamp out of range");
1537 }
1538}
1539
1540} // namespace btck
1541
1542#endif // BITCOIN_KERNEL_BITCOINKERNEL_WRAPPER_H
int flags
int btck_block_to_bytes(const btck_Block *block, btck_WriteBytes writer, void *user_data)
int btck_script_pubkey_to_bytes(const btck_ScriptPubkey *script_pubkey_, btck_WriteBytes writer, void *user_data)
btck_TxValidationResult btck_tx_validation_state_get_tx_validation_result(const btck_TxValidationState *state_)
Returns the validation result from an opaque btck_TxValidationState pointer.
int btck_chainstate_manager_import_blocks(btck_ChainstateManager *chainman, const char **block_file_paths_data, size_t *block_file_paths_lens, size_t block_file_paths_data_len)
Triggers the start of a reindex if the wipe options were previously set for the chainstate manager.
const btck_Coin * btck_transaction_spent_outputs_get_coin_at(const btck_TransactionSpentOutputs *transaction_spent_outputs, size_t coin_index)
Returns a coin contained in the transaction spent outputs at a certain index.
const btck_TransactionInput * btck_transaction_get_input_at(const btck_Transaction *transaction, size_t input_index)
Get the transaction input at the provided index.
uint32_t btck_coin_confirmation_height(const btck_Coin *coin)
Returns the block height where the transaction that created this coin was included in.
void btck_context_options_set_notifications(btck_ContextOptions *options, btck_NotificationInterfaceCallbacks notifications)
Set the kernel notifications for the context options.
btck_StringView btck_log_entry_get_function_name(const btck_LogEntry *entry)
Get the name of the function that produced the log statement.
btck_ContextOptions * btck_context_options_create()
Creates an empty context options.
btck_PrecomputedTransactionData * btck_precomputed_transaction_data_create(const btck_Transaction *tx_to, const btck_TransactionOutput **spent_outputs_, size_t spent_outputs_len)
Create precomputed transaction data for script verification.
const btck_BlockTreeEntry * btck_block_tree_entry_get_ancestor(const btck_BlockTreeEntry *block_tree_entry, int32_t height)
Return the ancestor of a btck_BlockTreeEntry at the given height.
int64_t btck_transaction_output_get_amount(const btck_TransactionOutput *output)
Get the amount in the output.
void btck_chainstate_manager_options_update_chainstate_db_in_memory(btck_ChainstateManagerOptions *chainman_opts, int chainstate_db_in_memory)
Sets chainstate db in memory in the options.
uint32_t btck_block_header_get_nonce(const btck_BlockHeader *header)
Get the nonce from btck_BlockHeader.
const btck_Txid * btck_transaction_out_point_get_txid(const btck_TransactionOutPoint *out_point)
Get the txid from the transaction out point.
btck_BlockValidationState * btck_block_validation_state_create()
Create a new btck_BlockValidationState.
btck_LogCategory btck_log_entry_get_category(const btck_LogEntry *entry)
Get the category of the log entry.
const btck_BlockTreeEntry * btck_block_tree_entry_get_previous(const btck_BlockTreeEntry *entry)
Returns the previous block tree entry in the tree, or null if the current block tree entry is the gen...
size_t btck_transaction_count_outputs(const btck_Transaction *transaction)
Get the number of outputs of a transaction.
int btck_witness_stack_get_item_at(const btck_WitnessStack *witness_stack, size_t index, btck_WriteBytes writer, void *user_data)
size_t btck_witness_stack_count_items(const btck_WitnessStack *witness_stack)
Return the number of items in a witness stack.
btck_ScriptPubkey * btck_script_pubkey_create(const void *script_pubkey, size_t script_pubkey_len)
Create a script pubkey from serialized data.
const btck_BlockTreeEntry * btck_chainstate_manager_get_best_entry(const btck_ChainstateManager *chainstate_manager)
Get the btck_BlockTreeEntry whose associated btck_BlockHeader has the most known cumulative proof of ...
btck_ChainParameters * btck_chain_parameters_create(const btck_ChainType chain_type)
Creates a chain parameters struct with default parameters based on the passed in chain type.
int32_t btck_block_header_get_version(const btck_BlockHeader *header)
Get the version from btck_BlockHeader.
int btck_set_mock_time(int64_t timestamp)
Override the current time with a fixed timestamp for testing.
btck_ValidationMode btck_block_validation_state_get_validation_mode(const btck_BlockValidationState *block_validation_state_)
Returns the validation mode from an opaque btck_BlockValidationState pointer.
btck_Block * btck_block_create(const void *raw_block, size_t raw_block_length)
Parse a serialized raw block into a new block object.
void btck_chainstate_manager_options_update_block_tree_db_in_memory(btck_ChainstateManagerOptions *chainman_opts, int block_tree_db_in_memory)
Sets block tree db in memory in the options.
int btck_block_tree_entry_equals(const btck_BlockTreeEntry *entry1, const btck_BlockTreeEntry *entry2)
uint32_t btck_block_header_get_bits(const btck_BlockHeader *header)
Get the nBits difficulty target from btck_BlockHeader.
const btck_Wtxid * btck_transaction_get_wtxid(const btck_Transaction *transaction)
Get the wtxid of a transaction.
int32_t btck_chain_get_height(const btck_Chain *chain)
Return the height of the tip of the chain.
btck_BlockHeader * btck_block_get_header(const btck_Block *block)
Get the btck_BlockHeader from the block.
size_t btck_block_count_transactions(const btck_Block *block)
Count the number of transactions contained in a block.
int64_t btck_log_entry_get_timestamp_ns(const btck_LogEntry *entry)
Get the wall-clock time when the entry was logged.
void btck_logging_set_min_level(btck_LogLevel level)
Set the minimum log level.
void btck_block_header_get_merkle_root(const btck_BlockHeader *header, unsigned char output[32])
btck_LoggingConnection * btck_logging_connection_create(btck_LogCallback callback, void *user_data, btck_DestroyCallback user_data_destroy_callback)
Start logging messages through the provided callback.
int btck_script_pubkey_verify(const btck_ScriptPubkey *script_pubkey, const int64_t amount, const btck_Transaction *tx_to, const btck_PrecomputedTransactionData *precomputed_txdata, const unsigned int input_index, const btck_ScriptVerificationFlags flags, btck_ScriptVerifyStatus *status)
uint32_t btck_log_entry_get_line(const btck_LogEntry *entry)
Get the line number of the source code that produced the log statement.
const btck_TransactionOutPoint * btck_transaction_input_get_out_point(const btck_TransactionInput *input)
Get the transaction out point.
btck_BlockSpentOutputs * btck_block_spent_outputs_read(const btck_ChainstateManager *chainman, const btck_BlockTreeEntry *entry)
btck_ChainstateManager * btck_chainstate_manager_create(const btck_ChainstateManagerOptions *chainman_opts)
Create a chainstate manager.
int btck_transaction_check(const btck_Transaction *tx, btck_TxValidationState *validation_state)
btck_BlockHash * btck_block_get_hash(const btck_Block *block)
Calculate and return the hash of a block.
const btck_TransactionSpentOutputs * btck_block_spent_outputs_get_transaction_spent_outputs_at(const btck_BlockSpentOutputs *block_spent_outputs, size_t transaction_index)
Returns a transaction spent outputs contained in the block spent outputs at a certain index.
btck_Context * btck_context_create(const btck_ContextOptions *options)
Create a new kernel context.
const btck_TransactionOutput * btck_coin_get_output(const btck_Coin *coin)
Return the transaction output of a coin.
uint32_t btck_transaction_get_locktime(const btck_Transaction *transaction)
Get a transaction's nLockTime value.
int btck_coin_is_coinbase(const btck_Coin *coin)
Returns whether the containing transaction was a coinbase.
int btck_wtxid_equals(const btck_Wtxid *wtxid1, const btck_Wtxid *wtxid2)
void btck_txid_to_bytes(const btck_Txid *txid, unsigned char output[32])
int btck_chainstate_manager_options_set_wipe_dbs(btck_ChainstateManagerOptions *chainman_opts, int wipe_block_tree_db, int wipe_chainstate_db)
Sets wipe db in the options.
uint32_t btck_transaction_get_version(const btck_Transaction *transaction)
Get a transaction's version.
btck_BlockHeader * btck_block_tree_entry_get_block_header(const btck_BlockTreeEntry *entry)
Return the btck_BlockHeader associated with this entry.
int btck_context_interrupt(btck_Context *context)
Interrupt can be used to halt long-running validation functions like when reindexing,...
const btck_ConsensusParams * btck_chain_parameters_get_consensus_params(const btck_ChainParameters *chain_parameters)
Get btck_ConsensusParams from btck_ChainParameters.
const btck_TransactionOutput * btck_transaction_get_output_at(const btck_Transaction *transaction, size_t output_index)
Get the transaction outputs at the provided index.
const btck_BlockTreeEntry * btck_chain_get_by_height(const btck_Chain *chain, int32_t height)
Retrieve a block tree entry by its height in the currently active chain.
void btck_context_options_set_chainparams(btck_ContextOptions *options, const btck_ChainParameters *chain_parameters)
int btck_block_header_to_bytes(const btck_BlockHeader *header, unsigned char output[80])
int64_t btck_log_entry_get_mocktime_s(const btck_LogEntry *entry)
Get the mock time in effect when the entry was logged.
int btck_chainstate_manager_options_set_database_cache_bytes(btck_ChainstateManagerOptions *chainman_opts, uint64_t database_cache_bytes)
Set the total database cache used by the chainstate manager.
const btck_WitnessStack * btck_transaction_input_get_witness_stack(const btck_TransactionInput *input)
Get the witness stack of a transaction input.
btck_BlockHeader * btck_block_header_create(const void *raw_block_header, size_t raw_block_header_len)
Create a btck_BlockHeader from serialized data.
uint32_t btck_block_header_get_timestamp(const btck_BlockHeader *header)
Get the timestamp from btck_BlockHeader.
btck_ChainParameters * btck_chain_parameters_create_signet(const void *challenge, size_t challenge_len)
Create a signet chain parameters struct with a user-provided challenge.
btck_BlockHash * btck_block_hash_create(const unsigned char block_hash[32])
Create a block hash from its raw data.
btck_BlockHash * btck_block_header_get_hash(const btck_BlockHeader *header)
Get the btck_BlockHash.
btck_LogLevel btck_log_entry_get_level(const btck_LogEntry *entry)
Get the severity level of the log entry.
btck_ValidationMode btck_tx_validation_state_get_validation_mode(const btck_TxValidationState *state_)
Returns the validation mode from an opaque btck_TxValidationState pointer.
void btck_wtxid_to_bytes(const btck_Wtxid *wtxid, unsigned char output[32])
int btck_transaction_input_get_script_sig(const btck_TransactionInput *input, btck_WriteBytes writer, void *user_data)
int btck_transaction_has_witness(const btck_Transaction *transaction)
Check whether a transaction has witness data.
void btck_context_options_set_validation_interface(btck_ContextOptions *options, btck_ValidationInterfaceCallbacks vi_cbs)
Set the validation interface callbacks for the context options.
uint32_t btck_transaction_out_point_get_index(const btck_TransactionOutPoint *out_point)
Get the output position from the transaction out point.
const btck_BlockHash * btck_block_header_get_prev_hash(const btck_BlockHeader *header)
Get the previous btck_BlockHash from btck_BlockHeader.
btck_Block * btck_block_read(const btck_ChainstateManager *chainman, const btck_BlockTreeEntry *entry)
const btck_Txid * btck_transaction_get_txid(const btck_Transaction *transaction)
Get the txid of a transaction.
btck_BlockValidationState * btck_chainstate_manager_process_block_header(btck_ChainstateManager *chainstate_manager, const btck_BlockHeader *header)
int btck_chain_contains(const btck_Chain *chain, const btck_BlockTreeEntry *entry)
const btck_BlockTreeEntry * btck_chainstate_manager_get_block_tree_entry_by_hash(const btck_ChainstateManager *chainman, const btck_BlockHash *block_hash)
size_t btck_block_spent_outputs_count(const btck_BlockSpentOutputs *block_spent_outputs)
Returns the number of transaction spent outputs whose data is contained in block spent outputs.
int btck_block_hash_equals(const btck_BlockHash *hash1, const btck_BlockHash *hash2)
int32_t btck_block_tree_entry_get_height(const btck_BlockTreeEntry *entry)
Return the height of a certain block tree entry.
const btck_ScriptPubkey * btck_transaction_output_get_script_pubkey(const btck_TransactionOutput *output)
Get the script pubkey of the output.
int btck_chainstate_manager_process_block(btck_ChainstateManager *chainman, const btck_Block *block, int *_new_block)
size_t btck_transaction_count_inputs(const btck_Transaction *transaction)
Get the number of inputs of a transaction.
int btck_block_check(const btck_Block *block, const btck_ConsensusParams *consensus_params, btck_BlockCheckFlags flags, btck_BlockValidationState *validation_state)
int btck_txid_equals(const btck_Txid *txid1, const btck_Txid *txid2)
btck_Transaction * btck_transaction_create(const void *raw_transaction, size_t raw_transaction_len)
Create a new transaction from the serialized data.
const btck_BlockHash * btck_block_tree_entry_get_block_hash(const btck_BlockTreeEntry *entry)
Return the block hash associated with a block tree entry.
void btck_chainstate_manager_options_set_worker_threads_num(btck_ChainstateManagerOptions *opts, int worker_threads)
Set the number of available worker threads used during validation.
int btck_transaction_to_bytes(const btck_Transaction *transaction, btck_WriteBytes writer, void *user_data)
btck_TransactionOutput * btck_transaction_output_create(const btck_ScriptPubkey *script_pubkey, int64_t amount)
Create a transaction output from a script pubkey and an amount.
btck_StringView btck_log_entry_get_message(const btck_LogEntry *entry)
Get the message text from a btck_LogEntry.
btck_TxValidationState * btck_tx_validation_state_create()
Create a new btck_TxValidationState.
const btck_Transaction * btck_block_get_transaction_at(const btck_Block *block, size_t index)
Get the transaction at the provided index.
const btck_Chain * btck_chainstate_manager_get_active_chain(const btck_ChainstateManager *chainman)
Returns the best known currently active chain.
btck_ChainstateManagerOptions * btck_chainstate_manager_options_create(const btck_Context *context, const char *data_dir, size_t data_dir_len, const char *blocks_dir, size_t blocks_dir_len)
Create options for the chainstate manager.
btck_StringView btck_log_entry_get_file_name(const btck_LogEntry *entry)
Get the name of the source file that produced the log statement.
btck_BlockValidationResult btck_block_validation_state_get_block_validation_result(const btck_BlockValidationState *block_validation_state_)
Returns the validation result from an opaque btck_BlockValidationState pointer.
void btck_block_hash_to_bytes(const btck_BlockHash *block_hash, unsigned char output[32])
uint32_t btck_transaction_input_get_sequence(const btck_TransactionInput *input)
Get a transaction input's nSequence value.
btck_StringView btck_log_entry_get_thread_name(const btck_LogEntry *entry)
Get the name of the thread that produced the log message.
size_t btck_transaction_spent_outputs_count(const btck_TransactionSpentOutputs *transaction_spent_outputs)
Returns the number of previous transaction outputs contained in the transaction spent outputs data.
#define btck_ChainType_REGTEST
#define btck_ScriptVerificationFlags_P2SH
evaluate P2SH (BIP16) subscripts
uint8_t btck_LogLevel
The severity of a log statement.
#define btck_TxValidationResult_NOT_STANDARD
otherwise didn't meet local policy rules
#define btck_TxValidationResult_CONFLICT
tx already in mempool or conflicts with a tx in the chain
#define btck_LogLevel_WARNING
#define btck_ScriptVerificationFlags_CHECKLOCKTIMEVERIFY
enable CHECKLOCKTIMEVERIFY (BIP65)
int(* btck_WriteBytes)(const void *bytes, size_t size, void *userdata)
Function signature for serializing data.
#define btck_TxValidationResult_RECONSIDERABLE
fails some policy, but might be acceptable if submitted in a (different) package
uint32_t btck_TxValidationResult
Indicates the reason why a transaction failed validation.
#define btck_ChainType_MAINNET
#define btck_BlockValidationResult_HEADER_LOW_WORK
the block header may be on a too-little-work chain
#define btck_Warning_UNKNOWN_NEW_RULES_ACTIVATED
#define btck_TxValidationResult_MISSING_INPUTS
transaction was missing some of its inputs
uint8_t btck_ChainType
#define btck_BlockValidationResult_INVALID_PREV
A block this one builds on is invalid.
#define btck_BlockCheckFlags_MERKLE
verify merkle root (and mutation detection)
#define btck_LogCategory_MEMPOOL
#define btck_TxValidationResult_UNKNOWN
transaction was not validated because package failed
#define btck_LogLevel_TRACE
#define btck_ChainType_TESTNET
#define btck_SynchronizationState_INIT_REINDEX
#define btck_BlockCheckFlags_BASE
run the base context-free block checks only
#define btck_ScriptVerifyStatus_ERROR_INVALID_FLAGS_COMBINATION
The flags were combined in an invalid way.
uint32_t btck_BlockValidationResult
A granular "reason" why a block was invalid.
#define btck_LogCategory_BENCH
uint8_t btck_ValidationMode
Whether a validated data structure is valid, invalid, or an error was encountered during processing.
#define btck_ScriptVerificationFlags_ALL
#define btck_LogCategory_LOCK
#define btck_LogCategory_PRUNE
uint8_t btck_SynchronizationState
Current sync state passed to tip changed callbacks.
#define btck_ChainType_TESTNET_4
#define btck_LogCategory_COINDB
#define btck_TxValidationResult_NO_MEMPOOL
this node does not have a mempool so can't validate the transaction
#define btck_BlockCheckFlags_ALL
enable all optional context-free block checks
#define btck_ScriptVerificationFlags_TAPROOT
enable TAPROOT (BIPs 341 & 342)
#define btck_ScriptVerifyStatus_ERROR_SPENT_OUTPUTS_REQUIRED
The taproot flag was set, so valid spent_outputs have to be provided.
#define btck_ScriptVerificationFlags_WITNESS
enable WITNESS (BIP141)
#define btck_BlockCheckFlags_POW
run CheckProofOfWork via CheckBlockHeader
uint32_t btck_ScriptVerificationFlags
Script verification flags that may be composed with each other.
#define btck_LogCategory_VALIDATION
#define btck_LogCategory_REINDEX
#define btck_LogLevel_DEBUG
#define btck_ScriptVerifyStatus_OK
#define btck_TxValidationResult_WITNESS_STRIPPED
transaction is missing a witness
#define btck_ScriptVerificationFlags_NONE
#define btck_LogCategory_RAND
#define btck_TxValidationResult_INPUTS_NOT_STANDARD
inputs (covered by txid) failed policy rules
#define btck_BlockValidationResult_CONSENSUS
invalid by consensus rules (excluding any below reasons)
#define btck_BlockValidationResult_UNSET
initial value. Block has not yet been rejected
#define btck_TxValidationResult_UNSET
initial value. Tx has not yet been rejected
#define btck_SynchronizationState_POST_INIT
#define btck_BlockValidationResult_MISSING_PREV
We don't have the previous block the checked one is built on.
uint8_t btck_ScriptVerifyStatus
A collection of status codes that may be issued by the script verify function.
#define btck_ValidationMode_INTERNAL_ERROR
#define btck_TxValidationResult_WITNESS_MUTATED
witness may have been malleated or is prior to SegWit activation
uint8_t btck_LogCategory
A collection of logging categories that may be encountered by kernel code.
#define btck_ValidationMode_INVALID
#define btck_ChainType_SIGNET
#define btck_TxValidationResult_CONSENSUS
invalid by consensus rules
uint32_t btck_BlockCheckFlags
Bitflags to control context-free block checks (optional).
#define btck_ScriptVerificationFlags_NULLDUMMY
enforce NULLDUMMY (BIP147)
#define btck_BlockValidationResult_INVALID_HEADER
invalid proof of work or time too old
uint8_t btck_Warning
Possible warning types issued by validation.
#define btck_LogCategory_NONE
Not tied to a specific category, e.g. most INFO, WARNING and ERROR entries.
#define btck_BlockValidationResult_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
#define btck_LogCategory_LEVELDB
#define btck_LogLevel_ERROR
#define btck_BlockValidationResult_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
#define btck_Warning_LARGE_WORK_INVALID_CHAIN
#define btck_LogLevel_INFO
#define btck_ScriptVerificationFlags_CHECKSEQUENCEVERIFY
enable CHECKSEQUENCEVERIFY (BIP112)
#define btck_TxValidationResult_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
#define btck_LogCategory_BLOCKSTORAGE
#define btck_ValidationMode_VALID
#define btck_LogCategory_KERNEL
#define btck_ScriptVerificationFlags_DERSIG
enforce strict DER (BIP66) compliance
#define btck_BlockValidationResult_MUTATED
the block's data didn't match the data committed to by the PoW
#define btck_LogCategory_TXPACKAGES
#define btck_TxValidationResult_MEMPOOL_POLICY
violated mempool's fee/size/descendant/RBF/etc limits
#define btck_SynchronizationState_INIT_DOWNLOAD
#define MAKE_RANGE_METHOD(method_name, ContainerType, SizeFunc, GetFunc, container_expr)
bool operator==(const Derived &other) const
std::array< std::byte, 32 > ToBytes() const
bool operator!=(const Derived &other) const
BlockHash(const std::array< std::byte, 32 > &hash)
BlockHash(btck_BlockHash *hash)
BlockHash(const BlockHashView &view)
BlockHashView(const btck_BlockHash *ptr)
BlockHashView PrevHash() const
std::array< std::byte, 32 > MerkleRoot() const
std::array< std::byte, 80 > ToBytes() const
BlockHeaderApi()=default
BlockHeader(btck_BlockHeader *header)
BlockHeader(std::span< const std::byte > raw_header)
BlockHeader(const BlockHeaderView &view)
BlockHeaderView(const btck_BlockHeader *ptr)
BlockHash GetHash() const
std::vector< std::byte > ToBytes() const
bool Check(const ConsensusParamsView &consensus_params, BlockCheckFlags flags, BlockValidationState &state) const
TransactionView GetTransaction(size_t index) const
BlockHeader GetHeader() const
Block(btck_Block *block)
size_t CountTransactions() const
Block(const std::span< const std::byte > raw_block)
TransactionSpentOutputsView GetTxSpentOutputs(size_t tx_undo_index) const
BlockSpentOutputs(btck_BlockSpentOutputs *block_spent_outputs)
int32_t GetHeight() const
BlockTreeEntry(const btck_BlockTreeEntry *entry)
std::optional< BlockTreeEntry > GetPrevious() const
bool operator==(const BlockTreeEntry &other) const
BlockTreeEntry GetAncestor(int32_t height) const
BlockHashView GetHash() const
BlockHeader GetHeader() const
ValidationMode GetValidationMode() const
BlockValidationResult GetBlockValidationResult() const
BlockValidationState(const BlockValidationStateView &view)
BlockValidationState(btck_BlockValidationState *state)
BlockValidationStateView(const btck_BlockValidationState *ptr)
std::optional< BlockTreeEntry > GetBlockTreeEntry(const BlockHash &block_hash) const
std::optional< Block > ReadBlock(const BlockTreeEntry &entry) const
BlockSpentOutputs ReadBlockSpentOutputs(const BlockTreeEntry &entry) const
BlockValidationState ProcessBlockHeader(const BlockHeader &header)
ChainView GetChain() const
BlockTreeEntry GetBestEntry() const
ChainMan(const Context &context, const ChainstateManagerOptions &chainman_opts)
bool ImportBlocks(const std::span< const std::string > paths)
bool ProcessBlock(const Block &block, bool *new_block)
ChainParams(std::span< const std::byte > signet_challenge)
ChainParams(ChainType chain_type)
ConsensusParamsView GetConsensusParams() const
ChainView(const btck_Chain *ptr)
BlockTreeEntry GetByHeight(int32_t height) const
bool Contains(BlockTreeEntry &entry) const
int32_t CountEntries() const
void SetWorkerThreads(int worker_threads)
ChainstateManagerOptions(const Context &context, std::string_view data_dir, std::string_view blocks_dir)
void UpdateBlockTreeDbInMemory(bool block_tree_db_in_memory)
void UpdateChainstateDbInMemory(bool chainstate_db_in_memory)
bool SetDatabaseCacheBytes(uint64_t database_cache_bytes)
bool SetWipeDbs(bool wipe_block_tree, bool wipe_chainstate)
CoinApi()=default
uint32_t GetConfirmationHeight() const
TransactionOutputView GetOutput() const
Coin(const CoinView &view)
Coin(btck_Coin *coin)
CoinView(const btck_Coin *ptr)
ConsensusParamsView(const btck_ConsensusParams *ptr)
Context(ContextOptions &opts)
void SetValidationInterface(std::shared_ptr< T > validation_interface)
void SetChainParams(ChainParams &chain_params)
void SetNotifications(std::shared_ptr< T > notifications)
Handle & operator=(const Handle &other)
Handle & operator=(Handle &&other) noexcept
Handle(const ViewType &view)
Handle(Handle &&other) noexcept
const CType * get() const
Handle(const Handle &other)
Iterator(const Collection *ptr)
Iterator()=default
auto operator+(difference_type n) const
auto operator-(difference_type n) const
std::random_access_iterator_tag iterator_category
std::random_access_iterator_tag iterator_concept
auto operator<=>(const Iterator &other) const
auto & operator+=(difference_type n)
friend Iterator operator+(difference_type n, const Iterator &it)
const Collection * m_collection
bool operator==(const Iterator &other) const
std::ptrdiff_t difference_type
auto & operator-=(difference_type n)
ValueType operator[](difference_type n) const
auto operator-(const Iterator &other) const
Iterator(const Collection *ptr, size_t idx)
virtual void FatalErrorHandler(std::string_view error)
virtual void WarningSetHandler(Warning warning, std::string_view message)
virtual void BlockTipHandler(SynchronizationState state, BlockTreeEntry entry, double verification_progress)
virtual ~KernelNotifications()=default
virtual void ProgressHandler(std::string_view title, int progress_percent, bool resume_possible)
virtual void WarningUnsetHandler(Warning warning)
virtual void FlushErrorHandler(std::string_view error)
virtual void HeaderTipHandler(SynchronizationState state, int64_t height, int64_t timestamp, bool presync)
Non-owning view over a btck_LogEntry.
std::optional< std::chrono::sys_seconds > MockTime() const
std::string_view FunctionName() const
LogLevel Level() const
std::string_view FileName() const
uint32_t Line() const
LogCategory Category() const
std::string_view ThreadName() const
std::string_view Message() const
LogEntry(const btck_LogEntry *entry)
std::chrono::sys_time< std::chrono::nanoseconds > Timestamp() const
Logger(std::unique_ptr< T > log)
OutPointApi()=default
OutPoint(const OutPointView &view)
OutPointView(const btck_TransactionOutPoint *ptr)
PrecomputedTransactionData(const Transaction &tx_to, std::span< const TransactionOutput > spent_outputs)
const Container * m_container
value_type front() const
const_iterator cbegin() const
value_type operator[](size_t index) const
Range(const Container &container)
size_t size() const
const_iterator cend() const
std::ptrdiff_t difference_type
iterator begin() const
Iterator< Container, value_type, GetFunc > iterator
iterator end() const
value_type back() const
value_type at(size_t index) const
std::invoke_result_t< decltype(GetFunc), const Container &, size_t > value_type
std::vector< std::byte > ToBytes() const
bool Verify(int64_t amount, const Transaction &tx_to, const PrecomputedTransactionData *precomputed_txdata, unsigned int input_index, ScriptVerificationFlags flags, ScriptVerifyStatus &status) const
ScriptPubkey(std::span< const std::byte > raw)
ScriptPubkey(const ScriptPubkeyView &view)
ScriptPubkeyView(const btck_ScriptPubkey *ptr)
TransactionInputView GetInput(size_t index) const
TransactionOutputView GetOutput(size_t index) const
std::vector< std::byte > ToBytes() const
Transaction(std::span< const std::byte > raw_transaction)
Transaction(const TransactionView &view)
WitnessStackView GetWitnessStack() const
std::vector< std::byte > GetScriptSig() const
TransactionInput(const TransactionInputView &view)
TransactionInputView(const btck_TransactionInput *ptr)
ScriptPubkeyView GetScriptPubkey() const
TransactionOutput(const TransactionOutputView &view)
TransactionOutput(const ScriptPubkey &script_pubkey, int64_t amount)
TransactionOutputView(const btck_TransactionOutput *ptr)
CoinView GetCoin(size_t index) const
TransactionSpentOutputs(btck_TransactionSpentOutputs *transaction_spent_outputs)
TransactionSpentOutputs(const TransactionSpentOutputsView &view)
TransactionSpentOutputsView(const btck_TransactionSpentOutputs *ptr)
TransactionView(const btck_Transaction *ptr)
TxValidationResult GetTxValidationResult() const
ValidationMode GetValidationMode() const
bool operator==(const TxidApi &other) const
std::array< std::byte, 32 > ToBytes() const
TxidApi()=default
bool operator!=(const TxidApi &other) const
Txid(const TxidView &view)
TxidView(const btck_Txid *ptr)
const CType * get() const
std::unique_ptr< CType, Deleter > m_ptr
virtual void PowValidBlock(BlockTreeEntry entry, Block block)
virtual void BlockConnected(Block block, BlockTreeEntry entry)
virtual ~ValidationInterface()=default
virtual void BlockDisconnected(Block block, BlockTreeEntry entry)
virtual void BlockChecked(Block block, BlockValidationStateView state)
const CType * get() const
const CType * m_ptr
View(const CType *ptr)
std::vector< std::byte > GetItem(size_t index) const
WitnessStack(const WitnessStackView &view)
WitnessStackView(const btck_WitnessStack *ptr)
bool operator==(const WtxidApi &other) const
WtxidApi()=default
bool operator!=(const WtxidApi &other) const
std::array< std::byte, 32 > ToBytes() const
Wtxid(const WtxidView &view)
WtxidView(const btck_Wtxid *ptr)
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
#define T(expected, seed, data)
constexpr T & operator|=(T &lhs, T rhs)
std::string_view ToStringView(btck_StringView view)
void set_mock_time(std::chrono::seconds timestamp)
constexpr T & operator&=(T &lhs, T rhs)
constexpr T operator~(T value)
std::vector< std::byte > write_bytes(const T *object, int(*to_bytes)(const T *, btck_WriteBytes, void *))
void logging_set_min_level(LogLevel level)
constexpr T operator&(T lhs, T rhs)
constexpr std::string_view Name(LogLevel level) noexcept
constexpr T operator|(T lhs, T rhs)
@ UNKNOWN_NEW_RULES_ACTIVATED
@ LARGE_WORK_INVALID_CHAIN
constexpr T operator^(T lhs, T rhs)
constexpr T & operator^=(T &lhs, T rhs)
void operator()(CType *ptr) const noexcept
A struct for holding the kernel notification callbacks.
void * user_data
Holds a user-defined opaque structure that is passed to the notification callbacks.
A non-owning view of a string.
Holds the validation interface callbacks.
void * user_data
Holds a user-defined opaque structure that is passed to the validation interface callbacks.
bool CheckTransaction(const CTransaction &tx, TxValidationState &state)
Definition tx_check.cpp:19
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
WalletContext context