5#define BITCOINKERNEL_BUILD
66 if (
flags & SCRIPT_VERIFY_CLEANSTACK && ~
flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS))
return false;
67 if (
flags & SCRIPT_VERIFY_WITNESS && ~
flags & SCRIPT_VERIFY_P2SH)
return false;
79 : m_writer{writer}, m_user_data{user_data} {}
84 void write(std::span<const std::byte> src)
86 if (m_writer(
std::data(src), src.size(), m_user_data) != 0) {
87 throw std::runtime_error(
"Failed to write serialization data");
99template <
typename C,
typename CPP>
101 static C* ref(CPP* cpp_type)
103 return reinterpret_cast<C*
>(cpp_type);
106 static const C* ref(
const CPP* cpp_type)
108 return reinterpret_cast<const C*
>(cpp_type);
111 template <
typename... Args>
112 static C* create(Args&&...
args)
114 auto cpp_obj{std::make_unique<CPP>(std::forward<Args>(
args)...)};
115 return reinterpret_cast<C*
>(cpp_obj.release());
118 static C* copy(
const C* ptr)
120 auto cpp_obj{std::make_unique<CPP>(get(ptr))};
121 return reinterpret_cast<C*
>(cpp_obj.release());
124 static const CPP& get(
const C* ptr)
126 return *
reinterpret_cast<const CPP*
>(ptr);
129 static CPP& get(C* ptr)
131 return *
reinterpret_cast<CPP*
>(ptr);
134 static void operator delete(
void* ptr)
136 delete reinterpret_cast<CPP*
>(ptr);
143struct btck_Block : Handle<btck_Block, std::shared_ptr<const CBlock>> {};
228struct LoggingConnection {
229 std::unique_ptr<std::list<std::function<void(
const std::string&)>>::iterator>
m_connection;
231 std::function<void(
void* user_data)> m_deleter;
237 auto connection{
LogInstance().
PushBackCallback([callback, user_data](
const std::string& str) { callback(user_data, str.c_str(), str.length()); })};
243 if (user_data && user_data_destroy_callback) {
244 user_data_destroy_callback(user_data);
246 throw std::runtime_error(
"Failed to start logging");
249 m_connection = std::make_unique<std::list<std::function<void(
const std::string&)>>::iterator>(connection);
250 m_user_data = user_data;
251 m_deleter = user_data_destroy_callback;
270 if (m_user_data && m_deleter) {
271 m_deleter(m_user_data);
287 ~KernelNotifications()
334 ~KernelValidationInterface()
348 btck_Block::copy(btck_Block::ref(&block)),
349 btck_BlockValidationState::ref(&stateIn));
357 btck_Block::copy(btck_Block::ref(&block)),
358 btck_BlockTreeEntry::ref(pindex));
366 btck_Block::copy(btck_Block::ref(&block)),
367 btck_BlockTreeEntry::ref(pindex));
375 btck_Block::copy(btck_Block::ref(&block)),
376 btck_BlockTreeEntry::ref(pindex));
381struct ContextOptions {
382 mutable Mutex m_mutex;
383 std::unique_ptr<const CChainParams> m_chainparams
GUARDED_BY(m_mutex);
385 std::shared_ptr<KernelValidationInterface> m_validation_interface
GUARDED_BY(m_mutex);
391 std::unique_ptr<kernel::Context>
m_context;
395 std::unique_ptr<util::SignalInterrupt> m_interrupt;
397 std::unique_ptr<ValidationSignals>
m_signals;
399 std::unique_ptr<const CChainParams> m_chainparams;
401 std::shared_ptr<KernelValidationInterface> m_validation_interface;
403 Context(
const ContextOptions* options,
bool& sane)
405 m_interrupt{
std::make_unique<
util::SignalInterrupt>()}
408 LOCK(options->m_mutex);
409 if (options->m_chainparams) {
410 m_chainparams = std::make_unique<const CChainParams>(*options->m_chainparams);
412 if (options->m_notifications) {
415 if (options->m_validation_interface) {
416 m_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateTaskRunner>());
417 m_validation_interface = options->m_validation_interface;
422 if (!m_chainparams) {
427 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr});
444struct ChainstateManagerOptions {
445 mutable Mutex m_mutex;
448 std::shared_ptr<const Context>
m_context;
451 ChainstateManagerOptions(
const std::shared_ptr<const Context>& context,
const fs::path& data_dir,
const fs::path& blocks_dir)
453 .chainparams = *context->m_chainparams,
457 m_blockman_options{
node::BlockManager::Options{
458 .chainparams = *context->m_chainparams,
459 .blocks_dir = blocks_dir,
462 .path = data_dir /
"blocks" /
"index",
465 m_context{context}, m_chainstate_load_options{
node::ChainstateLoadOptions{}}
471 std::unique_ptr<ChainstateManager> m_chainman;
472 std::shared_ptr<const Context>
m_context;
474 ChainMan(std::unique_ptr<ChainstateManager> chainman, std::shared_ptr<const Context> context)
485struct btck_Context : Handle<btck_Context, std::shared_ptr<const Context>> {};
500 if (raw_transaction ==
nullptr && raw_transaction_len != 0) {
504 DataStream stream{std::span{
reinterpret_cast<const std::byte*
>(raw_transaction), raw_transaction_len}};
513 return btck_Transaction::get(transaction)->vout.size();
518 const CTransaction& tx = *btck_Transaction::get(transaction);
520 return btck_TransactionOutput::ref(&tx.
vout[output_index]);
525 return btck_Transaction::get(transaction)->vin.size();
530 assert(input_index < btck_Transaction::get(transaction)->vin.size());
531 return btck_TransactionInput::ref(&btck_Transaction::get(transaction)->vin[input_index]);
536 return btck_Txid::ref(&btck_Transaction::get(transaction)->GetHash());
541 return btck_Transaction::copy(transaction);
547 WriterStream ws{writer, user_data};
562 if (script_pubkey ==
nullptr && script_pubkey_len != 0) {
565 auto data = std::span{
reinterpret_cast<const uint8_t*
>(script_pubkey), script_pubkey_len};
566 return btck_ScriptPubkey::create(
data.begin(),
data.end());
571 const auto& script_pubkey{btck_ScriptPubkey::get(script_pubkey_)};
572 return writer(script_pubkey.data(), script_pubkey.size(), user_data);
577 return btck_ScriptPubkey::copy(script_pubkey);
582 delete script_pubkey;
587 return btck_TransactionOutput::create(amount, btck_ScriptPubkey::get(script_pubkey));
592 return btck_TransactionOutput::copy(output);
597 return btck_ScriptPubkey::ref(&btck_TransactionOutput::get(output).scriptPubKey);
602 return btck_TransactionOutput::get(output).nValue;
611 const int64_t amount,
614 const unsigned int input_index,
634 std::vector<CTxOut> spent_outputs;
635 if (spent_outputs_ !=
nullptr) {
636 assert(spent_outputs_len == tx.vin.size());
637 spent_outputs.reserve(spent_outputs_len);
638 for (
size_t i = 0; i < spent_outputs_len; i++) {
639 const CTxOut& tx_out{btck_TransactionOutput::get(spent_outputs_[i])};
640 spent_outputs.push_back(tx_out);
644 assert(input_index < tx.vin.size());
648 txdata.
Init(tx, std::move(spent_outputs));
651 bool result =
VerifyScript(tx.vin[input_index].scriptSig,
652 btck_ScriptPubkey::get(script_pubkey),
653 &tx.vin[input_index].scriptWitness,
657 return result ? 1 : 0;
662 return btck_TransactionInput::copy(input);
667 return btck_TransactionOutPoint::ref(&btck_TransactionInput::get(input).prevout);
677 return btck_TransactionOutPoint::copy(out_point);
682 return btck_TransactionOutPoint::get(out_point).n;
687 return btck_Txid::ref(&btck_TransactionOutPoint::get(out_point).hash);
697 return btck_Txid::copy(txid);
702 std::memcpy(output, btck_Txid::get(txid).begin(), 32);
707 return btck_Txid::get(txid1) == btck_Txid::get(txid2);
753 return btck_LoggingConnection::create(callback, user_data, user_data_destroy_callback);
754 }
catch (
const std::exception&) {
766 switch (chain_type) {
788 return btck_ChainParameters::copy(chain_parameters);
793 delete chain_parameters;
798 return btck_ContextOptions::create();
804 LOCK(btck_ContextOptions::get(options).m_mutex);
805 btck_ContextOptions::get(options).m_chainparams = std::make_unique<const CChainParams>(btck_ChainParameters::get(chain_parameters));
811 LOCK(btck_ContextOptions::get(options).m_mutex);
812 btck_ContextOptions::get(options).m_notifications = std::make_shared<KernelNotifications>(notifications);
817 LOCK(btck_ContextOptions::get(options).m_mutex);
818 btck_ContextOptions::get(options).m_validation_interface = std::make_shared<KernelValidationInterface>(vi_cbs);
829 const ContextOptions* opts = options ? &btck_ContextOptions::get(options) :
nullptr;
830 auto context{std::make_shared<const Context>(opts, sane)};
832 LogError(
"Kernel context sanity check failed.");
835 return btck_Context::create(context);
840 return btck_Context::copy(context);
845 return (*btck_Context::get(context)->m_interrupt)() ? 0 : -1;
855 if (!btck_BlockTreeEntry::get(entry).pprev) {
856 LogInfo(
"Genesis block has no previous.");
860 return btck_BlockTreeEntry::ref(btck_BlockTreeEntry::get(entry).pprev);
865 auto& block_validation_state = btck_BlockValidationState::get(block_validation_state_);
873 auto& block_validation_state = btck_BlockValidationState::get(block_validation_state_);
874 switch (block_validation_state.GetResult()) {
899 if (data_dir ==
nullptr || data_dir_len == 0 || blocks_dir ==
nullptr || blocks_dir_len == 0) {
900 LogError(
"Failed to create chainstate manager options: dir must be non-null and non-empty");
905 fs::create_directories(abs_data_dir);
907 fs::create_directories(abs_blocks_dir);
908 return btck_ChainstateManagerOptions::create(btck_Context::get(context), abs_data_dir, abs_blocks_dir);
909 }
catch (
const std::exception& e) {
910 LogError(
"Failed to create chainstate manager options: %s", e.what());
917 LOCK(btck_ChainstateManagerOptions::get(opts).m_mutex);
918 btck_ChainstateManagerOptions::get(opts).m_chainman_options.worker_threads_num = worker_threads;
928 if (wipe_block_tree_db == 1 && wipe_chainstate_db != 1) {
929 LogError(
"Wiping the block tree db without also wiping the chainstate db is currently unsupported.");
932 auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)};
934 opts.m_blockman_options.block_tree_db_params.wipe_data = wipe_block_tree_db == 1;
935 opts.m_chainstate_load_options.wipe_chainstate_db = wipe_chainstate_db == 1;
941 int block_tree_db_in_memory)
943 auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)};
945 opts.m_blockman_options.block_tree_db_params.memory_only = block_tree_db_in_memory == 1;
950 int chainstate_db_in_memory)
952 auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)};
954 opts.m_chainstate_load_options.coins_db_in_memory = chainstate_db_in_memory == 1;
960 auto& opts{btck_ChainstateManagerOptions::get(chainman_opts)};
961 std::unique_ptr<ChainstateManager> chainman;
964 chainman = std::make_unique<ChainstateManager>(*opts.m_context->m_interrupt, opts.m_chainman_options, opts.m_blockman_options);
965 }
catch (
const std::exception& e) {
966 LogError(
"Failed to create chainstate manager: %s", e.what());
971 const auto chainstate_load_opts{
WITH_LOCK(opts.m_mutex,
return opts.m_chainstate_load_options)};
974 auto [status, chainstate_err]{
node::LoadChainstate(*chainman, cache_sizes, chainstate_load_opts)};
976 LogError(
"Failed to load chain state from your data directory: %s", chainstate_err.original);
981 LogError(
"Failed to verify loaded chain state from your datadir: %s", chainstate_err.original);
985 for (
Chainstate* chainstate :
WITH_LOCK(chainman->GetMutex(),
return chainman->GetAll())) {
987 if (!chainstate->ActivateBestChain(state,
nullptr)) {
992 }
catch (
const std::exception& e) {
993 LogError(
"Failed to load chainstate: %s", e.what());
997 return btck_ChainstateManager::create(std::move(chainman), opts.m_context);
1002 auto block_index =
WITH_LOCK(btck_ChainstateManager::get(chainman).m_chainman->GetMutex(),
1003 return btck_ChainstateManager::get(chainman).m_chainman->m_blockman.LookupBlockIndex(btck_BlockHash::get(block_hash)));
1008 return btck_BlockTreeEntry::ref(block_index);
1014 LOCK(btck_ChainstateManager::get(chainman).m_chainman->GetMutex());
1015 for (
Chainstate* chainstate : btck_ChainstateManager::get(chainman).m_chainman->GetAll()) {
1016 if (chainstate->CanFlushToDisk()) {
1017 chainstate->ForceFlushStateToDisk();
1018 chainstate->ResetCoinsViews();
1029 std::vector<fs::path> import_files;
1030 import_files.reserve(block_file_paths_data_len);
1031 for (uint32_t i = 0; i < block_file_paths_data_len; i++) {
1032 if (block_file_paths_data[i] !=
nullptr) {
1033 import_files.emplace_back(std::string{block_file_paths_data[i], block_file_paths_lens[i]}.c_str());
1037 }
catch (
const std::exception& e) {
1038 LogError(
"Failed to import blocks: %s", e.what());
1046 if (raw_block ==
nullptr && raw_block_length != 0) {
1049 auto block{std::make_shared<CBlock>()};
1051 DataStream stream{std::span{
reinterpret_cast<const std::byte*
>(raw_block), raw_block_length}};
1060 return btck_Block::create(block);
1065 return btck_Block::copy(block);
1070 return btck_Block::get(block)->vtx.size();
1075 assert(index < btck_Block::get(block)->vtx.size());
1076 return btck_Transaction::ref(&btck_Block::get(block)->vtx[index]);
1082 WriterStream ws{writer, user_data};
1092 return btck_BlockHash::create(btck_Block::get(block)->GetHash());
1102 auto block{std::make_shared<CBlock>()};
1103 if (!btck_ChainstateManager::get(chainman).m_chainman->m_blockman.ReadBlock(*block, btck_BlockTreeEntry::get(entry))) {
1107 return btck_Block::create(block);
1112 return btck_BlockTreeEntry::get(entry).nHeight;
1117 return btck_BlockHash::ref(btck_BlockTreeEntry::get(entry).phashBlock);
1122 return btck_BlockHash::create(std::span<const unsigned char>{block_hash, 32});
1127 return btck_BlockHash::copy(block_hash);
1132 std::memcpy(output, btck_BlockHash::get(block_hash).begin(), 32);
1137 return btck_BlockHash::get(hash1) == btck_BlockHash::get(hash2);
1147 auto block_undo{std::make_shared<CBlockUndo>()};
1148 if (btck_BlockTreeEntry::get(entry).
nHeight < 1) {
1150 return btck_BlockSpentOutputs::create(block_undo);
1152 if (!btck_ChainstateManager::get(chainman).m_chainman->m_blockman.ReadBlockUndo(*block_undo, btck_BlockTreeEntry::get(entry))) {
1153 LogError(
"Failed to read block spent outputs data.");
1156 return btck_BlockSpentOutputs::create(block_undo);
1161 return btck_BlockSpentOutputs::copy(block_spent_outputs);
1166 return btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.size();
1171 assert(transaction_index < btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.size());
1172 const auto* tx_undo{&btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.at(transaction_index)};
1173 return btck_TransactionSpentOutputs::ref(tx_undo);
1178 delete block_spent_outputs;
1183 return btck_TransactionSpentOutputs::copy(transaction_spent_outputs);
1188 return btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.size();
1193 delete transaction_spent_outputs;
1198 assert(coin_index < btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.size());
1199 const Coin* coin{&btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.at(coin_index)};
1200 return btck_Coin::ref(coin);
1205 return btck_Coin::copy(coin);
1210 return btck_Coin::get(coin).nHeight;
1215 return btck_Coin::get(coin).IsCoinBase() ? 1 : 0;
1220 return btck_TransactionOutput::ref(&btck_Coin::get(coin).
out);
1234 auto result = btck_ChainstateManager::get(chainman).m_chainman->ProcessNewBlock(btck_Block::get(block),
true,
true, &new_block);
1236 *_new_block = new_block ? 1 : 0;
1238 return result ? 0 : -1;
1243 return btck_Chain::ref(&
WITH_LOCK(btck_ChainstateManager::get(chainman).m_chainman->GetMutex(),
return btck_ChainstateManager::get(chainman).m_chainman->ActiveChain()));
1249 return btck_Chain::get(chain).Height();
1255 return btck_BlockTreeEntry::ref(btck_Chain::get(chain)[height]);
1261 return btck_Chain::get(chain).Contains(&btck_BlockTreeEntry::get(entry)) ? 1 : 0;
int btck_block_to_bytes(const btck_Block *block, btck_WriteBytes writer, void *user_data)
btck_ScriptPubkey * btck_script_pubkey_copy(const btck_ScriptPubkey *script_pubkey)
Copy a script pubkey.
void btck_logging_disable()
This disables the global internal logger.
btck_BlockHash * btck_block_hash_copy(const btck_BlockHash *block_hash)
Copy a block hash.
void btck_txid_destroy(btck_Txid *txid)
Destroy the txid.
int btck_script_pubkey_to_bytes(const btck_ScriptPubkey *script_pubkey_, btck_WriteBytes writer, void *user_data)
void btck_script_pubkey_destroy(btck_ScriptPubkey *script_pubkey)
Destroy the script pubkey.
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.
void btck_logging_enable_category(btck_LogCategory category)
Enable a specific log category for the global internal logger.
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_destroy(btck_Context *context)
Destroy the context.
void btck_context_options_set_notifications(btck_ContextOptions *options, btck_NotificationInterfaceCallbacks notifications)
Set the kernel notifications for the context options.
btck_ContextOptions * btck_context_options_create()
Creates an empty context options.
void btck_transaction_destroy(btck_Transaction *transaction)
Destroy the transaction.
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.
const btck_Txid * btck_transaction_out_point_get_txid(const btck_TransactionOutPoint *out_point)
Get the txid from the transaction out point.
void btck_logging_disable_category(btck_LogCategory category)
Disable a specific log category for the global internal logger.
void btck_transaction_spent_outputs_destroy(btck_TransactionSpentOutputs *transaction_spent_outputs)
Destroy the transaction spent outputs.
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...
void btck_chain_parameters_destroy(btck_ChainParameters *chain_parameters)
Destroy the chain parameters.
size_t btck_transaction_count_outputs(const btck_Transaction *transaction)
Get the number of outputs of a transaction.
void btck_block_destroy(btck_Block *block)
Destroy the block.
btck_ScriptPubkey * btck_script_pubkey_create(const void *script_pubkey, size_t script_pubkey_len)
Create a script pubkey from serialized data.
btck_Context * btck_context_copy(const btck_Context *context)
Copy the context.
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.
btck_ValidationMode btck_block_validation_state_get_validation_mode(const btck_BlockValidationState *block_validation_state_)
Returns the validation mode from an opaque block validation state 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.
static const kernel::Context btck_context_static
btck_ChainParameters * btck_chain_parameters_copy(const btck_ChainParameters *chain_parameters)
Copy the chain parameters.
size_t btck_block_count_transactions(const btck_Block *block)
Count the number of transactions contained in a block.
void btck_context_options_destroy(btck_ContextOptions *options)
Destroy the context options.
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.
btck_BlockSpentOutputs * btck_block_spent_outputs_copy(const btck_BlockSpentOutputs *block_spent_outputs)
Copy a block's spent outputs.
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.
const std::function< std::string(const char *)> G_TRANSLATION_FUN
btck_BlockHash * btck_block_get_hash(const btck_Block *block)
Calculate and return the hash of a block.
btck_Txid * btck_txid_copy(const btck_Txid *txid)
Copy a txid.
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.
void btck_transaction_out_point_destroy(btck_TransactionOutPoint *out_point)
Destroy the transaction out point.
int btck_coin_is_coinbase(const btck_Coin *coin)
Returns whether the containing transaction was a coinbase.
void btck_txid_to_bytes(const btck_Txid *txid, unsigned char output[32])
void btck_block_hash_destroy(btck_BlockHash *hash)
Destroy the block hash.
int btck_script_pubkey_verify(const btck_ScriptPubkey *script_pubkey, const int64_t amount, const btck_Transaction *tx_to, const btck_TransactionOutput **spent_outputs_, size_t spent_outputs_len, const unsigned int input_index, const btck_ScriptVerificationFlags flags, btck_ScriptVerifyStatus *status)
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.
int btck_context_interrupt(btck_Context *context)
Interrupt can be used to halt long-running validation functions like when reindexing,...
void btck_transaction_input_destroy(btck_TransactionInput *input)
Destroy the transaction input.
const btck_TransactionOutput * btck_transaction_get_output_at(const btck_Transaction *transaction, size_t output_index)
Get the transaction outputs at the provided index.
void btck_logging_set_level_category(btck_LogCategory category, btck_LogLevel level)
Set the log level of the global internal logger.
void btck_coin_destroy(btck_Coin *coin)
Destroy the coin.
void btck_context_options_set_chainparams(btck_ContextOptions *options, const btck_ChainParameters *chain_parameters)
btck_BlockHash * btck_block_hash_create(const unsigned char block_hash[32])
Create a block hash from its raw 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.
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_TransactionOutPoint * btck_transaction_out_point_copy(const btck_TransactionOutPoint *out_point)
Copy a transaction out point.
btck_TransactionInput * btck_transaction_input_copy(const btck_TransactionInput *input)
Copy a transaction input.
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.
const btck_BlockTreeEntry * btck_chain_get_by_height(const btck_Chain *chain, int height)
Retrieve a block tree entry by its height in the currently active chain.
btck_TransactionOutput * btck_transaction_output_copy(const btck_TransactionOutput *output)
Copy a transaction output.
int btck_block_hash_equals(const btck_BlockHash *hash1, const btck_BlockHash *hash2)
void btck_logging_connection_destroy(btck_LoggingConnection *connection)
Stop logging and destroy the logging connection.
btck_TransactionSpentOutputs * btck_transaction_spent_outputs_copy(const btck_TransactionSpentOutputs *transaction_spent_outputs)
Copy a transaction's spent outputs.
int32_t btck_block_tree_entry_get_height(const btck_BlockTreeEntry *entry)
Return the height of a certain block tree entry.
void btck_block_spent_outputs_destroy(btck_BlockSpentOutputs *block_spent_outputs)
Destroy the block spent outputs.
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_chain_get_height(const btck_Chain *chain)
Return the height of the tip of the chain.
int btck_txid_equals(const btck_Txid *txid1, const btck_Txid *txid2)
btck_Block * btck_block_copy(const btck_Block *block)
Copy a block.
void btck_chainstate_manager_destroy(btck_ChainstateManager *chainman)
Destroy the chainstate manager.
void btck_chainstate_manager_options_destroy(btck_ChainstateManagerOptions *options)
Destroy the chainstate manager options.
btck_Transaction * btck_transaction_create(const void *raw_transaction, size_t raw_transaction_len)
Create a new transaction from the serialized data.
btck_Coin * btck_coin_copy(const btck_Coin *coin)
Copy a coin.
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_logging_set_options(const btck_LoggingOptions options)
Set some options for the global internal logger.
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_Transaction * btck_transaction_copy(const btck_Transaction *transaction)
Copy a transaction.
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_BlockValidationResult btck_block_validation_state_get_block_validation_result(const btck_BlockValidationState *block_validation_state_)
Returns the validation result from an opaque block validation state pointer.
void btck_block_hash_to_bytes(const btck_BlockHash *block_hash, unsigned char output[32])
void btck_transaction_output_destroy(btck_TransactionOutput *output)
Destroy the transaction output.
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
uint8_t btck_LogLevel
The level at which logs should be produced.
int(* btck_WriteBytes)(const void *bytes, size_t size, void *userdata)
Function signature for serializing data.
#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_BlockValidationResult_INVALID_PREV
A block this one builds on is invalid.
#define btck_LogCategory_MEMPOOL
#define btck_LogLevel_TRACE
#define btck_ChainType_TESTNET
#define btck_SynchronizationState_INIT_REINDEX
void(* btck_LogCallback)(void *user_data, const char *message, size_t message_len)
Callback function types.
#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_PRUNE
uint8_t btck_SynchronizationState
Current sync state passed to tip changed callbacks.
#define btck_ChainType_TESTNET_4
#define btck_LogCategory_COINDB
#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.
void(* btck_DestroyCallback)(void *user_data)
Function signature for freeing user data.
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_LogCategory_RAND
#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_SynchronizationState_POST_INIT
#define btck_BlockValidationResult_MISSING_PREV
We don't have the previous block the checked one is built on.
#define btck_LogCategory_ALL
uint8_t btck_ScriptVerifyStatus
A collection of status codes that may be issued by the script verify function.
#define btck_ValidationMode_INTERNAL_ERROR
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_BlockValidationResult_INVALID_HEADER
invalid proof of work or time too old
uint8_t btck_Warning
Possible warning types issued by validation.
#define btck_BlockValidationResult_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
#define btck_LogCategory_LEVELDB
#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_LogCategory_BLOCKSTORAGE
#define btck_ValidationMode_VALID
#define btck_LogCategory_KERNEL
#define btck_BlockValidationResult_MUTATED
the block's data didn't match the data committed to by the PoW
#define btck_SynchronizationState_INIT_DOWNLOAD
bool m_always_print_category_level
bool m_log_sourcelocations
void SetLogLevel(Level level)
std::list< std::function< void(conststd::string &)> >::iterator PushBackCallback(std::function< void(const std::string &)> fun) EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Connect a slot to the print signal and return the connection.
void DisableLogging() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Disable logging This offers a slight speedup and slightly smaller memory usage compared to leaving th...
bool StartLogging() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Start logging (and flush all buffered messages)
void EnableCategory(LogFlags flag)
void DeleteCallback(std::list< std::function< void(const std::string &)> >::iterator it) EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Delete a connection.
void DisconnectTestLogger() EXCLUSIVE_LOCKS_REQUIRED(!m_cs)
Only for testing.
void AddCategoryLogLevel(LogFlags category, Level level)
void DisableCategory(LogFlags flag)
The block chain is a tree shaped structure starting with the genesis block at the root,...
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
static std::unique_ptr< const CChainParams > Main()
static std::unique_ptr< const CChainParams > RegTest(const RegTestOptions &options)
static std::unique_ptr< const CChainParams > TestNet()
static std::unique_ptr< const CChainParams > TestNet4()
static std::unique_ptr< const CChainParams > SigNet(const SigNetOptions &options)
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
An output of a transaction.
Implement this to subscribe to events generated in validation and mempool.
virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &block)
Notifies listeners that a block which builds directly on our current tip has been received and connec...
virtual void BlockConnected(ChainstateRole role, const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being connected.
virtual void BlockChecked(const std::shared_ptr< const CBlock > &, const BlockValidationState &)
Notifies listeners of a block validation result.
virtual void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being disconnected Provides the block that was disconnected.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Double ended buffer combining vector and stream-like interfaces.
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
std::string ToString() const
A base class defining functions for notifying about certain kernel events.
virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync)
virtual void fatalError(const bilingual_str &message)
The fatal error notification is sent to notify the user when an error occurs in kernel code that can'...
virtual void warningSet(Warning id, const bilingual_str &message)
virtual void progress(const bilingual_str &title, int progress_percent, bool resume_possible)
virtual InterruptResult blockTip(SynchronizationState state, const CBlockIndex &index, double verification_progress)
virtual void flushError(const bilingual_str &message)
The flush error notification is sent to notify the user that an error occurred while flushing block d...
virtual void warningUnset(Warning id)
static constexpr script_verify_flags from_int(value_type f)
boost::signals2::scoped_connection m_connection
@ BLOCK_HEADER_LOW_WORK
the block header may be on a too-little-work chain
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
@ BLOCK_RESULT_UNSET
initial value. Block has not yet been rejected
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static path absolute(const path &p)
static path PathFromString(const std::string &string)
Convert byte string to path object.
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, script_verify_flags flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ FAIL
Just act as if the signature was invalid.
static constexpr size_t DEFAULT_KERNEL_CACHE
Suggested default amount of cache reserved for the kernel (bytes)
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
BCLog::Logger & LogInstance()
#define LogDebug(category,...)
std::ostream & operator<<(std::ostream &os, BigO const &bigO)
std::variant< std::monostate, Interrupted > InterruptResult
Simple result type for functions that need to propagate an interrupt status and don't have other retu...
@ UNKNOWN_NEW_RULES_ACTIVATED
@ LARGE_WORK_INVALID_CHAIN
util::Result< void > SanityChecks(const Context &)
Ensure a usable environment with all necessary library support.
ChainstateLoadResult LoadChainstate(ChainstateManager &chainman, const CacheSizes &cache_sizes, const ChainstateLoadOptions &options)
ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager &chainman, const ChainstateLoadOptions &options)
void ImportBlocks(ChainstateManager &chainman, std::span< const fs::path > import_paths)
ValidationSignals & m_signals
std::shared_ptr< Chain::Notifications > m_notifications
static constexpr TransactionSerParams TX_WITH_WITNESS
void Serialize(Stream &, V)=delete
constexpr deserialize_type deserialize
Application-specific storage settings.
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
Options controlling the format of log messages.
int always_print_category_levels
Prepend the log category and level to log messages.
int log_time_micros
Log timestamps in microsecond precision.
int log_threadnames
Prepend the name of the thread to log messages.
int log_sourcelocations
Prepend the source location to log messages.
int log_timestamps
Prepend a timestamp to log messages.
A struct for holding the kernel notification callbacks.
btck_NotifyWarningUnset warning_unset
A previous condition leading to the issuance of a warning is no longer given.
btck_NotifyBlockTip block_tip
The chain's tip was updated to the provided block entry.
btck_NotifyWarningSet warning_set
A warning issued by the kernel library during validation.
btck_NotifyFlushError flush_error
An error encountered when flushing data to disk.
btck_NotifyProgress progress
Reports on current block synchronization progress.
btck_NotifyFatalError fatal_error
An unrecoverable system error encountered by the library.
btck_DestroyCallback user_data_destroy
Frees the provided user data structure.
void * user_data
Holds a user-defined opaque structure that is passed to the notification callbacks.
btck_NotifyHeaderTip header_tip
A new best block header was added.
Holds the validation interface callbacks.
btck_DestroyCallback user_data_destroy
Frees the provided user data structure.
btck_ValidationInterfaceBlockConnected block_connected
Called when a block is valid and has now been connected to the best chain.
btck_ValidationInterfaceBlockChecked block_checked
Called when a new block has been fully validated.
btck_ValidationInterfaceBlockDisconnected block_disconnected
Called during a re-org when a block has been removed from the best chain.
void * user_data
Holds a user-defined opaque structure that is passed to the validation interface callbacks.
btck_ValidationInterfacePoWValidBlock pow_valid_block
Called when a new block extends the header chain and has a valid transaction and segwit merkle root.
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
An options struct for ChainstateManager, more ergonomically referred to as ChainstateManager::Options...
Context struct holding the kernel library's logically global state, and passed to external libbitcoin...
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
This header provides an interface and simple implementation for a task runner.
SynchronizationState
Current sync state passed to tip changed callbacks.