mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-27 07:55:39 +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:
@@ -790,6 +790,105 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
class CoinApi
|
||||
{
|
||||
private:
|
||||
auto impl() const
|
||||
{
|
||||
return static_cast<const Derived*>(this)->get();
|
||||
}
|
||||
|
||||
friend Derived;
|
||||
CoinApi() = default;
|
||||
|
||||
public:
|
||||
uint32_t GetConfirmationHeight() const { return btck_coin_confirmation_height(impl()); }
|
||||
|
||||
bool IsCoinbase() const { return btck_coin_is_coinbase(impl()) == 1; }
|
||||
|
||||
TransactionOutputView GetOutput() const
|
||||
{
|
||||
return TransactionOutputView{btck_coin_get_output(impl())};
|
||||
}
|
||||
};
|
||||
|
||||
class CoinView : public View<btck_Coin>, public CoinApi<CoinView>
|
||||
{
|
||||
public:
|
||||
explicit CoinView(const btck_Coin* ptr) : View{ptr} {}
|
||||
};
|
||||
|
||||
class Coin : public Handle<btck_Coin, btck_coin_copy, btck_coin_destroy>, public CoinApi<Coin>
|
||||
{
|
||||
public:
|
||||
Coin(btck_Coin* coin) : Handle{coin} {}
|
||||
|
||||
Coin(const CoinView& view) : Handle{view} {}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
class TransactionSpentOutputsApi
|
||||
{
|
||||
private:
|
||||
auto impl() const
|
||||
{
|
||||
return static_cast<const Derived*>(this)->get();
|
||||
}
|
||||
|
||||
friend Derived;
|
||||
TransactionSpentOutputsApi() = default;
|
||||
|
||||
public:
|
||||
size_t Count() const
|
||||
{
|
||||
return btck_transaction_spent_outputs_count(impl());
|
||||
}
|
||||
|
||||
CoinView GetCoin(size_t index) const
|
||||
{
|
||||
return CoinView{btck_transaction_spent_outputs_get_coin_at(impl(), index)};
|
||||
}
|
||||
|
||||
MAKE_RANGE_METHOD(Coins, Derived, &TransactionSpentOutputsApi<Derived>::Count, &TransactionSpentOutputsApi<Derived>::GetCoin, *static_cast<const Derived*>(this))
|
||||
};
|
||||
|
||||
class TransactionSpentOutputsView : public View<btck_TransactionSpentOutputs>, public TransactionSpentOutputsApi<TransactionSpentOutputsView>
|
||||
{
|
||||
public:
|
||||
explicit TransactionSpentOutputsView(const btck_TransactionSpentOutputs* ptr) : View{ptr} {}
|
||||
};
|
||||
|
||||
class TransactionSpentOutputs : public Handle<btck_TransactionSpentOutputs, btck_transaction_spent_outputs_copy, btck_transaction_spent_outputs_destroy>,
|
||||
public TransactionSpentOutputsApi<TransactionSpentOutputs>
|
||||
{
|
||||
public:
|
||||
TransactionSpentOutputs(btck_TransactionSpentOutputs* transaction_spent_outputs) : Handle{transaction_spent_outputs} {}
|
||||
|
||||
TransactionSpentOutputs(const TransactionSpentOutputsView& view) : Handle{view} {}
|
||||
};
|
||||
|
||||
class BlockSpentOutputs : public Handle<btck_BlockSpentOutputs, btck_block_spent_outputs_copy, btck_block_spent_outputs_destroy>
|
||||
{
|
||||
public:
|
||||
BlockSpentOutputs(btck_BlockSpentOutputs* block_spent_outputs)
|
||||
: Handle{block_spent_outputs}
|
||||
{
|
||||
}
|
||||
|
||||
size_t Count() const
|
||||
{
|
||||
return btck_block_spent_outputs_count(get());
|
||||
}
|
||||
|
||||
TransactionSpentOutputsView GetTxSpentOutputs(size_t tx_undo_index) const
|
||||
{
|
||||
return TransactionSpentOutputsView{btck_block_spent_outputs_get_transaction_spent_outputs_at(get(), tx_undo_index)};
|
||||
}
|
||||
|
||||
MAKE_RANGE_METHOD(TxsSpentOutputs, BlockSpentOutputs, &BlockSpentOutputs::Count, &BlockSpentOutputs::GetTxSpentOutputs, *this)
|
||||
};
|
||||
|
||||
class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
|
||||
{
|
||||
public:
|
||||
@@ -831,6 +930,11 @@ public:
|
||||
if (!block) return std::nullopt;
|
||||
return block;
|
||||
}
|
||||
|
||||
BlockSpentOutputs ReadBlockSpentOutputs(const BlockTreeEntry& entry) const
|
||||
{
|
||||
return btck_block_spent_outputs_read(get(), entry.get());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace btck
|
||||
|
||||
Reference in New Issue
Block a user