mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 23:29:12 +01:00
kernel: Add function to read block undo data from disk to C header
This adds functions for reading the undo data from disk with a retrieved block tree entry. The undo data of a block contains all the spent script pubkeys of all the transactions in a block. For ease of understanding the undo data is renamed to spent outputs with seperate data structures exposed for a block's and a transaction's spent outputs. In normal operations undo data is used during re-orgs. This data might also be useful for building external indexes, or to scan for silent payment transactions. Internally the block undo data contains a vector of transaction undo data which contains a vector of the coins consumed. The coins are all int the order of the transaction inputs of the consuming transactions. Each coin can be used to retrieve a transaction output and in turn a script pubkey and amount. This translates to the three-level hierarchy the api provides: Block spent outputs contain transaction spent outputs, which contain individual coins. Each coin includes the associated output, the height of the block is contained in, and whether it is from a coinbase transaction.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <kernel/bitcoinkernel.h>
|
||||
|
||||
#include <chain.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <kernel/caches.h>
|
||||
@@ -28,6 +29,7 @@
|
||||
#include <sync.h>
|
||||
#include <tinyformat.h>
|
||||
#include <uint256.h>
|
||||
#include <undo.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/result.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
@@ -485,6 +487,9 @@ struct btck_ChainParameters : Handle<btck_ChainParameters, CChainParams> {};
|
||||
struct btck_ChainstateManagerOptions : Handle<btck_ChainstateManagerOptions, ChainstateManagerOptions> {};
|
||||
struct btck_ChainstateManager : Handle<btck_ChainstateManager, ChainMan> {};
|
||||
struct btck_Chain : Handle<btck_Chain, CChain> {};
|
||||
struct btck_BlockSpentOutputs : Handle<btck_BlockSpentOutputs, std::shared_ptr<CBlockUndo>> {};
|
||||
struct btck_TransactionSpentOutputs : Handle<btck_TransactionSpentOutputs, CTxUndo> {};
|
||||
struct btck_Coin : Handle<btck_Coin, Coin> {};
|
||||
|
||||
btck_Transaction* btck_transaction_create(const void* raw_transaction, size_t raw_transaction_len)
|
||||
{
|
||||
@@ -1004,6 +1009,89 @@ btck_Block* btck_block_read(const btck_ChainstateManager* chainman, const btck_B
|
||||
return btck_Block::create(block);
|
||||
}
|
||||
|
||||
btck_BlockSpentOutputs* btck_block_spent_outputs_read(const btck_ChainstateManager* chainman, const btck_BlockTreeEntry* entry)
|
||||
{
|
||||
auto block_undo{std::make_shared<CBlockUndo>()};
|
||||
if (btck_BlockTreeEntry::get(entry).nHeight < 1) {
|
||||
LogDebug(BCLog::KERNEL, "The genesis block does not have any spent outputs.");
|
||||
return btck_BlockSpentOutputs::create(block_undo);
|
||||
}
|
||||
if (!btck_ChainstateManager::get(chainman).m_chainman->m_blockman.ReadBlockUndo(*block_undo, btck_BlockTreeEntry::get(entry))) {
|
||||
LogError("Failed to read block spent outputs data.");
|
||||
return nullptr;
|
||||
}
|
||||
return btck_BlockSpentOutputs::create(block_undo);
|
||||
}
|
||||
|
||||
btck_BlockSpentOutputs* btck_block_spent_outputs_copy(const btck_BlockSpentOutputs* block_spent_outputs)
|
||||
{
|
||||
return btck_BlockSpentOutputs::copy(block_spent_outputs);
|
||||
}
|
||||
|
||||
size_t btck_block_spent_outputs_count(const btck_BlockSpentOutputs* block_spent_outputs)
|
||||
{
|
||||
return btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.size();
|
||||
}
|
||||
|
||||
const btck_TransactionSpentOutputs* btck_block_spent_outputs_get_transaction_spent_outputs_at(const btck_BlockSpentOutputs* block_spent_outputs, size_t transaction_index)
|
||||
{
|
||||
assert(transaction_index < btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.size());
|
||||
const auto* tx_undo{&btck_BlockSpentOutputs::get(block_spent_outputs)->vtxundo.at(transaction_index)};
|
||||
return btck_TransactionSpentOutputs::ref(tx_undo);
|
||||
}
|
||||
|
||||
void btck_block_spent_outputs_destroy(btck_BlockSpentOutputs* block_spent_outputs)
|
||||
{
|
||||
delete block_spent_outputs;
|
||||
}
|
||||
|
||||
btck_TransactionSpentOutputs* btck_transaction_spent_outputs_copy(const btck_TransactionSpentOutputs* transaction_spent_outputs)
|
||||
{
|
||||
return btck_TransactionSpentOutputs::copy(transaction_spent_outputs);
|
||||
}
|
||||
|
||||
size_t btck_transaction_spent_outputs_count(const btck_TransactionSpentOutputs* transaction_spent_outputs)
|
||||
{
|
||||
return btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.size();
|
||||
}
|
||||
|
||||
void btck_transaction_spent_outputs_destroy(btck_TransactionSpentOutputs* transaction_spent_outputs)
|
||||
{
|
||||
delete transaction_spent_outputs;
|
||||
}
|
||||
|
||||
const btck_Coin* btck_transaction_spent_outputs_get_coin_at(const btck_TransactionSpentOutputs* transaction_spent_outputs, size_t coin_index)
|
||||
{
|
||||
assert(coin_index < btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.size());
|
||||
const Coin* coin{&btck_TransactionSpentOutputs::get(transaction_spent_outputs).vprevout.at(coin_index)};
|
||||
return btck_Coin::ref(coin);
|
||||
}
|
||||
|
||||
btck_Coin* btck_coin_copy(const btck_Coin* coin)
|
||||
{
|
||||
return btck_Coin::copy(coin);
|
||||
}
|
||||
|
||||
uint32_t btck_coin_confirmation_height(const btck_Coin* coin)
|
||||
{
|
||||
return btck_Coin::get(coin).nHeight;
|
||||
}
|
||||
|
||||
int btck_coin_is_coinbase(const btck_Coin* coin)
|
||||
{
|
||||
return btck_Coin::get(coin).IsCoinBase() ? 1 : 0;
|
||||
}
|
||||
|
||||
const btck_TransactionOutput* btck_coin_get_output(const btck_Coin* coin)
|
||||
{
|
||||
return btck_TransactionOutput::ref(&btck_Coin::get(coin).out);
|
||||
}
|
||||
|
||||
void btck_coin_destroy(btck_Coin* coin)
|
||||
{
|
||||
delete coin;
|
||||
}
|
||||
|
||||
int btck_chainstate_manager_process_block(
|
||||
btck_ChainstateManager* chainman,
|
||||
const btck_Block* block,
|
||||
|
||||
Reference in New Issue
Block a user